ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Linux下SD卡分区实战:从fdisk到parted的完整指南

Linux下SD卡分区实战:从fdisk到parted的完整指南

1. 项目概述:为什么要在Linux下分区SD卡?

如果你手头有一张SD卡,无论是准备给树莓派做系统盘,还是想把它格式化成多个分区来分别存放数据和备份,在Linux系统下操作都是一个高效且透明的选择。与Windows下依赖图形化工具不同,Linux的命令行工具提供了更精细的控制权,你能清楚地知道每一个操作步骤背后的原理,这对于嵌入式开发、服务器维护或者仅仅是学习Linux系统管理来说,都是非常宝贵的实践经验。我遇到过很多新手,面对fdiskparted这些命令感到畏惧,但其实一旦理解了磁盘、分区、文件系统这几个核心概念,整个过程就像搭积木一样清晰。今天,我就以一张32GB的SD卡为例,带你走一遍从识别设备到完成分区的完整流程,并分享一些我踩过坑才总结出来的实操技巧。

2. 核心概念与工具选型解析

在动手之前,我们必须搞清楚几个关键概念,这能帮你理解每一步在做什么,而不是机械地输入命令。

2.1 磁盘、分区与文件系统:它们是什么关系?

你可以把整张SD卡想象成一块空地(物理磁盘)。直接在这块空地上盖房子(存放文件)是不现实的,因为太混乱了。我们首先需要在这块空地上划分出几个有明确边界的小区(分区)。最后,在每个小区里,我们还要建立一套管理规则,比如道路怎么修、门牌号怎么编,这套规则就是文件系统(如ext4, FAT32, NTFS)。所以,流程是:物理磁盘 -> 创建分区 -> 在分区上创建文件系统。

在Linux中,一切皆文件,磁盘设备也不例外。你的SD卡插入后,通常会被识别为/dev/sdX(如sdb,sdc)或/dev/mmcblkX(如mmcblk0)。如何区分?简单来说,通过USB读卡器连接的SD卡通常是/dev/sdX格式,而直接插入笔记本SD卡槽或某些嵌入式板载卡槽的,可能是/dev/mmcblkX格式。这是第一个容易混淆的点。

2.2 分区表类型:MBR vs. GPT

在划分小区(分区)之前,我们还需要一张总规划图,这张图就是分区表。它记录了分区的数量、大小和起始位置。主要有两种:

  1. MBR (Master Boot Record):传统格式,历史悠久,兼容性极好。但有两个主要限制:最多只支持4个主分区(可以通过扩展分区和逻辑分区绕开,但稍复杂);单个分区最大支持2TB。
  2. GPT (GUID Partition Table):现代格式,是UEFI启动的标配。它没有分区数量限制(实际操作系统会有限制),支持远超2TB的磁盘容量,并且自带备份,更安全可靠。

对于SD卡,如果你的用途是:

  • 树莓派(旧版):通常使用MBR,因为其Bootloader可能只认MBR。
  • 通用数据存储或现代UEFI设备:优先选择GPT。
  • 容量小于2TB:两者皆可,但GPT是未来趋势。

2.3 工具选择:fdisk vs. parted

Linux下最常用的两个分区工具是fdiskparted

  • fdisk:经典、交互式命令行工具。它简单直观,通过问答式菜单进行操作,非常适合初学者理解分区过程。但它对GPT的支持是后来加入的,在某些老版本系统中可能不是默认选项(需要使用gdisk命令处理GPT)。
  • parted:更强大、支持非交互式(脚本化)操作的工具。它从一开始就原生支持MBR和GPT,并且能处理更多高级功能(如调整已有分区大小)。它的命令语法更直接,但学习曲线稍陡。

我的建议是:如果你是第一次操作,从fdisk开始,它能帮你建立清晰的概念。当你需要批量操作或处理复杂分区时,再转向parted。本文将以fdisk(针对GPT分区表)和parted两种方式分别演示。

重要警告:分区操作会永久性擦除磁盘上的数据!请务必在操作前,通过lsblkfdisk -l命令反复确认你操作的是正确的设备(比如/dev/sdb),而不是你的系统盘(通常是/dev/sda)。误操作会导致数据丢失,无法轻易恢复。

3. 完整实操流程:从识别到挂载

现在,我们进入实战环节。请准备好你的SD卡和Linux环境(可以是实体机、虚拟机,或者通过SSH连接的远程服务器)。

3.1 第一步:准确识别SD卡设备

插入SD卡后,打开终端。我们需要找到系统分配给SD卡的设备名。

方法A:使用lsblk命令(推荐)

lsblk

这个命令会以树状图列出所有块设备(磁盘和分区)。输出类似:

NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 465.8G 0 disk ├─sda1 8:1 0 512M 0 part /boot/efi ├─sda2 8:2 0 732M 0 part /boot └─sda3 8:3 0 464.6G 0 part / sdb 8:16 1 29.7G 0 disk

这里,sda是我的系统硬盘,下面有三个分区。sdb就是我刚插入的、29.7G的SD卡,它目前还没有任何分区(下面没有├─└─开头的行)。RM列为1表示是可移动设备,这也能辅助判断。

方法B:使用fdisk -l命令(需要sudo权限)

sudo fdisk -l

这个命令会列出所有磁盘的详细信息。你需要在一堆输出中找到你的SD卡,通常是通过容量来判断。例如:

Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors Disk model: USB3.0 CRW -SD Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x00000000

这里明确指出了设备是/dev/sdb,容量29.7GiB,并且当前的分区表类型是dos(即MBR)。

记录下你的SD卡设备名,假设为/dev/sdb。接下来的所有操作都将基于这个设备名,请务必根据你的实际情况替换!

3.2 第二步:卸载已挂载的分区(如果存在)

如果这张SD卡之前被使用过,并且系统自动挂载了它的分区(比如在文件管理器里打开了),我们必须先卸载它,否则分区工具无法修改它。

# 首先,检查SD卡是否有分区被挂载 lsblk /dev/sdb # 如果看到类似 sdb1 后面有 MOUNTPOINT,比如 /media/username/XXX,就需要卸载 # 卸载分区,将 sdb1 替换为你的实际分区名 sudo umount /dev/sdb1 # 如果有多个分区,如 sdb2, sdb3,也需要逐一卸载 sudo umount /dev/sdb2

确保所有相关分区都卸载成功后,再进行下一步。

3.3 第三步:使用fdisk创建GPT分区(方案一)

假设我们打算将这张32GB的SD卡分成两个区:一个16GB的ext4分区用于Linux数据,一个16GB的FAT32分区用于跨平台共享。

  1. 启动fdisk并指定设备

    sudo fdisk /dev/sdb

    你会进入fdisk的交互式命令行,提示符变为Command (m for help):

  2. 创建新的GPT分区表(这会清除所有现有数据): 输入g然后按回车。这会创建一个新的GPT磁盘标签(分区表)。终端会提示:Created a new GPT disklabel (GUID: ...)

  3. 创建第一个分区(16GB, ext4)

    • 输入n创建新分区。
    • 分区号直接按回车接受默认值(1)。
    • 第一个扇区直接按回车接受默认值(通常是2048,为对齐留出空间)。
    • 设置分区大小:输入+16G然后回车。这表示分区从起始位置向后延伸16GB。
    • 此时第一个分区创建完成。默认分区类型是“Linux filesystem”,这正合我们意(对应ext4)。
  4. 创建第二个分区(剩余空间, FAT32)

    • 再次输入n创建第二个分区。
    • 分区号、起始扇区都直接按回车接受默认值(它会自动接在上一个分区之后)。
    • 结束扇区直接按回车,表示使用所有剩余空间。
    • 现在,我们需要更改这个分区的类型。输入t然后回车。
    • 选择分区号2
    • 输入分区类型代码L来列出所有已知类型代码。
    • 在列表中寻找“Microsoft basic data”或“W95 FAT32 (LBA)”,其代码通常是bc。我们输入c(对应W95 FAT32 LBA)。
    • 终端会提示:Changed type of partition 'Linux filesystem' to 'W95 FAT32 (LBA)'
  5. 检查分区布局: 输入p打印当前的分区表,检查一下是否和你预期的一致。应该能看到两个分区,sdb1和sdb2,大小和类型正确。

  6. 将更改写入磁盘(关键一步): 确认无误后,输入w然后回车,将分区表写入磁盘并退出fdisk。这是一个不可逆的操作!如果发现错了,可以输入q不保存退出。

3.4 第四步:使用parted创建分区(方案二)

如果你更喜欢parted的直接,或者需要脚本化,可以这样做:

  1. 启动parted

    sudo parted /dev/sdb
  2. 创建GPT分区表

    mklabel gpt

    输入yes确认。

  3. 创建第一个分区

    mkpart primary ext4 1MiB 16GiB
    • primary是分区类型(主分区)。
    • ext4是文件系统类型(parted会记录这个信息,但实际格式化仍需单独进行)。
    • 1MiB 16GiB是分区的起始和结束位置。这里强烈建议使用MiB/GiB为单位并从1MiB开始,这能保证分区的最佳性能(对齐)
  4. 创建第二个分区

    mkpart primary fat32 16GiB 100%

    100%表示用到磁盘末尾。

  5. 查看与退出

    print # 查看分区表 quit # 退出parted

3.5 第五步:在分区上创建文件系统(格式化)

分区只是划好了地盘,现在要给每个地盘建立管理规则(文件系统)。我们需要针对每个分区单独操作。

  1. 格式化第一个分区为ext4

    sudo mkfs.ext4 /dev/sdb1

    命令会执行,输出一些信息,最后显示Writing superblocks and filesystem accounting information完成。

  2. 格式化第二个分区为FAT32

    sudo mkfs.vfat -F 32 /dev/sdb2

    -F 32参数指定了FAT32格式。对于大于32GB的分区,Windows的format命令可能不允许用FAT32,但Linux的mkfs.vfat通常可以,不过出于兼容性考虑,大分区更推荐exFAT(sudo mkfs.exfat /dev/sdb2)。

3.6 第六步:挂载并使用新分区

格式化后,分区就可以使用了。你可以手动挂载到任意目录。

# 创建两个挂载点目录 sudo mkdir -p /mnt/data_ext4 sudo mkdir -p /mnt/data_fat32 # 挂载分区 sudo mount /dev/sdb1 /mnt/data_ext4 sudo mount /dev/sdb2 /mnt/data_fat32 # 检查挂载结果 df -h /dev/sdb1 /dev/sdb2

现在,你就可以通过/mnt/data_ext4/mnt/data_fat32这两个目录来访问SD卡上的两个分区了。向里面复制文件试试吧。

想让SD卡插入时自动挂载?这需要修改/etc/fstab文件,但考虑到SD卡可能在不同机器间插拔,自动挂载配置容易因设备名(/dev/sdb可能变成/dev/sdc)变化而出错。更现代的方案是使用文件系统的UUID或LABEL来标识分区,但这属于进阶内容,初期建议手动挂载更安全。

4. 高级技巧与深度解析

掌握了基本流程后,我们来看看一些能提升效率、避免问题的进阶知识。

4.1 分区对齐:为什么从1MiB开始?

在之前parted的示例中,我特意让分区从1MiB开始,而不是0扇区或1扇区。这叫做分区对齐。现代存储设备(SSD、SD卡、高级格式硬盘)的物理扇区大小通常是4KB(4096字节)。如果分区的起始位置不是4KB的整数倍,那么一个文件系统逻辑块(比如4KB)可能会跨越两个物理扇区。当读写这个块时,设备就需要进行两次操作,严重降低性能,这种现象称为“读写放大”。

1MiB(1048576字节,正好是4096的整数倍)开始,可以确保分区与绝大多数存储设备的物理结构对齐,从而获得最佳性能。fdisk的新版本在创建GPT分区时,默认起始扇区就是2048(2048扇区 * 512字节/扇区 = 1MiB),已经帮我们做了对齐。

4.2 使用UUID或LABEL挂载的稳定性

/etc/fstab中,用/dev/sdb1这样的设备名来挂载是非常不可靠的,因为设备名(sda,sdb,sdc)取决于系统检测到设备的顺序。今天你的SD卡是sdb,明天插了个U盘可能就变成sdc了。

更稳定的方法是使用UUID(全局唯一标识符)LABEL(卷标)

  • 查看分区的UUID和LABEL

    sudo blkid /dev/sdb1 /dev/sdb2

    输出类似:

    /dev/sdb1: UUID="a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" TYPE="ext4" /dev/sdb2: UUID="1234-ABCD" TYPE="vfat"
  • 在格式化时指定LABEL(可选但推荐):

    sudo mkfs.ext4 -L "MyLinuxData" /dev/sdb1 sudo mkfs.vfat -F 32 -n "MySharedData" /dev/sdb2

    之后在/etc/fstab中就可以这样写:

    UUID=a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8 /mnt/data_ext4 ext4 defaults 0 2 LABEL=MySharedData /mnt/data_fat32 vfat defaults,uid=1000,gid=1000,umask=022 0 0

    这样,无论设备名怎么变,系统都能准确找到并挂载正确的分区。

4.3 处理已分配全盘空间的分区表

有时候,你可能会遇到一种情况:SD卡显示有一个分区占用了全部容量(比如/dev/sdb1),但你用fdisk删除这个分区并创建新分区表时,可能会失败或报错。这通常是因为旧的分区信息还被内核缓存着。

解决方法:使用wipefs命令清除设备上的所有文件系统签名和分区表信息,然后让内核重新读取。

# 谨慎操作!确认/dev/sdb是你的SD卡 sudo wipefs -a /dev/sdb # 然后通知内核重新读取分区表 sudo partprobe /dev/sdb # 或者更彻底地,可以断开再重新连接SD卡硬件

执行完wipefs后,设备在lsblk里会显示为一个没有任何分区的纯净磁盘,此时再使用fdiskparted进行操作就会非常顺利。

5. 常见问题与排查技巧实录

即使按照步骤操作,也可能会遇到各种问题。这里记录了几个我亲身经历过的“坑”及其解决办法。

5.1 问题:fdisk中看不到新建的分区,或者lsblk不显示

  • 现象:在fdisk里用w命令保存退出后,立刻用lsblk查看,发现分区(如sdb1)没有出现。
  • 原因:内核没有及时更新内存中的分区表信息。
  • 解决:运行sudo partprobe /dev/sdb命令通知内核重新读取/dev/sdb的分区表。如果还不行,最彻底的方法是物理上重新拔插一次SD卡,或者使用sudo udevadm trigger

5.2 问题:无法格式化,提示“Device or resource busy”

  • 现象:运行mkfs命令时,报错/dev/sdb1 is apparently in use by the system; will not make a filesystem here!
  • 原因:该分区正在被系统使用,最常见的原因就是它被自动挂载了(比如桌面环境文件管理器的自动挂载功能)。
  • 解决
    1. 使用lsblkmount | grep sdb1确认分区是否被挂载。
    2. 使用sudo umount /dev/sdb1卸载它。
    3. 如果卸载失败,检查是否有终端窗口的当前工作目录(pwd)正在该分区下,或者是否有程序正在访问该分区内的文件。关闭这些程序或切换到其他目录。

5.3 问题:Windows无法识别Linux创建的分区

  • 现象:在Linux下分好区并格式化的SD卡,插到Windows电脑上,只显示其中一个分区(通常是FAT32那个),或者提示需要格式化。
  • 原因
    1. 文件系统不支持:Windows默认不支持ext2/3/4文件系统。所以ext4分区在Windows下不可见是正常的。
    2. 分区表问题:如果你创建的是GPT分区表,而你的Windows系统是较旧的Legacy BIOS模式,可能无法正确识别。
    3. “隐藏”的ESP/MSR分区:如果你不小心创建了EFI系统分区(ESP)或Microsoft保留分区(MSR),Windows可能会表现出奇怪的行为。
  • 解决
    1. 对于需要在Windows和Linux间共享的数据,请使用FAT32、exFAT或NTFS分区。
    2. 确保SD卡的分区表类型(MBR/GPT)与目标设备兼容。对于最大兼容性,老设备用MBR。
    3. 在Linux下用sudo fdisk -l /dev/sdb仔细检查分区类型。确保数据分区的类型是“Microsoft basic data”(代码0700in MBR 或EBD0A0A2-B9E5-4433-87C0-68B6B72699C7in GPT)。

5.4 问题:分区后容量“缩水”了

  • 现象:一张标称32GB的SD卡,分区格式化后,在文件管理器里显示只有29.7GB左右可用。
  • 原因:这是完全正常的,并非操作错误。厂商的“GB”是十进制(1GB = 10^9 bytes),而操作系统的“GiB”是二进制(1GiB = 2^30 bytes)。32,000,000,000 bytes ≈ 29.8 GiB。此外,文件系统本身(如ext4的inode表、日志区)和分区表也会占用少量空间。
  • 解决:无需解决,这是预期行为。你可以通过df -hsudo fdisk -l对比查看,总容量基本是匹配的。

5.5 快速问题排查清单

问题现象可能原因排查命令/步骤
找不到/dev/sdb设备SD卡未识别、接触不良、读卡器故障dmesg | tail查看内核日志;重新插拔;换读卡器或接口
fdisk命令报错或无响应设备被锁定、有进程占用sudo lsof | grep /dev/sdb查看占用进程;sudo umount卸载所有分区
格式化速度极慢或报I/O错误SD卡物理损坏、寿命将至sudo badblocks -sv /dev/sdb检测坏块(慎用,会写数据)
写入文件时提示“只读文件系统”文件系统损坏、SD卡写保护开关打开检查SD卡侧面的物理锁;尝试sudo fsck /dev/sdb1修复文件系统

最后,分享一个我自己的习惯:在对任何存储设备进行分区操作前,如果里面有重要数据,我一定会先用ddrsync做一次完整的磁盘或文件备份。命令看起来复杂,但dd if=/dev/sdb of=~/sd_card_backup.img bs=4M status=progress这一行命令,可能在某天会救你于水火。分区有风险,操作需谨慎,但一旦掌握了原理和工具,你就能完全掌控这些存储介质,让它们在你的项目中发挥最大效用。

返回列表