uboot移植 uboot啟動回顧

2021-09-20 13:59:42 字數 4144 閱讀 6778

一: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...