从零写 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 正是基于此思想 !
🏗️ 二、设备模型核心数据结构
- 设备结构体(device)
-
设备驱动(device_driver)
-
设备号管理
🔌 三、设备注册与驱动匹配
-
注册设备
-
TTY 设备注册示例
-
块设备注册示例(IDE)
✅ 所有设备通过统一接口注册 !
📁 四、实现 devfs:设备文件系统
devfs 是一个 内存中的虚拟文件系统 ,自动在 /dev 创建设备节点。
- devfs 超级块与 inode
-
自动创建设备节点
-
挂载 devfs
🧪 五、用户空间:通过 /dev 访问设备
-
列出所有设备
-
操作设备(与之前相同)
-
VFS 如何找到设备?
open(“/dev/tty0”)
→ VFS 查找 dentry
dentry 的 inode 包含
i_rdev = mkdev(4, 0)
VFS 调用
chrdev_open
,根据主设备号 4 找到 TTY 驱动
驱动的
fops
被用于后续
read
/
write
🔑 设备号是 VFS 与驱动之间的桥梁 !
🧱 六、字符设备与块设备框架
- 字符设备注册表
-
块设备注册表
-
驱动注册
🧪 七、测试:动态设备发现
内核启动日志:
用户空间验证:
✅ 所有设备自动出现在 /dev ,无需硬编码路径 !
⚠️ 八、高级话题:设备树与热插拔
- 设备树(Device Tree)
用于描述硬件拓扑(ARM 常用)
内核解析设备树,自动创建设备 -
热插拔(Hotplug)
USB 设备插入时,动态创建
/dev/sda
需要 netlink 事件通知用户空间 -
udev 替代 devfs
Linux 后期用
udev
(用户空间)替代 devfs
支持更灵活的命名规则(如
/dev/disk/by-id/…
)
💡 我们的 devfs 是简化版,但核心思想一致 !
💬 写在最后
设备模型是操作系统 硬件抽象的巅峰 。 它让驱动开发者专注硬件细节, 让用户和应用程序以统一方式访问设备。
今天你创建的 /dev/tty0 , 正是 Linux 中 /dev 目录的简化起源。
🌟 统一的抽象,是复杂系统的优雅解药。
📬 动手挑战 : 为你的 VGA 驱动添加设备注册,并在 /dev 中创建 vga 节点。 欢迎在评论区分享你的设备模型扩展!
👇 下一篇你想看: udev 用户空间设备管理 ,还是 USB 驱动框架 ?
#操作系统 #内核开发 #设备模型 #devfs #驱动架构 #硬件抽象 #从零开始
评论