<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 基于cortex-A8的Bootloader設計

基于cortex-A8的Bootloader設計

作者: 時(shí)間:2016-09-12 來(lái)源:網(wǎng)絡(luò ) 收藏

圖2  U-Boot第一階段啟動(dòng)流程

圖2 U-Boot第一階段啟動(dòng)流程

U-Boot上電后首先會(huì )設置cpu為管理模式,禁用L1緩存,關(guān)閉MMU和清除caches。之后會(huì )調用底層初始化函數lowlevel_init()。該函數實(shí)現如下:

.globl lowlevel_init

lowlevel_init:

push {lr}

#if defined(CONFIG_SPL_BUILD)

/* 初始化時(shí)鐘 */

bl system_clock_init

/* 初始化內存 */

bl mem_ctrl_asm_init

/* 初始化串口 */

bl uart_asm_init

#endif

pop {pc}

上述代碼中system_clock_init(), mem_ctrl_asm_init(),uart_asm_init()這三個(gè)函數需要開(kāi)發(fā)者結合具體硬件環(huán)境進(jìn)行修改和實(shí)現。

初始化完成之后,U-Boot會(huì )調用一個(gè)拷貝函數將BL2拷貝到內存地址為0x3FF00000處,然后跳轉到該位置執行BL2。在U-Boot中,BL1 和BL2是基于相同的一些源文件編譯生成的。開(kāi)發(fā)者在編寫(xiě)代碼時(shí)需要使用預編譯宏CONFIG_SPL_BUILD來(lái)實(shí)現BL1和BL2不同的功能。其拷貝函數實(shí)現如下:

void copy_code_2_sdram_and_run(void)

{

unsigned long ch;

void (*u_boot)(void);

ch = *(volatile unsigned int *)(0xD0037488); /* 根據該地址的值判斷傳輸通道 */

/* copy_bl2()函數不需要開(kāi)發(fā)者去實(shí)現,在出廠(chǎng)時(shí)已經(jīng)固化在了0xD0037F98地址處 */

copy_sd_mmc_to_mem copy_bl2 = (copy_sd_mmc_to_mem) (*(unsigned int *) (0xD0037F98));

unsigned int ret;

if (ch == 0xEB000000) { /* CONFIG_SYS_TEXT_BASE = 0x3FF00000 */

ret = copy_bl2(0, 49, 1024,(unsigned int *)CONFIG_SYS_TEXT_BASE, 0);

} else if (ch == 0xEB200000) {

ret = copy_bl2(2, 49, 1024,(unsigned int *)CONFIG_SYS_TEXT_BASE, 0);

} else {

return;

}

u_boot = (void *)CONFIG_SYS_TEXT_BASE;

(*u_boot)(); /* 跳轉到該地址執行 */

}

值得注意的是以上代碼中,copy_bl2()函數不需要開(kāi)發(fā)者去實(shí)現,在出廠(chǎng)時(shí)已經(jīng)將該函數固化在了0xD0037F98地址處。其函數原型如下:

u32 (*copy_sd_mmc_to_mem)(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);

/*

參數介紹:

channel:通道數2或0,該值通過(guò)讀取0xD0037488地址上的值判斷。

start_block:從第幾個(gè)扇區開(kāi)始拷貝,一個(gè)扇區為512byte。

block_size:拷貝多少個(gè)扇區,這里拷貝512K

trg:目的地址:0x3FF00000, 即離內存頂部1M的位置

init:是否需要初始化sd卡,寫(xiě)0即可。

*/

2.3.2 第二階段初始化

U-Boot進(jìn)入第二階段后會(huì )首先聲明一個(gè)gd_t結構體類(lèi)型的指針指向內存地址(0x40000000 - GD_SIZE)處。0x40000000為內存結束地址,GD_SIZE為結構體gd_t的大小。這樣相當于在內存最頂端分配了一段空間用于存放一個(gè)臨時(shí)結構體gd_t。該結構體在global_data.h中被定義,U-Boot用它來(lái)存儲所有的全局變量。之后U-Boot會(huì )調用 board_init_f()和board_init_r()兩個(gè)函數進(jìn)一步對底板進(jìn)行初始化。

(1)board_init_f()

進(jìn)入board_init_f()之后,U-Boot首先設置之前分配的臨時(shí)結構體,然后開(kāi)始劃分內存空間,其內存分配示意圖如下:

圖3  U-Boot內存分配狀態(tài)

圖3 U-Boot內存分配狀態(tài)

從內存分配狀態(tài)圖中我們可以看到,gd指針指向的臨時(shí)結構體存放在內存的最頂部。BL2代碼存放在內存地址0x3ff00000處,即距離內存頂部1M空間的位置。接下來(lái)依次分配malloc空間,bd_t結構體空間和gd_t結構體空間,并且重新設置棧。最后將臨時(shí)結構體拷貝到id指針所指向的位置。 board_init_f()實(shí)現過(guò)程大致如下:

unsigned int board_init_f(ulong bootflag)

{

memset((void *)gd, 0, sizeof(gd_t));

...

設置gd結構體;

...

addr = CONFIG_SYS_TEXT_BASE; /* CONFIG_SYS_TEXT_BASE = 0x3ff00000000 */

addr_sp = addr - TOTAL_MALLOC_LEN;

addr_sp -= sizeof (bd_t);

bd = (bd_t *) addr_sp;

gd->bd = bd;

addr_sp -= sizeof (gd_t);

id = (gd_t *) addr_sp;

...

memcpy(id, (void *)gd, sizeof(gd_t));

base_sp = addr_sp;

return (unsigned int)id;

}

(2)board_init_r()

board_init_r()負責對其他硬件資源進(jìn)行初始化。如網(wǎng)卡、Flash、MMC、中斷等。最后調用main_loop(),等待用戶(hù)輸入命令。

3 設計實(shí)現

3.1 支持Nand Flash讀寫(xiě)

Nand Flash是嵌入式系統中重要的存儲設備,其儲存對象包括Bootloader本身,操作系統內核,環(huán)境變量,根文件系統等,所以使能Nand Flash讀寫(xiě)是U-Boot移植過(guò)程中必須完成的一個(gè)步驟。U-Boot中Nand Flash初始化函數調用關(guān)系為:

board_init_r()->nand_init()->nand_init_chip()->board_nand_init()。

board_nand_init() 完成兩件事:(1)對關(guān)于Nand Flash控制器的相關(guān)寄存器進(jìn)行設置。(2)對nand_chip結構體進(jìn)行設置。我們需要設置的成員項有IO_ADDR_R,IO_ADDR_W,這兩個(gè)成員都指向地址0xB0E00010,即 Nand Flash控制器的數據寄存器的地址。另外還需要實(shí)現以下三個(gè)成員函數:

① void (*select_chip)(struct mtd_info *mtd, int chip);

該函數實(shí)現Nand Flash設備選中或取消選中。

② void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);



關(guān)鍵詞: cortext-A8 Bootloader設計 s5pv210

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>