从零写 OS 内核-第十篇:虚拟文件系统与 ext2 实现
“Initramfs 只是玩具,真正的操作系统需要持久化存储。 今天,我们设计 VFS 抽象层,并实现第一个磁盘文件系统——ext2!”
在上一篇中,我们通过内存中的 Initramfs 实现了用户程序加载,但这只是临时方案。 真正的操作系统必须能 从磁盘读写文件 ,支持持久化、大容量存储。
而 Linux 的经典文件系统 ext2 (Second Extended Filesystem)正是绝佳的学习对象: ✅ 结构清晰,文档齐全 ✅ 无日志(简单),适合裸机实现 ✅ 是 ext3/ext4 的基础
今天,我们就来: 1️⃣ 设计虚拟文件系统(VFS)抽象层 2️⃣ 解析 ext2 磁盘布局 3️⃣ 实现 open / read / readdir 系统调用
让你的 OS 能真正从硬盘(或 QEMU 虚拟磁盘)加载程序!
🌉 一、为什么需要 VFS(虚拟文件系统)?
不同文件系统(ext2、FAT32、NTFS)结构千差万别, 但用户程序只关心 open 、 read 、 write 等统一接口。
VFS 的核心思想 :
“用统一接口屏蔽底层差异”
VFS 核心对象:
| 对象 | 作用 |
|---|---|
| Superblock | 描述整个文件系统(块大小、inode 数等) |
| Inode | 描述单个文件(权限、大小、数据块指针) |
| Dentry | 目录项(文件名 → inode 映射) |
| File | 打开的文件实例(含当前读写位置) |
💡 VFS 是“面向对象”思想在 C 中的经典实践 。
💾 二、ext2 磁盘布局详解
ext2 将磁盘划分为 块组(Block Group) ,每个块组包含:
关键结构:
- 超级块(super_block)
-
Inode
-
数据块寻址
直接块
:
i_block[0~11]
→ 直接指向数据块
间接块:
i_block[12]
→ 指向一个块,该块包含 1024 个数据块指针(4KB/4B)
双重间接:
i_block[13]
→ 两级间接
三重间接:
i_block[14]
→ 三级间接(ext2 支持最大 2TB 文件!)
✅ 初期只需实现直接块 + 一级间接 ,即可支持 48KB + 4MB = ~4.2MB 文件。
🧱 三、VFS 核心数据结构设计
- 文件系统类型注册
-
超级块(内存中)
-
Inode(内存中)
-
文件描述符
⚙️ 四、实现 ext2 核心操作
-
读取磁盘块
-
从 inode 读取数据
-
解析路径(根目录 → inode)
📁 五、系统调用对接 VFS
sys_open:
sys_read:
🧪 六、测试:从 ext2 磁盘加载用户程序
步骤:
- 创建 ext2 镜像 :
-
QEMU 启动 :
-
内核中 :
运行效果:
✅ 成功从 ext2 文件系统加载并运行程序!
⚠️ 七、尚未实现但关键的功能
- 写支持
:更新 inode、位图、数据块
-
目录创建
:
mkdir
,
rmdir -
权限检查
:
i_mode
与进程 UID/GID 比较 -
缓存层
:块缓存(Buffer Cache)提升性能
🌱 下一步:实现块设备驱动(IDE/AHCI) ,让 OS 能真正访问物理硬盘!
💬 写在最后
ext2 虽然“古老”, 但它清晰的结构、成熟的文档, 使其成为学习文件系统的 最佳起点 。
今天你实现的 open / read , 正是 Linux VFS 层的简化版。
🌟 文件系统是操作系统的“记忆”——没有它,一切转瞬即逝。
📬 动手挑战 : 在 ext2 镜像中添加一个新文件,并在内核启动时读取其内容。 欢迎在评论区分享你的磁盘布局分析!
👇 下一篇你想看: 块设备驱动(IDE) ,还是 ext2 写支持与 mkdir ?
#操作系统 #内核开发 #文件系统 #ext2 #VFS #磁盘存储 #从零开始
📢 彩蛋 :关注后回复关键词 “ext2” ,获取:
完整 ext2 读取实现代码
ext2 磁盘镜像分析工具(Python)
QEMU + ext2 启动脚本
评论