You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 14:37:44