该工具是运行于 Linux 环境中的,为 xv6 系统生成磁盘文件系统的影像。其输入是可运行于 xv6 的多个应用程序。实现代码在 mkfs.c,其中 mkfs.c#L20 给出了 xv6 磁盘文件系统的布局。
xv6 有两个磁盘,分别是 xv6.img,和 fs.img,其中 fs.img 用于文件系统,而 xv6.img 用于装载引导程序和系统内核。
xv6.img 布局如下:
| boot block | kernel |
|---|---|
| 第 0 块 | 从 1 开始 |
在 Makefile 中,fs.img 的生成如下:
fs.img: mkfs README.md $(UPROGS)
./mkfs fs.img README.md $(UPROGS)
也就是说,文件系统是由 mkfs 程序生成的,包括布局、数据载入。文件系统的布局如下:
| 名字 | 引导块 | 超级块 | 日志区 | 索引节点区 | 位图区 | 数据区 |
|---|---|---|---|---|---|---|
| 大小 | 1 | 1 | nlog | ninodeblocks | nbitmap | FSSIZE-nmeta |
引导块占用第 0 号物理块,不属于文件系统管辖,如果系统中有多个文件系统,只有根文件系统才有引导程序放在引导块中,其余文件系统都不使用引导块。
超级块占用第 1 号物理块,是文件系统的控制块。超级块包括:文件系统的大小、空闲块数目、空闲块索引表、空闲 i 节点数目、空闲 i 节点索引表、封锁标记等。超级块是系统为文件分配存储空间、回收存储空间的依据。
在 xv6 中,引导块没有作用。
为了给之后的交换功能做准备,我们对 fs.img 的生成进行相应的改造,在数据区后面添加一个交换区。交换区是独立于文件系统之外的一个区域。
首先我们要对 fs.img 进行相应的扩张,fs.img 默认大小为 512000,也就是 1000 个 512 字节大小的盘块。我们扩展 fs.img 为 1024000 字节,后面的 512000 作为交换区。
在 param.h 的最后添加一行
#define SFSIZE 1000 // size of swap file in blocks
在 mkfs.c#L110 的循环中,i 的终止条件改为 i < FSSIZE + SFSIZE。
将 Makefile#L185 的 fs.img 的生成添加一行
fs.img: mkfs README.md $(UPROGS)
./mkfs fs.img README.md $(UPROGS)
dd if=README.md of=fs.img seek=1000 conv=notrunc
在 ide.c#L78 中盘块号的范围改为
if(b->blockno >= FSSIZE + SFSIZE)
此时,交换区的添加算是完成了。
log_write() 而直接使用 bwrite()。