从零写 OS 内核-第十三篇:sysfs —— 以文件形式暴露内核信息
“内核运行状态藏在寄存器和内存中,用户如何查看? 今天,我们实现 sysfs,让 CPU、内存、进程信息像普通文件一样可读!”
在上一篇中,我们让标准流(stdin/stdout/stderr)在 VFS 中工作,用户程序终于能“说话”了。 但操作系统不仅是程序的运行平台,更是 系统状态的管理者 ——用户需要监控 CPU 使用率、内存占用、进程列表等。
Linux 通过 sysfs ( /sys )和 procfs ( /proc )将内核数据结构 以文件形式暴露给用户空间 。 今天,我们就来实现一个 简化版 sysfs ,让你的 OS 拥有“自省”能力!
🧩 一、什么是 sysfs?为什么需要它?
sysfs 是一个 内存中的虚拟文件系统 ,它:
不占用磁盘空间
动态生成内容
(读文件时才计算)
组织为层次化目录
(反映内核对象关系)
典型 sysfs 路径:
| 路径 | 内容 |
|---|---|
| /sys/cpu/0/freq | CPU 0 频率(Hz) |
| /sys/mem/total | 总物理内存(KB) |
| /sys/kernel/version | 内核版本字符串 |
| /sys/devices/ide/hda/model | 磁盘型号 |
💡 核心思想 : 把内核数据结构映射为文件和目录 ,用户通过 cat 即可查看系统状态。
🏗️ 二、sysfs 架构设计
sysfs 本质是一个 特殊的文件系统类型 ,注册到 VFS 中:
核心对象:sysfs_dirent
每个文件/目录对应一个 sysfs_dirent :
🔑 show 回调是关键 :当用户 read 文件时,内核调用它生成内容。
⚙️ 三、实现 sysfs 文件操作
- sysfs inode 创建
-
sysfs 文件读操作
-
目录遍历(readdir)
📊 四、暴露系统信息:实现具体文件
-
CPU 信息
-
内存信息
-
内核版本
-
进程信息(动态生成)
🧪 五、测试:用户空间查看系统信息
内核初始化:
用户程序:
运行效果:
✅ 成功通过文件系统接口获取内核实时数据!
🛠️ 六、高级特性(可选)
- 可写 sysfs 文件
用于
运行时配置
(如
echo 1 > /sys/debug/enabled
)
实现
store
回调,解析用户写入的内容 -
符号链接
用于创建别名(如
/sys/cpu/current -> /sys/cpu/0
)
在
sysfs_dirent
中增加
target
字段 -
属性组(Attribute Groups)
自动为对象创建一组文件(如 CPU 对象自动有 freq/usage/temp)
通过宏简化注册
⚠️ 七、与 procfs 的区别
| 特性 | sysfs | procfs |
|---|---|---|
| 目的 | 导出 内核对象 (设备、驱动、模块) | 导出 进程信息 + 传统内核参数 |
| 结构 | 严格层次化(反映对象关系) | 扁平 + 进程子目录 |
| 现代用法 | Linux 2.6+ 主要接口 | 逐渐被 sysfs 取代(但 /proc 仍保留) |
💡 我们的实现融合两者 :既有 CPU/内存(传统 procfs),又有对象层次(sysfs)。
💬 写在最后
sysfs 不仅是调试工具, 更是 内核与用户空间对话的桥梁 。 它让复杂的内核状态变得 直观、可脚本化、可监控 。
今天你创建的 /sys/cpu/0/freq , 正是 Linux 中 /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 的简化版。
🌟 最好的接口,是用户早已熟悉的接口——比如文件。
📬 动手挑战 : 添加一个新的 sysfs 文件 /sys/kernel/uptime ,显示系统运行时间(秒)。 欢迎在评论区分享你的 sysfs 条目设计!
👇 下一篇你想看: procfs 实现(进程信息专用) ,还是 动态加载内核模块(.ko 文件) ?
#操作系统 #内核开发 #sysfs #虚拟文件系统 #系统监控 #VFS #从零开始
📢 彩蛋 :关注后回复关键词 “sysfs” ,获取:
完整 sysfs 实现代码(含目录/文件操作)
sysfs 条目注册宏(简化 API)
* 用户态 sysfs 查看工具(cat_sysfs.c)
评论