SWAP挑战性任务
SWAP挑战性任务实现报告
任务内容
任务使用swap_disk
挂载至MOS
作为swap
时存储磁盘。
PIIX4
的介绍:MOS
基于Malta
开发板,而其所使用板载的PIIX4
芯片组支持IDE
等设备并有两个独立的IDE
通道。
一个IDE
通道连一个IDE
控制器,一个控制器连两个IDE
设备,则MOS
的PIIX4
支持4块IDE
设备。
两个IDE
控制器偏移地址为:1.主控制器块偏移:0x1F0
;2.从控制器块偏移:0x170
(这些都基于PIIX4
的PCIIO
基地址0x18000000
,即实验中定义的MALTA_PCIIO_BASE
)
具体读写操作参考原有实现
为避免与文件系统使用的主IDE
控制器冲突,可在内核态使用从IDE
控制器读写磁盘,用于存储交换页面。
可修改Makefile
文件中定义的QEMU_FLAGS
变量来挂载多块磁盘。即多加一条:$(shell [ -f '$(swap_disk)' ] && echo '-drive id=swap,file=$(swap_disk),if=ide,format=raw') \
。0
、1
号IDE
磁盘由主控制器使用,2号由从控制器使用(注意此处两个控制器偏移量不尽相同),swap_disk
文件的创建参考empty_disk
。
新增数据结构
- 在
page
结构体增加如下内容:
PG_reference
:访问标志位,表示最近页面被访问过。list
:页表项链表,存放所有映射page
对应物理页的页表项。
- 内核空间新增:
active_list
:存放访问频繁的page
inactive_list
:存放访问不频繁的page
page_swapblock_map
:存放换出物理页向swap_disk
中磁盘块的映射关系page_state_set
:存放换出物理页page
中状态。
新增操作
schedule
刷新TLB
由于并不存在访问标志位,因此要在每次schedule
时刷新对应进程的所有TLB
,借助TLB
重填检测页面的访问。
TLB
重填逻辑
触发TLB
重填时,若存在映射关系,则将对应物理页page
执行如下操作:
检查page
的PG_referenced
标志位:
- 若
false
且不在active_list
和inactive_list
中:置true
并将page
加入inactive_list
尾部。 - 若
false
且在inactive_list
:将page
移动到active_list
尾部,置true
。 - 若
false
且在active_list
:置true
- 若
true
且在inactive_list
:移动到active_list
尾部。
维护Page
状态
主要维护新增的list
字段:
- 页面被分配或映射时,添加相应页表项指针
ptr
到list
中 - 页面取消映射时,移除对应页表项
实现swap_out
当syscall_mem_alloc
中page_alloc
尝试分配页面但无空闲页时触发:
- 使用
algo
算法选取一个非空闲物理页page
- 遍历
page
中的list
链表,修改页表项内容标记为其为换出页面便于后续访问触发缺页中断 - 将
page
结构体状态保存至page_state_set
,并初始化page
- 在
swap_disk
中找空闲磁盘块,并向其写入page
物理页中的内容,标记为非空闲(位图) - 将
page
作为page_alloc
结果并执行后续流程
实现swap_in
若用户访问虚地址触发缺页中断且中断页page
为换出页面时触发:
- 利用
page_swapblock_map
查询磁盘中非空闲块与换出页映射关系,找到page
对应的磁盘块,读出内容,标记为空闲 - 尝试找一页空闲物理页
Page
(无则使用swap_out
获得),将读取到的内容拷贝到Page
- 利用
page_state_set
将此前保留的结构体状态恢复至Page
- 遍历恢复后的
list
,所有页表项修改为映射Page
对应物理页的正常映射关系,并将list
移动到Page
结构体中(?) - 执行缺页异常
algo
替换算法
- 若
inactive_list
非空,遍历inactive_list
中到的page
- 若
page
的PG_...
为false
,结束算法返回page
- 若为
true
,置false
- 若
inactive_list
空,执行shrink_active_list
,并重复执行第一步
shrink_active_list
- 遍历
active_list
的page
- 若
page
的PG_...
为true
,置false
- 否则,将
page
加入inactive_list
定期更新inactive_list
每隔一段时间 ,执行一次shrink_active_list
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 yumooo!