lowlevel_init.s是中最重要的就是包含了lowlevel_init函式的實現部分,而lowlevel_init是start.中很重要的乙個函式。
ldr sp, =0xd0036000 /* end of sram dedicated to u-boot */
sub sp, sp, #12 /* set stack */
mov fp, #0
bl lowlevel_init /* go setup pll,mux,memory */
在start.s中第一次設定棧就是用來執行這個函式。
檢查復位的狀態:檢查的原因是硬體的復位分為好幾種狀態,除了真正按下復位按鍵進行硬體的復位這種成為冷啟動外,還存在熱啟動與睡眠狀態,所以在這裡確定我們的復位狀態到底是哪種情況。
/* check reset status */
ldr r0, =(elfin_clock_power_base+rst_stat_offset)
ldr r1, [r0]
bic r1, r1, #0xfff6ffff
cmp r1, #0x10000
beq wakeup_reset_pre
cmp r1, #0x80000
beq wakeup_reset_from_didle
io狀態的復位;
/* io retention release */
ldr r0, =(elfin_clock_power_base + others_offset)
ldr r1, [r0]
ldr r2, =io_ret_rel
orr r1, r1, r2
str r1, [r0]
關閉看門狗;
/* disable watchdog */
ldr r0, =elfin_watchdog_base /* 0xe2700000 */
mov r1, #0
str r1, [r0]
sram與srom中一些io口的設定;
/* sram(2mb) init for smdkc110 */
/* gpj1 srom_addr_16to21 */
ldr r0, =elfin_gpio_base
ldr r1, [r0, #gpj1con_offset]
bic r1, r1, #0xffffff
ldr r2, =0x444444
orr r1, r1, r2
str r1, [r0, #gpj1con_offset]
ldr r1, [r0, #gpj1pud_offset]
ldr r2, =0x3ff
bic r1, r1, r2
str r1, [r0, #gpj1pud_offset]
/* ps_hold pin(gph0_0) set to high */
ldr r0, =(elfin_clock_power_base + ps_hold_control_offset)
ldr r1, [r0]
orr r1, r1, #0x300
orr r1, r1, #0x1
str r1, [r0]
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 */
說到這裡就不得不再說說uboot的啟動過程了:
硬體在上電啟動也就是冷啟動後,會先執行固化在srom中的bl0階段的啟動**。而uboot在啟動時將自己分割成兩部分:bl1和bl2階段。bl1階段通常為uboot的前8kb**,bl2階段包含uboot的整段**。bl0階段執行完會第一階段的**到sram中進行執行,然後bl1階段的**執行,進行dram(ddr)的初始化等一些其他的初始化操作,最後引導第二階段bl2(其實也就是整個uboot)在dram中執行,進行進一步的初始化。
這樣一來,在dram中不僅放著bl1階段的**也放著bl2階段的**。在熱啟動或者是休眠轉態被喚醒時不必再在從啟動介質中拷貝bl1階段的**進行執行,可以直接在dram中執行uboot的整包程式。
經過當前執行位址與之前makefile中設定的_text_base進行比對,得知當前的執行環境是否在dram中,不是的話則說明程式執行在iram中,則需要進行時鐘的初始化,dram的初始化:
/* init system clock */
bl system_clock_init
/* memory initialize */
bl mem_ctrl_asm_init
實際分析可以知道:uboot中規定的可用的實體地址範圍為:0x30000000-0x4fffffff,一共512mb,其中30000000-3fffffff為dram0,40000000-4fffffff為dram1。
如果是是執行在dram中的話再進行下面串列埠的初始化:
/* for uart */
bl uart_asm_init
串列埠在初始化完之後會列印出'o',與後面再次列印的'k'組合成ok,是uboot啟動時最早列印出來的東西。
pop
end.... uboot移植(四) uboot啟動第一階段
1 bl0 bl1 bl2分別是什麼 1 bl0 s5pv210的irom中固化的 作用 初始化系統時鐘,設定看門狗,初始化棧,載入bl1 2 bl1 從外部啟動介質 nand sd卡 中載入的uboot.bin的前16k 作用 初始化ram,關閉cache,初始化ddr,設定棧,載入bl2 3 b...
uboot啟動第二階段之x load分析
開發板 dm3730 虛擬機器 ubuntu 14.04 編譯器 arm none linux gnueabi x loader 這幾天小小的研究了一下linux的啟動機制 所裡這裡做個小小的總結吧 現在一般的晶元的linux啟動機制是這樣的 上電自執行romcode也就是在rom裡固化的 romc...
u boot啟動流程 第一階段
具體分析參見另一篇blog 第一階段的啟動在.cpu arm920t start.s檔案中完成,之後執行c程式,對硬體進行更細緻的初始化操作 硬體初始化 設定svc模式 關閉watch dog 禁止irq 設定時鐘 fclk hclk pclk 禁止i cache d cache 禁止mmu和cac...