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);
|