从零写OS(三十六):ext2 写操作 —— 文件创建、引用计数与 tty 字符设备

前几章文件系统都是只读的。这一章实现 ext2 的写路径,让 echo hello > /tmp/a.txt && cat /tmp/a.txt 能正常工作,且重启后文件仍然存在。过程中还修了 fd 引用计数和 tty 字符设备两个问题。 ext2 磁盘结构回顾 块组 0: [超级块][组描述符][block bitmap][inode bitmap][inode table][数据块...] 关键字段: sb->s_free_inodes_count / gd->bg_free_inodes_count:空闲 inode 计数 sb->s_free_blocks_count / gd->bg_free_blocks_count:空闲 block 计数 gd->bg_inode_bitmap:inode bitmap 所在块号 gd->bg_block_bitmap:block bitmap 所在块号 gd->bg_inode_table:inode table 起始块号 inode 号从 1 开始;前 10 个是系统保留的(root=2,lost+found=11)。 alloc_inode / alloc_block alloc_inode uint32_t alloc_inode(void) { // 1. 读 inode bitmap 块 // 2. 找第一个为 0 的位(bit i → inode i+1) // 3. 置位,写回 bitmap // 4. 更新超级块和组描述符的 free_inodes_count // 5. 返回 inode 号(从 1 开始) } alloc_block uint32_t alloc_block(void) { // 1. 读 block bitmap 块 // 2. 找第一个为 0 的位,跳过 block 0(保留) // 3. 置位,写回 bitmap // 4. 更新超级块和组描述符的 free_blocks_count // 5. 清零新分配的块(避免垃圾数据) // 6. 返回块号 } 注意:block bitmap 的 bit 0 对应 block 0,必须跳过(block 0 不存在)。实际第一个可分配的块由文件系统布局决定(本项目中是 610)。 ...

May 22, 2026 · 3 min · 大飞

从零写OS(二十七):字符设备 —— /dev/null 和 /dev/zero

Linux 里有个特殊目录 /dev/,里面住着各种设备文件: /dev/null ← 写什么扔什么,读永远 EOF /dev/zero ← 读出来全是 \0 /dev/random ← 读出来是随机字节 /dev/tty ← 当前终端 对用户程序来说,它们和普通文件没区别:open、read、write、close,完全一样的接口。 这一章实现字符设备(char device)框架,让 VFS 能路由 /dev/ 路径,并内置 null 和 zero 两个最基础的设备。 什么是字符设备 字符设备(character device)的特点: 按字节读写,没有块/扇区的概念 没有随机寻址(不像磁盘文件可以 seek) 读写是即时的:写进去就消失(null)或立刻可读(zero/tty) 与之对应的是块设备(block device),如硬盘,以固定大小的块为单位操作。 设备注册表 核心数据结构 cdev_t: typedef struct { char name[16]; // 设备名,如 "null"、"zero" int (*open) (void); int (*read) (void *buf, uint32_t len); int (*write)(const void *buf, uint32_t len); void (*close)(int fd); int used; } cdev_t; static cdev_t devs[CDEV_MAX]; // 全局设备表 通过函数指针实现多态——不同设备注册不同的 read/write 实现。 chardev_register 向 devs[] 添加一个设备,chardev_open 按名字查找并调用 open()。 ...

May 14, 2026 · 2 min · 大飞
京ICP备14031575号-3