移植U-BOOT之裁剪和修改預設引數(易用性)啟動核心,以及對uboot進行分割槽
今天我們來裁剪U-BOOT,使其更加易用,修改預設引數,以及製作最終修改好得補丁檔案方便以後的快速移植。
那麼如果想看之前的關於網絡卡以及flash等的移植,請點選連結檢視:點選連結檢視
在裁剪修改之前呢,我們先來了解一下U-BOOT的環境引數(環境變數):
uboot在啟動的時候首先會讀取環境引數,然後判斷環境引數是否有效,如果設定的環境引數是無效的,那麼就使用預設的引數。
我們還要知道整個Linux系統在硬碟中(FLASH)中是如何分割槽的:
我們可以看到,uboot放到第一個分割槽,環境引數放到第二個分割槽,核心放到第三個分割槽,檔案系統放到第四個分割槽。
之前我們修改的U-BOOT啟動後,一直有一個警告:
顯示說CRC的引數錯誤,使用預設的環境變數。那麼我們就從這個問題引入吧。在uboot中搜索字串:using default environment
從而找到了:
Env_common.c(common目錄下)
const uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
.......
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(CONFIG_BOOTDELAY) "\0"
#endif
......
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) "\0"
#endif
......
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "\0"
#endif
}
bootargs是傳給核心的啟動引數,可以設定檔案系統的相關分割槽等。我們在配置檔案smdk2440.h中159行的地方定義一下:
#define CONFIG_BOOTARGS "console=ttySAC0 root=dev/mtdblock3" //代表核心從串列埠0啟動,檔案系統放到第3個分割槽
bootcmd是uboot用來啟動核心的引數,我們也在配置檔案中定義(bootargs定義的下面)定義一下(先隨便定義一個值):
#define CONFIG_BOOTCOMMAND "nand read 30000000 0xbac 0x200000;bootm 30000000"
//因為現在還無得知核心的分割槽的具體地址,先隨便設定一個值,用於演示,等我們把整個FLASH分割槽規劃好了之後,再來設定
bootdelay是uboot啟動後的那個倒數計時的引數,當uboot啟動後,進入倒計時啟動,我們按下任意鍵,進入uboot互動介面開始進行一些設定等操作。這裡我們就去預設值。
ipaddr我們已經很熟悉了,是uboot單板的ip地址,這個我們可以修改一下看看,這個在配置檔案smdk2440.h中已經由定義,我們找到將其修改為:
#define CONFIG_IPADDR 192.168.1.103
ethaddr表示網絡卡的MAC地址,再定義一下MAC地址:
#define CONFIG_ETHADDR 00:0c:29:4d:e4:f4 //lyy
好了,設定好我們常用的引數後,我們先來裁剪一下uboot,因為這個uboot實在是太大了。
我們在uboot命令列輸入help,發現有各種命令,有些命令根本不需要,那麼我們就需要把相關的巨集定義給去掉。
這裡我就不記錄了,去掉的地方太分散了,大概是去掉了usb,檔案系統的支援等。
然後重新編譯uboot,發現有一些錯誤,說我的有一些定義沒定義,但是,我已經把相關定義去掉了。重新:make distclean,然後make smdk2440_config,再make。沒有錯誤了(至於為什麼,我也不清楚,沒必要細究。)。
然後我們現在來分割槽:
首先看一下之前是怎麼分割槽的,啟動核心看一下之前是怎麼分割槽的:
0x00000000-0x00040000 : “bootloader” (0~256k)
0x00040000-0x00060000 : “params”
0x00060000-0x00260000 : “kernel”
0x00260000-0x10000000 : “root”
我們先來設定一下我們的引數的存放地址吧,因為之前我們設定好引數之後,每次都不敢save,就是怕破壞FLASH。
在配置檔案中,找到如下環境變數的相關定義:
#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x070000)
#define CONFIG_ENV_IS_IN_FLASH
#define CONFIG_ENV_SIZE 0x10000
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
那麼我們重新定義這些巨集,該怎麼定義呢?
在uboot命令列使用help命令檢視save相關的資訊:
然後我們在uboot原始碼中搜索字串:saveenv
找到了類似這樣的語句:
搜尋資訊:Env_flash.c (common):int saveenv(void)
我們去common目錄下看看Makefile,看看Env_flash.c的編譯依賴哪個巨集?找到了下面這句:
COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o
說明編譯Env_flash.c依賴的是CONFIG_ENV_IS_IN_NAND這個巨集的定義。那麼我們就定義這個巨集CONFIG_ENV_IS_IN_NAND:
所以我們將上面環境變數的巨集重新定義如下:
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x00040000
#define CONFIG_ENV_SIZE 0x20000
#define CONFIG_ENV_RANGE CONFIG_ENV_SIZE
然後重新編譯,沒有錯誤。
用tftp下載,先設定好ip等(參考上一篇文章):
tftp 30000000 u-boot.bin
protect off all
erase 0 3ffff (因為uboot經過裁剪後,大小變了,所以擦除和拷貝的地址會發生變化)
cp.b 30000000 0 40000
然後重啟:
由啟動知,已經有了倒數的命令,以及我們設定的ip等,都直接就存在了。
但是還是有呢個關於CRC的警告資訊,那是因為,那個CRC的變數沒有寫到FLSAH中,我們執行save命令,再重啟:
此時,就沒有那個警告資訊了,說明引數已經成功被寫進flash,說明上面修改的的引數儲存的地址的區域,也設定成功了。
然後我們燒寫核心:
tftp 30000000 uImage_4.3
nand erase 60000 200000
nand write 30000000 60000 200000
從這裡,就可以感覺到,燒寫個程式要這麼麻煩。下面我們就來修改程式碼,讓燒寫程式變得簡單:
在配置檔案中定義巨集:CONFIG_CMD_MTDPARTS(尋找方法類似於上面的找Makefile的方法)
#define CONFIG_CMD_MTDPARTS
#define MTDIDS_DEFAULT "nand0=jz2440-0" /* 表示哪一個裝置 */
#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot)," \
"128k(params)," \
"2m(kernel)," \
"-(rootfs)" \
在board.c中657行新增:
run_command("mtdparts default",0);
重新編譯,出現錯誤:
common/libcommon.o: In function get_mtd_info':
get_mtd_device_nm’
/work/system/u-boot-2012.04.01/common/cmd_mtdparts.c:306: undefined reference to
make: * [u-boot] Error 1
通過查詢,發現Mtdcore.c函式(在drivers/mtd目錄下)定義了get_mtd_device_nm這個函式,應該是沒有被編譯進核心,所以才顯示錯誤,去Makefile中檢視,發現,還需要定義這個巨集:CONFIG_MTD_DEVICE,那麼我們在配置檔案中再定義這個巨集:
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT "nand0=jz2440-0" /* 表示哪一個裝置 */
#define MTDPARTS_DEFAULT "mtdparts=jz2440-0:256k(u-boot)," \
"128k(params)," \
"2m(kernel)," \
"-(rootfs)" \
再重新編譯,沒有錯誤。燒寫uboot,重啟,在uboot命令列輸入:mtdparts,顯示如下:
再來燒寫核心時,就可以這樣燒寫核心了:
tftp 30000000 uImage_4.3
nand erase.part kernel
nand write 30000000 kernel
然後我們再回過頭把配置檔案中的這句話:
#define CONFIG_BOOTCOMMAND "nand read 30000000 0xbac 0x200000;bootm 30000000"
修改為:
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel 0x200000;bootm 30000000"
重新編譯,燒寫uboot,燒寫核心。重啟,發現可以直接啟動核心了,因為我們已經把讀核心的地址修改好了。