《電子技術(shù)應用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設計應用 > Uboot在S3C2440上的移植
Uboot在S3C2440上的移植
來源:微型機與應用2010年第24期
盧 偉, 潘 煉
(武漢科技大學 信息科學與工程學院自動化系,湖北 武漢434200)
摘要: 通過分析Uboot的文件結(jié)構(gòu)及其啟動流程,,詳細給出了Uboot在基于ARM920T開發(fā)板上的移植方案,,包括編譯、調(diào)試全過程,,最終能夠在Uboot命令方式下加載映像文件,,完成Linux內(nèi)核與yaffs映像文件的調(diào)試,,具有Bootloader移植的通用性。
Abstract:
Key words :

摘   要: 通過分析Uboot的文件結(jié)構(gòu)及其啟動流程,,詳細給出了Uboot在基于ARM920T開發(fā)板上的移植方案,,包括編譯、調(diào)試全過程,,最終能夠在Uboot命令方式下加載映像文件,,完成Linux內(nèi)核與yaffs映像文件的調(diào)試,具有Bootloader移植的通用性,。
關鍵詞: Uboot; S3C2440; ARM920T; 引導過程; 啟動代碼

1 Uboot移植環(huán)境準備
1.1 移植平臺的硬件組成

 硬件平臺是ARM9的體系結(jié)構(gòu),,ARM920T的CPU, SOC芯片是三星的S3C2440,,支持Nand Flash與Nor Flash的可選啟動方式,,其主要硬件資源如表1所示[1]。

 支持Nand Flash與Nor Flash啟動,,可以通過跳線來選擇啟動方式,。Nand Flash啟動時,最開始4 KB數(shù)據(jù)被硬拷貝到內(nèi)部Boot Internal SRAM,且被映射到nGCS0的片選空間0x0000,0000—0x0800,0000,;Nor Flash方式啟動時,,它直接被映射到nGCS0的片選空間。所以,,在Uboot移植時,,要考慮將Uboot燒寫到Nor flash上還是Nand Flash上。
1.2 Uboot工作原理
    Uboot的整體結(jié)構(gòu)如圖1所示,。

  從圖1可以看出,,這種分層結(jié)構(gòu)的Uboot分模塊化了,給移植帶來了很大的方便,。由于協(xié)議層與應用層是與目標硬件無關的,,因此移植工作主要集中在物理層和驅(qū)動層上面的修改。而Uboot支持串口下載,、網(wǎng)絡下載,,并提供了很多交互式命令。整個Uboot編譯,、連接過程如下:
  (1)創(chuàng)建編譯環(huán)境
    在MAKEFILE中會調(diào)用根目錄下的mkconfig文件,,如下:
    MKCONFIG:= $(SRCTREE)/mkconfig
    qq2440v3_config:unconfig
     @$(MKCONFIG)$(@:_config=)arm ARM920T qq2440v3 NULL s3c24x0
    Mkconfig文件引用傳入的參數(shù)$1=qq2440v3、$2=arm,、$3=arm920t,、$4=qq2440v3、$5=NULL、$6=s3c24x0,,流程如圖2所示,。

    (2)編譯流程
  編譯流程如圖3所示。

    最終生成內(nèi)存映像圖文件U-boot.map和可執(zhí)行二進制映像elf文件U-boot[2],,可以直接將生成的U-boot下載到SDRAM來單步調(diào)試,。
2 Uboot的移植操作
2.1存儲器映射與存儲器重映射

    存儲器映射,實現(xiàn)了統(tǒng)一編址,,方便了程序在32 bit尋址(4 GB尋址空間)的范圍內(nèi)能夠?qū)ぶ返饺我獾奈锢泶鎯^(qū),。
    S3C2440芯片不帶片內(nèi)Flash,帶片內(nèi)4  KB的SRAM,,被映射到了0x4000_0000~0x4000_1000的地址空間,外部的SDRAM被映射到bank6,網(wǎng)卡被映射到bank3,,F(xiàn)lash被映射到bank0。
    由于Uboot是上電后就運行,,因此需要將代碼定位在Flash從0x0000_0000的上電入口處,。為了提高系統(tǒng)加載速度并且實現(xiàn)在線編程功能,需要將整個Uboot從Flash中搬到RAM運行,即代碼從定位,,將整個代碼定位到SDRAM的0x3300_0000之后,來作為其實際的運行地址,,具體如圖4所示。

2.2 配置主機運行環(huán)境
    Uboot與Linux系統(tǒng)密切相關,,筆者在RH Linux的虛擬機中搭建了整個運行環(huán)境,,采用的是2.2.4的Linux內(nèi)核,arm-linux-gcc-3.4.1的交叉編譯工具[3],,需要在/root/.bashrc文件中做一下交叉編譯工具路徑的聲明,,即加上如下一句:
     export PATH=$PATH:/usr/local/arm/3.4.1/bin
     保存并退出,在終端下輸入“arm-linux-gcc-version”并回車,,如果能看到輸出版本信息為3.4.1,則代表路徑設置正確,,交叉編譯工具鏈已經(jīng)成功安裝,。
2.3 修改CPU相關代碼
    在調(diào)試Uboot時,如果每次都將二進制映像燒錄到Flash中,,不僅需要等待,,而且操作麻煩,本文是在調(diào)試階段將二進制映像直接燒錄到外部存儲器SDRAM中,,然后直接從該處運行,,這樣直接在內(nèi)存中運行,可以很方便地完成Uboot調(diào)試,。
    Uboot啟動的第一階段,,從.\cpu\arm920t\start.s開始執(zhí)行,依次完成關閉看門狗、關閉中斷,、設置CPU分頻比,、初始化SDRAM、代碼重定位,、設置堆棧,,最后跳轉(zhuǎn)到C函數(shù)的入口點。當在SDRAM中調(diào)試時,,內(nèi)存的初始化已經(jīng)預先完成了,因此不需要初始化SDRAM和代碼重定位的功能,。
    在.\include\configs\qq2430.h添加宏定義define CONFIG_SKIP_LOWLEVEL_INIT,就會跳過cpu_init_crit處的初始化SDRAM函數(shù),,代碼如下所示:
    #ifndef CONFIG_SKIP_LOWLEVEL_INIT
    cpu_init_crit:
    …
    當Uboot在SDRAM中運行時,代碼的入口地址_start與代碼在SDRAM中重定位的地址_TEXT_BASE相同,,直接跳轉(zhuǎn)到堆棧初始化處stack_setup,跳過了代碼的Flash到RAM的搬運,。代碼如下所示:
      adr    r0, _start        
         ldr    r1, _TEXT_BASE    
         cmp r0, r1                 
         beq  stack_setup
2.4 添加平臺相關代碼
    從匯編跳轉(zhuǎn)到C程序的入口點start_armboot時,,即位于./Lib_arm/Board.c中的start_armboot函數(shù),通過函數(shù)初始化數(shù)組來依次完成CPU(cpu_init),、板級(board_init),、中斷(interrupt_init)、環(huán)境變量(env_init),、串口(serial_init),、波特率(init_buardrate)、顯示(disp_banner),、Flash初始化(nand_init),,每個初始化后返回不為0的值,否則永遠在死循環(huán)中掛起,,需要重新啟動開發(fā)板,。
2.4.1 鎖相環(huán)時鐘的配置
    在smdk2410開發(fā)板的基礎上修改。在./board/qq2440v3下新建qq2440v3.c,,并且將Uboot中的./board/smdk2410/smdk2410.c內(nèi)容全部復制給qq2440v3.c,。在include/configs下新建qq2440v3.h配置文件,同時將include/configs/smdk2410.h全部復制給qq2440v3.h,。因為S3C2440與S3C2410的最高運行速率不一樣,,系統(tǒng)時鐘設置也不一樣,即鎖相環(huán)配置有差異,,因此內(nèi)部總線的分頻比系數(shù)是不同的,。S3C2440可運行于400 MHz,而S3C2410則是200 MHz,,需要更改系統(tǒng)時鐘部分,,使其增加對S3C2440的支持,。
    鎖相環(huán)輸出的MPLL(fclk時鐘頻率寄存器)與UPLL(USB控制時鐘頻率寄存器)計算式如下:
    MPLL=(2*m*Fin)/(p*2^s)         /*鎖相環(huán)輸出fclk頻率
    UPLL=(m*Fin)/(p*2^s)      /*鎖相環(huán)輸出USB控制頻率
    m=M(the value for divider M)+8,p=P(the value for divider P)+2,s=S
    其中m、p,、s為鎖相環(huán)的預置值,,控制輸出頻率, Fin為晶振頻率12 MHz。通過下面的宏定義分別給M,、P,、S賦值0x5c、0x01,、0x01就能輕松完成時鐘配置,。
    #define S3C2440_MPLL_400 MHz ((0x5c<<12)|(0x01<<4)|(0x01))
    #define S3C2440_UPLL_48 MHz ((0x38<<12)|(0x02<<4)|(0x02))
    #define S3C2440_CLKDIV 0x05 /* FCLK:HCLK:PCLK= 1:4:8, UCLK = UPLL
2.4.2 串口的配置
    S3C2440帶有3個UART,用異步通用串口uart0與上位機通信。串口時鐘用pclk時鐘,,即1/2 hclk時鐘,,1/8 fclk時鐘(mpll時鐘),get_PCLK()函數(shù)返回pclk時鐘頻率,。串口0工作于中斷模式,,通過FIFO緩存收發(fā),沒有校驗位,,1位停止位,,通過設置ULCON0寄存器與UFCON0來配置。為了提高數(shù)據(jù)傳送的可靠性,,使用了錯誤接收中斷機制,,能夠檢測溢出錯誤、奇偶校驗錯誤和幀錯誤,,相關錯誤狀態(tài)保存在錯誤狀態(tài)寄存器UTRSTAT0的對應位中,。
    串口的波特率用115 200 b/s,通過給波特率除數(shù)寄存器UBRDIV0賦值,,能夠確定串行發(fā)送接收波特率,。計算公式如下:
    UBRDIVn=(int) (UART clock/(buad rate*16))-1;
    其中UART clock為pclk時鐘,,buard rate為115 200,。
2.5 編譯并調(diào)試
    為了在內(nèi)存中運行,先要把鏈接腳本文件./Board/qq2440v3/U-boot.lds中的程序初始化運行地址.=0x0000,0000改為.=0x3300,0000,以方便直接在RAM中運行,。在終端控制臺中先進入Uboot的根目錄,,然后執(zhí)行命令make qq2440v3_config,,通過make all來編譯和連接程序,。編譯沒有錯誤的情況下,會在Uboot的根目錄下生成u-boot,、u-boot.srec和u-boot.bin三個文件,,分別對應于ELF格式,、S-Record格式和二進制格式。
    直接使用JTAG燒寫二進制u-boot.bin到SDRAM的0x3300,0000處,,燒寫完成之后,,將pc的指針指向該處運行,會在串口終端上顯示板子的自檢信息,,并給出提示符等待用戶輸入命令,,如圖5所示。

3 Uboot從Flash中啟動
  S3C2440既支持從Nor Flash中啟動,,也支持從Nand Flash中啟動,。Nor Flash的地址線與數(shù)據(jù)線分開,方便代碼存取且速度很快,,上電復位時直接把Nor Flash映射到了0x0000,0000地址處,。但是Nand Flash數(shù)據(jù)線與地址線復用,運行速度慢,,為了提高Nand Flash啟動效率,,S3C2440芯片加入了一個特殊機制,會在上電復位時,把Nand Flash前4 KB代碼硬拷貝到內(nèi)部SRAM的4 KB空間,,然后將SRAM的4 KB空間映射到0x0000,0000處,,這樣直接在SRAM中啟動Uboot,節(jié)省了啟動時間,。
3.1 從Nor Flash中運行
3.1.1添加Nor Flash驅(qū)動

 board/qq2440v3/Flash.c中的驅(qū)動只支持Nor Flash的AMDLV400和AMDLV800兩種芯片,不支持本文板子上的AM29LV160,,更不支持Nand Flash,只能用CFI標準接口連接,,在/drivers/cfiflash.c中定義了該接口標準下的讀寫函數(shù)的具體實現(xiàn),。要調(diào)用該驅(qū)動,應在配置頭文件/include/configs/qq2440v3.h中添加CFI的宏定義:
    #define CFG_FLASH_CFI_DRIVER 1
    并在board/qq2440v3/Makefile中去掉原來的Nor flash驅(qū)動的編譯,,即:
    COBJS:= qq2440v3.o flash.o 變量中去掉flash.o的連接,。
3.1.2 SDRam初始化并實現(xiàn)代碼從定位
    Uboot在Nor Flash中啟動后,在start.s階段除了要完成必要的寄存器設置外,,還要完成SDRAM的初始化以及代碼從定位,,即把Flash空間的Uboot映像搬運到SDRAM高地址空間中,然后在SDRAM中運行Uboot,??梢灾苯訌腘or Flash啟動Uboot,但從Nand Flash啟動要實現(xiàn)重定位,,在這里就一起實現(xiàn)了,。
    首先在.\include\configs\qq2430.h中去掉剛才添加宏定義define CONFIG_SKIP_LOWLEVEL_INIT,則會在start.s階段進入cpu_init_crit函數(shù)以完成I/D caches設置以及禁止MMU,,隨后進入lowlevel_init完成內(nèi)存寄存器組的設置,,如SDRAM位寬,、刷新率等的初始化工作。
    在.\include\configs\qq2430.h中去掉CONFIG_SKIP_
RELOCATE_UBOOT的宏定義,來完成整個代碼的重定位[5],。
     Uboot代碼區(qū)的長度為_bss_start-_armboot_start,,其中_bss_start與_armboot_start變量保存的都是代碼段的起始地址與終止地址。_start+_bss_start-_armboot_start為代碼區(qū)結(jié)束的絕對地址,,通過地址絕對尋址來復制代碼區(qū)的數(shù)據(jù)到內(nèi)存中TEXT_BASE地址區(qū)域,,其中TEXT_BASE在.\Board\QQ2440v3\Config.mk中被賦值,即TEXT_BASE=0x33000000,,表示代碼重定位在SDRAM中的運行起始地址,。
3.1.3 編譯并調(diào)試
    Uboot已經(jīng)能夠成功在SDRAM中啟動運行了,為了能夠從Nor Flash中啟動,,需要做如下工作,。
    先要把鏈接腳本文件./Board/qq2440v3/U-boot.lds中的程序初始化運行地址.=0x3300,0000改為.=0x0000,0000,通過硬件開關選擇開機啟動方式為Nor Flash,,完成Nor Flash映射到0地址處,。然后在終端控制臺編譯連接,直到?jīng)]有錯誤,。通過HJTAG燒錄進Nor Flash里面,,開機運行后串口終端輸出界面如圖6所示。

3.2 從Nand Flash中運行
3.2.1添加Nand Flash驅(qū)動

    S3C2440支持從Nand Flash啟動,,考慮到移植的通用性,,對于沒有Nor Flash的板子,就需要從Nand Flash啟動,。在.\drivers目錄下有兩種Nand的驅(qū)動,,.\Nand和.\Nand_legacy兩種驅(qū)動可以選擇,其中.\Nand能夠自動識別很多型號的Nand Flash,,并且是更新版本,,因此選擇這種驅(qū)動。根據(jù)Nand.c中的
    #if(CONFIG_COMMANDS&CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
    #include <nand.h>
    條件編譯選擇Nand驅(qū)動,,首先在板級配置頭文件qq2440v3.h中的宏定義CONFIG_COMMAND中添加CFG_CMD_NAND,,并且不定義CFG_NAND_LEGACY。在start_armboot()函數(shù)中會對外設逐一初始化,,Nand初始化代碼如下:
    #ifdefined(CFG_MAX_NAND_DEVICE) nand_init;
    #endif
    需要在板級配置頭文件qq2440v3.h中宏定義CFG_MAX_NAND_DEVICE,,因為smdk2410開發(fā)板不支持Nand Flash,因此需要自己來編寫Nand Flash驅(qū)動函數(shù)board_nand_init來被nand_init以及nand_init_chip調(diào)用,,以完成Nand Flash的硬件初始化,,包括使能Nand Flash控制器、初始化ECC,、使能片選信號,、設置時序等。
3.2.2添加cmd命令
    為了豐富Nand與網(wǎng)卡功能,,還需要在配置文件中添加Nand與網(wǎng)卡相關命令來調(diào)用相關函數(shù),。在板級配置頭文件qq2440v3.h中的CONFIG_COMMANDS宏定義中以邏輯“或”的形式添加CFG_CMD_NAND與CFG_CMD_NET,這樣便可以通過命令方式實現(xiàn)Nand Flash的讀寫以及網(wǎng)絡下載功能,。
    Uboot的網(wǎng)絡功能很強大,,可以方便地通過TFTP引導或者是NFS引導內(nèi)核映像或者文件系統(tǒng)到SDRAM,然后直接go到此處執(zhí)行,,在SDRAM中調(diào)試完成后,,再將映像文件燒錄到Flash中,不僅調(diào)試方便,,而且還節(jié)省下載時間,。
3.2.3 編譯并調(diào)試
    編譯過程跟Nor Flash啟動一樣,最后串口輸出信息如圖7所示,。

    此時,,整個Uboot的移植就算完成了,由于支持串口跟網(wǎng)卡驅(qū)動,,可以很方便地用這個Uboot來通過網(wǎng)卡下載內(nèi)核映像與文件系統(tǒng)到Flash,,通過串口輸出信息調(diào)試Uboot。
4 Uboot引導Linux內(nèi)核
4.1 內(nèi)核啟動參數(shù)的傳遞

    Uboot在引導內(nèi)核啟動時,通過標記列表的方式向內(nèi)核傳遞啟動參數(shù),。這些啟動參數(shù)預先以環(huán)境變量的方式保存在Flash中,,在./Lib_arm/Board.c中的初始化環(huán)境變量函數(shù)env_init()初始化,下面的函數(shù)來實現(xiàn)向kernel跳轉(zhuǎn),。
    theKernel (0, bd->bi_arch_number, bd->bi_boot_params); thekernel其實不是個函數(shù),而是指向內(nèi)核入口地址的指針,,為0x30008000。這里把它強行轉(zhuǎn)化為帶三個參數(shù)的函數(shù)指針,,會把三個參數(shù)保存到通用寄存器中,實現(xiàn)了向kernel傳遞信息的功能,,R0賦值為0,R1賦值為機器號,,R2賦值為啟動參數(shù)數(shù)據(jù)結(jié)構(gòu)的首地址[6],。
   標記列表實際上是內(nèi)存中的結(jié)構(gòu)體組成的列表,在./Lib_arm/Armlinux.c中函數(shù)setup_start_tag()來創(chuàng)建標記列表,。
4.2 tftp加載內(nèi)核映像
 對于已經(jīng)編譯好了的內(nèi)核映像文件zImage,,其格式是ELF的可執(zhí)行文件,首先要把它轉(zhuǎn)化成U-boot格式的文件uImage,,實際是添加了一個header定義,,直接用tools目錄下的工具mkimage就可用實現(xiàn),具體在終端中執(zhí)行如下操作:
    ①arm-linux-objcopy -O binary -R .note -R .comment -S vmlinux linux.bin
  ②gzip -9 linux.bin
    ③mkimage -A arm -O linux -T kernel -C gzip -a 0x30008000 -e 0x30008040 -n "Linux Kernel Image" -d linux.bin.gz uImage
    先從內(nèi)核文件中提取二進制文件,,然后壓縮,,最后構(gòu)造文件頭信息,,包括名稱、大小,、類型,、CRC校驗碼等,添加的頭信息占用0x40大小空間,。完成后下載內(nèi)核映像uImage,,如下操作:
    開啟主機tftp服務,將uImage放置tftp目錄下,,然后啟動Uboot,,運行tftp下載,镲除,、燒寫Nand Flash,,具體如圖8所示。

    最后燒寫文件系統(tǒng)映像,,與燒寫內(nèi)核映像一樣,,先tftp下載到內(nèi)存,然后再燒寫,,不同類型的文件系統(tǒng)nand燒寫命令不一樣,,本文用到的是yaffs文件類型,則通過Nand write.yaffs 0x30000000 0x1d0000 $(filesize)命令來燒寫,。
    本文研究了Uboot在基于S3C2440系統(tǒng)上的移植,,并且提出了可行性方案,通過邊搭建硬件環(huán)境邊調(diào)試Uboot,,使Uboot在嵌入式系統(tǒng)板上正常運行,,實現(xiàn)了串口通信、網(wǎng)口下載,、Flash燒錄等功能,,并且成功引導了Linux系統(tǒng),為后續(xù)的系統(tǒng)驅(qū)動程序開發(fā)奠定了基礎,,使得Uboot的移植具有開發(fā)的通用性,。

參考文獻
[1]  劉淼.嵌入式系統(tǒng)接口設計與Linux驅(qū)動程序開發(fā)[M]. 北京:北京航空航天大學出版社,2006.
[2] YAGHMOUR K. Building embedded Linux system[M]. [S.l.]:O’Reilly,2004.
[3] HENKEL J, XIAOBO SHARON HU, SHUVRA S. BHATTACHARYYA. Taking on the embedded system design challenge[J].IEEE Computer,2003,5(4):35-37.
[4] SD-Memory Card Specifications /Part1 Physical Layer  Specification Version 1.01[R]. [S.l.]:SD Group, 2001.
[5] SUMSUANG ELECTRONICS. S3C2410X User’s Manual[Z].Republic of Korea: Sumsang,2003.
[6] Configurations.Denx software engineering[EB/OL]. (2006-7-23)http://www.denx.de/wiki/DULG/Manual.

此內(nèi)容為AET網(wǎng)站原創(chuàng),,未經(jīng)授權(quán)禁止轉(zhuǎn)載,。