4、dd命令烧录:基础语法、实战操作与数据校验

说到烧录U-Boot,我个人最常用的工具就是dd命令。为什么?因为它简单、直接、几乎每个Linux系统都自带。你不需要装任何额外软件,一条命令就能把U-Boot写进SD卡或eMMC里。

但简单归简单,用不好也会出大问题。我见过不少新手,一个参数写错,整块板子就变砖了。今天我就把dd命令的用法、注意事项、还有我踩过的坑,一次性讲清楚。

4.1 dd命令基础语法

dd的全称是“data duplicator”,说白了就是个数据拷贝工具。它的核心语法其实就一句话:

dd if=输入文件 of=输出设备 bs=块大小 count=块数量 seek=跳过块数

我来解释一下这几个关键参数:

参数 含义 示例
if 输入文件(Input File) if=u-boot.bin
of 输出设备(Output File) of=/dev/sdb
bs 块大小(Block Size) bs=1M
count 写入的块数 count=4
seek 跳过前N个块 seek=1
我的习惯:我一般把bs设成1M,这样读写效率最高。但如果你要精确控制写入位置,比如只写前几个扇区,那就用bs=512(一个扇区的大小)。

4.2 烧录U-Boot到SD卡

烧录SD卡是最常见的场景。我以一块i.MX6ULL开发板为例,演示完整流程。

第一步:确认设备节点

插入SD卡后,先用lsblk或dmesg查看设备名:

lsblk
# 输出示例:
# sdb      8:16   1  14.9G  0 disk
# └─sdb1   8:17   1  14.9G  0 part  /media/sd
注意:千万不要搞错设备名!我曾经有一次把/dev/sda(系统盘)当成SD卡来写,结果系统直接崩溃。所以每次我都会用lsblk确认两遍。

第二步:卸载分区

如果SD卡有分区被挂载,先卸载:

sudo umount /dev/sdb1

第三步:执行烧录

对于i.MX6ULL,U-Boot需要烧录到SD卡的偏移1KB位置(即跳过前2个扇区):

sudo dd if=u-boot.imx of=/dev/sdb bs=1K seek=1 conv=fsync

这里seek=1表示跳过前1KB(即2个512字节扇区)。conv=fsync确保数据真正写入物理设备,而不是停留在缓存里。

第四步:验证写入

用dd把刚写的内容读出来,对比一下:

sudo dd if=/dev/sdb of=readback.bin bs=1K skip=1 count=512
md5sum u-boot.imx readback.bin

如果两个MD5值一致,说明烧录成功。

4.3 烧录U-Boot到eMMC

eMMC的烧录稍微复杂一点,因为eMMC通常是在板子上,需要通过U-Boot或Linux系统来操作。

场景一:在U-Boot命令行下烧录

如果你板子已经能启动到U-Boot,可以用mmc命令:

# 从SD卡读取U-Boot到内存
fatload mmc 0:1 0x12000000 u-boot.imx

# 写入eMMC(假设eMMC是mmc 1)
mmc dev 1
mmc write 0x12000000 0x2 0x400

场景二:在Linux系统下烧录

如果板子已经跑起了Linux,eMMC会显示为/dev/mmcblkX:

# 查看eMMC设备
ls /dev/mmcblk*

# 烧录U-Boot到eMMC(跳过前2个扇区)
sudo dd if=u-boot.imx of=/dev/mmcblk1 bs=512 seek=2 conv=fsync
关键区别:SD卡和eMMC的偏移量可能不同。比如有些芯片(如全志H3)要求U-Boot烧录到eMMC的8KB偏移处,而SD卡是1KB。一定要查芯片手册!

4.4 dd烧录的注意事项

用dd烧录,说白了就是“裸写”,没有任何保护机制。所以下面几点你一定要注意:

  1. 确认设备节点:写之前用lsblk、fdisk -l反复确认,别把系统盘给写了。
  2. 卸载分区:如果设备有挂载的分区,先umount,否则可能写入失败或数据损坏。
  3. 使用conv=fsync:不加这个参数,dd可能只写到缓存就返回了。拔卡后数据没真正写入,板子就起不来。
  4. 注意偏移量:不同芯片、不同存储介质的偏移量不一样。比如:
    • i.MX6ULL:SD卡偏移1KB,eMMC偏移1KB
    • 全志H3:SD卡偏移8KB,eMMC偏移8KB
    • Rockchip RK3399:SD卡偏移32KB,eMMC偏移32KB
  5. 不要写整个设备:U-Boot通常只有几百KB,你只需要写前几个MB就够了。用count参数限制写入量,避免破坏后面的分区数据。
我曾经犯过的错:有一次我烧录eMMC时忘了加seek参数,直接把U-Boot写到了eMMC的0偏移处。结果板子启动时,ROM代码在0偏移找不到合法的启动头,直接卡死了。后来只能拆机用SD卡启动,重新擦除eMMC才救回来。

4.5 数据校验:确保烧录无误

烧录完成后,一定要做校验。我常用的方法有三种:

方法一:MD5/SHA256校验

这是最常用的方法。先计算原始文件的哈希值,再读取设备上对应区域的内容,对比哈希:

# 计算原始文件哈希
md5sum u-boot.imx

# 从设备读取并计算哈希
sudo dd if=/dev/sdb bs=1K skip=1 count=512 | md5sum

方法二:cmp命令直接对比

如果你不想算哈希,可以直接用cmp命令逐字节对比:

sudo cmp -n 524288 u-boot.imx /dev/sdb 1

这里-n 524288表示只对比前512KB(U-Boot的大小),1表示从设备的第1KB开始对比。

方法三:读取后对比

先把设备内容读出来,再和原始文件对比:

# 读取设备内容
sudo dd if=/dev/sdb of=readback.bin bs=1K skip=1 count=512

# 对比文件
diff u-boot.imx readback.bin
我的建议:批量生产时,我会写一个自动化脚本,把烧录和校验做成一步。脚本里先执行dd,然后用md5sum对比,如果校验失败就报警。这样能避免人工操作失误。

4.6 本章知识体系

下面这张图总结了dd烧录的核心流程和关键点:

dd命令烧录U-Boot核心流程 第一步:准备 确认设备节点 第二步:卸载 umount分区 第三步:烧录 dd命令写入 第四步:校验 MD5/cmp对比 关键参数与注意事项 if=输入文件 of=输出设备 bs=块大小(建议1M或512) seek=跳过块数(注意偏移量) conv=fsync(强制同步写入) ⚠ 常见错误 ❌ 忘记加seek,写错偏移量 ❌ 忘记umount,写入失败 ❌ 忘记conv=fsync,数据丢失 ❌ 写错设备节点,系统崩溃

嗯,到这里dd命令烧录U-Boot的内容就讲完了。说白了,dd就是个“裸写”工具,用好了效率极高,用错了代价也大。我的建议是:每次烧录前默念三遍“确认设备、确认偏移、确认同步”,养成习惯就不会出问题。

可可精品资料库