上一節移植uboot支持了網卡驅動,這節裁剪和修改uboot默認參數
文章目錄
uboot的環境參數
首先,uboot會去校驗(CRC)存放環境變量的一段空間 ,若CRC有效則使用該空間裏的環境變量,無效則用默認的環境變量.
而我們移植的uboot,由於一直沒有使用save,所以沒有讀不出CRC校驗,使用的默認環境變量,如下圖所示:
修改uboot的默認環境變量
搜索using default environment
,發現這句話是在set_default_env()函數
default_environment這個變量,這是個全局字符數組,從字面上就可知道,這個是默認環境變量數組,裏面保存了各個環境值
查看 default_environment[]
bootargs="(環境變量裏最重要的一個),是傳遞給內核的環境變量,裏面會保存文件系統位置,控制檯console等等。
其他宏的含義如下
"bootcmd=", 用來啓動內核的命令
"bootdelay=",uboot啓動的倒計時,默認值爲5S,只有設置了bootcmd,該倒計時纔有用
"baudrate=",波特率,默認爲115200
"ethaddr=",網卡的MAC地址(也叫物理地址)
"ipaddr=",ip地址
"serverip=",使用tftp時的服務器地址
"netmask=",掩碼, 默認值爲255.255.255.0
"mtdparts=",mtd分區表
更改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 5 //uboot 倒計時
#define CONFIG_NETMASK 255.255.255.0 //掩碼
#define CONFIG_IPADDR 192.168.2.110 //本機IP
#define CONFIG_SERVERIP 192.168.2.1 //電腦IP
#define CONFIG_ETHADDR 08:00:3c:26:0b:5b //MAC地址
其中bootcmd是隨意寫的,因爲此時的內核位置還不確定放在哪(後面配置mtdparts命令後,會在後面修改)
由於nand中要劃分bootload空間、環境變量空間、內核空間、系統空間
而uboot就有400多k,所以我們需要裁剪uboot,裁剪後再來劃分內存分區
裁剪uboot
進入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
解決rtc_xxx,cmd_date.c 錯誤
由於屏蔽的宏在其它文件也會用到,而make在之前用過,再次make只會編譯修改過的文件.
所以輸入:
make clean
make smdk2440_config
make
make後,打印以下錯誤:
上面的cmd_date.c文件以及出錯變量rtc_xxx,從字面上來看顯然是與RTC有關,我們直接屏蔽該文件
通過Makefile,找到需要屏蔽宏CONFIG_CMD_DATE(宏定義位於include/configs/smdk2440.h):
屏蔽後,make成功,可以看到uboot只有200kb了:
設置分區
每次啓動內核時,都會打印以下分區信息:
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,還是照着這個來分區
所以我們通過sava -help命令,看它位於哪個文件,找到save命令相關宏
如下圖所示:
然後在si裏搜索saveenv
搜索如下圖所示:
可以發現,在env_flash.c 和env_nand.c這兩個文件都有saveenv()函數.
顯然env_flash.c的作用是,通過save命令將環境變量保存在nor flash.而env_nand.c,是將環境變量保存在nand flash裏.
接下來在common/Makefile搜索,看看這兩個文件依賴哪兩個宏
如下圖所示:
然後在smdk2440.h搜索這兩個宏,看看板卡默認配置的是不是env_nand.c
如下圖所示:
可以看到,smdk2440.h是將環境變量保存在nor flash,由於2440在nand啓動下是無法支持nor,所以我們需要屏蔽這三處宏,重新設置宏
設置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 //啓動內核
從這裏,看出燒個內核還需要記錄這些分區空間地址,非常麻煩
設置mtdparts命令(在舊版uboot裏,是mtd命令)
設置mtdparts命令
其實,我們可以使用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
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)" \
編譯報錯
提示get_mtd_device_nm
未定義,但是我們在Mtdcore.c中已經定義了,所以有可能是這個Mtdcore.c沒有被編譯進內核。
查看 drivers/mtd/Makefile中的定義部分,需要定義CONFIG_MTD_DEVICE 宏
重新編譯燒寫測試
以前擦除:nand erase 60000 200000
現在擦除:nand erase kernel
發現報錯了
執行 help medparts
我們先執行mtdparts defaults
,再執行nand erase kernel,成功了。
接着我們把這條命令添加到代碼中去自動執行。
在board_init_r()函數裏的for(;;)前面添加(位於arch/arm/lib/board.c):
run_command("mtdparts default", 0); //添加此處代碼
for (;;) {
main_loop();
}
這樣uboot每次啓動時,都會執行一次mtdparts default命令,使它根據默認參數來自動分區.
mtdparts命令就此設置好了
然後重新修改,之前設置的環境參數bootcmd(位於smdk2440.h):
將
#define CONFIG_BOOTCOMMAND "nand read 0x30000000 0x60000 0x200000; bootm 0x30000000" //bootcmd
改爲:
#define CONFIG_BOOTCOMMAND "nand read 0x30000000 kernel; bootm 0x30000000" //bootcmd
測試mtdparts分區
輸入mtdparts,查看默認分區名稱:
如上圖所示,接下來我們便可以直接使用kernel名字來擦除kernel分區,並燒寫內核了
步驟如下:
tftp 30000000 uImage
nand erase.part kernel //等於nand erase 200000 60000
nand write 30000000 kernel //從sdram拷貝到nand