移植u-boot-2016.11到JZ2440(六:修改源码之环境变量、裁剪uboot与设置分区)
目录
6. 修改源码之裁剪uboot、设置分区与环境变量
6.1 裁剪uboot
6.1.1 裁剪include/configs/jz2440.h文件
6.1.1.1 去掉USB支持
6.1.1.2 去掉RTC
6.1.1.3 去掉BOOTP选项
6.1.1.4 去掉部分不需要的命令行配置
6.1.1.5 去掉文件系统
6.1.2 裁剪configs/jz2440_defconfig文件
6.1.3 重新编译
6.2 设置分区
6.2.1 修改源码设置分区
6.2.2 使用分区名烧写文件
6.3 环境变量
6.3.1 修改默认环境变量
6.3.2 修改支持保存环境变量
6. 修改源码之裁剪uboot、设置分区与环境变量
6.1 裁剪uboot
在上一节移植u-boot-2016.11到JZ2440(五:修改源码之支持DM9000C网卡)修改完的u-boot.bin达到了480多KB,其中有很多无用的代码,下面我们首先来裁剪uboot。在配置文件include/configs/jz2440.h文件里面定义的很多宏,部分宏决定了会编译哪些代码进uboot,我们也许用不上的就要去掉。
6.1.1 裁剪include/configs/jz2440.h文件
6.1.1.1 去掉USB支持
/************************************************************
* USB support (currently only works with D-cache off)
************************************************************/
#if 0
#define CONFIG_USB_OHCI
#define CONFIG_USB_OHCI_S3C24XX
#define CONFIG_DOS_PARTITION
#endif
6.1.1.2 去掉RTC
/************************************************************
* RTC
************************************************************/
#if 0
#define CONFIG_RTC_S3C24X0
#endif
6.1.1.3 去掉BOOTP选项
/*
* BOOTP options
*/
#if 0
#define CONFIG_BOOTP_BOOTFILESIZE
#define CONFIG_BOOTP_BOOTPATH
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
#endif
6.1.1.4 去掉部分不需要的命令行配置
/*
* Command line configuration.
*/
#if 0
#define CONFIG_CMD_BSP
#define CONFIG_CMD_DATE
#endif
6.1.1.5 去掉文件系统
/*
* File system
*/
#if 0
#define CONFIG_CMD_UBIFS
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_YAFFS2
#define CONFIG_RBTREE
#endif
#define CONFIG_CMD_MTDPARTS
6.1.2 裁剪configs/jz2440_defconfig文件
修改configs/jz2440_defconfig文件,如下:
CONFIG_ARM=y
CONFIG_TARGET_JZ2440=y
CONFIG_BOOTDELAY=5
# CONFIG_SYS_STDIO_DEREGISTER is not set
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="JZ2440 # "
# CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
# CONFIG_CMD_DHCP=y
CONFIG_CMD_PING=y
# CONFIG_CMD_CACHE=y
# CONFIG_CMD_EXT2=y
# CONFIG_CMD_FAT=y
# CONFIG_CMD_UBI=y
# CONFIG_USB=y
# CONFIG_USB_STORAGE=y
# CONFIG_USB_KEYBOARD=y
6.1.3 重新编译
执行./remake.sh重新编译,新的u-boot.bin只有233KB左右了,如下:
6.2 设置分区
6.2.1 修改源码设置分区
我们可以使用mtdparts命令,得到如下输出:
查找“mtdids not defined, no default present”字符串定位到mtdparts_init()函数中如下代码(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)语句,在同文件有如下定义:
我们的之前的各个配置文件默认没有定义MTDIDS_DEFAULT宏,所以执行mtdparts时输出错误信息,查看其它单板头文件是如何定义的,然后在include/configs/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)" \
执行./remake.sh重新编译,烧写启动后进入uboot命令行执行“mtdparts default”命令时,uboot就会检测是否有CONFIG_CMD_MTDPARTS宏,然后再根据上面的MTDPARTS_DEFAULT宏保存的mtd分区信息,来将nand分区。再执行"mtdparts"如下:
下面修改代码,让uboot启动时自动设置分区(执行“mtdparts default”命令),在uboot进入main_loop()死循环之前添加执行命令代码(run_command("mtdparts default", 0);),修改run_main_loop()函数如下(common/board_r.c文件中):
static int run_main_loop(void)
{
#ifdef CONFIG_SANDBOX
sandbox_main_loop_init();
#endif
run_command("mtdparts default", 0); /* 执行"mtdparts default"命令 */
/* main_loop() can return to retry autoboot, if so just run it again */
for (;;)
main_loop();
return 0;
}
执行./remake.sh重新编译,新uboot启动时就会自动设置分区了。
6.2.2 使用分区名烧写文件
以前的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
6.3 环境变量
6.3.1 修改默认环境变量
修改完的uboot启动后执行print命令如下:
可以看到一些默认的环境变量,下面看看这些环境变量是在哪里调用输出的。首先定位“using default environment”是在set_default_env()函数里打印的,该函数代码如下(common/env_common.c文件):
void set_default_env(const char *s)
{
int flags = 0;
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 {
flags = H_INTERACTIVE;
puts(s);
}
} else {
puts("Using default environment\n\n");
}
if (himport_r(&env_htab, (char *)default_environment,
sizeof(default_environment), '\0', flags, 0,
0, NULL) == 0)
error("Environment import failed: errno = %d\n", errno);
gd->flags |= GD_FLG_ENV_READY;
gd->flags |= GD_FLG_ENV_DEFAULT;
}
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
执行./remake.sh重新编译,烧写启动新uboot时就会默认使用上面的环境变量,不需要每次启动都去修改变量了。
6.3.2 修改支持保存环境变量
如果想修改环境变量,而又不想修改源码,可以在命令行设置环境变量后,执行“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 //要擦除的环境变量的大小
执行./remake.sh重新编译,烧写启动新uboot,测试如下:
执行save命令就会把之前set的内容保存到NAND Flash里的分区2里了,以后重启开发板都会使用新保存的环境变量。