如何读写UBOOT的env变量
一般情况下,内核需要的参数都是通过bootargs传入kernel,而kernel一般对其也不需要进行写操作。但一些特殊情况,如OTA升级时候需要修改标志,让bootloader可以在下次启动时进入recovery模式。此时就有可能对env变量进行写入。这个写入通常可以通过uboot中的fw_env控件来实现。编译方法很简单 ,在uboot下
make env
进入uboot/tools/env可以看到编译完成的fw_printenv,但是这个只能显示,如果需要修改,则必须ln 一个软链接到fw_printenv,否则无法操作
ln -s fw_printenv fw_setenv
这里还需要注意,如果选择了定义CONFIG文件位置,如/etc/fw_env.config,需要把fw_env.config拷贝到系统的/etc目录下,这个config文件用于配置uboot env的存储位置,如下文件,默认存储了两份,一份在/dev/mtd1 0x0000 0x4000,一份在/dev/mtd2 0x0000 0x4000,这个根据你的系统来定,如emmc 分区中可以配成/dev/mmcblk0 0xc000 0x4000
# 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 #/dev/mmcblk0 0xc0000 0x20000 # VFAT example #/boot/uboot.env 0x0000 0x4000
另外如果你想直接在你的应用程序中使用这个库文件,可以把目录下的lib.a链接到你的应用中。导出的函数有
extern int fw_printenv(int argc, char *argv[]); extern char *fw_getenv (char *name); extern int fw_setenv (int argc, char *argv[]); extern int fw_parse_script(char *fname); extern int fw_env_open(void); extern int fw_env_write(char *name, char *value); extern int fw_env_close(void); extern unsigned long crc32 (unsigned long, const unsigned char *, unsigned);
根据自己需要,使用起来非常方便。
唯一需要注意的是操作是加文件锁,防止多个进程写入,数据出错,大概流程如下,具体可以参考 fw_env_main.c
const char *lockname = "/var/lock/" CMD_PRINTENV ".lock"; int lockfd = -1; lockfd = open(lockname, O_WRONLY | O_CREAT | O_TRUNC, 0666); flock(lockfd, LOCK_EX); //set or read uboot env flock(lockfd, LOCK_UN);