1. 为什么需要SD卡双分区?
在嵌入式Linux开发中,SD卡双分区是常见的系统部署方案。简单来说,就是把一张SD卡分成两个独立区域:FAT32格式的BOOT分区和EXT4格式的rootfs分区。这种设计可不是为了看起来专业,而是有实实在在的好处。
我刚开始接触Petalinux时也不理解为什么要这么麻烦,直到有次更新应用程序时把整个系统搞崩了才明白。双分区最大的优势就是系统与数据分离:BOOT分区放启动文件(如BOOT.BIN、image.ub),rootfs分区放根文件系统。这样当需要更新应用程序时,只需要替换rootfs分区中的文件,完全不会影响启动流程。
另一个实际好处是兼容性。FAT32是通用文件系统,几乎所有硬件都能识别,确保uboot能顺利加载内核;而EXT4则是Linux原生文件系统,支持权限控制、符号链接等高级特性。我在一次项目中就遇到过单分区方案导致设备节点权限丢失的问题,改用双分区后迎刃而解。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 准备工作与环境搭建
2.1 硬件准备清单
- SD卡:建议Class10以上速度,容量至少8GB(我用的是32GB SanDisk Extreme)
- 读卡器:确保能被虚拟机识别(遇到过USB3.0读卡器需要特别配置的情况)
- 开发环境:
- Ubuntu 16.04/18.04 LTS(实测20.04也行)
- VMware/VirtualBox虚拟机(物理机直接操作更简单)
特别提醒:操作前务必备份SD卡数据,分区操作会清空所有内容!我就曾因为忘记备份损失过重要资料。
2.2 软件工具安装
分区工具推荐使用gparted,比fdisk更直观:
bash复制sudo apt update
sudo apt install gparted -y
如果使用虚拟机,记得在插入SD卡时选择连接到虚拟机。遇到过读卡器无法识别的情况,这时需要:
- 在VMware设置中将USB控制器改为USB3.0模式
- 执行
lsusb确认设备是否识别 - 可能需要重启VMware USB仲裁服务:
bash复制sudo vmware-usbarbitrator restart
3. 使用gparted进行分区实战
3.1 清除原有分区
打开gparted时会显示所有存储设备,务必确认选择的是SD卡(根据容量判断)。我有个同事误操作格式化了硬盘,血的教训!
操作步骤:
- 右键点击现有分区 → Unmount
- 再次右键 → Delete
- 重复直到所有分区变为"unallocated"
注意:有些SD卡会有隐藏的保留分区(尤其在Windows格式化过的),一定要全部删除。
3.2 创建BOOT分区
- 右键unallocated空间 → New
- 关键参数设置:
- 文件系统:fat32
- 大小:建议512MB-1GB(我习惯设1GB,避免后期镜像过大)
- Free space preceding:至少4MB(留给uboot参数)
- 设置分区标签为"BOOT"(非必须但建议)

3.3 创建rootfs分区
- 选中剩余空间 → New
- 关键参数:
- 文件系统:ext4
- 使用全部剩余空间
- 标签设为"rootfs"
- 点击√应用操作
常见坑点:
- 如果ext4创建失败(显示unknown),尝试:
- 稍微缩小分区大小(不要用满全部空间)
- 换用其他品牌SD卡(某些廉价卡兼容性差)
4. 文件系统部署详解
4.1 BOOT分区文件部署
将Petalinux生成的启动文件复制到BOOT分区:
bash复制cp BOOT.BIN /media/$USER/BOOT/
cp image.ub /media/$USER/BOOT/
重要检查项:
- 确认文件完整复制(遇到过因SD卡接触不良导致的文件损坏)
- 检查文件权限(特别是从Windows复制时可能丢失可执行权限)
4.2 rootfs分区解压技巧
解压根文件系统时需要root权限:
bash复制sudo tar xvf rootfs.tar.gz -C /media/$USER/rootfs
优化建议:
- 添加
--keep-directory-symlink参数保留符号链接 - 解压后执行
sync确保数据完全写入 - 检查
/dev目录是否生成设备节点
遇到过解压后系统无法启动的情况,最后发现是SD卡速度跟不上导致文件损坏。解决方法:
bash复制sudo chmod -R 755 /media/$USER/rootfs # 确保权限正确
sudo find /media/$USER/rootfs -type d -exec chmod 755 {} \;
5. 启动验证与排错
5.1 常见启动问题
-
卡在"Waiting for root device":
- 检查
/dev/mmcblk0p2是否正确(有些板子是mmcblk1p2) - 确认Petalinux配置中Root filesystem type设为EXT4
- 检查
-
内核panic:
- 检查image.ub是否包含匹配的内核和设备树
- 确认rootfs解压完整(比较文件数量)
-
uboot无法加载镜像:
- 尝试重新格式化BOOT分区(fat32 -F 32)
- 检查BOOT.BIN是否针对当前硬件生成
5.2 调试技巧
- 通过串口查看完整启动日志
- 在uboot中手动测试加载:
bash复制
fatload mmc 0:1 0x10000000 image.ub bootm 0x10000000 - 修改uboot环境变量:
bash复制setenv bootargs 'console=ttyPS0,115200 root=/dev/mmcblk0p2 rw' saveenv
6. 高级配置技巧
6.1 分区大小优化
通过实测给出推荐值:
| 分区类型 | 最小容量 | 推荐容量 | 存放内容 |
|---|---|---|---|
| BOOT | 256MB | 1GB | BOOT.BIN, image.ub |
| rootfs | 2GB | 剩余全部 | 系统文件、应用数据 |
6.2 自动化部署脚本
创建部署脚本deploy_sd.sh:
bash复制#!/bin/bash
BOOT_PART="/media/$USER/BOOT"
ROOTFS_PART="/media/$USER/rootfs"
echo "=== 清空分区 ==="
rm -rf $BOOT_PART/*
sudo rm -rf $ROOTFS_PART/*
echo "=== 复制BOOT文件 ==="
cp BOOT.BIN image.ub $BOOT_PART/
echo "=== 解压rootfs ==="
sudo tar xvf rootfs.tar.gz -C $ROOTFS_PART
echo "=== 设置权限 ==="
sudo chown -R root:root $ROOTFS_PART
sudo chmod -R 755 $ROOTFS_PART
echo "=== 同步数据 ==="
sync
6.3 多系统启动方案
通过修改uboot实现双系统切换:
- 在SD卡上创建第二个rootfs分区(如mmcblk0p3)
- 设置uboot环境变量:
bash复制setenv bootargs_system1 'root=/dev/mmcblk0p2' setenv bootargs_system2 'root=/dev/mmcblk0p3' setenv bootcmd 'run bootcmd_system1' # 默认启动系统1
7. 实际项目经验分享
在工业控制器项目中,我们要求系统能回滚到上一个版本。最终方案是:
- BOOT分区:1GB(存放三套启动文件)
- rootfs_a:8GB(当前系统)
- rootfs_b:8GB(备份系统)
- data分区:剩余空间(应用数据)
通过uboot脚本检测系统健康度,异常时自动切换分区。这个方案成功解决了现场升级失败导致设备变砖的问题。
另一个性能优化案例:通过调整ext4参数提升IO性能:
bash复制sudo mkfs.ext4 -O ^has_journal -E stride=4,stripe_width=512 -L rootfs /dev/mmcblk0p2
在频繁写操作的场景下,这样配置可以减少约30%的写放大效应。
