2、环境变量基础概念:env的存储位置与默认值/当前值
U-Boot 环境变量(Environment Variables)是系统启动配置的核心数据载体,它决定了内核加载地址、启动参数、网络配置、文件系统挂载方式等关键行为。理解环境变量的存储位置、默认值与当前值的差异,是进行启动优化的第一步。
2.1 环境变量的存储位置
U-Boot 支持将环境变量存储在多种非易失性存储介质中,具体取决于硬件平台和启动设备。常见的存储介质包括 NOR Flash、NAND Flash、MMC/SD 卡、SPI Flash 以及 EEPROM。不同介质的读写特性、容量和可靠性直接影响环境变量的管理策略。
| 存储介质 | 典型应用场景 | 读写特性 | 环境变量大小限制 | 冗余备份支持 |
|---|---|---|---|---|
| NOR Flash | 低容量、高可靠性启动设备 | 支持 XIP(就地执行),字节可读,块擦除 | 通常 64KB ~ 256KB | 支持双备份 |
| NAND Flash | 大容量嵌入式设备 | 页读写,块擦除,存在坏块 | 通常 128KB ~ 512KB | 需坏块管理,支持冗余 |
| MMC/SD 卡 | 树莓派、开发板、消费电子 | 块设备,扇区读写,支持分区 | 通常 128KB ~ 1MB | 支持双备份(主/冗余分区) |
| SPI Flash | 低成本、小引脚数嵌入式系统 | 串行接口,页读写,块擦除 | 通常 64KB ~ 128KB | 支持双备份 |
| EEPROM | 老旧或特殊工业设备 | 字节读写,寿命长,容量小 | 通常 2KB ~ 16KB | 较少支持 |
2.2 环境变量的默认值与当前值
U-Boot 环境变量存在两个层次的值:默认值(Default Values)和当前值(Current Values)。理解两者的区别和切换机制,是调优环境变量的基础。
2.2.1 默认值(Default Values)
默认值是在 U-Boot 编译时,通过 include/configs/ 目录下的板级配置头文件(如 myboard.h)或 CONFIG_EXTRA_ENV_SETTINGS 宏定义的。这些值被编译进 U-Boot 二进制文件,作为出厂或恢复时的基准配置。
/* 示例:include/configs/myboard.h 中的默认环境变量定义 */
#define CONFIG_EXTRA_ENV_SETTINGS \
"bootargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw\0" \
"bootcmd=mmc dev 0; fatload mmc 0:1 0x42000000 zImage; bootz 0x42000000\0" \
"ipaddr=192.168.1.100\0" \
"serverip=192.168.1.1\0" \
"netmask=255.255.255.0\0" \
"ethaddr=00:11:22:33:44:55\0"
2.2.2 当前值(Current Values)
当前值是 U-Boot 运行时从存储介质(如 MMC、SPI Flash)中加载到内存中的环境变量副本。用户可以通过 setenv、editenv 等命令修改当前值,并通过 saveenv 命令将修改写回存储介质。
2.2.3 默认值与当前值的切换流程
U-Boot 启动时,环境变量的加载顺序如下:
- 检查存储介质: U-Boot 尝试从配置的存储位置(如 MMC 的特定分区、SPI Flash 的偏移地址)读取环境变量。
- 校验完整性: 如果读取成功,U-Boot 会校验 CRC 或校验和,判断数据是否完整。
- 加载当前值: 校验通过后,将存储介质中的环境变量加载到内存中的
env_t结构体,作为当前值。 - 回退默认值: 如果存储介质为空、损坏或校验失败,U-Boot 使用编译时定义的默认值,并打印警告信息。
2.3 环境变量的存储格式与冗余机制
U-Boot 环境变量在存储介质中通常以 env_t 结构体形式保存,包含头部校验信息和键值对数据。为了提高可靠性,许多平台支持双备份(Redundant Environment)机制。
| 字段 | 说明 | 大小 |
|---|---|---|
| crc | 32 位 CRC 校验值,用于检测数据完整性 | 4 字节 |
| flags | 标志位,指示当前副本是否有效(0x00 有效,0xFF 无效) | 1 字节 |
| data | 环境变量键值对数据,格式为 key=value\0 连续存储 |
可变(最大 CONFIG_ENV_SIZE) |
2.4 常见环境变量操作命令
在 U-Boot 命令行中,与环境变量相关的主要命令如下:
| 命令 | 功能 | 示例 |
|---|---|---|
printenv |
打印所有当前环境变量 | printenv bootargs |
setenv |
设置或删除环境变量 | setenv bootdelay 3 |
saveenv |
将当前环境变量保存到存储介质 | saveenv |
env default |
恢复环境变量为默认值(不保存) | env default -a |
env import |
从内存或文件导入环境变量 | env import -t 0x42000000 $filesize |
env export |
将环境变量导出到内存或文件 | env export -t 0x42000000 |
printenv 导出当前环境变量作为备份,然后使用 env default -a 恢复默认值,再逐步修改关键参数(如 bootdelay、bootargs、loadaddr),每次修改后执行 saveenv 并重启验证效果。
2.5 环境变量存储位置对启动性能的影响
环境变量的读取速度直接影响 U-Boot 的启动时间。不同存储介质的读取延迟差异显著:
- NOR Flash: 读取延迟最低(约 50-100ns),适合快速加载环境变量,但容量小、成本高。
- SPI Flash: 读取延迟中等(约 1-5μs),通过 SPI 接口传输,适合大多数嵌入式系统。
- MMC/SD 卡: 读取延迟较高(约 1-10ms),因为需要初始化 SD 总线、发送命令、等待响应。在启动优化中,MMC/SD 卡的环境变量读取往往是瓶颈之一。
- NAND Flash: 读取延迟较高(约 10-50μs),且需要 ECC 校验,进一步增加时间开销。
CONFIG_ENV_SIZE 也能缩短读取时间。