从零写 OS 内核-第二十二篇:设备模型与 devfs —— 统一管理所有硬件设备

从零写 OS 内核-第二十二篇:设备模型与 devfs —— 统一管理所有硬件设备

“你的内核有 UART、VGA、IDE、TTY,但它们各自为政,无法统一管理。 今天,我们构建设备模型,实现 devfs,让所有设备像文件一样被发现和操作!”

在前面的篇章中,我们实现了多个硬件驱动:

UART

(串口)
VGA

(显卡)
IDE

(硬盘)
TTY

(终端)
PIT

(时钟)

但这些驱动都是 孤立的 :

没有统一的设备注册机制
用户无法通过
/dev
查看可用设备
新增驱动需硬编码路径(如
open(“/dev/tty0”)

真正的操作系统,必须提供 统一的设备抽象 ,并支持 动态设备发现 。

今天,我们就来: ✅ 设计设备模型(Device Model) ✅ 实现 devfs(设备文件系统) ✅ 自动挂载 /dev 并列出所有设备

让你的 OS 拥有 现代设备管理能力 !


🧩 一、为什么需要设备模型?

当前驱动的问题:

问题 后果
无统一接口 每个驱动实现自己的 open / read
设备路径硬编码 用户需记住 /dev/tty0 、 /dev/hda
无法动态发现 新增设备需修改内核代码

设备模型的核心思想:

“一切设备皆对象,一切操作皆文件”

设备注册

:驱动启动时向内核注册设备
设备类(Class)

:按类型分组(如 tty、block、input)
设备文件系统(devfs)

:自动在
/dev
创建设备节点

💡 Linux 的 sysfs + devtmpfs 正是基于此思想 !


🏗️ 二、设备模型核心数据结构

  1. 设备结构体(device)

  2. 设备驱动(device_driver)

  3. 设备号管理


🔌 三、设备注册与驱动匹配

  1. 注册设备

  2. TTY 设备注册示例

  3. 块设备注册示例(IDE)

✅ 所有设备通过统一接口注册 !


📁 四、实现 devfs:设备文件系统

devfs 是一个 内存中的虚拟文件系统 ,自动在 /dev 创建设备节点。

  1. devfs 超级块与 inode

  2. 自动创建设备节点

  3. 挂载 devfs


🧪 五、用户空间:通过 /dev 访问设备

  1. 列出所有设备

  2. 操作设备(与之前相同)

  3. VFS 如何找到设备?

    open(“/dev/tty0”)

    → VFS 查找 dentry
    dentry 的 inode 包含
    i_rdev = mkdev(4, 0)
    VFS 调用
    chrdev_open
    ,根据主设备号 4 找到 TTY 驱动
    驱动的
    fops
    被用于后续
    read
    /
    write

🔑 设备号是 VFS 与驱动之间的桥梁 !


🧱 六、字符设备与块设备框架

  1. 字符设备注册表

  2. 块设备注册表

  3. 驱动注册


🧪 七、测试:动态设备发现

内核启动日志:

用户空间验证:

✅ 所有设备自动出现在 /dev ,无需硬编码路径 !


⚠️ 八、高级话题:设备树与热插拔

  1. 设备树(Device Tree)

    用于描述硬件拓扑(ARM 常用)
    内核解析设备树,自动创建设备

  2. 热插拔(Hotplug)

    USB 设备插入时,动态创建
    /dev/sda
    需要 netlink 事件通知用户空间

  3. udev 替代 devfs

    Linux 后期用
    udev
    (用户空间)替代 devfs
    支持更灵活的命名规则(如
    /dev/disk/by-id/…

💡 我们的 devfs 是简化版,但核心思想一致 !


💬 写在最后

设备模型是操作系统 硬件抽象的巅峰 。 它让驱动开发者专注硬件细节, 让用户和应用程序以统一方式访问设备。

今天你创建的 /dev/tty0 , 正是 Linux 中 /dev 目录的简化起源。

🌟 统一的抽象,是复杂系统的优雅解药。


📬 动手挑战 : 为你的 VGA 驱动添加设备注册,并在 /dev 中创建 vga 节点。 欢迎在评论区分享你的设备模型扩展!

👇 下一篇你想看: udev 用户空间设备管理 ,还是 USB 驱动框架 ?


#操作系统 #内核开发 #设备模型 #devfs #驱动架构 #硬件抽象 #从零开始

最后修改: 2026年7月1日

作者

评论

发表评论

您的邮箱地址不会被公开。