U-Bootが第一段階の開始します

サムスンに基づくExynos 4412

リンクのu-ブートからU-boot.ldsスクリプトは、我々はこれが開始start.sからの文書をまとめたものです知っているので、U-bootブートの第一段階と、確かにここから、CPUでこのファイル/ arm_cortexa9 /フォルダ次回、文書によると、U-bootブートの最初のフェーズの段階の分析でのステップをしましょう。

#include <config.h>
#include <version.h>
#if defined(CONFIG_ENABLE_MMU)
#include <asm/proc/domain.h>
#endif
#if defined(CONFIG_S5PV310)
#include <s5pv310.h>
#endif
#if defined(CONFIG_S5PC210)
#include <s5pc210.h>
#endif

上記のコードは、必要なヘッダファイルを含んでいます。

    .word 0x2000
    .word 0x0
    .word 0x0
    .word 0x0

プログラム16バイトのヘッダパリティの冒頭で定義Ubootスペースを埋める、ブロックのヘッダチェックサム値は、後に書き込まれます。

.globl _start
_start: b   reset
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq
    ldr pc, _fiq

_undefined_instruction:
    .word undefined_instruction
_software_interrupt:
    .word software_interrupt
_prefetch_abort:
    .word prefetch_abort
_data_abort:
    .word data_abort
_not_used:
    .word not_used
_irq:
    .word irq
_fiq:
    .word fiq

割り込みベクタテーブルの定義は、ここでは、リセットラベルを参照してください、それは同じ場所に任意の他のベクターの割り込みベクタテーブルのようではありませんが、ジャンプスタートによって達成します。ここでは、リセットを分析します

#if 0
    /*
     * set the cpu to SVC32 mode and IRQ & FIQ disable
     */
    mrs r0, cpsr
    bic r0, r0, #0x3f
    orr r0, r0, #0xd3
    msr cpsr, r0
#else//*****ly
    mrs r0, cpsr
    bic r0, r0, #0x1f
    orr r0, r0, #0xd3
    msr cpsr,r0
#endif

上記のコードは、CPUの動作モード管理モードを設定し、遮蔽IRQおよびFIQ割り込みます。

#if 1 //*****ly
cache_init:
    mrc p15, 0, r0, c0, c0, 0   @ read main ID register
    and r1, r0, #0x00f00000 @ variant
    and r2, r0, #0x0000000f @ revision
    orr r2, r2, r1, lsr #20-4   @ combine variant and revision
    cmp r2, #0x30
    mrceq   p15, 0, r0, c1, c0, 1   @ read ACTLR
    orreq   r0, r0, #0x6        @ Enable DP1(2), DP2(1)
    mcreq   p15, 0, r0, c1, c0, 1   @ write ACTLR
    /*
     * Invalidate L1 I/D
     */
    mov r0, #0          @ set up for MCR
    mcr p15, 0, r0, c8, c7, 0   @ invalidate TLBs
    mcr p15, 0, r0, c7, c5, 0   @ invalidate icache

    /*
     * disable MMU stuff and caches
     */
    mrc p15, 0, r0, c1, c0, 0
    bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
    bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
    orr r0, r0, #0x00001000 @ set bit 12 (---I) Icache
    orr r0, r0, #0x00000002 @ set bit 1  (--A-) Align
    orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
    mcr p15, 0, r0, c1, c0, 0
#endif

閉じるキャッシュとMMU、キャッシュとMMUをコプロセッサCP15によって管理され、そうするCP15は、適切なレジスタに設定されています

    /* Read booting information */
    ldr r0, =POWER_BASE
    ldr r1, [r0,#OMR_OFFSET]
    bic r2, r1, #0xffffffc1

    cmp     r2, #0xA
    moveq   r3, #BOOT_ONENAND

    /* SD/MMC BOOT */
    cmp     r2, #0x4
        moveq   r3, #BOOT_MMCSD 

    /* eMMC4.3 BOOT */
    cmp     r2, #0x6
    moveq   r3, #BOOT_EMMC43

    /* eMMC441 BOOT */
    cmp     r2, #0x28
    moveq   r3, #BOOT_EMMC441
    
    ldr r0, =INF_REG_BASE
    str r3, [r0, #INF_REG3_OFFSET]   

メディアが最初から開始されるかを決定するためにブート情報を読み込み

    bl  lowlevel_init   /* go setup pll,mux,memory */

ボードは、このフォルダ内に配置されるので、それは、開発ボードに関連しているので、我々は、lowlevel_initを入力してくださいここで初期lowlevel_initへジャンプ

lowlevel_init:
#if 1//*****ly
    /* use iROM stack in bl2 */
    ldr sp, =0x02060000
#endif
    push    {lr}

    /* check reset status  */
    ldr     r0, =(INF_REG_BASE + INF_REG1_OFFSET)
        ldr     r1, [r0]

    /* AFTR wakeup reset */
    ldr r2, =S5P_CHECK_DIDLE
    cmp r1, r2
    beq exit_wakeup

    /* Sleep wakeup reset */
    ldr r2, =S5P_CHECK_SLEEP
    cmp r1, r2
    beq wakeup_reset

        /* PS-Hold high */
        ldr r0, =0x1002330c
        ldr r1, [r0]
        orr r1, r1, #0x300
        str r1, [r0]

        ldr     r0, =0x11000c08
        ldr r1, =0x0
        str r1, [r0]

        /* Clear  MASK_WDT_RESET_REQUEST  */
        ldr r0, =0x1002040c
        ldr r1, =0x00
        str r1, [r0]
        
#ifdef check_mem /*liyang 20110822*/
    /* when we already run in ram, we don't need to relocate U-Boot.
     * and actually, memory controller must be configured before U-Boot
     * is running in ram.
     */
    ldr r0, =0xff000fff
    bic r1, pc, r0      /* r0 <- current base addr of code */
    ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */
    bic r2, r2, r0      /* r0 <- current base addr of code */
    cmp     r1, r2                  /* compare r0, r1                  */
    beq     1f          /* r0 == r1 then skip sdram init   */
#endif
    /* add by cym 20130218 */
    /* init system clock */
    bl system_clock_init_scp
    
    /* Memory initialize */
    bl mem_ctrl_asm_init_ddr3

    /* end add */
    

    bl tzpc_init
    
    b   1f
    1:

#ifdef CONFIG_EVT1___
    /* store DMC density information in DRAM */
    /* mem_ctrl_asm_init returns dmc_density in r6 */
    ldr r0, =CFG_UBOOT_BASE
    sub r0, r0, #4
    str r6, [r0]
#endif
#if 0 //test for mt6620 turn off GPC1(0)
    /*wenpin.cui: headphone and sw uart switch init*/
    ldr r0, =0x11000C44
    ldr r1, [r0]
    and r1, r1, #0x4    
    cmp r1, #0x4    /*uart*/    
    beq out 

    ldr     r0, =0x11400084  /* GPC1(0)  */
    ldr     r1, [r0]    /* read GPC1DAT status*/
    orr r1, r1, #0x1    /* GPC1(0) output high  */
    str     r1, [r0]

    ldr     r0, =0x11400080  /* GPC1(0)  */
    ldr r1, [r0]
    and r1, r1, #0xfffffff0
    orr     r1, r1, #0x1    /* GPC1(0) output  */
    str     r1, [r0]
#endif
out:
    /* for UART */
    bl uart_asm_init

それが関係している主なもの:(U-ブートがメモリ内にすでにある場合は、次の3つのステップをスキップし、)メモリ内のコードかどうかを判断するために、システムクロックの初期化、メモリの初期化、tzpcの初期化、および最終的にはシリアルポートの初期化、スタートに戻って.Sファイル

    ldr r0, =0x1002330C  /* PS_HOLD_CONTROL register */
    ldr r1, =0x00005300  /* PS_HOLD output high */
    str r1, [r0]

開発ボードの電源がラッチ提供します

    /* get ready to call C functions */
    ldr sp, _TEXT_PHY_BASE  /* setup temp stack pointer */
    sub sp, sp, #12
    mov fp, #0          /* no previous frame, so fp=0 */

メモリ機能Cの次のセットのためにスタック

    ldr r0, =0xff000fff
    bic r1, pc, r0      /* r0 <- current base addr of code */
    ldr r2, _TEXT_BASE      /* r1 <- original base addr in ram */
    bic r2, r2, r0      /* r0 <- current base addr of code */
    cmp     r1, r2                  /* compare r0, r1                  */
    beq     after_copy      /* r0 == r1 then skip flash copy   */

現在のコードは、SDRAMで実行されている場合はSDRAMの現在のコードが実行されるかどうかの決定、コードの再配置はスキップされます。

    ldr r0, =INF_REG_BASE
    ldr r1, [r0, #INF_REG3_OFFSET]
    cmp r1, #BOOT_NAND      /* 0x0 => boot device is nand */
    beq     nand_boot
    
    cmp r1, #BOOT_ONENAND   /* 0x1 => boot device is onenand */
    beq     onenand_boot
    
    cmp     r1, #BOOT_EMMC441
    beq     emmc441_boot
    
    cmp     r1, #BOOT_EMMC43
    beq     emmc_boot
    
    cmp     r1, #BOOT_MMCSD
    beq     mmcsd_boot
    
    cmp     r1, #BOOT_NOR
    beq     nor_boot
    
    cmp     r1, #BOOT_SEC_DEV
    beq     mmcsd_boot

審判の起動モード

nand_boot:
    mov r0, #0x1000
    bl  copy_from_nand
    b   after_copy

onenand_boot:
    bl  onenand_bl2_copy  /*goto 0x1010*/
    b   after_copy
//ly
second_mmcsd_boot:
    ldr   r3, =BOOT_MMCSD   
    ldr r0, =INF_REG_BASE
    str r3, [r0, #INF_REG3_OFFSET]
    
mmcsd_boot:
#ifdef CONFIG_CLK_1000_400_200
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS2_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0xf
    str r1, [r0, r2]
#endif
    bl      movi_uboot_copy
    b       after_copy

emmc_boot:
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS1_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0x3
    str r1, [r0, r2]
#endif
    bl      emmc_uboot_copy
    b   after_copy

emmc441_boot:
#if defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
    ldr r0, =CMU_BASE
    ldr r2, =CLK_DIV_FSYS3_OFFSET
    ldr r1, [r0, r2]
    orr r1, r1, #0x3
    str r1, [r0, r2]
#endif
    bl      emmc441_uboot_copy
//ly 20110824
    ldr   r0, =0x43e00000
    ldr   r1, [r0]
    ldr   r2, =0x2000
    cmp r1, r2
    bne  second_mmcsd_boot
    b   after_copy


nor_boot:
@   bl  read_hword
    b   after_copy

異なるブートブートコードに対応して、コードのこの部分は、U-ブートがメモリにない実行された場合にのみことに注意してください

#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
    /* enable domain access */
    ldr r5, =0x0000ffff
    mcr p15, 0, r5, c3, c0, 0       @load domain access register

    /* Set the TTB register */
    ldr r0, _mmu_table_base
    ldr r1, =CFG_PHY_UBOOT_BASE
    ldr r2, =0xfff00000
    bic r0, r0, r2
    orr r1, r0, r1
    mcr p15, 0, r1, c2, c0, 0

    /* Enable the MMU */
mmu_on:
    mrc p15, 0, r0, c1, c0, 0
    orr r0, r0, #1
    mcr p15, 0, r0, c1, c0, 0
    nop
    nop
    nop
    nop
#endif

MMUを有効に設定MMU、

stack_setup:
#if defined(CONFIG_MEMORY_UPPER_CODE)
    ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)
#else
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area                      */
    sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
#if defined(CONFIG_USE_IRQ)
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub sp, r0, #12     /* leave 3 words for abort-stack    */

#endif

メモリ内のスタックメモリ全体の利用計画、適切な場所を設定することにより

clear_bss:
    ldr r0, _bss_start      /* find start of bss segment        */
    ldr r1, _bss_end        /* stop here                        */
    mov     r2, #0x00000000     /* clear                            */

clbss_l:
    str r2, [r0]        /* clear loop...                    */
    add r0, r0, #4
    cmp r0, r1
    ble clbss_l
    
    ldr pc, _start_armboot

_start_armboot:
    .word start_armboot

クリアBSSセクション、start_armbootの実行にジャンプ、U-bootの最初のフェーズが完了し起動します。

何を、U-ブート物事は何をすべきかの最初のフェーズ以下要約したものです。

  1. 提供される例外ベクタ(例外ベクタ)
  2. 閉じるIRQ、FIQ、SVCモードの設定
  3. クローズキャッシュ、MMU
  4. 起動モードを決定します
  5. lowlevel_init(主にシステム・クロック、SDRAMの初期化、シリアルポートの初期化等を初期化します)
  6. 開発ボードの電源がラッチ提供します
  7. セットメモリスタック
  8. EMMCにメモリからコピーUboot
  9. 設定とオープンMMU
  10. メモリ内のスタックメモリ全体の利用計画、適切な場所を設定することにより
  11. クリアBSSセクション、U-bootの第一段階を実行し、start_armbootに遠くジャンプを実行します

おすすめ

転載: www.cnblogs.com/YinShijia/p/12021621.html