上一篇
Linux识别硬盘的底层原理
- Linux
- 2025-07-02
- 4744
Linux通过内核驱动识别物理存储设备,在
/dev
目录生成设备文件(如sda、nvme0n1),系统读取设备分区表(如MBR/GPT)识别分区,用户需挂载分区才能访问文件系统数据。
硬件探测:内核与硬件的初次握手
- 固件层交互 (BIOS/UEFI):
- 计算机启动时,固件(BIOS或UEFI)执行初始硬件检测(POST)。
- 它识别连接到主板上的存储控制器(如SATA控制器、NVMe控制器、USB主控制器、RAID卡)以及它们连接的基本设备。
- 固件将这些信息构建成一张硬件设备表,传递给启动的Linux内核。
- 内核初始化与总线扫描:
- Linux内核启动后,其核心部分和内置的驱动程序开始工作。
- 内核按层次扫描系统总线(如PCIe, USB, SCSI, ATA):
- PCIe总线: 识别NVMe SSD控制器、SATA控制器、HBA卡(主机总线适配器)、RAID控制器等。
- USB总线: 识别插入的U盘、移动硬盘。
- SCSI总线: 不仅包括物理SCSI设备,现代Linux内核将SATA/SAS/USB大容量存储/NVMe设备都映射到统一的SCSI子系统(
sd
驱动)进行管理,简化了架构。 - 其他总线: 如虚拟总线(用于虚拟机环境)。
- 内核为检测到的每个控制器加载相应的内核模块(驱动)(如
ahci
for SATA,nvme
for NVMe,usb-storage
for USB drives,megaraid_sas
for LSI RAID cards),如果模块未内置,udev(见下文)会动态加载。
设备节点创建:与用户空间的桥梁
udev
守护进程登场:- 内核检测到新设备(如一个磁盘控制器识别到一个新硬盘)时,会在内核内部生成一个
uevent
(用户事件)。 udev
(用户空间设备管理器)监听来自内核的这些uevent
事件。
- 内核检测到新设备(如一个磁盘控制器识别到一个新硬盘)时,会在内核内部生成一个
- 创建设备文件 (
/dev/...
):udev
根据接收到的设备信息(如设备类型、厂商ID、产品ID、唯一标识符如WWN或UUID、在总线上的位置等),应用存储在/etc/udev/rules.d/
和/lib/udev/rules.d/
目录下的规则集。- 这些规则决定:
- 在
/dev
目录下创建设备文件的名称(如sda
,nvme0n1
,vda
)。 - 设备文件的权限和所有权。
- 创建有意义的符号链接(如
/dev/disk/by-id/ata-WDC_WD40EFZX-68AWUN0_WD-WX32DA19K9XK
,/dev/disk/by-uuid/5e3a7bb5-...
),提供稳定、持久的访问点,即使设备物理位置(如哪个SATA端口)改变。
- 在
- 常见的磁盘设备文件命名约定:
/dev/sdX
: SCSI/SATA/SAS/USB 磁盘 (e.g.,sda
,sdb
,sdc
),分区为数字后缀 (e.g.,sda1
,sda2
)。/dev/nvmeXnY
: NVMe 固态硬盘 (e.g.,nvme0n1
表示第一个控制器的第一个命名空间),分区为p
加数字 (e.g.,nvme0n1p1
)。/dev/vdX
: 虚拟化环境(如KVM)中的虚拟磁盘 (e.g.,vda
,vdb
),分区类似sdX
。/dev/mmcblkX
: SD卡/eMMC存储 (e.g.,mmcblk0
),分区为p
加数字 (e.g.,mmcblk0p1
)。
分区表识别:理解磁盘布局
- 工具介入 (
partprobe
,blkid
):- 设备节点创建后,用户空间工具(通常由
udev
规则触发或系统管理员手动运行)开始工作。 partprobe
(或blockdev --rereadpt
): 通知内核重新读取指定块设备(如/dev/sda
)的分区表,这对于新分区或分区表更改后让内核感知至关重要。
- 设备节点创建后,用户空间工具(通常由
- 读取分区表:
- 内核(通过相应的驱动)读取磁盘前端的分区表信息。
- 常见的分区表格式:
- MBR (Master Boot Record): 传统格式,最多支持4个主分区(或3主+1扩展,扩展内可含多个逻辑分区)。
- GPT (GUID Partition Table): 现代标准,支持更多分区(通常128个)、更大磁盘容量、存储磁盘唯一GUID和分区唯一GUID。
- 内核根据分区表信息,为检测到的每个分区在
/dev
目录下创建对应的设备文件(如/dev/sda1
,/dev/nvme0n1p2
),同样由udev
规则管理其命名和链接。
文件系统识别与挂载:访问存储内容
- 文件系统探测 (
blkid
,lsblk -f
):- 工具如
blkid
或lsblk -f
会读取每个分区(如/dev/sda1
)开头的超级块 (Superblock) 信息。 - 超级块包含关键元数据,用于识别分区上格式化的文件系统类型(如ext4, XFS, Btrfs, NTFS, FAT32, swap)以及唯一的文件系统UUID。
- 这些信息被缓存(例如在
/run/blkid
)并可通过udev
规则创建/dev/disk/by-uuid/
和/dev/disk/by-label/
(如果文件系统有标签)链接。
- 工具如
- 挂载 (
mount
):- 识别出文件系统后,用户(或自动挂载服务如
udisks2
/桌面环境)才能使用mount
命令将分区关联到目录树中的一个挂载点(如/mnt/data
,/home
)。 - 手动挂载:
sudo mount /dev/sdb1 /mnt/mydrive
- 通过UUID/Label挂载 (更可靠):
sudo mount UUID="5e3a7bb5-..." /mnt/mydrive
或sudo mount LABEL="MyData" /mnt/mydrive
- 自动挂载:
/etc/fstab
: 系统启动时自动挂载的配置文件,可指定设备(路径、UUID或Label)、挂载点、文件系统类型、挂载选项等。- udisks2 / GVfs: 在桌面环境中,插入可移动媒体(U盘)时,该服务会自动探测、挂载(通常在
/run/media/$USER/
下)并在文件管理器中显示。
- 识别出文件系统后,用户(或自动挂载服务如
- 访问数据:
- 挂载成功后,挂载点目录(如
/mnt/mydrive
)就成为访问该分区文件系统内容的入口,应用程序和用户可以通过标准的文件操作(读、写、创建、删除)使用存储空间。
- 挂载成功后,挂载点目录(如
高级存储管理 (LVM, RAID, Multipath)
对于更复杂的存储配置,Linux提供强大的企业级工具:
- LVM (Logical Volume Manager):
- 物理磁盘(PV)加入卷组(VG),在VG上创建灵活的逻辑卷(LV)。
- 内核通过
device-mapper
(dm
) 驱动创建LV对应的设备文件(如/dev/mapper/vg00-lv_root
,/dev/vg00/lv_home
)。 udev
和 LVM 工具 (pvscan
,vgscan
,lvscan
) 协同工作,在启动或添加PV时激活VG和LV。
- 软件 RAID (mdadm):
- 将多个物理磁盘组合成RAID阵列(如RAID 0, 1, 5, 6, 10)。
- 内核的
md
(多设备)驱动管理RAID阵列,创建对应的设备文件(如/dev/md0
)。 mdadm
工具负责组装、监控和管理阵列。
- 多路径 I/O (Multipath):
- 为高可用性,服务器通常通过多条物理路径(如不同的HBA卡和交换机)连接到存储(SAN)。
device-mapper-multipath
(dm-multipath
) 驱动将指向同一物理LUN(逻辑单元号)的多条路径聚合成一个单一的虚拟设备(如/dev/mapper/mpatha
)。- 提供故障切换和负载均衡。
关键工具与命令速查
- 查看块设备:
lsblk
(清晰树状图),fdisk -l
,parted -l
,blkid
,cat /proc/partitions
- 查看SCSI/SATA设备:
lsscsi
,lspci | grep -i "sata|sas|scsi"
- 查看USB设备:
lsusb
,usb-devices
- 查看内核信息:
dmesg | grep -i "scsi|sata|usb|sd|nvme"
(查看探测日志) - 重新扫描总线/设备:
- SCSI:
echo "- - -" > /sys/class/scsi_host/hostX/scan
(替换X) - 重新读分区表:
partprobe /dev/sdX
或blockdev --rereadpt /dev/sdX
- SCSI:
- 管理挂载:
mount
,umount
, 查看/etc/fstab
,df -hT
,findmnt
- LVM:
pvdisplay
,vgdisplay
,lvdisplay
,pvs
,vgs
,lvs
- 软件RAID:
cat /proc/mdstat
,mdadm --detail /dev/mdX
- 多路径:
multipath -ll
常见问题与排查
- 设备未出现在
/dev
下? 检查dmesg
看内核是否识别硬件/驱动;检查udev
规则/日志(journalctl -u udev
)。 - 分区未显示? 运行
partprobe /dev/sdX
;检查分区表是否损坏(fdisk
,gdisk
,testdisk
)。 - 文件系统无法挂载?
dmesg
看错误;blkid
确认类型;尝试fsck
修复;检查/etc/fstab
语法。 - 性能慢? 检查
dmesg
/journalctl
有无错误/降级信息;使用hdparm -tT /dev/sdX
(谨慎),dd
,fio
测试;检查IO调度器(cat /sys/block/sdX/queue/scheduler
)、队列深度、是否启用写入缓存(需安全策略支持)。 - LVM/VG/LV未激活? 运行
vgchange -ay
。
引用说明:
- Linux内核文档 (
Documentation/block/
,Documentation/admin-guide/devices.txt
) – https://www.kernel.org/doc/html/latest/ udev
手册页 (man 7 udev
,man 8 udevadm
) 及 systemd 项目文档 – https://www.freedesktop.org/software/systemd/man/lsblk
,blkid
,fdisk
,parted
,mount
,lvm
,mdadm
,multipath
等工具的手册页 (man
)- Linux Standard Base (LSB) 规范 (部分相关) – https://refspecs.linuxfoundation.org/lsb.shtml
- SCSI, ATA, NVMe, UEFI 等硬件接口标准文档 (由相关标准组织发布)