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

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

3天内不再提示

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

jf_44130326 来源:Linux1024 作者:Linux1024 2026-04-27 07:11 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

环境变量(env)是U-Boot的核心配置机制,无需重新编译即可灵活调整启动参数。在Rockchip(RK)平台上,环境变量不仅继承了U-Boot的通用特性,还针对RK芯片架构做了大量定制化设计。本文将从通用概念、RK平台特殊处理、工作流程、调试方法等维度,全面拆解RK平台环境变量的底层逻辑与实操技巧。

一、环境变量的通用概念

1.1什么是环境变量?

环境变量是U-Boot中以“键值对”形式存储的配置信息,示例如下:

bootdelay=3bootcmd=mmc dev0; fatload mmc00x40400000 Image; booti0x40400000

这些变量在U-Boot启动时加载,直接控制启动流程、设备信息、内存布局等核心配置。

1.2环境变量的存储结构

环境变量在存储介质上的结构定义于include/environment.h,核心结构如下:

typedefstructenvironment_s{ uint32_t  crc;    /* CRC32校验 */#ifdefCONFIG_SYS_REDUNDAND_ENVIRONMENT unsignedcharflags;  /* 冗余标志 */#endif unsignedchardata[ENV_SIZE];/* 实际数据 */}env_t;

数据区存储规则

•以结尾的字符串列表,格式为name=value;

•整个列表以双结束。

1.3环境变量的存储位置

U-Boot支持多类存储介质,RK平台常用的有:

•MMC/eMMC(最主流);

•SPI Flash(SPI NOR/NAND);

•NAND Flash(大容量存储);

•FAT文件系统(以文件形式存储);

•NOWHERE(仅内存运行,不持久化)。

二、RK平台的特殊处理

2.1架构专属配置

RK平台在u-boot/env/Kconfig中设有专属配置段,定义环境变量的核心参数:

ifARCH_ROCKCHIPconfig ENV_OFFSET  hex"Environment offset" default0x3f8000/* 默认偏移地址 */config ENV_SIZE  hex"Environment size" default0x8000 /* 32KB大小 */ifENVF  config ENV_OFFSET_REDUND  config ENV_NAND_OFFSET  config ENV_NOR_OFFSET  ...endifendif

2.2分区布局规范

RK平台默认分区布局定义于include/configs/rockchip-common.h,核心片段如下:

#define PARTS_RKIMG  "uuid_disk=${uuid_gpt_disk};" "name=uboot,start=8MB,size=4MB,uuid=${uuid_gpt_loader2};" "name=trust,size=4M,uuid=${uuid_gpt_atf};" "name=misc,size=4MB,uuid=${uuid_gpt_misc};" "name=resource,size=16MB,uuid=${uuid_gpt_resource};" "name=kernel,size=32M,uuid=${uuid_gpt_kernel};" "name=boot,size=32M,bootable,uuid=${uuid_gpt_boot};"  ...

关键结论:环境变量通常存储在uboot分区的0x3f8000偏移位置(4MB - 32KB)。

2.3 RK3576内存布局定制

针对RK3576芯片,include/configs/rk3576_common.h定义了内存布局相关环境变量:

#defineENV_MEM_LAYOUT_SETTINGS "scriptaddr=0x40500000" "pxefile_addr_r=0x40600000" "fdt_addr_r=0x48300000" "kernel_addr_r=0x40400000" "kernel_addr_c=0x45480000" "ramdisk_addr_r=0x4a200000"

2.4启动设备自动检测

RK平台内置智能启动设备检测逻辑,自动识别启动介质:

#defineRKIMG_DET_BOOTDEV  "rkimg_bootdev=" "if mmc dev 1 && rkimgtest mmc 1; then "   "setenv devtype mmc; setenv devnum 1; echo Boot from SDcard;" "elif mmc dev 0; then "   "setenv devtype mmc; setenv devnum 0;" "elif mtd_blk dev 0; then "   "setenv devtype mtd; setenv devnum 0;" "elif rknand dev 0; then "   "setenv devtype rknand; setenv devnum 0;" "elif rksfc dev 0; then "   "setenv devtype spinand; setenv devnum 0;" "elif rksfc dev 1; then "   "setenv devtype spinor; setenv devnum 1;" "else;"   "setenv devtype ramdisk; setenv devnum 0;" "fi; "

2.5多启动方式支持

RK平台支持Android、Fit、RKP、Distro等多种启动方式:

#define RKIMG_BOOTCOMMAND  "boot_android${devtype}${devnum};" "boot_fit;" "bootrkp;" "run distro_bootcmd;"

三、环境变量的工作流程

3.1整体流程

wKgZO2nunHaADmIRAAeqRjIdgAA229.png

3.2 MMC存储详细流程

RK平台最常用的MMC存储流程如下:

3.3核心代码路径

wKgZO2nunHaAXqpyAAFXSSjzsjw336.png

初始化核心逻辑(env/env.c):

intenv_init(void){ structenv_driver *drv = env_driver_lookup_default(); intret = -ENOENT;
 if(!drv)   return-ENODEV; if(drv->init)    ret = drv->init(); if(ret == -ENOENT) {   // 使用默认环境    gd->env_addr = (ulong)&default_environment[0];    gd->env_valid = ENV_VALID;   return0;  } returnret;}

环境驱动查找逻辑

staticstructenv_driver*env_driver_lookup(enumenv_location loc) { structenv_driver*drv; constintn_ents =ll_entry_count(structenv_driver, env_driver); structenv_driver*entry;
  drv =ll_entry_start(structenv_driver, env_driver); for(entry = drv; entry != drv + n_ents; entry++) {   if(loc == entry->location)     returnentry;  } returnNULL;}

四、环境变量的使用与调试

4.1常用命令

功能 命令示例
查看所有环境变量 printenv/env
查看特定变量 printenv bootcmd
设置环境变量 setenv bootcmd "mmc dev 0; fatload mmc 0 0x40400000 Image; booti 0x40400000"
保存环境变量 saveenv
删除环境变量 setenv bootcmd
恢复默认环境 env default -a

4.2调试技巧

1.启用调试日志:编译时开启Kconfig调试选项,或在源码中添加printf输出;

2.检查环境有效性

if(gd->env_valid == ENV_INVALID) { printf("使用默认环境n");}

3.手动读取环境数据

# 从MMC读取环境数据到内存0x40500000mmcread0x405000000x3f80000x10# 查看内存数据md0x40500000

4.CRC校验验证:环境数据前4字节为CRC32值,可手动计算验证。

4.3常见问题排查

问题现象 可能原因 解决方法
保存环境变量后重启丢失 1. saveenv执行失败
2.存储介质故障
3.偏移地址配置错误
1.检查saveenv输出日志
2.验证CONFIG_ENV_OFFSET配置
3.测试存储介质读写功能
启动提示bad CRC 1.环境数据损坏
2.首次启动无环境数据
执行env default -a恢复默认环境
环境变量过大无法保存 变量数量/长度超出ENV_SIZE限制 1.清理无用变量
2.增大CONFIG_ENV_SIZE配置

4.4关键配置选项

配置项 作用 默认值(RK平台)
CONFIG_ENV_IS_IN_MMC 启用MMC存储环境变量 开启
CONFIG_ENV_OFFSET 环境变量存储偏移 0x3f8000
CONFIG_ENV_SIZE 环境变量存储空间大小 0x8000(32KB)
CONFIG_SYS_MMC_ENV_DEV 指定MMC设备号 根据硬件配置
CONFIG_ENV_OFFSET_REDUND 冗余环境备份偏移 可选配置

五、RK专属:ENVF环境片段机制

ENVF(Environment Fragment)是RK平台特有的环境变量增强机制,允许将环境变量存储在专用分区,实现动态覆盖与合并。

5.1核心配置

config ENVF bool"Environment fragment is store in envf partition"  dependsonENV_IS_NOWHEREconfig ENVF_LIST string"Specific environments white list of env fragment" default"blkdevparts mtdparts sys_bootargs app reserved"

5.2典型使用场景

•动态配置分区信息;

•存储产品定制化参数;

•跨固件版本共享核心配置。

六、实战案例:RK3576自定义环境变量

6.1修改默认环境(编译期)

在板级配置文件include/configs/rk3576_common.h中添加自定义变量:

#define CONFIG_EXTRA_ENV_SETTINGS  ENV_MEM_LAYOUT_SETTINGS "partitions="PARTS_RKIMG  ROCKCHIP_DEVICE_SETTINGS  RKIMG_DET_BOOTDEV  BOOTENV "my_custom_var=hello_rk3576" "bootargs_append=console=ttyS2,1500000n8"

6.2运行时修改(命令行)

# 设置自定义启动参数setenvbootargs console=ttyS2,1500000n8 root=/dev/mmcblk0p7 rootwait rw# 保存配置saveenv# 重启生效reset

七、总结

RK平台的U-Boot环境变量机制,在通用U-Boot基础上做了三大核心增强:

1.多介质适配:完美支持MMC、SPI、NAND等主流存储;

2.智能启动:自动检测启动设备,适配多场景启动需求;

3.灵活扩展:通过ENVF机制实现环境变量动态管理。

掌握上述知识点,既能快速定位环境变量相关问题,也能根据项目需求灵活定制启动配置,充分发挥RK平台的硬件特性。

参考文件

•u-boot/env/env.c:核心环境管理逻辑;

•u-boot/env/mmc.c:MMC存储实现;

•u-boot/include/environment.h:环境数据结构定义;

•u-boot/include/configs/rockchip-common.h:RK通用配置;

•u-boot/include/configs/rk3576_common.h:RK3576专属配置;

•u-boot/env/Kconfig:环境变量配置选项。

审核编辑 黄宇

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

    关注

    0

    文章

    137

    浏览量

    39948
  • Rockchip
    +关注

    关注

    0

    文章

    93

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    吃透RK3576 U-Boot.map文件!嵌入式开发调试、性能优化、代码裁剪全攻略

    “宝藏文件”,解锁调试、分析、优化的全套实战技巧。 一、U-Boot.map 是什么? U-Boot.map 是 U-Boot 编译链接阶段生成的内存布局映射文件,记录了可执行文件在内
    的头像 发表于 04-27 07:11 462次阅读
    吃透<b class='flag-5'>RK</b>3576 <b class='flag-5'>U-Boot</b>.map文件!嵌入式开发调试、性能优化、代码裁剪全攻略

    飞凌嵌入式ElfBoard-环境变量之删除清空环境变量environ

    (\"PATH\")); } return 0;}2)代码解析在清理环境变量之前先获取一次PATH环境变量的值,然后通过将 environ 赋值为 NULL 立即清空当前进程的所有环境变量
    发表于 03-26 10:23

    飞凌嵌入式ElfBoard-环境变量之删除清空环境变量clearenv

    有的场景需要清空环境变量,然后再重新进行构建,如果是使用unsetent的话会比较繁琐;clearenv() 将当前进程的环境变量列表清空,使得后续的环境变量访问(如getenv())返回 NULL
    发表于 03-26 10:22

    飞凌嵌入式ElfBoard-环境变量之添加修改环境变量setenv

    been unset8)代码解析使用 setenv(\"MY_VAR\", \"12345\", 1) 设置环境变量 MY_VAR 的值为 \"
    发表于 03-26 09:24

    飞凌嵌入式ElfBoard-环境变量之添加修改环境变量putenv

    string is test2. The test_env string is (null)7)代码解析前后两次通过getenv()获取环境变量不一致的原因,在于使用putenv()添加环境
    发表于 03-26 09:22

    飞凌嵌入式ElfBoard-环境变量之获取环境变量

    在shell命令行中可以通过多种方式查看环境变量;shell本身就是一个进程,子进程会继承父进程的环境变量副本,可以直接通过env命令查看当前shell进程的所有环境变量;如果想查看特
    发表于 03-13 08:50

    深入解析U-Boot image.c:RK平台镜像处理核心逻辑

    在瑞芯微(RK平台的嵌入式开发中,U-Boot作为核心的启动加载程序,负责完成镜像解析、校验、加载等关键流程。而image.c正是U-Boot
    的头像 发表于 02-24 16:46 1810次阅读
    深入<b class='flag-5'>解析</b><b class='flag-5'>U-Boot</b> image.c:<b class='flag-5'>RK</b><b class='flag-5'>平台</b>镜像处理核心逻辑

    深入解析RK3588 U-Boot板级文件:evb_rk3588.c核心逻辑拆解

    在嵌入式开发领域,瑞芯微RK3588凭借超强的算力、丰富的接口和广泛的场景适配性,成为高端边缘计算、消费电子项目的热门选择。而U-Boot作为嵌入式系统的“第一道门”,负责硬件初始化、引导内核启动,其板级适配代码直接决定了芯片硬件能力的落地。
    的头像 发表于 02-24 15:24 975次阅读
    深入<b class='flag-5'>解析</b><b class='flag-5'>RK</b>3588 <b class='flag-5'>U-Boot</b>板级文件:evb_<b class='flag-5'>rk</b>3588.c核心逻辑拆解

    U-Boot SPL核心文件spl.c深度解析:从启动流程到调试优化

    解析 U-Boot 中 spl.c 文件的功能与作用,探讨其在系统调试和优化中的价值,并通过流程图和脑图帮助开发者快速掌握核心要点。
    的头像 发表于 02-05 14:08 453次阅读
    <b class='flag-5'>U-Boot</b> SPL核心文件spl.c<b class='flag-5'>深度</b><b class='flag-5'>解析</b>:从启动流程到调试优化

    深入解析U-Boot命令处理核心文件:功能、调试与开发价值

    在嵌入式系统开发中,U-Boot 作为主流的引导加载程序,其命令处理、交互逻辑和自动启动流程是核心功能模块。本文将围绕command.c、cli.c和autoboot.c三个关键文件,从核心
    的头像 发表于 02-03 15:44 998次阅读
    深入<b class='flag-5'>解析</b><b class='flag-5'>U-Boot</b>命令处理核心文件:功能、调试与开发价值

    深入解析U-Boot核心文件board_f.c:知识点、调试要点与开发价值

    在嵌入式系统开发中,U-Boot 作为应用最广泛的引导程序,其底层初始化逻辑直接决定了硬件启动的稳定性与可靠性。
    的头像 发表于 02-03 15:38 867次阅读
    深入<b class='flag-5'>解析</b><b class='flag-5'>U-Boot</b>核心文件board_f.c:知识点、调试要点与开发价值

    解析Rockchip平台U-Boot核心文件:boot_rkimg.c到底做了什么?

    在嵌入式开发中,U-Boot 作为引导程序的 “中流砥柱”,负责初始化硬件、加载内核并启动系统。对于 Rockchip 平台的设备(如常见的开发板、智能终端),boot_rkimg.c 是 U
    的头像 发表于 02-03 15:29 955次阅读
    <b class='flag-5'>解析</b>Rockchip<b class='flag-5'>平台</b><b class='flag-5'>U-Boot</b>核心文件:<b class='flag-5'>boot</b>_rkimg.c到底做了什么?

    RK3588平台串口配置修改指南:切换至串口8

    在嵌入式开发中,串口作为基础调试接口至关重要。本文档针对 RK3588 平台,详细介绍如何将系统默认串口修改为串口 8(UART8),包括 U-Boot 阶段和内核阶段的配置调整。该修
    的头像 发表于 02-01 16:37 1391次阅读

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

    的启动代码,拆解 RK3506 平台 U-Boot 重定位的实现逻辑、关键步骤与底层原理。 路径:u-boot/arch/arm/cpu/armv7/start.S 一、重定位的
    的头像 发表于 11-28 07:05 996次阅读
    深入理解 <b class='flag-5'>RK</b>3506 <b class='flag-5'>U-Boot</b> 重定位:从代码到原理

    WIN10配置Hbird-SDK环境变量

    按照胡老师的《RISC-V CPU下工程与实践》的7.4的151和152页配置Hbird-SDK的环境变量,出现了问题。 问题如下: 首先创建setup_config.bat,之后CMD中运行
    发表于 10-27 06:38