備註:本文中使用的u-boot版本是2010.3
第一階段:初始化soc相關的配置,例如:系統時鐘、mmu、看門狗等;並為c語言提供執行環境
1、第一階段:組合語言階段.globl _start1.1進入管理模式_start: b reset //復位異常 --> 進入管理模式:復位電平有效時觸發
ldr pc, _undefined_instruction //未定義指令異常 --> 未定義指令模式:cpu無法識別的指令時觸發
ldr pc, _software_interrupt //軟中斷異常 -->管理模式:swi指令觸發
ldr pc, _prefetch_abort //預取指令異常 -->中止模式:獲取指令不存在時觸發
ldr pc, _data_abort //資料異常 --> 中止模式:獲取資料不存在時觸發
ldr pc, _not_used //保留位
ldr pc, _irq //中斷異常 -->irq模式
ldr pc, _fiq //快速中斷異常 -->fiq模式
當cpu上電時,復位電平有效,cpu當做是復位異常處理,因此在此異常向量表中將執行一下指令,使得進入管理模式(supervisor):
b reset
reset:
/* * set the cpu to svc32 mode and irq & fiq disable
*/mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
1.2 關閉資料cache 和 mmu為什麼要關閉資料cache呢,這是因為在裝置剛上電的時候,記憶體的初始化會比較慢,當cpu初始化完成後,
記憶體此時還沒做好準備,如果此時對記憶體進行資料讀取,會導致資料預取異常。
為什麼要關閉mmu?在裝置剛上電時,mmu並為初始化;其次,在會組合語言階段一般是通過操作暫存器的實際實體地址
進行配置。因此為了避免mmu的干擾,把其給遮蔽。
1.3 lowlevel_init
跳轉至符號標籤『lowlevel_init』,關閉看門狗、對系統時鐘、sdram等進行初始:
bl system_clock_init //系統時鐘初始化
bl mem_ctrl_asm_init_ddr3 //初始化ddr3
bl uart_asm_init //初始化串列埠
/* 初始化串列埠會先後列印『o』、『k』 兩個字元 */
/* print 'o' */
ldr r1, =0x4f4f4f4f
str r1, [r0, #utxh_offset]
/* print 'k' */
ldr r0, =elfin_uart_console_base
ldr r1, =0x4b4b4b4b
str r1, [r0, #utxh_offset]
1.4 重定位mmu_table:
…….set __base,0x400
//實體地址
// 512mb for sdram with cacheable
.rept 0x600 - 0x400
//虛擬位址範圍
fl_section_entry __base,3,0,1,1
.set __base,__base+1
.endr
……
1.5 初始化c語言執行環境
初始化棧stack_setup:為c語言提供執行環境
清除bss段:bss段用於存放初始化值為0的全域性變數和未初始化的全域性變數;並將未初始化的全域性變數初始化為0,這也是為什麼在c語言中為什麼乙個未初始化全域性變數其值為0的原因。
跳轉到c語言執行階段:start_armboot
stack_setup:
ldr sp, =(cfg_uboot_base + cfg_uboot_size - 0x1000)
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
movr2, #0x00000000 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
addr0, r0, #4
cmp r0, r1
ble clbss_l
ldr pc, _start_armboot //將pc指標指向start_armboot函式的位址
_start_armboot:
.word start_armboot
2、第二階段:c語言階段
c語言的啟動階段的啟動函式:start_armboot,在該函式中中實現了板子相關的初始化配置
重要結構:init_sequence指標陣列,包含了板級初始化的相關函式,以下列出了函式的呼叫關係和功能:
start_armboot:
init_sequence指標陣列
board_init,板級相關的初始化(board/samsung/smdkc210),例如網絡卡驅動
interrupt_init,中斷相關的初始化
env_init,環境變數相關的初始化
init_baudrate,波特率初始化
serial_init,串列埠初始化
console_init_f,控制台第一階段初始化
display_banner,列印uboot相關的資訊
print_cpuinfo,列印cpu相關的資訊
checkboard,列印開發板相關的資訊
dram_init,配置可用記憶體大小
display_dram_config,顯示記憶體大小函式:
env_relocate (),初始化環境變數
enable_interrupts,啟動中斷
main_loop:根據啟動延時進行判斷,是進入啟動kernel階段,還是進行u-boot命令解析控制台
2.1 命令解析、並將引數傳遞給kernel
main_loop函式:通過呼叫run_command函式,執行命令解析
void main_loop (void)
……for (;;)
}
下面列出了解析名後的函式呼叫關係:
run_command-->(cmdtp->cmd) (cmdtp, flag, argc, argv):『s = getenv ("bootcmd")』-->do_bootm函式
do_bootm
do_bootm_linux<-->boot_fn(0, argc, argv, &images)(typedef 型別重新命名)
do_bootm_linux:
thekernel = (void (*)(int, int, uint))images->ep;//指向kernel的起始位址
thekernel(0,machid,bd->bi_boot_params);//將3個引數傳分別寫入暫存器r0,r1,r2傳遞給kernel
u boot 啟動過程
u boot 分為兩個階段第一階段是彙編,入口是 arch arm cpu armv7 start.s,第二階段是 c 語言,入 口是 board.c 第一階段 1.異常向量表定義 2.設定 svc32 模式 arm 七種工作模式 3.呼叫 cpu init crit 進行 cpu 相關初始化 1 ...
u boot啟動過程 1
u boot的啟動過程 1.start.s檔案 此彙編檔案是u boot啟動的第乙個檔案,首先確定是冷啟動還是熱啟動,boot cold or boot warm 通過對r21寫0x01 cold or ox02 warm 完成。接著在boot warm中 1 判斷是否定義config cogent...
u boot 原始碼分析 1 啟動過程分析
kbuild 啟動過程 第二階段 總結參考 對於uboot,我一直是雲裡霧裡的乙個狀態,這部分讓我感到自己很菜,不用縱向深入地掌握uboot整個細節,但是相對它有乙個整體流程上的把握,包括uboot的啟動啟動過程,在整個啟動過程中會涉及到哪些檔案,以此的呼叫過程是什麼?抱著這幾個問題,大量蒐集資料,...