xv6 pagetable labs

参考大佬写的答案:详细版简洁版
(个人水平有限,如文中有问题,希望不吝赐教)

先搞清两种页表:

页表是虚拟地址实现的基础
1.内核页表:

  1. 操作系统映射完之后,由芯片查表,所以我们看不到查内核页表的代码,只有建立内核页表的代码。
  2. 内核页表不是从0开始,而是在某些特定地址上有特定的映射,貌似和设计者有关系。(像xv6这种直接映射页表,也就是内核页表的虚拟地址和物理地址一样的,就和芯片硬件有关)图的左侧是内核页表

2.用户页表:

  1. 操作系统建表并且查表。
  2. 从虚拟地址0开始,用多少就建多少,这也是为什么实验第三问有PLIC限制条件的原因,因为虚拟地址从0开始往上加,控制最高的地址就好。

问:题目中要我们写的进程内核页表,是属于内核页表,还是用户页表?
答:应该是内核页表,因为它的建立由程序完成,查表由芯片完成。

查表由芯片完成——这句话的意思。我是这么认为的:在第三问的copyin_new()里边有:
memmove((void *) dst, (void *)srcva, len);
意思就是直接把虚拟地址srcva的内容复制到虚拟地址dst。中间的把虚拟地址映射成物理地址的代码没有写。这不是交给芯片完成了吗?

难点

  1. 理解问题啥意思有点难,第二问的意思是:为每个进程加一个内核页表。(这里比较难以捉摸,因为usertests本来就可以运行,然后题目要求加完内核页表之后,也要能运行usertests。)
  2. 为啥作业要这么折腾,本来可以跑的代码,还要加个内核页表,这不多此一举?可能是内核页表是由芯片进行查表,而用户页表由操作系统进行查表。老师的目的是要我们区分这两点。
  3. 说说我遇到的代码上的问题,针对第三问(复制用户页表到内核页表):
    1.在freeproc里边释放内核页表的时候,sz一定要向上取整PGROUNDUP(sz):查看图片
    2.在sys_sbrk里边增加内核页表的时候,如果参考的是文章开头给出的简洁版答案:uvm2k(p->pagetable, p->kpagetable, sz-n, sz),请一定注意这里的sz,sz经前面的sz = uvmalloc(p->pagetable, sz, sz + n),已经是增加之后的大小,所以一定的要减去n。
    3.参考的两篇博客都没有提到过。这个在实验的提示里边有:在userinit函数添加复制用户页表到内核页表的代码。
    4.复制内核的内核页到进程的内核页时。注意不要把CLINT复制过去,以及在freeproc里面不要释放CLINT。(原因是题目提示说,从进程的进程页表复制到进程的内核页表,最多不超过PLIC,然后可以看到在PLIC下面只有CLINT,也就是说这里可以给进程随便用,别分配给CLINT了)具体的可以看地址图,图的左边有PLIC和CLINT的位置关系。

最后:

只需要细心点,这个原理前面大佬的答案都有说到。就是复制已有的用户页表到内核页表。受限于水平,这次实验得分只有30/66:

== Test pte printout == 
$ make qemu-gdb
pte printout: FAIL (9.8s) 
    ...
         .. .. ..511: pte 0x0000000020001c0b pa 0x0000000080007000
         init: starting sh
         $ echo hi
         hi
         $ qemu-system-riscv64: terminating on signal 15 from pid 2732 (make)
    MISSING '^page table (0x00000000[0-9a-f]+)$'
    QEMU output saved to xv6.out.pteprint
== Test answers-pgtbl.txt == answers-pgtbl.txt: FAIL 
    Cannot read answers-pgtbl.txt
== Test count copyin == 
$ make qemu-gdb
count copyin: OK (2.0s) 
== Test usertests == 
$ make qemu-gdb
Timeout! (300.1s) 
== Test   usertests: copyin == 
  usertests: copyin: OK 
== Test   usertests: copyinstr1 == 
  usertests: copyinstr1: OK 
== Test   usertests: copyinstr2 == 
  usertests: copyinstr2: OK 
== Test   usertests: copyinstr3 == 
  usertests: copyinstr3: OK 
== Test   usertests: sbrkmuch == 
  usertests: sbrkmuch: OK 
== Test   usertests: all tests == 
  usertests: all tests: FAIL 
    ...
                     sepc=0x0000000000002188 stval=0x000000000000fbc0
         OK
         test opentest: OK
         test writetest: OK
         test writebig: qemu-system-riscv64: terminating on signal 15 from pid 3178 (make)
    MISSING '^ALL TESTS PASSED$'
== Test time == 
time: FAIL 
    Cannot read time.txt
Score: 30/66
Makefile:314: recipe for target 'grade' failed
make: *** [grade] Error 1
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值