linux块设备驱动通过/sys/block实时映射内核设备模型:每个设备对应gendisk实例,含device/、queue/、holders/等子目录;queue/支持调度器切换与i/o调优;分区为独立目录且动态更新。

Linux 块设备驱动的管理,核心在于理解 sysfs 如何将内核中抽象的设备模型映射为用户空间可读写的文件结构。它不是简单地“查看设备”,而是通过 /sys/block 下的层级关系、属性文件和符号链接,把驱动注册、设备拓扑、队列参数、分区状态等关键信息实时暴露出来。
/sys/block 是块设备的统一视图入口
所有已识别的块设备(如 mmcblk0、sda、nvme0n1)都会在 /sys/block/ 下生成同名子目录。这个目录本身不存储设备数据,而是内核对 block_device 结构体的 sysfs 表达——每个子目录对应一个 gendisk 实例。
- 目录名即设备主节点名,例如 ls /sys/block 可见 mmcblk0、loop0 等;
- 每个子目录下包含 device/(指向 /sys/devices 中的真实设备路径)、queue/(I/O 队列参数)、holders/(挂载该设备的逻辑卷或 DM 设备)、slaves/(底层物理设备,如 RAID 成员盘)等关键子目录;
- 直接位于设备目录下的文件(如 size、ro、range)是只读属性,反映当前设备状态;
- 部分文件(如 queue/scheduler、queue/iostats)支持写入,用于动态调整调度策略或启用统计功能。
通过 device/ 和 devices/ 关联驱动与硬件拓扑
/sys/block/*/device 是一个符号链接,指向 /sys/devices/ 下对应的实际设备路径。这个跳转揭示了驱动与总线、平台控制器之间的绑定关系。
- 例如:readlink /sys/block/mmcblk0/device 可能返回 ../../devices/platform/soc/7824000.sdhci/mmc_host/mmc0/mmc0:0001,说明该 eMMC 设备由 SDHCI 控制器驱动,挂载在 soc 平台总线上;
- 顺着这个路径进入 /sys/devices/,能看到完整的设备树结构:从 platform → sdhci → mmc_host → mmc0 → mmc0:0001,每一级都对应一个 kobject,也对应一个驱动模块或平台设备;
- 在 device 目录下还能看到 driver 符号链接,指向实际加载的驱动(如 /sys/bus/platform/drivers/sdhci_pltfm),确认驱动是否已成功 probe。
利用 queue/ 子目录调优 I/O 行为
/sys/block/*/queue/ 是块设备驱动最关键的配置接口之一,它暴露的是 request_queue 的运行时参数,直接影响性能与功耗。
- rotational:值为 0 表示 SSD 或 eMMC(非旋转介质),影响 I/O 调度器选择逻辑;
- scheduler:显示当前启用的 I/O 调度器(如 mq-deadline、kyber、none),可通过 echo kyber > scheduler 切换(需驱动支持多队列);
- nr_requests:单次请求队列最大请求数,调大可提升吞吐,但增加延迟;
- iosched/(若存在):特定调度器的细粒度参数,如 deadline 的 fifo_batch、read_expire 等;
- add_random:控制是否将设备 I/O 时间戳贡献给内核熵池,对嵌入式系统熵源有实际意义。
分区信息与动态变更感知
块设备的分区(如 mmcblk0p1、sda1)同样出现在 /sys/block/ 下,但它们是独立的子目录,且不包含 device/ 链接——因为分区本身没有独立的硬件实体,只是主设备上的逻辑切片。
- 分区目录下有 start 和 size 文件,单位为扇区(通常是 512 字节),可用于计算偏移与容量;
- partition 文件内容为 1,标识其为分区而非主设备;
- 当执行 fdisk、partprobe 或内核检测到分区表变更时,/sys/block/ 下会自动增删分区目录,无需重启;
- 注意:某些精简内核可能禁用 CONFIG_SYSFS_DEPRECATED_V2,导致旧版分区命名(如 sda1)不再出现,需依赖 udev 规则或 /proc/partitions 辅助识别。
sysfs 对块设备的呈现不是静态快照,而是内核设备模型的实时镜像。掌握它,等于掌握了从驱动加载、硬件绑定、I/O 配置到分区变更的全链路可观测能力。不复杂但容易忽略











