linux移植u-boot(一)——U-Boot詳解+自定義命令實戰
2015-02-07
一、Bootloader
簡單地說:Bootloader主要功能就是 在系統上電時開始執行,初始化硬件和設備,准備好軟件環境,最后調用操作系統。
具體的包含:關閉你看門狗WATCHDOG,改變系統時鍾,初始化存儲控制器
,將操作系統內核代碼復制到內存中去運行。
為了開發方便,可以增加網絡功能,從PC上通過串口或者網絡下載文件,燒寫文件,將flash上的內核代碼解壓后運行等。
Bootloader分為兩種模式:
(1):啟動加載模式:上電后,Bootloader在板子上的某個固態存儲設備上將操作系統加載到RAM中運行,沒有用戶的介入
(2):下載模式:開發人員可以使用各種命令,允許在各種工作模式之間切換,通過串口或者網絡來下載內核文件,並將他們直接放在內存中運行,這就是我們我們所說的U-BOOT。
嵌入式linux操作系統從軟件角度可以分為四個層次:
-
引導加載程序bootloader
-
linux內核
-
文件系統
-
用戶應用程序
一般的u-boot分為單階段,多階段兩種:
多階段u-boot具有更好的可移植性,可以用兩個階段來概括;
第一階段:使用匯編來實現,完成一些依賴於CPU體系結構的初始化,包括光比WATCHDOG,關中斷,設置CPU的速度和時鍾頻率,RAM初始化。
硬件設備初始化 => 為加載Bootloader的第二階段代碼准備RAM空間 => 復制Bootloader的第二階段代碼到RAM空間中 => 設置好棧 => 跳轉到第二階段代碼的C入口。
第二階段:使用C語言來實現,可以實現更為復雜的功能。
初始化本階段要使用的硬件設備 => 檢測系統內存映射 => 將內核映像和根文件系統映像從Flash上讀到RAM空間中 => 為內核設置啟動參數 => 調用內核。
Bootlaoder與內核的交互(參數傳遞的標記方式)
-
設置標記ATAG_CORE, 已標記此為開始。
-
設置內核標記
-
設置命令行標記,就是一個字符串,用來控制內核的一些行為
-
設置標記ATAG_NONE,標記列表以其結束
常用的bootloader包括LILO, GRUB, loadlin, ROLO, Etherboot, BLOB, U-Boot, RedBoot, Vivi等,此處我們研究U-Boot;
二、U-Boot分析與移植
U-Boot,全稱Universal Boot Loader, 遵循GPL條款的開業代碼項目。
U-Boot下面有26個子目錄:分為四類:
-
平台相關的或者開發板相關的 board、cpu、lib_i386類似
-
通用的函數 include、lib_generic、common
-
通用設備驅動程序 disk、drivers、dtt、fs、nand_spl、net、post、rtc
-
U-Boot工具,示例程序,文檔 doc、examples、tools
U-Boot 的配置、編譯、鏈接過程
配置過程:
配置文件為根目錄下的mkconfig,
例如,執行make smdk2410_config 實際上就是執行如下命令
./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0
結果:
-
開發板名稱BOARD_NAME 等於 $1
-
創建到平台/開發板的相關的頭文件的鏈接
-
創建頂層Makefile包含的文件include/config.mk
-
創建開發板相關的頭文件include/config.h $include <configs/$1.h>
編譯、鏈接
make all
總結一下U-Boot的編譯流程
-
首先編譯cpu/$(CPU)/start.S ,對不同的CPU,還可能編譯cpu/$(CPU)下的其他文件。
-
然后,對平台/開發板相關的每個目錄,每個通用目錄都使用它們各自的Makefile生成的相應的庫
-
將1、2步驟生成的.0、.a文件按照board/$(BOARDDIR)/config.mk 文件中制定的代碼段起始地址,board/$(BOARDDIR)/U-Boot.lds 鏈接腳本進行鏈接
-
第3步得到的ELF格式的U-Boot,然后Makefile還會將其轉化成二進制格式文件,S-Record格式。
燒寫內核映像文件uImage
將uImage放在主機的上的tftp或nfs目錄下,確保已經開啟tftp或nfs服務。
然后運行命令下載文件,擦除,燒寫NAND Flash
tftp 0x80800000 uImage
nand erase 0x0 0x00200000
nand write.jffs2 0x80800000 0x0 $(filesize)
注:nand write.jffs2不要求文件的長度是頁對齊(512字節對齊)
也可以使用nand wirte 但是長度要是512字節對齊
燒寫文件系統映像
tftp 080800000 yaffs.img
nand erase 0xa00000 0x3600000
nand write.yaffs 0x80800000 0xa00000 $(filesize)
使用U-Boot 來燒寫程序
tftp 0x30000000 test.bin
go 0x30000000
注意:生成適用於EasyARM-iMX257的U-Boot文件需要按如下步驟進行操作:
首先,進入u-boot-2009.08目錄,清除原有的編譯文件,其對應的終端命令如下:
$ cd u-boot-2009.08
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- distclean
其次,需要配置U-Boot的平台為mx25_3stack_config,對應的終端命令如下:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- mx25_3stack_config
Configuring for mx25_3stack board...
然后,執行編譯,對應的終端命令如下:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
編譯完成后將在u-boot-2009.08目錄下得到u-boot.bin文件。
Loadb 0x80800000 -將uImage從串口發送到davinci的ddr2中0x80800000處。
Protect off all -去掉寫保護
Erase 0x200000 0x204ffff -擦除nor flash中uImage占用的空間
Cp.b 0x80800000 0x2050000 0x14b008 -將傳送到ddr2中的uImage文件拷貝到flash中
Save -保存flash的內容
補充說明:
如果板卡上已經有u-boot,需要升級為新版的u-boot時,則可以操作如下:
使用超級終端的利用串口發送u-boot到davinci板卡,然后利用在線更新的方式完成u-boot燒寫,具體步驟:
1)Protect off all -去掉寫保護
2)Erase 0x2000000 0x204ffff -擦除nor flash中u-boot占用的空間
3)Loadb 0x80800000 -將u-boot文件通過串口發送到davinci的ddr2
4)Cp.b 0x80800000 0x2000000 0x17398 -將傳送到ddr2中
u-boot文件拷貝到flash中
5)Save -保存flash的內容
三、U-Boot增加自定義命令實例
我們在u-boot下增加我們自定義hello命令。
-
首先我們在u-boot的common目錄下增加一個cmd_hello.c文件
參照其他命令的書寫方式,代碼如下
#include <image.h> #include <malloc.h> #include <u-boot/zlib.h> #include <bzlib.h> #include <environment.h> #include <lmb.h> #include <linux/ctype.h> #include <asm/byteorder.h>
int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int i = 0; printf("hello,Lover雪!!!\nthe argcs are \n"); for(i = 0 ; i<argc ; i++) printf("argv[%d]: %s\n",i,argv[i]); return 0; }
U_BOOT_CMD( hello, CONFIG_SYS_MAXARGS, 1, do_hello, "This is a user defined command hello,Lover雪!!!", "hello,long help ......\n" ); |
-
修改common下面的makefile文件,告訴U-Boot編譯我們自定義的C文件
參考Makefile中其他文件的定義,加入一句
COBJS-y += cmd_hello.o |
-
重新make編譯 u-boot
