上一節S3C2440移植uboot之支持DM9000移植uboot支持了網卡驅動,這節裁剪和修改uboot默認參數
@[TOC]linux
首先,uboot會去校驗(CRC)存放環境變量的一段空間 ,若CRC有效則使用該空間裏的環境變量,無效則用默認的環境變量.
而咱們移植的uboot,因爲一直沒有使用save,因此沒有讀不出CRC校驗,使用的默認環境變量,以下圖所示:數組
搜索using default environment
,發現這句話是在set_default_env()函數
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):oop
#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,裁剪後再來劃份內存分區測試
進入smdk2440.h,把不須要的功能的宏去掉,好比usb,文件系統,rtc等
1)去掉usb支持spa
/************************************************************ // * 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選項3d
/* // * BOOTP options // */ //#define CONFIG_BOOTP_BOOTFILESIZE //#define CONFIG_BOOTP_BOOTPATH //#define CONFIG_BOOTP_GATEWAY //#define CONFIG_BOOTP_HOSTNAME
4)去掉部分不須要的命令行配置code
// #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
因爲屏蔽的宏在其它文件也會用到,而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,因此咱們須要屏蔽這三處宏,從新設置宏
在其它板卡里搜索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命令,經過分區名字來代替這些地址,好比之前的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,查看默認分區名稱:
如上圖所示,接下來咱們即可以直接使用kernel名字來擦除kernel分區,並燒寫內核了
步驟以下:
tftp 30000000 uImage nand erase.part kernel //等於nand erase 200000 60000 nand write 30000000 kernel //從sdram拷貝到nand
下一節S3C2440移植uboot之支持燒寫yaffs映像及製做補丁咱們將移植uboot支持yaffs文件系統。
如遇到排版錯亂的問題,能夠經過如下連接訪問個人CSDN。
**CSDN:[CSDN搜索「嵌入式與Linux那些事」]