一:uboot啟動的第一階段start.s(路徑uboot/cpu/s5pc11x/start.s)
1:#include //標頭檔案包含,config.**件原始碼中不存
在,配置後自動生成;路徑/include/linux/config.h;
2:#include //標頭檔案包含,version.**件原始碼中不存
在,配置後自動生成;路徑/include/version.h;
3:#include //標頭檔案包含,asm/proc是鏈結
符號,實際指向include/asm-arm/proc-armv/domain.h;
4:填充uboot的前16位元組,為後面的crc校驗佔位;
5:構建異常向量表,但uboot中並沒有設定異常處理,發生異常時重
啟即可;
6:balignl 16,0xdeadbeef 記憶體對齊,如果不對齊則用0xdeadbeef進行填充;
7:復位函式,通過msr命令來操作cp15協處理器的後8位,設定為svc模式;
8:l2cache設定相關;關閉mmu;
9:讀取ompin引腳的電平高低來判斷啟動方式(sd卡 nand等);
10:第一次設定棧,因為這個時候ddr還沒有被初始化,所以這次設定棧是在sdram中;
11:lowlevel_init函式;
(1)check reset status :檢查cpu復位狀態(熱上電,睡眠模式喚醒不需要初始化ddr;冷上電需要初始化ddr);
(2) io retention release :復位後io口的儲存與恢復;
(3)disable watchdog :關看門狗;
(4)ps_hold pin(gph0_0) set to high :設定開發板供電鎖存
(5)判斷當前**執行的位置是在sdram還是ddr中,主要思路是通過
bic將當前pc位置和_text_base(uboot在ddr的起始位址)的高8位和
低12位清零,比較剩下的中間12位是否相等,如果相等,則在當前代
碼則在ddr中執行,如果不相等,則當前**在sdram中執行;在ddr中
執行則不需要初始化時鐘和ddr,在sdram中執行則需要初始化時鐘和
ddr;
(6)串列埠初始化,並列印出'ok',ok是乙個中間的檢查標誌,如果沒
有看到ok則代表是lowlevel_init函式之前出了問題,如果列印了ok則
代表是lowlevel_init後面出了問題;
12:set ps_hold signal to high :再次設定開發板供電鎖存
13:get ready to call c functions:第二次設定棧,在ddr中,位
置是0x33e00000;
14:判斷當前**執行位置是在ddr還是sdram,如果在sdram則完成重
定位,將bl2(整個uboot)複製到鏈結位址33e00000處
15:開啟mmu,進行虛擬位址對映;
16:第三次設定棧,目的是為了使棧更加安全,記憶體使用合理,位址
是0x33e00000+2m-1k;
17:clear_bss: 清bss段;
18:ldr pc, _start_armboot 短跳轉到start_armboot函式,進行
uboot啟動的第二階段;
二:uboot啟動的第二階段start_armboot()函式(路徑 uboot/lib_arm/board.c)
1:gd bd位址的設定:gd在ddr中的位置33e00000+2m-912k-512k,bd
在gd下面,緊挨著;gd是乙個結構體指標,放在暫存器r8中,gd所指
向的結構體中存放的都是一些全域性變數gd->bd也是乙個結構體裡面存
放著bi_baudrate 波特率(開發板的波特率);
bi_ip_addr ip位址; bi_enetaddr mac位址; bi_arch_number
機器碼;
bi_boot_params 將來給核心傳參的引數的存放位址0x30000010
struct
bi_dram[config_nr_dram_banks];ddr的起始位址和大小;
2:通過乙個for迴圈來遍歷init_sequence函式指標陣列中的指標,最
後通過判斷最後乙個函式是不是null來跳出這個迴圈
(1)cpu_init:乙個空函式,返回0
(2)reloc_init
(3)board_init:初始化網絡卡(dm9000),獲取機器碼
bi_arch_number 和分配bi_boot_params的記憶體位址;
(4)interrupt_init:初始化定時器4,設定10ms定時,用於
bootdelay ;
(5)env_init:環境變數的設定;
(6)init_baudrate:初始化波特率(控制台的波特率,數值上和開
發板的波特率相等);
(7)serial_init:初始化串列埠,串列埠在第一階段start.s 中就已經
初始化了,所以這個函式什麼也沒做;
(8)console_init_f:控制台初始化的第一階段,在uboot中沒有用
到控制台,而是直接呼叫串列埠傳送函式puts();
(9)display_banner:列印uboot的版本資訊,也就是我們在主
makefile設定的uboot的版本號;
(10)print_cpuinfo:初始化時鐘;
(11)checkboard:列印開發板資訊 ,board: x210;
(12)init_func_i2c:這裡沒使用i2c,所以這個函式實際沒起作
用;(13)dram_init():gd-bd.bi_dram結構體內各個變數的賦值,也就
是每片ddr的起始位址和大小;
(14)display_dram_config:列印ddr的配置資訊;
3:mem_malloc_init (cfg_uboot_base + cfg_uboot_size -
cfg_malloc_len - cfg_stack_size); 分配堆空間,
33e00000+2m-896k-512k
4:#if defined(config_x210):不同開發板獨有的初始化,我們是
x210,所以執行這個條件編譯。這裡面主要是初始化mmc控制器,並打
印sd/mmc 的大小;
5:env_relocate();環境變數的重定位,將sd卡中的環境變數讀取到
ddr中,需要注意的是第一次啟動uboot的時候sd卡時沒有env分割槽,而
是使用uboot內部硬編碼的一套環境變數,然後寫到sd卡中。
6:gd->bd->bi_ip_addr = getenv_ipaddr ("ipaddr"); 獲取開發板
的ip位址,這個ip位址在x210_sd.h中有定義,並通過gd->bd來維護
(下面是mac位址,同ip一樣)
7:devices_init();裝置初始化;
8:jumptable_init();跳轉表初始化,因為這裡的跳轉表只被賦值,
而沒有被引用,所以並無實際作用;
9:console_init_r ();控制台初始化的第二階段,控制台初始化的主
要部分都在第二階段完成;
10:enable_interrupts();中斷初始化,這裡是cpsr暫存器中總中斷
標誌位的使能,但是由於uboot中並沒有使用到中斷所以這個函式並沒
實際作用;
11:loadaddr;bootfile;這兩個環境變數都是核心啟動相關的環境變
量;12:board_late_init (); 開發板級別的晚期初始化,也是最後的初
始化,實際是乙個空函式;
13:x210_preboot_init();x210開發板在啟動起來之前的初始化,主
要是led的初始化和logo的顯示;
14:check menukey to update from sd :uboot提供了一種方便的刷
機方式,當我們需要公升級系統時,只需要將系統燒錄到sd卡的相應扇
區,在啟動時按下left按鍵,便可實現簡便地公升級系統;
15:for (;;) //死迴圈 輸入命令 解析命令
輸入命令 解析命令.... ;
uboot啟動第二階段結束
u boot移植詳解 初識u boot
u boot是一種普遍用於嵌入式系統中的bootloader。bootloader是基於特定硬體平台來實現的,因此幾乎不可能為所有的嵌入式系統建立乙個通用的bootloader,不同的處理器架構都有不同的bootloader,bootloader不但依賴於cpu的體系結構,還依賴於嵌入式系統板級裝置...
uboot移植之uboot和kernel的引數傳遞
從uboot啟動核心的形式thekernel 0,machid,bd bi boot params 可以看出uboot給核心傳遞了3個引數,第1個是0,第2個是機器碼,第3個是引數列表在sdram的起始位置 剛好滿足一下呼叫核心的條件 r0 0。r1 機器型別id r2 啟動引數標記列表在ram 中...
uboot移植記錄
首先是uboot移植記錄系列。這系列文章適合於uboot移植的初學者,這裡基於常見的開發平台s3c2410。若需要移植uboot到乙個全新開發板,則需要參考更多的資料並對uboot有更深入的了解。本人對此也有所鑽研,也有個較牛的同事專門做這這個的,呵呵 若感興趣的朋友大家可以一起 因此關於新平台ub...