天天看點

UBOOT之start.s分析

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的空間配置設定如下:

UBOOT之start.s分析

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