基于eMMC的CRAMFS分区启动及双CRAMFS根文件系统U-Boot适配问题咨询
解决方案:U-Boot 2016 处理双CRAMFS分区及MMC分区识别问题
我之前在嵌入式项目里折腾过CRAMFS和老版本U-Boot的组合,结合你的问题场景,给你梳理下可行的解决思路:
一、U-Boot中处理双CRAMFS分区的方法
因为你的MMC分区无法被mmc part识别,所以我们需要手动指定分区的起始偏移和大小(从主机fdisk -l的结果转换而来),配合cramfsload命令完成内核和设备树的加载,再实现双分区的启动切换。
1. 转换分区参数
从fdisk -l emmc.img中拿到两个CRAMFS分区的Start(起始扇区)和Sectors(扇区数),转换成U-Boot能用的字节偏移(默认扇区大小是512字节):
- 字节偏移 = 起始扇区 × 512
- 分区大小(可选)= 扇区数 × 512
比如假设第一个分区起始扇区是2048,那字节偏移就是2048×512=1048576(即0x100000)。
2. 配置U-Boot环境变量
在U-Boot命令行中设置相关变量(也可以写入U-Boot源码的默认环境变量,避免每次重启重新设置):
# 1. 设置加载地址(根据你的内存布局调整,确保不与内核、设备树冲突) setenv cramfsaddr 0x80800000 # zImage加载地址 setenv fdtaddr 0x82000000 # 设备树加载地址 # 2. 设置两个CRAMFS分区的字节偏移(替换成你实际计算的值) setenv rootfs1_offset 0x100000 setenv rootfs2_offset 0x2100000 # 3. 设置对应分区的启动参数 setenv bootargs_root1 'console=ttyS0,115200 root=/dev/mmcblk0p1 rootfstype=cramfs ro' setenv bootargs_root2 'console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=cramfs ro' # 4. 定义两个分区的启动脚本 setenv bootcmd_root1 'mmc dev 0; setenv bootargs ${bootargs_root1}; cramfsload ${cramfsaddr} ${rootfs1_offset} /boot/zImage; cramfsload ${fdtaddr} ${rootfs1_offset} /boot/your_dtb.dtb; bootz ${cramfsaddr} - ${fdtaddr}' setenv bootcmd_root2 'mmc dev 0; setenv bootargs ${bootargs_root2}; cramfsload ${cramfsaddr} ${rootfs2_offset} /boot/zImage; cramfsload ${fdtaddr} ${rootfs2_offset} /boot/your_dtb.dtb; bootz ${cramfsaddr} - ${fdtaddr}' # 5. 设置默认启动逻辑(比如默认从分区1启动,可手动切换) setenv current_root 1 setenv bootcmd 'if test ${current_root} -eq 1; then run bootcmd_root1; else run bootcmd_root2; fi' # 保存环境变量到EMMC saveenv
3. 切换启动分区
如果需要切换到分区2启动,只需在U-Boot命令行执行:
setenv current_root 2 saveenv reset
二、解决mmc part无法识别分区的问题
你提到主机fdisk -l能看到分区,但U-Boot的mmc part识别不到,大概率是以下几个原因:
1. 检查分区表类型与U-Boot配置
- 如果你的镜像用的是GPT分区表,U-Boot 2016默认可能未开启GPT支持,需要重新编译U-Boot,开启
CONFIG_PARTITION_TYPE_GPT=y配置项。 - 如果是MBR分区表,确认分区类型ID是否为
0x83(Linux分区):在主机上用fdisk进入分区编辑模式,修改分区类型为0x83,重新生成镜像。
2. 验证分区表完整性
在主机上检查EMMC镜像的分区表签名是否正确(MBR分区表最后两个字节必须是0xAA55):
hexdump -C emmc.img | tail -20
如果最后一行不是000001fe 55 aa,说明分区表损坏,需要重新用Buildroot或genimage生成正确的镜像。
3. 检查EMMC对齐与U-Boot驱动
- 确保分区起始扇区是4K对齐的(即起始扇区是8的倍数,因为4K=8×512),老版本U-Boot对不对齐的分区可能识别异常。
- 执行
mmc info命令确认U-Boot能正确识别EMMC设备,如果mmc info无输出或信息错误,需要检查U-Boot的EMMC驱动配置是否正确(比如CONFIG_MMC=y、CONFIG_MMC_SDHCI=y等)。
注意事项
- 确保内核已开启CRAMFS支持(
CONFIG_CRAMFS=y),否则无法挂载CRAMFS根文件系统。 cramfsload命令的格式是cramfsload <load_addr> <offset> <filename>,其中offset是分区在EMMC中的字节偏移,不是CRAMFS镜像内部的偏移。
内容的提问来源于stack exchange,提问作者sankerspace
相关产品推荐
相关产品推荐

