在linux系统中通过fw_printenv查看和设置u-boot中的环境变量

uboot下可以通过命令访问(printenv)和修改环境变量(setenv),但是如果需要在Linux系统下访问这些数据该怎么办呢?其实uboot早就帮我们想好了。


 1、编译fw_printenv工具

source /opt/poky/environment... 

创建交叉编译环境。

更改u-boot/tools/env/Make 

添加CC

CC=aarch64-poky-linux-gcc -march=armv8-a -mtune=cortex-a57.cortex-a53 --sysroot=/opt/poky/2.4.2/sysroots/aarch64-poky-linux
override HOSTCC = $(CC)
$(warning $(HOSTCC))

编译(根据自己平台):

make ARCH=arm CROSS_COMPILE=aarch64-poky-linux- envtools


2、安装fw_printenv工具
      到/tools/env目录中,将编译好的fw_printenv拷贝到目标机的文件系统中,并通过"ln -s fw_printenv fw_setenv",创建一个fw_setenv到fw_printenv的软链。

      这个工具还需要一个配置文件,以获取uboot的ENV区域的位置信息。默认状态下,请将fw_env.config文件拷贝到目标机的文件系统的/etc目录下。然后结合uboot配置中定义的ENV区和Linux下mtd分区的情况修改配置文件。具体的修改方法见fw_env.config文件中的说明及/tools/env/README文件。

 

3、fw_printenv工具的使用
    其实fw_printenv使用起来和uboot下的printenv和setenv指令是一模一样的。
    打印uboot环境变量:

    fw_printenv [[ -n name ] | [ name ... ]]

   如果不指定name,fw_printenv会打印出ENV区中的所有环境变

 

4.当指定的环境变量大小不正确时提示,这里是imx8mm

#:/etc# fw_printenv

Warning: Bad CRC, using default environment

其中device name, Device offset,Env size应该分别对应于uboot源码目录中include/configs/imx8mm_evk.h或者u-boot.cfg相关文件中的

#define CONFIG_ENV_IS_IN_MMC 1

#define CONFIG_ENV_OFFSET (64 * SZ_64K)

#define CONFIG_ENV_SIZE 0x1000

 

# Block device example

device name       Device offset          Env. size

/dev/mmcblk1     0x400000                0x1000

 

注意:

  如果还有问题,应该是本来就没有保存环境变量,请参考《启动时出现错误:*** Warning - bad CRC or NAND》这个笔记

      

5. 设置uboot环境变量:
fw_setenv name [ value ... ]

如果不指定value,表示要删除这个name的环境变量。

 

6. 另外如果你想直接在你的应用程序中使用这个库文件,可以把目录下的lib.a链接到你的应用中。

导出的函数有

1
2
3
4
5
6
7
8
9
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

1
2
3
4
5
6
7
8
9
10
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);

 

posted @ 2020-11-19 16:49  luoyuna  阅读(3462)  评论(1编辑  收藏  举报