1. 程式人生 > >移植U-BOOT之裁剪和修改預設引數(易用性)啟動核心,以及對uboot進行分割槽

移植U-BOOT之裁剪和修改預設引數(易用性)啟動核心,以及對uboot進行分割槽

今天我們來裁剪U-BOOT,使其更加易用,修改預設引數,以及製作最終修改好得補丁檔案方便以後的快速移植。

那麼如果想看之前的關於網絡卡以及flash等的移植,請點選連結檢視:點選連結檢視

在裁剪修改之前呢,我們先來了解一下U-BOOT的環境引數(環境變數):
uboot在啟動的時候首先會讀取環境引數,然後判斷環境引數是否有效,如果設定的環境引數是無效的,那麼就使用預設的引數。

我們還要知道整個Linux系統在硬碟中(FLASH)中是如何分割槽的:
Linux系統的分割槽
我們可以看到,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相關的資訊:
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
然後重啟:
裁剪後的uboot啟動
由啟動知,已經有了倒數的命令,以及我們設定的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':
/work/system/u-boot-2012.04.01/common/cmd_mtdparts.c:306: undefined reference to
get_mtd_device_nm’
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,燒寫核心。重啟,發現可以直接啟動核心了,因為我們已經把讀核心的地址修改好了。