色偷偷偷久久伊人大杳蕉,色爽交视频免费观看,欧美扒开腿做爽爽爽a片,欧美孕交alscan巨交xxx,日日碰狠狠躁久久躁蜜桃

x
x

基于cortex-A8的Bootloader設(shè)計(jì)

發(fā)布時(shí)間:2015-5-7 14:29    發(fā)布者:designapp

            隨著整個(gè)微電子行業(yè)日新月異的發(fā)展,ARM處理器已經(jīng)帶給了人們?cè)絹碓蕉嗟捏@喜。目前它憑借著自身高性能,低成本,低功耗等特點(diǎn),已經(jīng)廣泛應(yīng)用于消費(fèi)電子、數(shù)字家電、及工業(yè)生產(chǎn)等領(lǐng)域中。ARM公司推出的新一代cortex系列產(chǎn)品為開發(fā)人員提供了更多不同層面的選擇。cortex-A8為cortex系列中的“A”系,屬于ARMV7架構(gòu),主要面向搭載操作系統(tǒng)的,高性能的應(yīng)用領(lǐng)域。Bootloader是系統(tǒng)上電后執(zhí)行的第一段代碼,其功能類似于電腦的BIOS。簡(jiǎn)單來說,Bootloader主要的工作有兩點(diǎn):其一是初始化底層硬件資源,為操作系統(tǒng)啟動(dòng)提供必要的環(huán)境;其二是從存儲(chǔ)設(shè)備中讀取操作系統(tǒng)鏡像并啟動(dòng)。但為了方便后期開發(fā),我們往往要為Bootloader添加其他的功能。如支持串口打印調(diào)試信息,支持nfs網(wǎng)絡(luò)下載,支持根文件系統(tǒng)燒寫等。本文以u(píng)-boot-2013.01為源碼包,設(shè)計(jì)和實(shí)現(xiàn)了一個(gè)基于s5pv210平臺(tái)的,功能齊全且高效穩(wěn)定的Bootloader。
1 硬件平臺(tái)
1.1 s5pv210簡(jiǎn)介
    s5pv210是三星公司推出的一款基于cortex-A8架構(gòu)的,高性能的應(yīng)用處理器。該處理器支持ARM V7指令集,具有32位內(nèi)部總線結(jié)構(gòu),主頻最高可達(dá)1GHz。另外該處理器還支持掛接LPDDR1、LPDDR2和DDR2類型的RAM,F(xiàn)lash方面可選擇Nand Flash,Nor Flash等。不僅如此,該處理器還提供了包括串口、LCD、IIC、SPI、USB、HDMI等豐富的外部接口資源。目前s5pv210以其高效的性能和卓越的圖形處理能力已經(jīng)廣泛的應(yīng)用于智能手機(jī)和平板電腦之中。
1.2 s5pv210的啟動(dòng)方式
    s5pv210支持多種啟動(dòng)方式,下圖為s5pv210啟動(dòng)的流程圖:
                     


圖1  s5pv210的啟動(dòng)流程

s5pv210的啟動(dòng)過程由BL0,BL1和BL2(BL為Bootloader的簡(jiǎn)稱)三部分代碼實(shí)現(xiàn),其中BL0在出廠時(shí)已經(jīng)被固化到64KB的iROM中。s5pv210上電后首先執(zhí)行BL0,該段代碼主要負(fù)責(zé)一些簡(jiǎn)單的初始化工作,如關(guān)看門狗,初始化ICache等。然后BL0會(huì)根據(jù)硬件設(shè)置判斷為何種方式啟動(dòng),并將BL1從啟動(dòng)設(shè)備(OneNand,Nand Flash,USB,UART,SD card等)拷貝到Internal SRAM的BL1區(qū)中。最后BL0會(huì)比較一個(gè)校驗(yàn)值,如果相等則跳轉(zhuǎn)到BL1中繼續(xù)執(zhí)行,否則轉(zhuǎn)入其他啟動(dòng)方式。該校驗(yàn)值存在BL1的頭部中,其大小為16字節(jié)。
開發(fā)人員一般會(huì)單獨(dú)編寫一個(gè)工具對(duì)BL1編譯出的二進(jìn)制文件添加頭部。其校驗(yàn)值(checksum)的計(jì)算方法如下:
...
a = Buf + SPL_HEADER_SIZE;   
for(i = 0, checksum = 0; i


       
2 軟件平臺(tái)  
2.1 U-Boot介紹
U-Boot(全稱Universal Boot Loader)是Bootloader的一種,其他常見的Bootloader還有RedBoot,vivi等。與之相比,U-Boot具有代碼開源,可靠性和擴(kuò)展性較高等優(yōu)點(diǎn)。另外,對(duì)于類似于Nand Flash、Nor Flash、網(wǎng)卡、LCD等硬件資源的,U-Boot已經(jīng)抽象出與硬件平臺(tái)無關(guān)的代碼作為設(shè)備驅(qū)動(dòng)源碼提供給開發(fā)者。對(duì)于與硬件平臺(tái)相關(guān)的代碼,U-Boot將其定義成宏,并保留到配置文件中。開發(fā)者往往只需要修改這些宏的值就能成功使用這些硬件資源,這讓我們的移植工作變得十分簡(jiǎn)單。
2.2 U-Boot中幾個(gè)比較重要的源文件
U-Boot的源碼包包含有上千個(gè)源文件,但經(jīng)過分析之后,可以找出如下幾個(gè)比較重要的源文件(括號(hào)中為該源文件所在源碼包的位置)。
(1)start.S(arch\arm\cpu\armv7\start.S)
    通過分析U-Boot的鏈接文件可以發(fā)現(xiàn),start.S是U-Boot上電后被執(zhí)行的第一個(gè)源文件。該源文件包括定義了異常向量入口,相關(guān)的全局變量,禁用L2緩存,關(guān)閉MMU等,之后跳轉(zhuǎn)到lowlevel_init()函數(shù)中繼續(xù)執(zhí)行。
(2)lowlevel_init.S(board\samsung\smdkv210\lowlevel_init.S)
     該源文件同樣用匯編代碼編寫,其中只定義了一個(gè)函數(shù)lowlevel_init()。該函數(shù)實(shí)現(xiàn)對(duì)平臺(tái)硬件資源的一系列初始化過程,包括關(guān)看門狗,初始化系統(tǒng)時(shí)鐘,內(nèi)存和串口。
(3)mem_setup.S(board\samsung\smdkv210)
    該源文件包含對(duì)內(nèi)存進(jìn)行初始化的匯編源碼。
(4)board.c(arch\arm\lib\board.c)
    該源文件是用C編寫的,主要實(shí)現(xiàn)了U-Boot第二階段啟動(dòng)過程。包括初始化環(huán)境變量,串口控制臺(tái),F(xiàn)lash和打印調(diào)試信息等,最后調(diào)用main_loop()函數(shù)。
(5)smdkv210.h(include\configs\Smdkv210.h)
s5pv210平臺(tái)的配置文件,該源文件定義了一些與CPU或者外設(shè)相關(guān)的參數(shù),這些參數(shù)都是用宏來定義的。
2.3 U-Boot啟動(dòng)的一般流程
2.3.1 第一階段初始化
U-Boot的啟動(dòng)過程分為兩個(gè)階段,第一個(gè)階段主要由匯編代碼實(shí)現(xiàn),負(fù)責(zé)對(duì)CPU及底層硬件資源的初始化。第二階段用C實(shí)現(xiàn),負(fù)責(zé)使能Flash,網(wǎng)卡和引導(dǎo)操作系統(tǒng)等。其第一階段流程如下圖所示:


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

U-Boot上電后首先會(huì)設(shè)置cpu為管理模式,禁用L1緩存,關(guān)閉MMU和清除caches。之后會(huì)調(diào)用底層初始化函數(shù)lowlevel_init()。該函數(shù)實(shí)現(xiàn)如下:
.globl lowlevel_init
lowlevel_init:
        push   {lr}
#if defined(CONFIG_SPL_BUILD)
        /* 初始化時(shí)鐘 */
        bl  system_clock_init
        /* 初始化內(nèi)存 */
        bl  mem_ctrl_asm_init
        /* 初始化串口 */
        bl  uart_asm_init
#endif
        pop    {pc}
上述代碼中system_clock_init(), mem_ctrl_asm_init(),uart_asm_init()這三個(gè)函數(shù)需要開發(fā)者結(jié)合具體硬件環(huán)境進(jìn)行修改和實(shí)現(xiàn)。
初始化完成之后,U-Boot會(huì)調(diào)用一個(gè)拷貝函數(shù)將BL2拷貝到內(nèi)存地址為0x3FF00000處,然后跳轉(zhuǎn)到該位置執(zhí)行BL2。在U-Boot中,BL1和BL2是基于相同的一些源文件編譯生成的。開發(fā)者在編寫代碼時(shí)需要使用預(yù)編譯宏CONFIG_SPL_BUILD來實(shí)現(xiàn)BL1和BL2不同的功能。其拷貝函數(shù)實(shí)現(xiàn)如下:
void copy_code_2_sdram_and_run(void)
{
        unsigned long ch;
        void (*u_boot)(void);  
        ch = *(volatile unsigned int *)(0xD0037488);  /* 根據(jù)該地址的值判斷傳輸通道 */
/* copy_bl2()函數(shù)不需要開發(fā)者去實(shí)現(xiàn),s5pv210在出廠時(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)(); /* 跳轉(zhuǎn)到該地址執(zhí)行 */
}
值得注意的是以上代碼中,copy_bl2()函數(shù)不需要開發(fā)者去實(shí)現(xiàn),s5pv210在出廠時(shí)已經(jīng)將該函數(shù)固化在了0xD0037F98地址處。其函數(shù)原型如下:
u32 (*copy_sd_mmc_to_mem)(u32 channel, u32 start_block, u16 block_size, u32 *trg, u32 init);
/*
參數(shù)介紹:
channel:通道數(shù)2或0,該值通過讀取0xD0037488地址上的值判斷。
start_block:從第幾個(gè)扇區(qū)開始拷貝,一個(gè)扇區(qū)為512byte。
block_size:拷貝多少個(gè)扇區(qū),這里拷貝512K
trg:目的地址:0x3FF00000, 即離內(nèi)存頂部1M的位置
init:是否需要初始化sd卡,寫0即可。
*/





       
2.3.2 第二階段初始化
U-Boot進(jìn)入第二階段后會(huì)首先聲明一個(gè)gd_t結(jié)構(gòu)體類型的指針指向內(nèi)存地址(0x40000000 - GD_SIZE)處。0x40000000為內(nèi)存結(jié)束地址,GD_SIZE為結(jié)構(gòu)體gd_t的大小。這樣相當(dāng)于在內(nèi)存最頂端分配了一段空間用于存放一個(gè)臨時(shí)結(jié)構(gòu)體gd_t。該結(jié)構(gòu)體在global_data.h中被定義,U-Boot用它來存儲(chǔ)所有的全局變量。之后U-Boot會(huì)調(diào)用board_init_f()和board_init_r()兩個(gè)函數(shù)進(jìn)一步對(duì)底板進(jìn)行初始化。
(1)board_init_f()
進(jìn)入board_init_f()之后,U-Boot首先設(shè)置之前分配的臨時(shí)結(jié)構(gòu)體,然后開始劃分內(nèi)存空間,其內(nèi)存分配示意圖如下:


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

從內(nèi)存分配狀態(tài)圖中我們可以看到,gd指針指向的臨時(shí)結(jié)構(gòu)體存放在內(nèi)存的最頂部。BL2代碼存放在內(nèi)存地址0x3ff00000處,即距離內(nèi)存頂部1M空間的位置。接下來依次分配malloc空間,bd_t結(jié)構(gòu)體空間和gd_t結(jié)構(gòu)體空間,并且重新設(shè)置棧。最后將臨時(shí)結(jié)構(gòu)體拷貝到id指針?biāo)赶虻奈恢谩oard_init_f()實(shí)現(xiàn)過程大致如下:
unsigned int board_init_f(ulong bootflag)
{
memset((void *)gd, 0, sizeof(gd_t));
...
設(shè)置gd結(jié)構(gòu)體;
...
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()負(fù)責(zé)對(duì)其他硬件資源進(jìn)行初始化。如網(wǎng)卡、Flash、MMC、中斷等。最后調(diào)用main_loop(),等待用戶輸入命令。




       
3 設(shè)計(jì)實(shí)現(xiàn)
3.1 支持Nand Flash讀寫
Nand Flash是嵌入式系統(tǒng)中重要的存儲(chǔ)設(shè)備,其儲(chǔ)存對(duì)象包括Bootloader本身,操作系統(tǒng)內(nèi)核,環(huán)境變量,根文件系統(tǒng)等,所以使能Nand Flash讀寫是U-Boot移植過程中必須完成的一個(gè)步驟。U-Boot中Nand Flash初始化函數(shù)調(diào)用關(guān)系為:
board_init_r()->nand_init()->nand_init_chip()->board_nand_init()。
board_nand_init()完成兩件事:(1)對(duì)s5pv210關(guān)于Nand Flash控制器的相關(guān)寄存器進(jìn)行設(shè)置。(2)對(duì)nand_chip結(jié)構(gòu)體進(jìn)行設(shè)置。我們需要設(shè)置的成員項(xiàng)有IO_ADDR_R,IO_ADDR_W,這兩個(gè)成員都指向地址0xB0E00010,即 Nand Flash控制器的數(shù)據(jù)寄存器的地址。另外還需要實(shí)現(xiàn)以下三個(gè)成員函數(shù):
① void (*select_chip)(struct mtd_info *mtd, int chip);
該函數(shù)實(shí)現(xiàn)Nand Flash設(shè)備選中或取消選中。
② void (*cmd_ctrl)(struct mtd_info *mtd, int dat, unsigned int ctrl);
該函數(shù)實(shí)現(xiàn)對(duì)Nand Flash發(fā)送命令或者地址。
③ int (*dev_ready)(struct mtd_info *mtd);
該函數(shù)實(shí)現(xiàn)檢測(cè)Nand Flash設(shè)備狀態(tài)。
最后將成員ecc.mode設(shè)置為NAND_ECC_SOFT,即ECC軟件校驗(yàn)。
配置文件中相應(yīng)的宏定義如下所示:
#define CONFIG_NAND_S5PV210   /* 告訴Makefile編譯Nand模塊 */
#define CONFIG_SYS_MAX_NAND_DEVICE    1   /* 指定設(shè)備數(shù)量 */
#define CONFIG_SYS_NAND_BASE     0xB0E00000    /* Nand Flash 控制器的基址 */
3.2 支持網(wǎng)卡
支持nfs或tftp網(wǎng)絡(luò)下載會(huì)極大的方便我們從Linux服務(wù)器上下載文件或鏡像到硬件平臺(tái)上。所以使能網(wǎng)卡在U-Boot移植過程中也顯得非常重要。以網(wǎng)卡dm9000為例,U-Boot已經(jīng)抽象出一套完整的關(guān)于dm9000的驅(qū)動(dòng)代碼(其源碼路徑為drivers\net\dm9000x.c)。用戶只需要根據(jù)具體的硬件電路配置相應(yīng)的宏即可。U-Boot中dm9000網(wǎng)卡初始化函數(shù)的調(diào)用關(guān)系為:
board_init_r()->eth_initialize()->board_eth_init()->dm9000_initialize()。
配置文件中相應(yīng)的宏定義如下所示:
#define CONFIG_DRIVER_DM9000     /* DM9000網(wǎng)卡模塊加入編譯 */
#define CONFIG_DM9000_BASE       (0x88001000)  /* 基地址 */
#define DM9000_IO                (CONFIG_DM9000_BASE)  /* IO口地址 */
#define DM9000_DATA              (CONFIG_DM9000_BASE + 0x300C)  /* 數(shù)據(jù)口地址 */
3.3.支持環(huán)境變量的保存和修改
為了方便用戶配置,U-Boot將一部分變量,如串口波特率、ip地址、內(nèi)核參數(shù)、啟動(dòng)命令等存在Flash或SD卡上,這部分?jǐn)?shù)據(jù)稱為環(huán)境變量。每次上電啟動(dòng)時(shí),U-Boot會(huì)檢查Flash或SD卡上是否存放有環(huán)境變量。如果有則將其讀取出來并使用,如果沒有就使用默認(rèn)的環(huán)境變量。默認(rèn)的環(huán)境變量定義在env_default.h中。用戶也可以隨時(shí)修改或保存環(huán)境變量到Flash或SD卡中。
對(duì)于環(huán)境變量的移植也非常簡(jiǎn)單。以Nand Flash為例,開發(fā)人員在smdkv210.h源文件中只需要添加如下的宏定義即可:
#define CONFIG_ENV_IS_IN_NAND          /* 告訴Makefile環(huán)境變量保存在Nand Flash中 */
#define CONFIG_ENV_OFFSET           0x80000  /* 環(huán)境變量保存的Nand Flash中的偏移地址 */
#define CONFIG_ENV_SIZE             0x20000   /* 環(huán)境變量的大小 */
#define CONFIG_ENV_OVERWRITE       /* 規(guī)定環(huán)境變量和覆蓋 */




       
4. 測(cè)試結(jié)果
4.1. 測(cè)試U-Boot啟動(dòng)
測(cè)試平臺(tái)的軟硬件環(huán)境:
◆ 硬件平臺(tái)為友善之臂的smart210開發(fā)板;
◆ Linux服務(wù)器版本為ubuntu9.0;
◆ U-Boot版本為2013-01;
◆ GCC交叉編譯工具鏈版本為4.3.2。
首先將修改后的源碼包放到裝有交叉編譯工具鏈的Linux服務(wù)器上,輸入命令make即可以編譯生成兩個(gè)二進(jìn)制文件。一個(gè)是smdkv210-spl.bin,即BL1代碼,存放在spl目錄下。另一個(gè)是u-boot.bin,即BL2代碼,存放在頂層目錄下。然后插入SD卡,執(zhí)行write2sd.sh腳本就可以把BL1和BL2分別燒寫到SD卡的第1扇區(qū)和第49扇區(qū)。write2sd.sh腳本實(shí)現(xiàn)如下:
#!/bin/sh
sudo dd iflag=dsync oflag=dsync if=spl/smdkv210-spl.bin of=/dev/sdc seek=1
sudo dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdc seek=49
燒寫完成之后將SD卡插入到smart210開發(fā)板的SD卡槽中,連接好串口和網(wǎng)線,上電啟動(dòng)。之后可以通過串口工具(本次測(cè)試使用的是SecureCRT)看到輸出信息如圖四所示,表示該U-Boot已經(jīng)成功運(yùn)行在開發(fā)板上。


圖四  測(cè)試U-Boot啟動(dòng)

  
4.2 測(cè)試Nand Flash和網(wǎng)卡。
在等待命令狀態(tài)下輸入“nfs 20000000 192.168.1.123:/work/nfs_root/uImage”,該命令表示從ip為192.168.1.123的Linux服務(wù)器上,通過nfs下載該服務(wù)器上“/work/nfs_root”目錄下的uImage,并存放在內(nèi)存地址為0x20000000處。uImage為適配于s5pv210開發(fā)板的Linux內(nèi)核鏡像。等待一段時(shí)間后看到“Bytes transferred = 2127008 (2074a0 hex)”字樣,表示下載成功。
下載成功之后輸入命令“nand erase.part kernel”,該命令表示擦除Nand Flash上的kernel分區(qū)。接著輸入命令“nand write 20000000 kernel”,該命令表示拷貝內(nèi)存地址為0x20000000的內(nèi)容,燒寫到Nand Flash的kernel分區(qū)中。內(nèi)存地址0x20000000存放的內(nèi)容正是之前我們從Linux服務(wù)器上下載下來的uImage。kernel保存在環(huán)境變量mtdparts中,kernel規(guī)定了該分區(qū)的起始地址和大小。執(zhí)行完這兩條命令后看到“4194304 bytes written: OK”字樣,表示系統(tǒng)內(nèi)核已經(jīng)成功燒寫到Nand Flash中,證明了Nand Flash和網(wǎng)卡均可以正常使用。其實(shí)驗(yàn)結(jié)果如圖五所示:
           


圖五  測(cè)試Nand Flash和網(wǎng)卡

4.3 測(cè)試引導(dǎo)內(nèi)核啟動(dòng)
燒寫完內(nèi)核之后執(zhí)行boot命令就可以啟動(dòng)該內(nèi)核。boot命令實(shí)際上是執(zhí)行環(huán)境變量bootcmd中的一條語(yǔ)句,其內(nèi)容為“nand read 20000000 kernel; bootm 20000000”,該語(yǔ)句表示從Nand Flash的kernel分區(qū)中讀出內(nèi)核并存放在內(nèi)存地址為0x20000000處,然后跳轉(zhuǎn)在該地址執(zhí)行內(nèi)核鏡像。啟動(dòng)過程中可以看到串口打印出如圖六所示的信息,證明了該U-Boot已經(jīng)成功支持引導(dǎo)Linux操作系統(tǒng)。


圖六   測(cè)試引導(dǎo)內(nèi)核啟動(dòng)

結(jié)語(yǔ)
本文從硬件,軟件兩個(gè)方面分析了s5pv210的特性及啟動(dòng)方式,然后通過u-boot-2013.01源碼包詳細(xì)闡述了U-Boot啟動(dòng)過程中的兩個(gè)階段,最后結(jié)合smart210開發(fā)板成功設(shè)計(jì)了一個(gè)基于SD卡啟動(dòng)的,多功能的Bootloader。測(cè)試結(jié)果表明該Bootloader支持Nand Flash 讀寫,nfs網(wǎng)絡(luò)下載,環(huán)境變量保存和修改等功能,為后期開發(fā)帶來了極大的便利。



本文地址:http://m.54549.cn/thread-148983-1-1.html     【打印本頁(yè)】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點(diǎn)和對(duì)其真實(shí)性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時(shí)間更正或刪除。
您需要登錄后才可以發(fā)表評(píng)論 登錄 | 立即注冊(cè)

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號(hào) | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表