本文主要是介绍mit6.s081 lab10 mmap,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.添加mmap和munmap的syscall
2…为了追踪每个process使用mmap产生的映射区域,使用VMA去记录mmap时的address, length, permission, file等信息。可以创建一个固定大小的VMA数组来进行实现,16个VMA元素已经足够。在proc.h中定义VMA结构体,在proc中添加VMA数组,数组的大小为16。需要注意的是VMA结构体中有offset成员,用于记录addr对应在文件中的偏移量。
struct VMA {uint addr;int offset;int length;int prot;int flags;struct file *f;
};#define NVMA 16// Per-process state
struct proc {
....struct VMA vma_array[NVMA];
};
3.实现mmap函数,在process的地址空间中找到一块空闲的区域去映射文件,添加这片区域的VMA,并在VMA中记录这篇区域对应的file指针,增加file的引用计数,所以即便对该文件使用close函数该文件也仍然有效。在mmap不应该分配物理内存获取读取文件,分配物理内存和读取文件应当在发生page fault时发生,这种设计是为了保证mmap在对大文件进行映射时足够快,以及节省使用mmap的内存。在sys_mmap函数中的主要工作是在proc的VMA数组中找出一个空闲的VMA,使用该VMA记录相关信息,在这个实验的实现中addr和offset默认为0,vma的addr为当前proc的sz,proc->sz在添加完这段映射区域后增加length,最后增加文件的引用。
// mmap的addr和offset始终为0,不需要处理
uint64 sys_mmap(void) {int length, prot, flags;struct file *f;struct VMA *free_vma = 0;struct proc *cur_proc = myproc();if(argint(1, &length) < 0 || argint(2, &prot) < 0 || argint(3, &flags) < 0 || argfd(4, 0, &f) < 0)return 0xffffffffffffffff;if ((flags & MAP_SHARED) && (prot & PROT_WRITE) && !f->writable)return 0xffffffffffffffff;for (int i = 0; i < NVMA; i++) {if (cur_proc->vma_array[i].f == 0) {free_vma = cur_proc->vma_array + i;break;}}if (free_vma == 0) {return 0xffffffffffffffff;}free_vma->addr = cur_proc->sz;free_vma->offset = 0;free_vma->length = length;free_vma->prot = prot;free
这篇关于mit6.s081 lab10 mmap的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!