U-Boot 环境变量机制与启动流程

1. U-Boot 环境变量机制

U-Boot 的环境变量系统是其灵活性和可配置性的核心。环境变量存储在非易失性存储器中(如 Flash、EEPROM 等),可以在 U-Boot 运行时修改并保存。

1.1 环境变量基本操作

常用环境变量操作命令:

            # 打印所有环境变量
            printenv
            
            # 设置环境变量
            setenv <variable> <value>
            
            # 保存环境变量到存储设备
            saveenv
            
            # 删除环境变量
            setenv <variable>
        
注意:使用 setenv 命令后,必须执行 saveenv 才能将修改永久保存到存储设备中。

1.2 环境变量存储位置

U-Boot 环境变量通常存储在以下位置之一:

在编译 U-Boot 时,可以通过配置文件(如 include/configs/<board>.h)或设备树指定环境变量的存储位置和大小。

2. bootcmd 与 bootargs 的作用

2.1 bootcmd - 自动启动命令

bootcmd 是 U-Boot 中最重要的环境变量之一,它定义了系统自动启动时执行的命令序列。

典型 bootcmd 示例:

            # 从 MMC 加载内核并启动
            setenv bootcmd 'mmc dev 0; fatload mmc 0:1 ${loadaddr} zImage; bootz ${loadaddr}'
            
            # 从 TFTP 服务器加载内核并启动
            setenv bootcmd 'tftp ${loadaddr} zImage; bootz ${loadaddr}'
            
            # 复杂的多阶段启动流程
            setenv bootcmd 'run findfdt; run mmcboot; run netboot; run usbboot'
        

2.2 bootargs - 内核启动参数

bootargs 包含了传递给 Linux 内核的命令行参数,这些参数控制着内核的启动行为。

常见 bootargs 参数:

参数 说明
root=/dev/mmcblk0p2 指定根文件系统设备
console=ttyS0,115200 指定控制台设备和波特率
rootfstype=ext4 指定根文件系统类型
rw 以读写方式挂载根文件系统
init=/sbin/init 指定初始化程序

典型 bootargs 示例:

            # 基本启动参数
            setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait'
            
            # 网络根文件系统 (NFS)
            setenv bootargs 'console=ttyS0,115200 root=/dev/nfs nfsroot=192.168.1.100:/nfsroot ip=dhcp'
            
            # 带设备树的启动参数
            setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait earlyprintk'
        

3. 自定义启动流程

3.1 网络启动 (TFTP + NFS)

网络启动常用于开发和调试阶段,可以快速更新内核和文件系统而无需烧写存储设备。

            # 设置网络参数
            setenv ipaddr 192.168.1.10
            setenv serverip 192.168.1.100
            setenv netmask 255.255.255.0
            setenv gatewayip 192.168.1.1
            
            # 网络启动命令
            setenv netboot 'tftp ${loadaddr} zImage; tftp ${fdtaddr} dtb; setenv bootargs console=ttyS0,115200 root=/dev/nfs nfsroot=${serverip}:/nfsroot ip=${ipaddr}; bootz ${loadaddr} - ${fdtaddr}'
            
            # 设置为默认启动方式
            setenv bootcmd 'run netboot'
            saveenv
        

3.2 本地存储启动 (MMC/SD)

本地存储启动是产品部署时的常用方式,具有更高的可靠性。

            # MMC 启动命令
            setenv mmcboot 'mmc dev 0; fatload mmc 0:1 ${loadaddr} zImage; fatload mmc 0:1 ${fdtaddr} dtb; setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait; bootz ${loadaddr} - ${fdtaddr}'
            
            # 设置为默认启动方式
            setenv bootcmd 'run mmcboot'
            saveenv
        

3.3 多阶段启动流程

可以创建复杂的多阶段启动流程,实现灵活的启动策略。

            # 定义多个启动方式
            setenv mmcboot '...'  # MMC启动命令
            setenv netboot '...'  # 网络启动命令
            setenv usbboot '...'  # USB启动命令
            
            # 定义查找设备树的命令
            setenv findfdt '...'
            
            # 定义默认启动顺序
            setenv bootcmd 'run findfdt; run mmcboot; run netboot; run usbboot'
            saveenv
        
警告:在修改启动命令时,务必保留一个可用的恢复方法(如串口访问),否则可能导致系统无法启动。

3.4 条件启动与延时启动

U-Boot 支持通过环境变量实现条件判断和延时启动。

            # 检查按钮状态决定启动方式
            setenv check_button 'gpio input 23; if test $? -eq 0; then setenv boottype normal; else setenv boottype recovery; fi'
            
            # 延时启动
            setenv delayed_boot 'sleep 5; run ${boottype}_boot'
            
            # 组合启动流程
            setenv bootcmd 'run check_button; run delayed_boot'
            saveenv
        

4. 最佳实践