目录
6. 修改源码之裁剪uboot、设置分区与环境变量
6.1 裁剪uboot
6.1.1 去掉USB支持
6.1.2 去掉RTC
6.1.3 去掉BOOTP选项
6.1.4 去掉部分不需要的命令行配置
6.1.5 去掉文件系统
6.2 设置分区
6.2.1 修改源码设置分区
6.2.2 使用分区名烧写文件
6.3 环境变量
6.3.1 修改默认环境变量
6.3.2 修改保存环境变量
在上一节移植u-boot-2012.04.01到JZ2440(五:修改源码之支持DM9000C网卡)修改完的uboot.bin达到了370多KB,其中有很多无用的代码,下面我们首先来裁剪uboot。在配置文件include/configs/jz2440.h文件里面定义的很多宏,部分宏决定了会编译哪些代码进uboot,我们也许用不上的就要去掉。
/************************************************************
* USB support (currently only works with D-cache off)
************************************************************/
#if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_KEYBOARD
#define CONFIG_USB_STORAGE
#define CONFIG_DOS_PARTITION
#endif
/************************************************************
* RTC
************************************************************/
#if 0
#define CONFIG_RTC_S3C24X0
#endif
/*
* BOOTP options
*/
#if 0
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
#endif
#if 0
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#endif
... ...
#if 0
#define CONFIG_CMD_USB
#endif
/*
* File system
*/
#if 0
#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_RBTREE
#endif
此时重新编译uboot(make distclean;make jz2440_comfig;make),新的u-boot.bin只有200KB左右了。
我们可以使用mtdparts命令,得到如下输出:
查找“not defined, no default present”字符串定位到mtdparts_init()函数中如下代码(common/cmd_mtdparts.c文件):
int mtdparts_init(void)
{
/* get variables */
ids = getenv("mtdids");
parts = getenv("mtdparts");
current_partition = getenv("partition");
... ...
/* if mtdids varible is empty try to use defaults */
if (!ids) {
if (mtdids_default) {
debug("mtdids variable not defined, using default\n");
ids = mtdids_default;
setenv("mtdids", (char *)ids);
} else {
printf("mtdids not defined, no default present\n");
return 1;
}
}
... ...
}
显然没有定义mtdids环境变量,ids为0,执行if (mtdids_default)语句,在同文件有如下定义:
我们的单板头文件(include/configs/jz2440.h)默认没有定义MTDIDS_DEFAULT宏,所以执行mtdparts时输出错误信息,查看其它单板头文件是如何定义的,然后在jz2440.h中添加如下代码:
/*
* mtdparts
*/
#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命令行执行“mtdparts default”命令时,uboot就会检测是否有CONFIG_CMD_MTDPARTS宏,然后再根据上面的MTDPARTS_DEFAULT宏保存的mtd分区信息,来将nand分区。如下:
下面修改代码,让uboot启动时自动设置分区(执行“mtdparts default”命令),在uboot进入main_loop()死循环之前添加执行命令代码(run_command("mtdparts default", 0);),修改board_init_r()函数如下(arch/arm/lib/board.c文件中):
这样当uboot启动时就会自动设置分区了。
以前的uboot烧写uImage:
tftp 30000000 uImage
nand erase 60000 200000
nand write 30000000 60000 200000
现在uboot烧写uImage还可以使用:
tftp 30000000 uImage
nand erase.part kernel
nand write 30000000 kernel
修改完的uboot启动后执行print命令如下:
可以看到一些默认的环境变量,下面看看这些环境变量是在哪里调用输出的。首先定位“using default environment”是在set_default_env()函数里打印的,该函数代码如下(common/env_common.c文件):
void set_default_env(const char *s)
{
if (sizeof(default_environment) > ENV_SIZE) {
puts("*** Error - default environment is too large\n\n");
return;
}
if (s) {
if (*s == '!') {
printf("*** Warning - %s, "
"using default environment\n\n",
s + 1);
} else {
puts(s);
}
} else {
puts("Using default environment\n\n");
}
if (himport_r(&env_htab, (char *)default_environment,
sizeof(default_environment), '\0', 0) == 0)
error("Environment import failed: errno = %d\n", errno);
gd->flags |= GD_FLG_ENV_READY;
}
default_environment是个全局字符数组,这就是是默认环境变量数组,里面保存了各个环境值,部分如下:
所以只需要修改相关宏就能修改默认环境变量了,网卡相关宏定义在include/configs/jz2440.h文件中,修改如下内容:
改为:
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel;bootm 30000000"
#define CONFIG_ETHADDR 00:0c:29:f2:9f:35
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.1.17
#define CONFIG_SERVERIP 192.168.1.12
这样当uboot启动时就会默认使用上面的环境变量,不需要每次启动都去修改变量了。
如果想修改环境变量,而又不想修改源码,可以在命令行设置环境变量后,执行“save”命令保存,但是有如下输出:
在源码搜索“saveenv”如下:
可以看到有保存环境变量的许多文件,我们可以查看common目录下哪些文件被编译了或者查看该目录下的Makefile,发现上面这些文件只有env_flash.c被编译进uboot了(Makefile里判断宏CONFIG_ENV_IS_IN_FLASH),而该文件的函数是操作NOR Flash的,也就是将环境变量保存在NOR Flash。
由于2440在nand启动下是无法支持NOR Flash的,所以我们将环境变量保存到NAND Flash里的分区2,也就是要使用env_nand.c文件,修改单板保存环境变量相关宏内容(include/configs/jz2440.h):
改为如下(env_nand.c里面查找到需要定义下面这些宏才能正确使用):
#define CONFIG_ENV_IS_IN_NAND //Makeflie里面编译env_nand.c的条件宏
#define CONFIG_ENV_OFFSET 0x00040000 //环境变量起始地址
#define CONFIG_ENV_SIZE 0x20000 //环境变量的大小(NAND Flash需要设置为块对齐大小)
#define CONFIG_ENV_RANGE CONFIG_ENV_SIZE //要擦除的环境变量的大小
重新编译(make distclean;make jz2440_config;make),烧写新uboot启动,测试如下:
执行save命令就会把之前set的内容保存到NAND Flash里的分区2里了,以后重启开发板都会使用新保存的环境变量。