网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 电子/半导体 > 嵌入式技术 >

从现象到本质,彻底搞懂U-Boot env存储机制

时间:2026-05-20 08:32

人气:

作者:admin

标签:

导读:前言:在瑞芯微平台的项目开发中,不少工程师都踩过这样一个“诡异”的坑:setenv改完、saveenv也保存了,重启设备后环境变量却莫名地回到了默认值。本文将带你从现象到本质,彻底...

前言:

在瑞芯微平台的项目开发中,不少工程师都踩过这样一个“诡异”的坑:setenv改完、saveenv也保存了,重启设备后环境变量却莫名地回到了默认值。本文将带你从现象到本质,彻底搞懂U-Boot环境变量的存储机制,并给出完整的配置方案。

一、问题复现

日常开发调试时,我们会需要修改 U-Boot 环境变量(比如调整启动延时bootdelay、修改启动命令),操作步骤很简单,举个例子:

1. 设备上电,串口按Ctrl+C进入 U-Boot 命令行;

2. 查看当前变量:printenv;

5a6884a2-53e3-11f1-ab55-92fbcf53809c.png

3. 修改目标变量(示例改启动延时为 3 秒):setenv bootdelay 3;

5a7b6338-53e3-11f1-ab55-92fbcf53809c.png

4. 保存配置:saveenv,提示保存成功;

5a876c64-53e3-11f1-ab55-92fbcf53809c.png

5. 重启设备,再次printenv——修改完全消失,变回默认值!

5a9310be-53e3-11f1-ab55-92fbcf53809c.png

问题的本质在哪里?

二、根因分析

要理解这个现象,需要先搞清楚U-Boot环境变量的存储机制。U-Boot在编译时通过一系列CONFIG宏来决定环境变量的存储位置,而瑞芯微平台的SDK默认配置是:

CONFIG_ENV_IS_NOWHERE

这个配置的语义非常直白——环境变量“无处可存”,这个配置下,环境变量仅存在内存中,saveenv只是临时写入内存,断电 / 重启后内存数据清空,变量自然恢复默认,这就是修改失效的根源。

想要永久保存变量,必须开启存储介质持久化配置,瑞芯微平台常用且推荐以下选项:

配置宏存储介质
CONFIG_ENV_IS_IN_MMCeMMC / SD卡
CONFIG_ENV_IS_IN_NANDNAND Flash
CONFIG_ENV_IS_IN_SPI_FLASHSPI Flash
CONFIG_ENV_IS_IN_BLK_DEVBLK框架层设备(RK平台推荐)

因此对于瑞芯微平台,尤其是使用eMMC作为存储介质的场景,推荐启用CONFIG_ENV_IS_IN_MMC,将环境变量直接写入eMMC的指定扇区,实现真正的持久化存储


三、解决方案

眺望电子的瑞芯微系列核心板均使用 EMMC 颗粒存储,打开CONFIG_ENV_IS_IN_MMC,搞定永久保存。

3.1开启Uboot核心配置

在U-Boot的配置中,关闭CONFIG_ENV_IS_NOWHERE,并启用:

CONFIG_ENV_IS_IN_MMC

同时需要关注两个关键参数:

CONFIG_ENV_OFFSET 0x3f8000 // 环境变量在eMMC中的起始偏移地址CONFIG_ENV_SIZE 0x8000 // 环境变量占用空间大小(默认32KB)

注意:CONFIG_ENV_OFFSET和CONFIG_ENV_SIZE的具体值需要根据你的分区表和固件布局来确认。后续配置fw_env.config时也会用到这两个值,务必保持一致。

完成上述配置后重新编译U-Boot并烧录,此时通过setenv + saveenv修改的环境变量就会被写入eMMC,重启后依然有效。

3.2Linux 用户空间操作环境变量

开发后期,不想反复进 U-Boot 命令行,可在 Linux 系统下用fw_printenv/fw_setenv工具直接读写 EMMC 中的 U-Boot 环境变量,使用前需要确保:

已启用 CONFIG_ENV_IS_IN_MMC(否则工具读取不到有效数据)

正确配置 fw_env.config

在U-Boot源码目录下执行:

./make.shenv

5a9e5dac-53e3-11f1-ab55-92fbcf53809c.png

执行命令后生成文件

5aab9c06-53e3-11f1-ab55-92fbcf53809c.png

此处需要配置env文件,匹配 EMMC 偏移和大小

git diff fw_env.configdiff --git a/u-boot/tools/env/fw_env.config b/u-boot/tools/env/fw_env.configindex 7916ebd..fd2f7aa 100644--- a/u-boot/tools/env/fw_env.config+++ b/u-boot/tools/env/fw_env.config@@ -8,8 +8,8 @@# 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+#/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@@ -23,7 +23,7 @@# end of the device/partition, rather than a forwards offset from the start.# Block device example-#/dev/mmcblk0 0xc0000 0x20000+/dev/mmcblk0 0x3f8000 0x80000#/dev/mmcblk0 -0x20000 0x20000# VFAT example

编译后将fw_env.config 移动到板子的/etc 路径下;

将fw_printenv 移动到板子的/usr/local/bin 路径下;

后续可用该工具进行boot的变更,进行fw_printenv 操作前需要先进行fw_printenv 的软连接

ln-s /usr/bin/fw_printenv /usr/bin/fw_setenv

fw_printenv 查看某个变量:

fw_printenvbootdelay

使用fw_setenv设置环境变量 :

fw_setenvbootdelay3fw_printenv

删除一个环境变量:fw_setenv 变量 后不带参数即为删除该变量

fw_setenvbootdelay

注意:如果配置了CONFIG_ENV_IS_IN_MMC 配置,系统启动时会从emmc中读取env信息,此处EMMC的env信息并不会随着烧录而进行更改 将会永远保持不变。

可以通过瑞芯微的擦除所有扇区工具进行清除,清除该EMMC的env信息之后,后续初次重启将会变为默认的env信息。

5ab68ec2-53e3-11f1-ab55-92fbcf53809c.png


四、进阶操作

如果需要固件携带一组默认的环境变量,而不是依赖首次启动后的手动配置,那如何从源码中进行环境变量的更改呢???

要想从源码目录进行参数的更改需要进行如下操作:

默认环境变量定义在:

u-boot/include/env_default.h

找到default_environment数组,这里列出了所有编译期固化的环境变量。例如,修改bootdelay的默认值,可以找到:

5ac25478-53e3-11f1-ab55-92fbcf53809c.png

"bootdelay="__stringify(CONFIG_BOOTDELAY)"\0"

然后修改对应的CONFIG_BOOTDELAY配置即可。

5ad42a7c-53e3-11f1-ab55-92fbcf53809c.png

如果需要添加全新的自定义环境变量,直接在数组中添加一行:

diff--git a/u-boot/include/env_default.h b/u-boot/include/env_default.hindex 853c290..446bfe6100644---a/u-boot/include/env_default.h+++b/u-boot/include/env_default.h@@-103,6+103,7@@ const uchar default_environment[]={#ifdefCONFIG_SYS_SOC "soc=" CONFIG_SYS_SOC "\0"#endif+ "YWF_ENV=" "2002""\0"#ifdefCONFIG_SILENT_CONSOLE "silent=enable\0"#endif

5ae05a68-53e3-11f1-ab55-92fbcf53809c.png

"YWF_ENV=""2002""\0"

重新编译U-Boot后,这个新变量就会出现在默认环境变量中,用户依然可以通过setenv在运行时覆盖它。

5aead240-53e3-11f1-ab55-92fbcf53809c.png


五、总结

瑞芯微 U-Boot 环境变量修改失效,核心就是关闭CONFIG_ENV_IS_NOWHERE、开启CONFIG_ENV_IS_IN_MMC,配合saveenv即可永久保存;

本文从日常调试用 U-Boot 命令行,批量维护改源码默认值,后期运维用 Linux 工具,三种场景全覆盖,掌握这一套配置逻辑,无论是开发调试还是量产维护,再也不用反复踩坑!

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信