上一节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那些事”]