作为一名嵌入式Linux开发者,我经常需要在I.MX6ULL平台上进行系统部署。TF卡烧写是最基础却最容易出问题的环节,今天我就把多年积累的经验系统梳理出来,特别是那些官方文档不会告诉你的"坑"。
在I.MX6ULL开发中,我们通常采用混合分区方案:
这种设计基于三个关键考量:
实际项目中我曾遇到过EXT4分区在Windows下无法识别的问题,后来发现可以用Linux虚拟机访问,或者使用ext2read等工具在Windows下读取EXT4分区内容。
典型的分区表如下(使用fdisk查看):
code复制Device Boot Start End Sectors Size Id Type
/dev/sdb1 2048 133119 131072 64M c W95 FAT32 (LBA)
/dev/sdb2 133120 4194303 4061184 1.9G 83 Linux
这里第一个分区是FAT32,第二个是EXT4,前2048个扇区(1MB)保留给U-Boot。
Buildroot的构建过程可以分为三个阶段:
关键配置项:
Buildroot构建完成后,各组件需要放置到正确位置:
| 组件 | 存放位置 | 文件系统格式 |
|---|---|---|
| U-Boot | 裸区(未分区空间) | 无 |
| zImage | FAT32分区 | FAT32 |
| .dtb文件 | FAT32分区 | FAT32 |
| rootfs | EXT4分区 | EXT4 |
我曾犯过一个典型错误 - 把ARM架构的根文件系统烧录到x86开发机,导致系统无法启动。切记要确认架构匹配!
bash复制# 确认TF卡设备节点(非常重要!)
lsblk
# 烧写U-Boot到裸区(注意是设备节点而非分区)
sudo dd if=u-boot-imx6ull-14x14-evk.imx of=/dev/sdX bs=1K seek=2 conv=fsync
参数解析:
bs=1K:每次读写块大小为1KBseek=2:跳过前2KB(i.MX6ULL的BootROM要求)conv=fsync:确保数据完全写入物理设备血的教训:曾经误把/dev/sda当作TF卡设备,导致主机系统崩溃。务必反复确认设备节点!
bash复制# 使用fdisk创建分区
sudo fdisk /dev/sdX
# 命令序列:
# n (新建分区), p (主分区), 1 (分区号), 2048 (起始扇区), +64M (大小)
# t (修改类型), c (FAT32)
# n, p, 2 (剩余空间)
# w (写入)
# 格式化分区
sudo mkfs.vfat -F 32 -n BOOT /dev/sdX1
sudo mkfs.ext4 -L rootfs /dev/sdX2
正确操作流程:
bash复制# 挂载分区
sudo mount /dev/sdX1 /mnt/boot
sudo mount /dev/sdX2 /mnt/rootfs
# 复制文件
cp zImage *.dtb /mnt/boot/
tar xvf rootfs.tar -C /mnt/rootfs
# 卸载分区(必须执行!)
sync
sudo umount /mnt/boot
sudo umount /mnt/rootfs
常见错误:
通过串口查看启动参数:
bash复制cat /proc/cmdline
典型输出差异:
root=/dev/mmcblk0p2root=/dev/mmcblk1p2在U-Boot命令行中检查:
bash复制printenv mmcdev
正确应该显示:
code复制mmcdev=0 # 表示从SD卡启动
无法进入U-Boot:
内核panic:
根文件系统挂载失败:
TF卡选型:
文件系统优化:
bash复制# EXT4关闭访问时间记录
tune2fs -o journal_data_writeback /dev/sdX2
tune2fs -O ^has_journal /dev/sdX2
内核参数调整:
在bootargs中添加:
code复制rootflags=data=writeback commit=5
这是我常用的烧写脚本示例:
bash复制#!/bin/bash
DEVICE=$1
if [ -z "$DEVICE" ]; then
echo "Usage: $0 /dev/sdX"
exit 1
fi
# 烧写U-Boot
dd if=u-boot.imx of=$DEVICE bs=1K seek=2 conv=fsync
# 创建分区
parted -s $DEVICE mklabel msdos
parted -s $DEVICE mkpart primary fat32 1MiB 65MiB
parted -s $DEVICE mkpart primary ext4 65MiB 100%
# 格式化
mkfs.vfat -F 32 -n BOOT ${DEVICE}1
mkfs.ext4 -L rootfs ${DEVICE}2
# 挂载并复制文件
mount ${DEVICE}1 /mnt/boot
mount ${DEVICE}2 /mnt/rootfs
cp zImage *.dtb /mnt/boot/
tar xvf rootfs.tar -C /mnt/rootfs
# 清理
sync
umount /mnt/boot
umount /mnt/rootfs
使用这个脚本可以大幅减少人工操作失误。建议保存为flash_sd.sh,使用时执行:
bash复制sudo ./flash_sd.sh /dev/sdX
记得在实际使用前,一定要确认设备节点是否正确!