标签:
实验说明书4.3.3 关键数据结构和相关函数分析 中有一段话:
实验二中有关内存的数据结构和相关操作都是直接针对实际存在的资源--物理内存空间的管理,没有从一般应用程序对内存的“需求”考虑,即需要有相关的数据 结构和操作来体现一般应用程序对虚拟内存的“需求”。一般应用程序的对虚拟内存的“需求”与物理内存空间的“供给”没有直接的对应关系。ucore是通过page fault异常处理来间接完成这二者之间的衔接。 page_fault函数不知道哪些是“合法”的虚拟页,原因是ucore还缺少一定的数据结构来描述这种不在物理内存中的“合法”虚拟页。为此 ucore通过建立mm_struct和vma_struct数据结构,描述了ucore模拟应用程序运行所需的合法内存空间。当访问内存产生page fault异常时,可获得访问的内存的方式(读或写)以及具体的虚拟内存地址,这样ucore就可以查询此地址,看是否属于vma_struct数据结构 中描述的合法地址范围中,如果在,则可根据具体情况进行请求调页/页换入换出处理(这就是练习2涉及的部分);如果不在,则报错。
首先看ide.h中给出的对ide的基本操作:
void ide_init(void); bool ide_device_valid(unsigned short ideno); size_t ide_device_size(unsigned short ideno); int ide_read_secs(unsigned short ideno, uint32_t secno, void *dst, size_t nsecs); int ide_write_secs(unsigned short ideno, uint32_t secno, const void *src, size_t nsecs);
swapfs.c文件中的函数依赖于上面的操作:
void swapfs_init(void) { static_assert((PGSIZE % SECTSIZE) == 0); if (!ide_device_valid(SWAP_DEV_NO)) { panic("swap fs isn‘t available.\n"); } max_swap_offset = ide_device_size(SWAP_DEV_NO) / (PGSIZE / SECTSIZE); } int swapfs_read(swap_entry_t entry, struct Page *page) { return ide_read_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); } int swapfs_write(swap_entry_t entry, struct Page *page) { return ide_write_secs(SWAP_DEV_NO, swap_offset(entry) * PAGE_NSECT, page2kva(page), PAGE_NSECT); }
可以说是ide.c中函数的一个wrapper或者shell。
采用面向对象的编程方法,swap.c属于外壳层,swap_fifo.c是真正的实现层。对外的接口是swap.c中实现的函数,而我们想改变内部的算法,就可以重新写一个实现层,只要改变sm = &swap_manager_fifo;即可。这种编程方法在很多情况下很实用。
实验三中仅仅通过执行check_swap函数在内核中分配一些页,模拟对这些页的访问,然后通过do_pgfault来调用swap_map_swappable函数来查询这些页的访问情况并间接调用相关函数,换出“不常用”的页到磁盘上。
标签:
原文地址:http://www.cnblogs.com/fluray/p/5300020.html