当前位置:首页 > Linux > 正文

Linux识别硬盘的底层原理

Linux通过内核驱动识别物理存储设备,在 /dev目录生成设备文件(如sda、nvme0n1),系统读取设备分区表(如MBR/GPT)识别分区,用户需挂载分区才能访问文件系统数据。

硬件探测:内核与硬件的初次握手

  1. 固件层交互 (BIOS/UEFI)
    • 计算机启动时,固件(BIOS或UEFI)执行初始硬件检测(POST)。
    • 它识别连接到主板上的存储控制器(如SATA控制器、NVMe控制器、USB主控制器、RAID卡)以及它们连接的基本设备。
    • 固件将这些信息构建成一张硬件设备表,传递给启动的Linux内核。
  2. 内核初始化与总线扫描
    • 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(见下文)会动态加载。

设备节点创建:与用户空间的桥梁

  1. udev 守护进程登场
    • 内核检测到新设备(如一个磁盘控制器识别到一个新硬盘)时,会在内核内部生成一个uevent(用户事件)。
    • udev(用户空间设备管理器)监听来自内核的这些uevent事件。
  2. 创建设备文件 (/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)。

分区表识别:理解磁盘布局

  1. 工具介入 (partprobe, blkid)
    • 设备节点创建后,用户空间工具(通常由udev规则触发或系统管理员手动运行)开始工作。
    • partprobe (或 blockdev --rereadpt): 通知内核重新读取指定块设备(如/dev/sda)的分区表,这对于新分区或分区表更改后让内核感知至关重要。
  2. 读取分区表
    • 内核(通过相应的驱动)读取磁盘前端的分区表信息。
    • 常见的分区表格式:
      • MBR (Master Boot Record): 传统格式,最多支持4个主分区(或3主+1扩展,扩展内可含多个逻辑分区)。
      • GPT (GUID Partition Table): 现代标准,支持更多分区(通常128个)、更大磁盘容量、存储磁盘唯一GUID和分区唯一GUID。
    • 内核根据分区表信息,为检测到的每个分区/dev目录下创建对应的设备文件(如/dev/sda1, /dev/nvme0n1p2),同样由udev规则管理其命名和链接。

文件系统识别与挂载:访问存储内容

  1. 文件系统探测 (blkid, lsblk -f)
    • 工具如blkidlsblk -f会读取每个分区(如/dev/sda1)开头的超级块 (Superblock) 信息。
    • 超级块包含关键元数据,用于识别分区上格式化的文件系统类型(如ext4, XFS, Btrfs, NTFS, FAT32, swap)以及唯一的文件系统UUID
    • 这些信息被缓存(例如在/run/blkid)并可通过udev规则创建/dev/disk/by-uuid//dev/disk/by-label/(如果文件系统有标签)链接。
  2. 挂载 (mount)
    • 识别出文件系统后,用户(或自动挂载服务如udisks2/桌面环境)才能使用mount命令将分区关联到目录树中的一个挂载点(如/mnt/data, /home)。
    • 手动挂载sudo mount /dev/sdb1 /mnt/mydrive
    • 通过UUID/Label挂载 (更可靠): sudo mount UUID="5e3a7bb5-..." /mnt/mydrivesudo mount LABEL="MyData" /mnt/mydrive
    • 自动挂载
      • /etc/fstab: 系统启动时自动挂载的配置文件,可指定设备(路径、UUID或Label)、挂载点、文件系统类型、挂载选项等。
      • udisks2 / GVfs: 在桌面环境中,插入可移动媒体(U盘)时,该服务会自动探测、挂载(通常在/run/media/$USER/下)并在文件管理器中显示。
  3. 访问数据
    • 挂载成功后,挂载点目录(如/mnt/mydrive)就成为访问该分区文件系统内容的入口,应用程序和用户可以通过标准的文件操作(读、写、创建、删除)使用存储空间。

高级存储管理 (LVM, RAID, Multipath)

对于更复杂的存储配置,Linux提供强大的企业级工具:

Linux识别硬盘的底层原理  第1张

  1. 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。
  2. 软件 RAID (mdadm)
    • 将多个物理磁盘组合成RAID阵列(如RAID 0, 1, 5, 6, 10)。
    • 内核的md(多设备)驱动管理RAID阵列,创建对应的设备文件(如/dev/md0)。
    • mdadm 工具负责组装、监控和管理阵列。
  3. 多路径 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/sdXblockdev --rereadpt /dev/sdX
  • 管理挂载mount, umount, 查看/etc/fstab, df -hT, findmnt
  • LVMpvdisplay, vgdisplay, lvdisplay, pvs, vgs, lvs
  • 软件RAIDcat /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 等硬件接口标准文档 (由相关标准组织发布)
0