U-boot SD 卡启动全流程详解
本文详细介绍如何将 SD 卡分区、写入 U-Boot,制作 LicheePi 镜像并启动 F1C100s 开发板。涵盖分区格式、U-Boot 写入方法、启动脚本编写、注意事项。
目录
- 1. SD 卡分区
- 2. U-Boot 写入说明
- 3. boot.env 与 boot.scr 的关系
- 4. F1C100s 启动流程
- 5. 如何写入 U-Boot 不破坏分区
- 6. 生成并使用 boot.scr
- 7. 写入命令带进度显示
- 8. 判断写入成功的方法
- 9. 参考分区表示例分析
- 10. 总结
1. SD 卡分区
- SD 卡分为两个分区:
- 第1分区:FAT32 格式,用于放置内核镜像、设备树文件和启动脚本(如
boot.scr
)。 - 第2分区:ext4 格式,用于放置根文件系统(rootfs)。
- 第1分区:FAT32 格式,用于放置内核镜像、设备树文件和启动脚本(如
示例分区表:
/dev/mmcblk0p1 * 2048 18431 16384 8M c W95 FAT32 (LBA)
/dev/mmcblk0p2 18432 7774207 7755776 3.7G 83 Linux
- 其中第1分区从第2048扇区(约1MB)开始。
2. U-Boot 写入说明
- U-Boot 是裸机启动程序,不能作为普通文件放在 FAT 分区里。
- 正确做法是将 U-Boot 二进制文件(通常为
u-boot-sunxi-with-spl.bin
)写入 SD 卡的前 1MB 空间,通常从 8KB(seek=8)处开始写入。 - 写入命令示例:
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8 conv=fsync
- 这样写不会破坏 SD 卡的 MBR 和分区表,也不会影响 FAT/ext4 分区。
3. boot.env 与 boot.scr 的关系
boot.env
是一个纯文本格式的 U-Boot 脚本,里面写启动命令。- U-Boot 不会直接识别
boot.env
,必须用mkimage
工具将其转换成二进制脚本文件boot.scr
。
转换命令:
mkimage -C none -A arm -T script -d boot.env boot.scr
- 生成的
boot.scr
放入 FAT 分区根目录,U-Boot 启动时会自动执行。
4. F1C100s 启动流程
- 设备上电后,硬件首先读取 SD 卡前部的 U-Boot。
- U-Boot 初始化硬件,挂载第1分区(FAT32)。
- U-Boot 加载并执行
boot.scr
脚本。 - 脚本加载内核(
zImage
)和设备树文件(.dtb
)。 - 启动 Linux 内核,挂载根文件系统(ext4 分区)。
5. 如何写入 U-Boot 不破坏分区
- 查看分区起始扇区:
sudo fdisk -l /dev/mmcblk0
- 确认第1分区起始扇区(通常≥2048,代表1MB起始)。
- 使用
dd
命令跳过前8KB,写入 U-Boot:
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8 conv=fsync
- 这样写入位置在 8KB 到 1MB 之间,不会覆盖 MBR 或分区表,保证数据安全。
6. 生成并使用 boot.scr
- 编写启动脚本
boot.env
,例如:
setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=5
fatload mmc 0:1 0x80008000 zImage
fatload mmc 0:1 0x80A00000 f1c100s-licheepi-nano.dtb
bootz 0x80008000 - 0x80A00000
- 使用
mkimage
转换:
mkimage -C none -A arm -T script -d boot.env boot.scr
- 把
boot.scr
放入 FAT 分区:
sudo cp boot.scr /mnt/boot/
这里注意,如果仍从nor-flash启动,uboot的bootcmd 改为 run distro_bootcmd,即按顺序尝试各启动方式。
🧠 总结图解流程:
run distro_bootcmd
└─> boot_targets=fel mmc0 pxe dhcp
├─> run bootcmd_fel
├─> run bootcmd_mmc0
└─> mmc dev 0
└─> scan_dev_for_boot_part
└─> for partition:
└─> if boot.scr → source
└─> if extlinux.conf → sysboot
├─> run bootcmd_pxe
└─> run bootcmd_dhcp
7. 写入命令带进度显示
- 使用支持的
dd
版本加参数:
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8 conv=fsync status=progress
- 或者使用
pv
结合dd
(需要安装pv
):
sudo apt install pv
sudo pv u-boot-sunxi-with-spl.bin | sudo dd of=/dev/mmcblk0 bs=1024 seek=8 conv=fsync
8. 判断写入成功的方法
dd
命令执行结束无报错,并显示写入字节数。fdisk -l /dev/mmcblk0
查看分区表正常。- 可用
dd
和hexdump
查看写入扇区内容:
sudo dd if=/dev/mmcblk0 bs=1024 skip=8 count=16 | hexdump -C
- 最终将 SD 卡插入开发板,连接串口,观察启动日志,确认 U-Boot 正常启动。
9. 参考分区表示例分析
/dev/mmcblk0p1 * 2048 18431 16384 8M c W95 FAT32 (LBA)
/dev/mmcblk0p2 18432 7774207 7755776 3.7G 83 Linux
- 起始扇区2048对应1MB起始。
dd
写入从8KB开始,完全位于第1分区起始前。- MBR 和分区表在扇区0,大小不足8KB,不被覆盖。
10. 总结
步骤 | 说明 |
---|---|
分区 | 一个 FAT32 分区放内核、设备树、启动脚本,一个 ext4 放 rootfs |
写入 U-Boot | 使用 dd 从 8KB 开始写入 u-boot-sunxi-with-spl.bin 到裸设备 |
生成启动脚本 | 用 mkimage 转换 boot.env 为 boot.scr |
拷贝启动文件 | 将 boot.scr 、zImage 、.dtb 拷入 FAT32 分区 |
写入 rootfs | 解压或拷贝 rootfs 到 ext4 分区 |
启动验证 | 观察串口日志确认 U-Boot 和 Linux 内核启动正常 |
祝你开发顺利!🚀