关于Linux下 修改访问uboot环境变量分区内容补充!
时间:2018年03-21
背景:项目需要在Linux下也能修改flash分区中的env环境变量
一、引言
问:uboot下可以通过命令访问和修改环境变量,在Linux系统下该怎样访问这些数据?
答:用uboot提供的fw_printenv工具
二、该怎么做?
1、下载新版本的uboot,在uboot/tools/下可看见env/ 目录,里面存放的就是该工具的源码
2、编译fw_printenv工具
在uboot顶层目录下编译该工具: make CROSS_COMPILE=arm-linux- env
3、安装fw_printenv工具
到/tools/env目录中,将编译好的fw_printenv拷贝到目标机的文件系统中/bin/,并通过"ln -s fw_printenv fw_setenv",创建一个fw_setenv到fw_printenv的软链接。
4、配置fw_env.config文件
请将uboot/tools/env/fw_env.config文件拷贝到目标机的文件系统的/etc目录下。然后结合uboot配置中定义的ENV区和Linux下mtd分区的情况修改配置文件。具体的修改方法见fw_env.config文件中的说明及/tools/env/README文件。
说明:在使用此工具时,需要注意fw_env.config很重要,如果配置不对,那么将出现错误!!因为我用的是mmc卡,而不是传统的nand flash或norflash,因此在/tools/env/README中的说明对于我便有点出入,不太合适。为此,在认真阅读fw_printenv代码之后才发现原来是因为fw_env.config配置有点问题。下面给出对于mmc卡作为存储设备的,fw_env.config配置:
# Configuration file for fw_(printenv/setenv) utility.
# Up to two entries are valid, in this case the redundant
# environment sector is assumed present.
# Notice, that the "Number of sectors" is not required on NOR and SPI-dataflash.
# Futhermore, if the Flash sector size is ommitted, this value is assumed to
# be the same as the Environment size, which is valid for NOR and SPI-dataflash
# NOR example
# MTD device name Device offset Env. size Flash sector size Number of sectors
#/dev/mtd1 0x0000 0x4000 0x4000
#/dev/mtd2 0x0000 0x4000 0x4000
# MTD SPI-dataflash example
# MTD device name Device offset Env. size Flash sector size Number of sectors
#/dev/mtd5 0x4200 0x4200
#/dev/mtd6 0x4200 0x4200
# NAND example
#/dev/mtd0 0x4000 0x4000 0x20000 2
# Block device example
# device name env_offset Env.bin_size Env.bin_size Env_partition_sectors
/dev/mmcblk0 0x3000000 0x20000 0x20000 0x8000
请注意最后/dev/mmcblk0部分。
三、fw_printenv工具的使用
fw_printenv使用起来和uboot下的printenv和setenv指令是一模一样的。
四、问题补充!
1、在进行fw_printenv操作时,发现fw_printenv工具在读取env分区时,env分区的第一个uint32为env的crc32的校验码存放区间。
2、fw_printenv在读取env分区时,如果env.cfg一开始有注释,如下图
那么其生成的env.bin在crc32校验码后面为0,此时fw_printenv在读env内容时,没有任何内容打印出来,这个是其工具代码没有做好,其原代码如下:
if (fw_env_open())
return -1;
if (argc == 1) { /* Print all env variables */
for (env = environment.data; *env; env = nxt + 1) { //如果crc32校验码后面为0,那么*env会为0,则循环会直接退出
for (nxt = env; *nxt; ++nxt) { //所以就不会打印任何内容,解决办法是,找到0以后的位置,从那里开始
if (nxt >= &environment.data[ENV_SIZE]) {//就可以了
fprintf (stderr, "## Error: "
"environment not terminated\n");
return -1;
}
}
printf ("%s\n", env);
}
return 0;
}
替换代码:
if (argc == 1) {
for(j=0,env = environment.data;!(*env);j++)
env = environment.data + j;
/* Print all env variables */
for (; *env; env = nxt + 1) {
for (nxt = env; *nxt; ++nxt) {
if (nxt >= &environment.data[ENV_SIZE]) {
fprintf (stderr, "## Error: "
"environment not terminated\n");
return -1;
}
}
printf ("%s\n", env);
}
return 0;
}
3、fw_setenv 时提示Warning: Bad CRC, using default environment
这个就是配置文件没配好的结果。