在copyout函数中也要增加页面错误处理,因为copyout是在内核中调用的,缺页不会进入usertrap。因此在copyout中判断缺页错误,如果是因为COW则分配新的页: intcopyout(pagetable_tpagetable, uint64 dstva,char*src, uint64 len){ uint64 n, va0, pa0;pte_t*pte;while(len >0){// 查找虚拟地址dstva对应的物...
uvm的部分都完成了,还有copyout需要修改,这是一个大坑,因为是内核修改用户页,不会经过用户页表合法标记位的审查,所以这里对copyout的每一页都要进行地址重分配。 int copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) { uint64 n, va0, pa0; while(len > 0){ va0 = PGROUNDDOWN...
注意要在程序中声明extern pte_t* walk(pagetable_t, uint64, int); 3.2.5.copyout() 还需要在kernel/vm.c的copyout()函数中增加页面错误处理。copyout使内核状态下修改用户态的页面内存,缺页不会进入usertrap,因此进行特殊处理。 先声明外部函数walk。 使用于刚才相似的方法,来分配页面,...
在第二个部分,我们需要去为每个进程去设置独立的内核页表和内核栈。在第三个部分,需要把用户页表映射到内核页表上,并修改copyin和copyout函数,从而来加快参数的传递。下面来整体把握一下整个流程! main函数:xv6!启动! 首先是在main函数里面有许多启动的初始化程序,现在我们来看一眼这些内容。 voidmain(){if(cpuid...
Exec在栈页下面放了一个无法访问的页,那么程序试图使用超过一个页时会产生错误。这个无法访问的页同时允许exec处理过大的参数;那种情况下,exec使用的把参数拷贝到栈的copyout(2118)函数会注意到目标页无法访问,会返回-1。 在新内存镜像准备期间,如果exec发现类似非法程序段的错误,它跳转到bad标签,释放新镜像并返回-...
int copyout(pde_t *pgdir, uint va, void *p, uint len) { char *buf, *pa0; uint n, va0; buf = (char*)p; while(len > 0){ va0 = (uint)PGROUNDDOWN(va); pa0 = uva2ka(pgdir, (char*)va0); //va0在pgdir的映射下的内核地址 if(pa0 == 0) return -1; n = PGSIZE -...
您需要初始化一个本地rtcdate结构体,以您想要的方式写入/修改它,然后使用vm.h中的copyout函数将它复制...
以kvm开头的函数操作内核页表;以uvm开头的函数操作用户页表;其他函数同时用于这两种页表。copyout和copyin将数据复制到或复制出被作为系统调用参数的用户虚拟地址;它们在vm.c中,因为它们需要显式转换用户空间的地址,以便找到相应的物理内存。 在机器启动时,在启动序列的靠前部分,main调用kvminit(kernel/vm.c:22)来...
打开文件后,通过read系统调用读取数据。数据从内核空间复制到用户空间,使用copyout函数实现这个过程。内核需要访问用户进程的页表机制,以手动完成vm->pm的地址转换,从而将数据写入用户进程空间。写文件时,流程与读文件类似,但涉及从用户空间复制数据到block,并最终写回磁盘。写操作包括在缓存中修改标记位...
exec 会在栈的页下方放一个无法访问的页,这样当程序尝试使用超过一个页的栈时就会出错。另外,这个无法访问的页也让 exec 能够处理那些过于庞大的参数;当参数过于庞大时,exec 用于将参数拷贝到栈上的函数 copyout 会发现目标页无法访问,并且返回 -1。