这个 lab 花费的时间比较久, 越底层越难 debug
任务 1 要求打印第一个用户进程的页表 , 一号进程在 0 号进程 exec 后得到, 在这里判断id==1 后 执行 vmprint , 参数为页目录
每个页目录有 512 个 entry (PTE) , 只有 PTE_V flag 为 1 的才为有效 entry , flag 为 PTE_V 并且有设置 PTE_R,W,X 其中一个的才算 leaf , 保存物理地址的 entry , 知道这两个后就可以递归的遍历并打印页表的内容
打印后可以看到页表只分配了第一个和后面两个,第一个是内核给进程分配的一页 stack , 后面两个一个是 trapframe,一个是 traopoline,用于系统调用使用 , 并且 PTE_U 都没有设置 , 不能在用户态操作
任务 2 相当耗时 , 查阅了很多资料后才做出来 . 要解决的问题是: 由于目前内核页表跟用户进程页表是分开的, 每次上下文切换到需要切换页表,有一定的开销, 所以要求在初始化进程页表的时候,把内核页表也映射到进程页表中,使得上下文切换不再需要切换页表,但这样就有一个限制,内核是从 0x8000000 开始的, 所以0 x8000000 以上的地址用户态一律不能使用 , 留下的只有 0x0000 -> 0x800000 共 128M 的内存 , 一开始感觉这样好像不合理, 后来发现 linux 也是这样做的
并且有了这样的一个实现后, 内核解用户态指针再也不需要软件模拟遍历页表了, 直接解就行 , 这部分需要修改 copyin 和 copyout 的代码
需要修改的还有 exec 和 fork , fork 的实现在 allocproc 中
同时 free 的时候也要 free kpagetable, 但是不能 free 和内核共享部分的物理地址
并且内核在用户进程的第一个 page 中有控制硬件相关的映射, 这部分需要在用户进程第一个 page 分配后也映射进去 , 否则也会造成奇怪的 bug 触发点
调度不同进程的时候, 改为使用 kpagetable
使用 gdb 调试打印内存布局
$ usertests
usertests starting
test execout: OK
test copyin: OK
test copyout: OK
test copyinstr1: OK
test copyinstr2: OK
test copyinstr3: OK
test truncate1: OK
test truncate2: OK
test truncate3: OK
test reparent2: OK
test pgbug: OK
test sbrkbugs: usertrap(): unexpected scause 0x000000000000000c pid=3234
sepc=0x00000000000053fc stval=0x00000000000053fc
usertrap(): unexpected scause 0x000000000000000c pid=3235
sepc=0x00000000000053fc stval=0x00000000000053fc
OK
test badarg: OK
test reparent: OK
test twochildren: OK
test forkfork: OK
test forkforkfork: OK
test argptest: OK
test createdelete: OK
test linkunlink: OK
test linktest: OK
test unlinkread: OK
test concreate: OK
test subdir: OK
test fourfiles: OK
test sharedfd: OK
test exectest: OK
test bigargtest: OK
test bigwrite: OK
test bsstest: OK
test sbrkbasic: OK
test sbrkmuch: OK
test kernmem: usertrap(): unexpected scause 0x000000000000000d pid=6214
sepc=0x000000000000201a stval=0x0000000080000000
usertrap(): unexpected scause 0x000000000000000d pid=6215
sepc=0x000000000000201a stval=0x000000008000c350
usertrap(): unexpected scause 0x000000000000000d pid=6216
sepc=0x000000000000201a stval=0x00000000800186a0
usertrap(): unexpected scause 0x000000000000000d pid=6217
sepc=0x000000000000201a stval=0x00000000800249f0
usertrap(): unexpected scause 0x000000000000000d pid=6218
sepc=0x000000000000201a stval=0x0000000080030d40
usertrap(): unexpected scause 0x000000000000000d pid=6219
sepc=0x000000000000201a stval=0x000000008003d090
usertrap(): unexpected scause 0x000000000000000d pid=6220
sepc=0x000000000000201a stval=0x00000000800493e0
usertrap(): unexpected scause 0x000000000000000d pid=6221
sepc=0x000000000000201a stval=0x0000000080055730
usertrap(): unexpected scause 0x000000000000000d pid=6222
sepc=0x000000000000201a stval=0x0000000080061a80
usertrap(): unexpected scause 0x000000000000000d pid=6223
sepc=0x000000000000201a stval=0x000000008006ddd0
usertrap(): unexpected scause 0x000000000000000d pid=6224
sepc=0x000000000000201a stval=0x000000008007a120
usertrap(): unexpected scause 0x000000000000000d pid=6225
sepc=0x000000000000201a stval=0x0000000080086470
usertrap(): unexpected scause 0x000000000000000d pid=6226
sepc=0x000000000000201a stval=0x00000000800927c0
usertrap(): unexpected scause 0x000000000000000d pid=6227
sepc=0x000000000000201a stval=0x000000008009eb10
usertrap(): unexpected scause 0x000000000000000d pid=6228
sepc=0x000000000000201a stval=0x00000000800aae60
usertrap(): unexpected scause 0x000000000000000d pid=6229
sepc=0x000000000000201a stval=0x00000000800b71b0
usertrap(): unexpected scause 0x000000000000000d pid=6230
sepc=0x000000000000201a stval=0x00000000800c3500
usertrap(): unexpected scause 0x000000000000000d pid=6231
sepc=0x000000000000201a stval=0x00000000800cf850
usertrap(): unexpected scause 0x000000000000000d pid=6232
sepc=0x000000000000201a stval=0x00000000800dbba0
usertrap(): unexpected scause 0x000000000000000d pid=6233
sepc=0x000000000000201a stval=0x00000000800e7ef0
usertrap(): unexpected scause 0x000000000000000d pid=6234
sepc=0x000000000000201a stval=0x00000000800f4240
usertrap(): unexpected scause 0x000000000000000d pid=6235
sepc=0x000000000000201a stval=0x0000000080100590
usertrap(): unexpected scause 0x000000000000000d pid=6236
sepc=0x000000000000201a stval=0x000000008010c8e0
usertrap(): unexpected scause 0x000000000000000d pid=6237
sepc=0x000000000000201a stval=0x0000000080118c30
usertrap(): unexpected scause 0x000000000000000d pid=6238
sepc=0x000000000000201a stval=0x0000000080124f80
usertrap(): unexpected scause 0x000000000000000d pid=6239
sepc=0x000000000000201a stval=0x00000000801312d0
usertrap(): unexpected scause 0x000000000000000d pid=6240
sepc=0x000000000000201a stval=0x000000008013d620
usertrap(): unexpected scause 0x000000000000000d pid=6241
sepc=0x000000000000201a stval=0x0000000080149970
usertrap(): unexpected scause 0x000000000000000d pid=6242
sepc=0x000000000000201a stval=0x0000000080155cc0
usertrap(): unexpected scause 0x000000000000000d pid=6243
sepc=0x000000000000201a stval=0x0000000080162010
usertrap(): unexpected scause 0x000000000000000d pid=6244
sepc=0x000000000000201a stval=0x000000008016e360
usertrap(): unexpected scause 0x000000000000000d pid=6245
sepc=0x000000000000201a stval=0x000000008017a6b0
usertrap(): unexpected scause 0x000000000000000d pid=6246
sepc=0x000000000000201a stval=0x0000000080186a00
usertrap(): unexpected scause 0x000000000000000d pid=6247
sepc=0x000000000000201a stval=0x0000000080192d50
usertrap(): unexpected scause 0x000000000000000d pid=6248
sepc=0x000000000000201a stval=0x000000008019f0a0
usertrap(): unexpected scause 0x000000000000000d pid=6249
sepc=0x000000000000201a stval=0x00000000801ab3f0
usertrap(): unexpected scause 0x000000000000000d pid=6250
sepc=0x000000000000201a stval=0x00000000801b7740
usertrap(): unexpected scause 0x000000000000000d pid=6251
sepc=0x000000000000201a stval=0x00000000801c3a90
usertrap(): unexpected scause 0x000000000000000d pid=6252
sepc=0x000000000000201a stval=0x00000000801cfde0
usertrap(): unexpected scause 0x000000000000000d pid=6253
sepc=0x000000000000201a stval=0x00000000801dc130
OK
test sbrkfail: usertrap(): unexpected scause 0x000000000000000d pid=6265
sepc=0x0000000000003e76 stval=0x0000000000012000
OK
test sbrkarg: OK
test validatetest: OK
test stacktest: usertrap(): unexpected scause 0x000000000000000d pid=6269
sepc=0x0000000000002188 stval=0x000000000000fbc0
OK
test opentest: OK
test writetest: OK
test writebig: OK
test createtest: OK
test openiput: OK
test exitiput: OK
test iput: OK
test mem: OK
test pipe1: OK
test preempt: kill... wait... OK
test exitwait: OK
test rmdot: OK
test fourteen: OK
test bigfile: OK
test dirfile: OK
test iref: OK
test forktest: OK
test bigdir: OK
ALL TESTS PASSED
for(int i = 0; i < max && srcva + i < p->sz; i++){
80006542: cc85 beqz s1,8000657a
init: starting sh scause 0x000000000000000d sepc=0x0000000080006550 stval=0x0000000000000968 panic: kerneltrap
fork() bug: ukvmcopy(np->kpagetable, np->pagetable, np->sz, p->sz); ukvmcopy(np->kpagetable, np->pagetable, np->sz, 0);
== Test usertests == Timeout! (300.2s)
== Test usertests: copyin ==
usertests: copyin: FAIL
Failed copyin
== Test usertests: copyinstr1 ==
usertests: copyinstr1: FAIL
Failed copyinstr1
== Test usertests: copyinstr2 ==
usertests: copyinstr2: FAIL
Failed copyinstr2
== Test usertests: copyinstr3 ==
usertests: copyinstr3: FAIL
Failed copyinstr3
== Test usertests: sbrkmuch ==
usertests: sbrkmuch: FAIL
Failed sbrkmuch
== Test usertests: all tests ==
usertests: all tests: FAIL (0.6s)
...
copy success
copy success
copy success
copy success
copy suqemu-system-riscv64: terminating on signal 15 from pid 92624 (