開發板上電後,執行U-Boot的第一條指令,然後順序執行U-Boot啟動函數。函數調用。
看一下board/smsk2410/u-boot.lds這個連結指令碼,可以知道目標程式的各部分連結順序。第一個要連結的是cpu/arm920t/start.o,那麼U-boot的入口指令一定位於這個程式中。下面分析一下程式跳轉和函數調用關係以及函數實現。
1. cpu/arm920t/start.S
這個組譯工具是U-Boot的入口程式,開頭就是複位向量的代碼。
U-Boot啟動代碼流程圖
_start: breset//複位向量<br />ldrpc, _undefined_instruction<br />ldrpc, _software_instruction<br />ldrpc, _prefetch_abort<br />ldrpc, _data_abort<br />ldrpc, _not_used<br />ldrpc, _irq//中斷向量<br />ldrpc, _fiq//中斷向量<br />...<br />/* the actual reset code */<br />reset://複位啟動子程式<br />/* 設定CPU為SVC32模式 */<br />mrsr0, cpsr<br />bicr0, r0, #0x1f<br />orrr0, r0, #0xd3<br />msrcpsr, r0<br />/* 關閉看門狗 */<br />/* 這些初始化代碼在系統重啟的時候執行,運行時熱複位從RAM中啟動不執行 */<br />#ifdef CONFIG_INIT_CRITICAL<br />blcpu_init_crit<br />#endif<br />relocate:/* 把U-Boot重新置放到RAM */<br />adrr0, _start/* r0是當前代碼的位置 */<br />ldrr1, _TEXT_BASE/* 測試判斷是從Flash啟動,還是RAM */<br />cmpr0, r1/* 比較r0和r1, 調試的時候不要執行重新置放 */<br />beqstack_setup/* 如果r0等於r1, 跳過重定位代碼 */<br />/* 準備重新置放代碼 */<br />ldr r2, _armboot_start<br />ldrr3, _bss_start<br />subr2, r3, r2 /* r2得到armboot的大小 */<br />addr2, r0, r2/* r2得到要複製代碼的末尾地址 */<br />copy_loop: /* 重新置放代碼 */<br />ldmiar0!, {r3-r10}/* 從源地址[r0]複製 */<br />stmid r1!, {r3-r10}/* 複製到目的地址[r1] */<br />cmpr0, r2/* 複製資料區塊直到來源資料末尾地址[r2] */<br />ble copy_loop<br />/* 初始化堆棧等 */<br />stack_setup:<br />ldrr0, _TEXT_BASE /* 上面是126KiB 重定位的u-boot */<br />subr0, r0, #CFG_MALLOC_LEN /* 向下是記憶體配置空間 */<br />subr0, r0, #CFG_GBL_DATA_SIZE /* 然後是bdinfo結構體地址空間 */<br />#ifdef CONFIG_USE_IRQ<br />subr0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)<br />#endif<br />subsp, r0, #12/* 為abort-stack預留3個字 */<br />clear_bss:<br />ldrr0, _bss_start/* 找到bss段起始地址 */<br />ldrr1, _bss_end/* bss段末尾地址 */<br />movr2, #0x00000000/* 清零 */<br />clbss_l:str r2, [r0]/* bss段地址空間清零迴圈 */<br />add r0, r2, #4<br />cmp r0, r1<br />bne clbss_l<br />/* 跳轉到start_armboot函數入口,_start_armboot字儲存函數入口指標 */<br />ldr pc, _start_armboot<br />_start_armboot: .word start_armboot //start_armboot函數在lib_arm/board.c中實現<br />/* 關鍵的初始化子程式 */<br />cpu_init_crit:<br />...// 初始化CACHE,關閉MMU等操作指令<br />/* 初始化RAM時鐘<br /> * 因為記憶體時鐘是依賴開發板硬體的,所以在board的相應目錄下可以找到memsetup.S檔案<br />*/<br />mov ip, lr<br />blmemsetup//memsetup子程式在board/smdk2410/memsetup.S中實現<br />mov lr, ip<br />mov pc, lr<br />