IMX6 uboot的啟動流程


網上看了后,做了個記錄,主要是一個流程,具體代碼沒有分析,有空再細看。

cpu在上電之后,它們會干些什么?

答:檢查電壓大小,確定啟動模式等。

簡單的檢查之后呢?

答:一般從固化在cpu內部的rom里面執行一小段code。這一小段code具體做了些什么呢?各個cpu廠商會不同,具體我也不知道。

但是我們應該知道,這小段code必須完成確認啟動模式,並初始化啟動設備,搬移燒錄在啟動設備里面的代碼到ddr里面。

ok,搬移了代碼后,cpu如何識別代碼?將doc,txt文件燒進去行么?

答:當然不行,燒錄的文件也是有格式要求的。

格式在哪里定呢?稍等,先要知道生成的uboot.bin文件需要有個指導文件,就是uboot.lds,它的作用是在編譯過程中,決定各個可執行程序段的位置。

其代碼如下:

 1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
 2 OUTPUT_ARCH(arm)
 3 ENTRY(_start)
 4 SECTIONS
 5 {
 6     . = 0x00000000;
 7 
 8     . = ALIGN(4);
 9     .text       :
10     {
11       /* WARNING - the following is hand-optimized to fit within    */
12       /* the sector layout of our flash chips!    XXX FIXME XXX    */
13       board/freescale/mx6q_sabreauto/flash_header.o    (.text.flasheader)
14       cpu/arm_cortexa8/start.o
15       board/freescale/mx6q_sabreauto/libmx6q_sabreauto.a    (.text)
16       lib_arm/libarm.a        (.text)
17       net/libnet.a            (.text)
18       drivers/mtd/libmtd.a        (.text)
19       drivers/mmc/libmmc.a        (.text)
20 
21       . = DEFINED(env_offset) ? env_offset : .;
22       common/env_embedded.o(.text)
23 
24       *(.text)
25     }
26 
27     . = ALIGN(4);
28     .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
29 
30     . = ALIGN(4);
31     .data : { *(.data) }
32 
33     . = ALIGN(4);
34     .got : { *(.got) }
35 
36     . = .;
37     __u_boot_cmd_start = .;
38     .u_boot_cmd : { *(.u_boot_cmd) }
39     __u_boot_cmd_end = .;
40 
41     . = ALIGN(4);
42     _end_of_copy = .; /* end_of ROM copy code here */
43     __bss_start = .;
44     .bss : { *(.bss) }
45     _end = .;
46 }
View Code

代碼咱不分析,只看 

.text    :
 {
   /* WARNING - the following is hand-optimized to fit within */
   /* the sector layout of our flash chips! XXX FIXME XXX */
   board/freescale/mx6q_sabreauto/flash_header.o (.text.flasheader)

......

它的第一要存儲的文件是flash_header的內容。回到主題,cpu如何識別代碼?在第一個存儲的文件里面,必須要有特定的格式。這里稱作:IVT(image vector table)結構體。

good,cpu通過這個結構體規定的順序來執行。其定義如下:(網上摘錄)

header
entry: Absolute address of the first instruction to execute from the image
reserved1: Reserved and should be zero
dcd: Absolute address of the image DCD. The DCD is optional so this field may be set to NULL if no DCD is required. See
Device Configuration Data (DCD) for further details on DCD.
boot data: Absolute address of the Boot Data
self: Absolute address of the IVT. Used internally by the ROM
csf: Absolute address of Command Sequence File (CSF) used by the HAB library. See High Assurance Boot (HAB) for
details on secure boot using HAB. This field must be set to NULL when not performing a secure boot
reserved2: Reserved and should be zero

我們關心以下幾個:
entry: 入口函數,在程序中指定,如:ENTRY(_start)
dcd: Device Configuration Data, 設備配置數據,用來配置設備的。因為剛上電,設備的參數都是默認的,不能達到最優效果,甚至有些設備不進行初始化根本就無法工作。
那怎么辦呢?就需要在使用這些設備之前,進行一些設置,如內存等等。
dcd中可以設置如下這些東東:
Address range                                      Start address       Last Address
IOMUX Control (IOMUXC) registers     0x020E0000        0x020E3FFF
CCM register set                                   0x020C4000        0x020C7FFF
ANADIG registers                                 0x020C8000        0x020C8FFF
MMDC register set                                0x021B0000        0x021B7FFF
IRAM Free Space                                 0x00907000        0x00937FF0
EIM                                                       0x08000000        0x0FFEFFFF
DDR                                                      0x10000000        0xFFFFFFFF

////////////////////////////////////////////////////////////////////////////////////////////////////

ok,既然知道了cpu要執行的順序,那我們來看看這是個什么順序,打開flash_header.S

 1 .section ".text.flasheader", "x"
 2     b    _start
 3     .org    CONFIG_FLASH_HEADER_OFFSET
 4 
 5 ivt_header:       .word 0x402000D1 /* Tag=0xD1, Len=0x0020, Ver=0x40 */
 6 app_code_jump_v:  .word _start
 7 reserv1:          .word 0x0
 8 dcd_ptr:          .word dcd_hdr
 9 boot_data_ptr:      .word boot_data
10 self_ptr:         .word ivt_header
11 #ifdef CONFIG_SECURE_BOOT
12 app_code_csf:     .word __hab_data
13 #else
14 app_code_csf:     .word 0x0
15 #endif
16 reserv2:          .word 0x0
17 
18 boot_data:        .word TEXT_BASE
19 #ifdef CONFIG_SECURE_BOOT
20 image_len:        .word __hab_data_end - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
21 #else
22 image_len:        .word _end_of_copy  - TEXT_BASE + CONFIG_FLASH_HEADER_OFFSET
23 #endif
24 plugin:           .word 0x0

dcd的配置在dcd_ptr:          .word dcd_hdr。uboot首先就要通過這個地址段來配置和優化ddr。
boot_data_ptr:      .word boot_data啟動代碼放置的地方及大小。

app_code_jump_v:  .word _start  第一個執行的函數。

以上文件大多在:/board/freescale/mx6q_sabresd/ 目錄下。

 

 

 

羅里吧嗦那么多,自己都有點亂了,艹,其實就是一個uboot.bin文件要被識別,必須在其文件頭的地方,有一個正確的格式。就這樣!然后根據這個格式,開啟我們的啟動之旅吧。

第一階段:start.S    /cpu/arm_cortexa8/start.S

主要完成定義入口地址、設置異常向量、設置CPU的頻率、初始化內存控制器、加載Uboot第二階段代碼代碼到RAM、初始化堆棧、跳轉到RAM運行第二階段程序。

第二階段:lib_arm/board.c中的start_armboot是第二階段開始的代碼,其主要完成系統內核、中斷、時鍾、接口、設備包括FLASH、DISPLAY、網絡等的初始化,並進入命令循環,接收用戶命令后完成相應的工作。

在第二階段的main_loop函數中,根據設置的參數,可在uboot環境下調試或調轉到內核。具體可以網上參考。main_loop-->run_command-->do_bootm_linux.

大概就是這個流程,代碼沒分析,見諒!

參照:

http://blog.csdn.net/njuitjf/article/details/20563867

http://blog.csdn.net/sz_zh/article/details/7930341

謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM