基于U-Boot的RPI CM4 eMMC分区创建及多启动配置问询
环境信息
- 硬件:树莓派计算模块4(RPI CM4),8GB板载eMMC
- 引导加载程序:U-Boot
- 当前MMC设备及分区情况:
U-Boot> mmc list mmcnr@7e300000: 1 mmc@7e340000: 0 (eMMC) U-Boot> mmc part Partition Map for MMC device 0 -- Partition Type: DOS Part Start Sector Num Sectors UUID Type 1 2048 247808 dda41d44-01 0c 2 249856 60821504 dda41d44-02 83
- 当前eMMC硬件分区状态:
U-Boot> mmc hwpartition Partition configuration: No enhanced user data area No GP1 partition No GP2 partition No GP3 partition No GP4 partition
需求
- 创建分区存储应用服务调用的配置文件
- 实现多启动功能:支持从多个存储区升级固件,当bank0不可用时自动从bank1加载内核与根文件系统;需通过U-Boot脚本自动化完成分区创建及检查
问题解答
1. 配置文件存储方案及软硬分区区别
最佳方案
直接创建软件分区(即类似现有part1、part2的part3)存储配置文件是最优选择。操作灵活,无需修改eMMC硬件设置,应用程序可像挂载普通分区一样访问它,完全满足配置文件读写需求。
软件分区 vs 硬件分区的区别
- 软件分区:是在eMMC用户数据区上通过分区表(比如当前用的DOS分区表)划分的逻辑分区,属于系统/U-Boot层面的逻辑划分,无需修改eMMC硬件寄存器。优点是灵活易修改,支持标准文件系统,应用程序可直接识别挂载。
- 硬件分区:是eMMC芯片硬件层面划分的专属分区(如GP1-GP4),属于芯片级物理分区,需通过
mmc hwpartition修改硬件配置。这类分区多用于厂商固件存储、安全分区等特殊场景,不适合存应用配置——操作复杂,且系统对其支持不如软件分区完善。
关于part3的可用性
完全可以创建part3软件分区,格式化后挂载为文件系统供应用程序访问,不需要使用硬件分区。只要在分区表中添加该分区,Linux系统下格式化(如ext4)后,就能像使用part2一样读写配置文件。
2. U-Boot脚本实现自动化分区与多启动
思路说明
多启动核心是划分两个独立固件分区(bank0和bank1,对应软件分区part2、part3或调整现有分区),每个分区包含完整引导文件(内核、设备树、根文件系统),U-Boot脚本检查bank0可用性,正常则从bank0启动,异常则切换到bank1。
步骤1:自动化分区创建脚本
编写create_partitions.scr脚本(执行前务必备份数据,分区操作会清除现有数据):
# 切换到MMC设备0 mmc dev 0 # 清除原有分区表 mmc erase 0 2048 # 定义分区规划: # part1: 保留原引导分区 # part2: bank0根文件系统分区 # part3: bank1根文件系统分区 # part4: 配置文件存储分区 setenv partitions "name=boot,start=2048,size=247808,type=0c;name=root0,start=249856,size=30410752,type=83;name=root1,start=30660608,size=30410752,type=83;name=config,start=61071360,size=2097152,type=83" # 写入GPT分区表 gpt write mmc 0 $partitions # 验证分区创建结果 mmc part echo "分区创建完成!"
提示:分区大小可根据8GB eMMC总容量调整,上述数值为参考分配。
步骤2:多启动检查脚本
编写multi_boot.scr脚本,实现自动检测与启动切换:
# 切换到MMC设备0 mmc dev 0 # 读取bank0根分区(part2)前1024扇区,检查可用性 mmc read 0x10000000 249856 1024 if test $? -eq 0; then echo "bank0正常,从bank0启动..." # 设置bank0启动参数 setenv bootargs "root=/dev/mmcblk0p2 rootwait rw" load mmc 0:1 0x80000000 zImage load mmc 0:1 0x82000000 bcm2711-rpi-cm4.dtb bootz 0x80000000 - 0x82000000 else echo "bank0异常,切换到bank1启动..." # 设置bank1启动参数 setenv bootargs "root=/dev/mmcblk0p3 rootwait rw" load mmc 0:1 0x80000000 zImage_bank1 load mmc 0:1 0x82000000 bcm2711-rpi-cm4.dtb bootz 0x80000000 - 0x82000000 fi
说明:
mmc read通过读取分区扇区判断可用性,实际可根据需求改成检查特定文件存在性或分区完整性- 若bank1使用独立内核文件,需修改文件名(如示例中的
zImage_bank1),也可保持内核文件名一致,仅切换分区- 设备树文件通常可共用,无需修改
脚本使用方法
- 将脚本转换为U-Boot可执行格式:
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Multi Boot Script" -d multi_boot.scr multi_boot.img
- 将生成的
multi_boot.img放入eMMC的boot分区(part1) - 在U-Boot中设置自动执行脚本:
setenv bootcmd 'load mmc 0:1 0x80000000 multi_boot.img; source 0x80000000' saveenv
内容的提问来源于stack exchange,提问作者Saranya Natarajan
相关产品推荐
相关产品推荐

