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-&