XV6

本节实现物理内存和磁盘盘块数据的交互。尝试将 1 块物理页帧的数据存放到 8 块盘块上。然后将 8 块盘块的数据取到另一块物理页帧上,检测数据是否正确。

文件系统的盘块大小为 512 字节,而内存页帧大小为 4096 字节。若要实现交换功能,那么一个页帧需要 8 个盘块存储,为了尽量复用 xv6 的代码,我们的文件读写以 8 个盘块对齐,这样就可以存储整个物理页帧了。

xv6 的磁盘读写必须经过日志层和缓存层,我们将 4096 大小的页帧写到 8 块连续的 512 大小的盘块中,并在页表项记录开始盘块的盘块号。先在 bio.c 中进行相应的修改。这里由于 xv6 默认的文件系统设备号只有 1 个,dev=1,所以我们直接使用 1 作为 dev 参数。

// 将 4096 字节的物理页帧写到 blockno 为起始的连续的 8 块盘块中
void swapout(char *pa, uint blockno) 

从连续的 8 块盘块中读取内容到 1 块物理页帧中。

void swapin(char *pa, uint blockno)

2. 分配盘块

和文件的分配盘块函数 balloc 类似,除了要分配连续的 8 块盘块以外,如果盘块是以 8 块对齐的就没问题。

uint balloc8(uint dev)

释放使用 balloc8() 分配的盘块。

void balloc8(int dev, uint b)

3. 测试程序

3.1 测试页请求

分配页的时候,我们一开始并没有真正把页分配给进程,只是将页表的相应位进行设置而已。如果进程要访问该页,则会触发请求,然后

  1. 如果有空闲物理内存,则直接从 kmem 中获取内存。
  2. 如果没有空闲物理内存,则将某些进程的页换出磁盘,腾出物理页帧来使用。