5.移植uboot-設置默認環境變量,裁剪,並分區


在上一章使uboot支持網卡傳輸文件后,但是每次啟機時,環境變量都要變為默認值,需要重新設置ip,MAC地址才行,由於沒有配置mtdparts命令,啟動內核也不成功

所以本章主要學習:

  • 1)修改環境變量默認值
  • 2)裁剪uboot  
  • 3)分區,設置mtdparts命令

1.修改之前,先來理解下uboot的環境參數

首先,uboot會去校驗(CRC)存放環境變量的一段空間 ,若CRC有效則使用該空間里的環境變量,無效則用默認的環境變量.

而我們移植的uboot,由於一直沒有使用save,所以沒有讀不出CRC校驗,使用的默認環境變量,如下圖所示:

 

 

2.來修改uboot的默認環境變量

(PS:uboot此時的內存分區還沒修改,所以每次設置環境后,不能用save保存,怕破壞掉nand里面的內容)

2.1搜索using default environment,找到位於set_default_env()函數:

 

從上面代碼可以看到, default_environment這個變量,這是個全局字符數組,從字面上就可知道,這個是默認環境變量數組,里面保存了各個環境值

 

2.2進入default_environment[]看看

 

這個數組比較長,所以只剪切一部分,其中MK_STR()的作用就是將數值轉換為字符串

這些都是環境參數,比如"bootargs="(環境變量里最重要的一個),里面會保存文件系統位置,控制台console等等

我們以bootargs為例:

在default_environment[]數組里,若CONFIG_BOOTARGS宏有值,便會組成一串字符串"bootargs=... ..."

比如在以前的uboot里,可以看到:

bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0
//root:指定文件系統位置
//init:指定內核啟動后執行的第一個應用程序
//console:指定使用哪個終端,比如串口0,使用ttySAC0

其它宏也是這樣.比如我們熟悉的有:

  • "bootcmd=", 用來啟動內核的命令
  • "bootdelay=",uboot啟動的倒計時,默認值為5S,只有設置了bootcmd,該倒計時才有用
  • "baudrate=",波特率,默認為115200
  • "ethaddr=",網卡的MAC地址(也叫物理地址)
  • "ipaddr=",ip地址
  • "serverip=",使用tftp時的服務器地址
  • "netmask=",掩碼, 默認值為255.255.255.0
  • "mtdparts=",mtd分區表

 

2.3所以接下來,便修改smdk2440.h里面與環境相關的宏

設置默認環境變量宏(位於include/configs/smdk2440.h):

#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"   //bootargs
#define CONFIG_BOOTCOMMAND "nand read  0x30000000 0x60000 0x200000; bootm 0x30000000" //bootcmd
#define CONFIG_BOOTDELAY       10                      //uboot 倒計時      
#define CONFIG_NETMASK         255.255.255.0           //掩碼
#define CONFIG_IPADDR          192.168.2.103           //本機IP
#define CONFIG_SERVERIP        192.168.2.101           //電腦IP
#define CONFIG_ETHADDR         08:00:3e:26:0a:5b       //MAC地址

其中bootcmd是隨意寫的,因為此時的內核位置還不確定放在哪(后面配置mtdparts命令后,會在4.6小節修改)

由於nand中要划分bootload空間、環境變量空間、內核空間、系統空間

而uboot就有400多k,所以我們需要裁剪uboot,裁剪后再來划分內存分區

 

3.裁剪uboot

uboot很多文件都是基於Makefile,里面通過判斷宏來加載文件.而宏大部分都定義在include/configs/smdk2440.h

3.1進入smdk2440.h,把不需要的功能的宏去掉,比如usb,文件系統,rtc等

1)去掉usb支持

/************************************************************
// * USB support (currently only works with D-cache off)
// ************************************************************/

//#define CONFIG_USB_OHCI //#define CONFIG_USB_KEYBOARD //#define CONFIG_USB_STORAGE //#define CONFIG_DOS_PARTITION

2)去掉rtc支持

/************************************************************
// * RTC
// ************************************************************/

//#define CONFIG_RTC_S3C24X0

3)去掉BOOTP選項

/*
// * BOOTP options
// */

//#define CONFIG_BOOTP_BOOTFILESIZE
//#define CONFIG_BOOTP_BOOTPATH
//#define CONFIG_BOOTP_GATEWAY
//#define CONFIG_BOOTP_HOSTNAME

4)去掉部分不需要的命令行配置

// #define CONFIG_CMD_DHCP     //動態主機配置協議命令行
// #define CONFIG_CMD_USB      //USB命令行

5)去掉文件系統

/*
// * File system
// */

//#define CONFIG_CMD_FAT
//#define CONFIG_CMD_EXT2
//#define CONFIG_CMD_UBI
//#define CONFIG_CMD_UBIFS
//#define CONFIG_CMD_MTDPARTS
//#define CONFIG_MTD_DEVICE
//#define CONFIG_MTD_PARTITIONS
//#define CONFIG_YAFFS2
//#define CONFIG_RBTR

3.2 編譯

由於屏蔽的宏在其它文件也會用到,而make在之前用過,再次make只會編譯修改過的文件.

所以輸入:

make clean                  
make s3c2440config
make                 

make后,打印以下錯誤:

common/libcommon.o: In function `do_date':
/work/system/u-boot-2012.04.01/common/cmd_date.c:60: undefined reference to `rtc_reset'
/work/system/u-boot-2012.04.01/common/cmd_date.c:63: undefined reference to `rtc_get'
/work/system/u-boot-2012.04.01/common/cmd_date.c:72: undefined reference to `rtc_set'
/work/system/u-boot-2012.04.01/common/cmd_date.c:81: undefined reference to `rtc_get'
make: *** [u-boot] 錯誤 1

上面的cmd_date.c文件以及出錯變量rtc_xxx,從字面上來看顯然是與RTC有關,我們直接屏蔽該文件

通過Makefile,找到需要屏蔽宏CONFIG_CMD_DATE(宏定義位於include/configs/smdk2440.h):

 

 屏蔽后,make成功,可以看到uboot只有200kb了:

 

接下來,便開始分區,使我們的環境變量能保存在uboot指定位置里

 

4.設置分區

以前,我們每次啟動內核時,都會打印以下分區信息:

Creating 4 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x00000000-0x00040000 : "bootloader"            //存放uboot
0x00040000-0x00060000 : "params"                //存放環境變量
0x00060000-0x00260000 : "kernel"                //存放內核
0x00260000-0x10000000 : "root"                  //存放文件系統

所以,我們新的uboot,還是照着這個來分區

還記得之前,我們每次設置了環境變量,都不敢用save命令來保存.

4.1所以我們通過sava -help命令,看它位於哪個文件,找到save命令相關宏

如下圖所示:

 

4.2然后在si里搜索saveenv

搜索如下圖所示:

 

可以發現,在env_flash.c 和env_nand.c這兩個文件都有saveenv()函數.

顯然env_flash.c的作用是,通過save命令將環境變量保存在nor flash.

env_nand.c,是將環境變量保存在nand flash里.

4.3接下來在common/Makefile搜索,看看這兩個文件依賴哪兩個宏

如下圖所示:

 

4.4然后在smdk2440.h搜索這兩個宏,看看板卡默認配置的是不是env_nand.c

如下圖所示:

可以看到,smdk2440.h是將環境變量保存在nor flash,由於2440在nand啟動下是無法支持nor,所以我們需要屏蔽這三處宏,重新設置宏

4.5設置save相關宏

在其它板卡里搜索CONFIG_ENV_IS_IN_NAND,看看別人是怎么通過宏配置save的,然后在env_nand.c文件里搜索宏,來看宏是怎么用的

最終宏修改為如下所示(位於include/configs/smdk2440.h):

//#define CONFIG_ENV_ADDR                    (CONFIG_SYS_FLASH_BASE + 0x070000)
//#define CONFIG_ENV_IS_IN_FLASH
//#define CONFIG_ENV_SIZE               0x10000

#define CONFIG_ENV_SIZE                 0x20000       //環境變量空間大小
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET               0x40000          //位於0x40000~(0X40000+0x20000)
#define CONFIG_ENV_RANGE                CONFIG_ENV_SIZE  //環境變量的擦除范圍,要>=SIZE

 上面的CONFIG_ENV_RANGE宏,其實不定義,內核也會自動定義(位於env_nand.c):

 

然后重新編譯新的uboot,就可以使用save命令保存環境變量了.

接着我們燒寫內核: 

tftp 30000000 uImage
nand erase 60000 200000                         
nand write 30000000 60000 200000        //保存在內核分區里
bootm 30000000                         //啟動內核

從這里,看出燒個內核還需要記錄這些分區空間地址,非常麻煩

4.6 設置mtdparts命令(在舊版uboot里,是mtd命令)

其實,我們可以使用mtdparts命令,通過分區名字來代替這些地址,比如以前的uboot,直接輸入:

nand erase kernel              //這個kernel名字就等於: 60000 200000 
nand write  30000000 kernel    //這個kernel名字就等於: 60000 200000 

由於smdk2440板卡里沒有配置mtdparts命令,所以步驟如下所示:

1)搜索mtdparts,發現位於common/cmd_mtdparts.c

2) 在common/Makefile搜索,找到cmd_mtdparts.c文件依賴CONFIG_CMD_MTDPARTS宏

 

3)在其它板卡里搜索CONFIG_CMD_MTDPARTS,看看別人是怎么通過宏配置nand的,別人寫的配置如下所示:

 

  • "-":表示剩余空間都是文件系統。

(PS:當執行mtdparts default命令時,uboot就會檢測是否有CONFIG_CMD_MTDPARTS宏,然后再根據上面的MTDPARTS_DEFAULT宏保存的mtd分區信息,來將nand和nor分區)

4)設置mtdparts相關宏

接下來,便復制上面的宏到smdk2440.h中,改為:

/*-----------------------------------------------------------------------
 * mtdparts
 */
#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT           "nand0=smdk2440-0"  
#define MTDPARTS_DEFAULT       "mtdparts=smdk2440-0:256k(u-boot),"      \ 
                                          "128k(params),"            \         
                                          "2m(kernel),"  \      
                                          "-(rootfs)"        \

然后重新修改,之前設置的環境參數bootcmd(位於smdk2440.h):

#define CONFIG_BOOTCOMMAND "nand read  0x30000000 0x60000 0x200000; bootm 0x30000000" //bootcmd

改為:

#define CONFIG_BOOTCOMMAND "nand read  0x30000000 kernel; bootm 0x30000000"    //bootcmd

5)修改好后,我們還需要在board_init_r()函數里的for(;;)前面添加(位於arch/arm/lib/board.c):

  run_command("mtdparts default", 0);       //添加此處代碼
 
       for (;;) {
              main_loop();
       }

這樣uboot每次啟動時,都會執行一次mtdparts default命令,使它根據默認參數來自動分區.

mtdparts命令就此設置好了

接下來,便重新燒寫uboot,來測試

 

5.測試mtdparts分區

輸入mtdparts,查看默認分區名稱:

 

如上圖所示,接下來我們便可以直接使用kernel名字來擦除kernel分區,並燒寫內核了

步驟如下:

tftp 30000000 uImage
nand erase.part kernel      //等於nand erase 200000    60000
nand write 30000000 kernel  //從sdram拷貝到nand 

 

接下來,下章來使uboot支持yaffs及制作補丁

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM