reset: mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr,r0
#ifndef CONFIG_SKIP_LOWLEVEL_INIT blcpu_init_crit //此函數就在start.s中 #endif
cpu_init_crit: 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
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, #0x00000002 @ set bit 1 (--A-) Align orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB mcr p15, 0, r0, c1, c0, 0
mov ip, lr @ persevere link reg across call bllowlevel_init @闆級初始化 mov lr, ip @ restore link mov pc, lr @ back to my caller
lowlevel_init做的主要工作就是關閉看門狗,關閉中斷,初始化時鐘,初始化DDR,初始化序列槽,如果定義了CONFIG_NAND,還會初始化nand控制器,初始化安全域控制器。此函數在lowlevel_init.S檔案中,該檔案目錄為: board/廠家名/闆名/,如 :board/samsung/smdkc100/lowlevel_init.S
主要由以下幾個函數組成: bl system_clock_init 初始化時鐘 bl mem_ctrl_asm_init 初始化DDR bl uart_asm_init 初始化序列槽 bl tzpc_init 初始化安全域 #if defined(CONFIG_NAND) bl nand_asm_init 簡單初始化NAND #endif 對于以上函數不做詳細說明,對照資料手冊可自己更改。 以上函數全在lowlevel_init.S中,但注意 mem_ctrl_asm_init 可能不在 lowlevel_init.S中,而在 mem_setup.S檔案中,此檔案與 lowlevel_init.S在一個目錄中。
relocate: @ relocate U-Boot to RAM adr r0, _start @ r0 <- current position of code ldr r1, _TEXT_BASE @ test if we run from flash or RAM cmp r0, r1 @ don't reloc during debug beq stack_setup
ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 @ r2 <- size of armboot add r2, r0, r2 @ r2 <- source end address
copy_loop: @ copy 32 bytes at a time ldmia r0!, {r3 - r10} @ copy from source address [r0] stmia r1!, {r3 - r10} @ copy to target address [r1] cmp r0, r2 @ until source end addreee [r2] ble copy_loop #endif
其實這個段重定位代碼是将片内IRAM中的代碼搬移到DDR中。而我們通常是要将NAND中的資料搬移到DDR中,是以上面這段搬移代碼可以忽略,自己寫一個從NAND搬移資料到DDR的函數,放在此處。可以用C語言寫,但注意一定要是位置無關碼,因為此時我們的程式還運作在IRAM中,實際運作位址與連結位址不符。用C語言寫位置無關碼時,要全部使用局部變量。
ldr sp,=(0x22000000) bl copy_uboot_to_ram copy_uboot_to_ram函數便是一個從nand搬移代碼到DDR的C語言函數,具體自己實作。
_TEXT_BASE: .wordTEXT_BASE _TEXT_BASE這個變量定義在start.S中,TEXT_BASE在連結腳本中定義
stack_setup: ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ) #endif sub sp, r0, #12 @ leave 3 words for abort-stack and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d
以上這段代碼主要為環境變量,動态記憶體malloc,全局結構體變量gd_t配置設定空間。以及設定了一個absort棧。配置設定空間後,uboot的空間配置設定如下:
CONFIG_SYS_MALLOC_LEN CONFIG_SYS_GBL_DATA_SIZE 以上兩個值在include/autoconf.mk中定義
clear_bss: ldr r0, _bss_start @ find start of bss segment ldr r1, _bss_end @ stop here mov r2, #0x00000000 @ clear value clbss_l: str r2, [r0] @ clear BSS location cmp r0, r1 @ are we at the end yet add r0, r0, #4 @ increment clear index pointer bne clbss_l @ keep clearing till at end
以上這段代碼主要的作用為清除BSS段
ldr pc, _start_armboot 跳到C函數,此函數在lib_arm/Board.c中定義,注:此時uboot才從片内ram跳轉到了DDR2