0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

眺望电子 2026-05-20 08:32 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言:

瑞芯微平台的项目开发中,不少工程师都踩过这样一个“诡异”的坑: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 工具,三种场景全覆盖,掌握这一套配置逻辑,无论是开发调试还是量产维护,再也不用反复踩坑!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5212

    文章

    20746

    浏览量

    338441
  • u-boot
    +关注

    关注

    0

    文章

    141

    浏览量

    39993
  • 瑞芯微
    +关注

    关注

    27

    文章

    896

    浏览量

    54723
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    U-boot的基本介绍

    本文开始,将陆续推送“手把手教你移植U-boot”系列文章,目标是由浅入深地讲解U-boot的工作流程、原理、配置方法和移植方法,手把手教你完成U-boot的移植工作,默认硬件开发平
    发表于 07-14 16:52 4301次阅读
    <b class='flag-5'>U-boot</b>的基本介绍

    U-boot的执行流程

    本文主要讲述了U-boot的执行流程。
    发表于 07-14 16:58 1411次阅读
    <b class='flag-5'>U-boot</b>的执行流程

    U-Boot的启动及移植分析

    bootloader 开发是嵌入式系统必不可少而且十分重要的部分,U-Boot 为功能强大的bootloader 开发软件。本文详细分析了U-Boot 的启动流程,并结合其源码,阐述了U-Boot 在S3C2410 目标板上的
    发表于 09-01 16:34 27次下载

    Porting U-Boot to the Control

    In this paper, the way of porting U-Boot to Control Computer Based MPC8349 will beintroduced
    发表于 01-25 15:45 13次下载

    u-boot的Makefile分析

    u-boot的Makefile分析 U-BOOT是一个LINUX下的工程,在编译之前必须已经安装对应体系结构的交叉编译环境,这里只针对ARM,编译器系列软件为arm-linux-*。 U-BOOT的下载
    发表于 05-17 09:16 2315次阅读

    U-Boot结构功能介绍

      U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少
    发表于 07-30 09:17 1490次阅读
    <b class='flag-5'>U-Boot</b>结构功能介绍

    u-boot学习指南

    自己的开发板上,这个过程主要是修改主芯片相关代码以及开发板硬件相关代码,包括启动文件 Start.s、NAND 读写程序、USB 通信程序、相应的 IO 口配置等开发板上的资源,这里发分享u-boot
    发表于 11-17 15:54 2次下载

    u-boot简介

    U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。U-Boot的作用是系统引导。U-Boot
    发表于 10-14 11:17 4026次阅读

    fireflyAIO-3288J主板U-Boot使用简介

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-20 10:06 2466次阅读
    fireflyAIO-3288J主板<b class='flag-5'>U-Boot</b>使用简介

    fireflyAIO-3399J主板U-Boot使用介绍

    RK U-Boot 基于开源的 U-Boot 进行开发,工作模式有启动加载模式和下载模式。
    的头像 发表于 12-24 10:00 2702次阅读
    fireflyAIO-3399J主板<b class='flag-5'>U-Boot</b>使用介绍

    U-Boot架构浅析

    导读:嵌入式Linux系统搭建,bootloader是必不可少的一环,而U-Boot已成嵌入式Linux事实标准。所以较为深入的分析U-Boot的设计,对于更...
    发表于 02-07 11:56 7次下载
    <b class='flag-5'>U-Boot</b>架构浅析

    Linux U-Boot开发指南

    介绍 U-Boot 的编译打包、基本配置、常用命令的使用、基本调试方法等, 为 U-BOOT 的移植及应用开发提供了基础。
    的头像 发表于 03-06 10:28 2718次阅读
    Linux <b class='flag-5'>U-Boot</b>开发指南

    u-boot armv8链接脚本

    u-boot armv8链接脚本 在进行源码分析之前,首先看看u-boot的链接脚本,通过链接脚本可以整体了解一个u-boot的组成,并且可以在启动分析中知道某些逻辑是在完成什么工作
    的头像 发表于 12-07 11:19 1736次阅读

    深入理解 RK3506 U-Boot 重定位:代码原理

     U-Boot 代码初始加载地址(通常是片内 ROM 或 Flash)复制运行效率更高的片外 RAM,再切换执行环境 RAM 中运行。 本文将结合 
    的头像 发表于 11-28 07:05 1110次阅读
    深入理解 RK3506 <b class='flag-5'>U-Boot</b> 重定位:<b class='flag-5'>从</b>代码<b class='flag-5'>到</b>原理

    深度解析 RK 平台 U-Boot 环境变量(env):原理、配置与实战

    环境变量(env)是 U-Boot 的核心配置机制,无需重新编译即可灵活调整启动参数。在 Rockchip(RK)平台上,环境变量不仅继承了 U-Boot 的通用特性,还针对 RK 芯
    的头像 发表于 04-27 07:11 617次阅读
    深度解析 RK 平台 <b class='flag-5'>U-Boot</b> 环境变量(<b class='flag-5'>env</b>):原理、配置与实战