Skip to content

导引:点亮什么与为什么

先把边界说清楚:006 的写是够用但朴素的。它没有日志、没有事务、没有多缓冲,全程靠 005 那块唯一的 DMA 缓冲做「读—改—写」;文件写实际只覆盖到直接块加单间接块的头一个槽(大文件会被静默截断);时间戳全是 0,因为 Cinux 还没有实时时钟。这些不是疏漏,是这一章我们主动选择的最小可写集。我们会逐个说清楚为什么是这样、踩了什么坑。

这一章我们要点亮什么

在 005 的只读 ext2 之上,把「写」这一整套补齐。四件事。

第一,写回基础设施。005 只有 read_block,这一章加 write_block,以及围绕它的 write_disk_inodewrite_superblockwrite_bgdt。它们统一长一个样:先读、再改、再写回(read-modify-write)。为什么是这个姿势,是本章的主线。

第二,两个分配器。要建文件就得有地方放它的 inode 和数据块,所以要能从块位图里分一块、从 inode 位图里分一个 inode。alloc_block/free_blockalloc_inode/free_inode 干这件事。

第三,建、删、写内容create(建文件)、mkdir(建目录)、unlink(删),以及 Ext2FileOps::write(往文件里写字节)。这几个把分配器和写回基础设施串成一条链。

第四,接上用户态。四个新系统调用 sys_creat/sys_mkdir/sys_unlink/sys_rmdir(号码复用 Linux 的 85/83/87/84),加上 shell 的 touchmkdirrmrmdir,以及 echo> 重定向。

验收点很直白:在 shell 里 echo hi > /hello.txt,然后把它读回来,看到 hi。能写进去、能读出来、还落了盘,这一章就成了。

为什么现在需要它

为什么紧跟 005。005 证明了一件事:Cinux 的 VFS 抽象(FileSystem 接口、Inode、挂载表)能接上一个按 ext2 标准布局的真磁盘文件系统。但只读意味着这套抽象只被「读」这一侧验证过。写的难度不在「写」这个动作本身,而在它牵出的一连串新问题:新文件放哪、新 inode 从哪来、目录项怎么插进去、改完哪些元数据要同步刷盘、中途失败了怎么回滚。把这些走通,VFS 这套抽象才算真正立住。

还有一笔关于「复用」的账,和 005 一样漂亮。这一章的写路径几乎不长在新发明上:块 I/O 还是走 001 的 AHCI(只是第一次真正用了它的 write)、文件对象和操作表还是 003 的 Inode + InodeOps、挂载还是 003 的 vfs_mount_add。我们做的事,是给 003 的 InodeOps 加上 write/create/mkdir/unlink 四个虚方法,再让 ext2 实现它们。main.cpp 一行没动——挂载还是 005 的 static Ext2 ext2(ahci, 1)vfs_mount_add("/", &ext2)。006 的全部新意,都在 ext2 内部和 syscall 层。

顺带说一句关于 AHCI 的。001 那章我们让 AHCI 能 read,005 的 ext2 只用它读。其实 AHCI 的 write(走 ATA WRITE DMA EXT,命令码 0x35)在 005 那波重构里就已经备好了,只是一直没人调。006 是它第一次真正被用来落盘。所以本章不会讲「怎么给 AHCI 加写」,那早就有了;我们讲的是 ext2 怎么用它,以及用它写盘时要注意什么。

035_multi_terminal-45-gf25de18 · f25de18 · 2026-08-04