![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
6.S081
文章平均质量分 82
xoreaxeax
这个作者很懒,什么都没留下…
展开
-
6.S081 2020 lab6 copy on write 记录
当进程想要写一个cow页面,导致page fault,在usertrap中为它分配物理页,将原来的页内容复制到新的物理页上,将触发异常的虚拟页映射到新的物理页上,修改权限为可写,并清除PTE_COW位。在fork子进程的时候不需要复制父进程的物理页给子进程,而是让子进程的页表映射到同一个物理页,修改二者的PTE让其变为只读,让父进程和子进程读共享,节约fork时间和内存空间。当其中某个进程需要写的时候,再为其分配新的物理页。还需要修改的是mappage函数,删除下图部分,因为在cow场景下,这是合法的。原创 2024-03-10 22:50:19 · 335 阅读 · 0 评论 -
6.S081 2020 lab5 lazy allocation 记录
还有一种情形是,如果用户是通过系统调用(如write,read)访问一个未分配的页,那么此时不会在用户态发生page fault(因为实际执行访存指令的时候已经在内核态了)。lazy allocation要做的是就是当用户调用sbrk为进程申请增加内存空间时,不立刻为进程分配物理内存,而是等到用户第一次访问到某个没有被分配过的页面时,再为进程分配物理内存并建立映射。这里修改的仅仅是当n大于0的情况,由于现在是lazy allocation,所以不急着马上分配物理内存,而是简单的修改进程的sz大小。原创 2024-03-04 11:01:35 · 550 阅读 · 0 评论 -
6.S081 2020 lab7 Multithreading 记录
这是因为切换用户线程时都是在调用thread_switch函数,thread_switch中切换出去再恢复回来可以看成是一个函数调用,thread_switch的调用者会保存caller-save的寄存器,等执行完thread_switch再恢复它们原本的值,所以在thread_switch中只需要保存那些callee-save的寄存器就可以了,还能节省空间。这里有个简单的小优化,由于不同的bucket上的读写是不冲突的所以可以每个bucket使一个锁(也就是降低锁的颗粒度)来提升性能,代码如下。原创 2024-03-18 23:39:55 · 326 阅读 · 0 评论 -
6.S081 2020 lab4 trap 记录
从下图可以看到,对于每一个函数栈帧,地址(fp - 8)指向的是当前函数的返回值地址,也就是上一个函数的地址,这就是我们需要打印的东西。(fp - 16)处则是上一个栈帧的栈底的地址。为了实现打调用栈上函数的地址的功能,需要用到寄存器fp的值,寄存器fp的值指向的是当前函数栈帧的栈底,实验指导已经提供了一个读取fp值的函数。它做的事情很简单,只是在返回用户态时将trapframe的状态恢复到执行handler之前的状态。,只需要将进程的trapframe中epc的值设为handler的地址即可。原创 2024-02-24 00:17:33 · 1428 阅读 · 0 评论 -
6.S081 2020 lab3 pgtbl 记录
第三个实验要求copyin和copyinstr能够直接使用进程在用户态传进来的指针,也就是说,需要在进程的内核页表中和进程的用户页表做相同的映射。xv6 book中可以看到内核的PLIC下面还有一段叫做CLINT的空间,但实验提示似乎让我们不用在意这段内存是否被覆盖,这是因为这段空间仅在内核启动时会用到(xv6的第五章会说),进程在内核态中不需要用到这段内存,所以可以放心覆盖。由于此处创建的不是全局内核页表,而是每个进程自己私有的进程内核页表,所以kstack的虚拟地址可以用同一个。原创 2024-02-13 18:32:01 · 1796 阅读 · 3 评论