服务公告
蓝易云cdn:linux系统中u-boot命令的EMMC
发布时间:2026-01-24 00:03
在 U-Boot 里,eMMC 与 SD 卡都归到 “MMC 子系统”(所以命令统一叫 mmc),差别主要在两点:
1)设备编号/控制器不同(mmc 0/1/... 取决于板级 DTS/驱动初始化顺序)
2)eMMC 额外有硬件分区(boot0/boot1/RPMB/用户区),而 SD 基本只有“用户区 + 分区表”。(docs.u-boot.org)
下面按“现场排障 + 量产烧录 + 启动加载”三个最常用场景,把关键命令讲透。🔧

1)先识别:当前看到的是 eMMC 还是 SD(以及它们分别是几号)
mmc list
mmc dev
mmc rescan
mmc info
解释:
mmc list:列出板子上启用的 MMC 设备(可能是 eMMC 控制器、SD 控制器各一个)。(docs.u-boot.org)mmc dev:显示当前正在操作的设备号。(docs.u-boot.org)mmc rescan:重新扫描卡/设备(热插拔 SD 或初始化异常时必用)。(docs.u-boot.org)mmc info:打印厂商/容量/总线速率/模式等信息,用于判断到底插的是 SD 还是板载 eMMC。(docs.u-boot.org)
企业化建议:你要把“设备号”当成运行时变量管理(例如 mmcdev),别写死,避免同一套脚本换板就翻车。🙂
2)看分区:SD/eMMC 用户区的分区表怎么读
mmc dev 0
mmc part
解释:
mmc dev 0:切到mmc0(这里只是示例,实际以mmc list为准)。(docs.u-boot.org)mmc part:显示该 MMC 设备用户区的分区列表(FAT/ext4 的分区号等)。(docs.u-boot.org)
注意:这一步看的是“用户区”的分区表;eMMC 的 boot0/boot1 属于“硬件分区”,不一定有常规分区表。
3)从分区加载文件:fatload / ext4load(最常用的启动链路)
fatload mmc 0:1 ${kernel_addr_r} Image
ext4load mmc 0:2 ${fdt_addr_r} board.dtb
解释:
fatload:从 FAT 分区读文件到内存;mmc 0:1表示设备 0 的第 1 分区。ext4load:从 ext4 分区读文件到内存;mmc 0:2表示设备 0 的第 2 分区。${kernel_addr_r}/${fdt_addr_r}:内存加载地址(不同平台默认变量名可能不同,但思路一致:把内核/DTB先搬进 DDR)。Image/board.dtb:你实际放在分区里的文件名(可换成zImage、uImage等)。
这类加载方式的核心价值:可读、可维护、可做 A/B 分区升级;你不用记扇区偏移,只要文件系统是健康的就能启动。
4)原始读写:mmc read / write / erase(烧录、救砖、对齐校验必备)
mmc read ${loadaddr} 0x800 0x200
mmc write ${loadaddr} 0x800 0x200
mmc erase 0x800 0x200
解释:
mmc read addr blk# cnt:从 MMC 的 块地址 blk# 开始,读取 cnt 个块到内存addr。(docs.u-boot.org)mmc write addr blk# cnt:把内存addr的数据写回 MMC 的块区间。(docs.u-boot.org)mmc erase blk# cnt:擦除指定块区间。(docs.u-boot.org)0x800/0x200是示例(十六进制块号/块数)。块大小通常是 512B(以mmc info显示为准)。(docs.u-boot.org)
务实提醒:原始写入属于“不可逆操作”,量产脚本里务必先做 mmc dev/mmc info 校验,避免把 SD 当 eMMC 写爆,现场会很尴尬。
5)eMMC 专属:boot0 / boot1(这才是 SD 没有的“隐藏战场”)
mmc dev 0 1
mmc dev 0 2
mmc dev 0 0
解释:
mmc dev <dev> <hwpart>:第二个参数用于选择 eMMC 的硬件分区。(u-boot.denx.narkive.com)- 常见约定:
hwpart=0:用户区(正常分区表所在区域)hwpart=1:boot0hwpart=2:boot1 (u-boot.denx.narkive.com)
- 这就是为什么“eMMC 能做双备份引导(boot0/boot1)”,而 SD 通常做不到同等级的硬件引导冗余。
一句话记住:**SD 主要玩“分区”,eMMC 还要额外玩“硬件分区”。**🙂
6)把这些串成可运营的启动逻辑(典型 bootcmd 思路)
setenv mmcdev 0
mmc dev ${mmcdev}
if mmc rescan; then
fatload mmc ${mmcdev}:1 ${kernel_addr_r} Image
fatload mmc ${mmcdev}:1 ${fdt_addr_r} board.dtb
booti ${kernel_addr_r} - ${fdt_addr_r}
fi
解释:
setenv mmcdev 0:把设备号参数化,方便后续切换 SD/eMMC(或多控制器)。mmc rescan:确保介质在线、初始化成功后再加载,提升启动健壮性。(docs.u-boot.org)booti:启动 AArch64 的 Linux Image(不同架构/镜像格式可能用bootm/bootz,但流程本质一致:先 load,再 boot)。- 这类脚本化链路是做“量产 + 远程升级”的基础骨架。
如果你愿意把你的板子信息补一句(SoC 型号/是 ARM32 还是 ARM64、mmc list 输出、你是要“从 SD 启动烧录 eMMC”还是“直接从 eMMC boot0/boot1 启动”),我可以按你的目标给你一套更贴近生产的命令序列(含校验、回读比对、A/B 切换策略),确保可复制、可交付、可规模化。
已经是第一篇啦!
下一篇: 服务器路由命令有哪些常用技巧?