思考题

Thinking 4.1

  • 进入内核态时首先使用SAVE_ALL函数将sp寄存器数据存入k0k1中,同时使用sp的数据将通用寄存器数据压栈,存入环境控制块中,再次使用时将其出栈即可。
  • 不可以,在调用过程中,将系统调用号存入了a0,因此寄存器中数据发生了改变。a1-a3寄存器没有显式改变,但也未规定不可以发生改变,因此出于正确性考虑,最优方法通过栈中数据使用。
  • 函数中所有数据来源均是环境的数据栈,而数据栈中的数据均是在调用时传入的,因此sys函数与msyscall中参数相同。
  • 修改了Trapframe->epc += 4,保证返回用户态时可以执行下一条指令;修改了Trapframe->regs[2] = returnRes,保证v0寄存器中存储返回结果。

Thinking 4.2

  • 在设定env的各项参数时有可能出现错误,导致未正确设定env_id,这种env是不可以使用的。该函数在构建进程和查询使用进程的过程中均有使用。如果缺少判断,在实际使用时有可能出现通过envid寻找不到相应env的情况。

Thinking 4.3

  • (++i) << (1 + LOG2NENV)保证返回值一定不为0。
  • 在函数envid2env()中,如果获得的envid为0,那么获得的env就是当前环境curenv

Thinking 4.4

关于 fork 函数的两个返回值,下面说法正确的是:
A、fork 在父进程中被调用两次,产生两个返回值
B、fork 在两个进程中分别被调用一次,产生两个不同的返回值
C、fork 只在父进程中被调用了一次,在两个进程中各产生一个返回值
D、fork 只在子进程中被调用了一次,在两个进程中各产生一个返回值

  • C.函数在两个进程中均要进入,在父进程中完整进行,并返回子进程env_id;子进程中仅复制父进程上下文,并返回0.因此,完整调用仅在父进程中进行了一次。

Thinking 4.5

  • UTOPTLIM之间储存的是和内核相关的页表信息。UTOPUSTACKTOP之间是异常处理栈无效内存,最终需要被映射的页面只有USTACKTOP之下的部分

Thinking 4.6

  • vptvpd分别是指向用户页表和用户页目录的指针。用该指针数值(页基地址)加上相对基址偏移即可获得页表项地址。
  • 两个指针分别指向用户地址空间中页表的首地址和页目录的首地址。
  • vpd的值位于UVPTUVPT+PDMAP之间,说明某个页表可以映射到该页目录。而每个页目录都有对应页表,因此实现了自映射机制。
  • 不行,用户态只能访问页表,不可以修改。

Thinking 4.7

  • 用户态程序写入COW页表,触发异常,进入页写入异常的处理程序,并调用pgfault函数处理。如果在该函数中仍写入COW页,将会再次触发异常,出现“异常重入”现象。
  • 异常处理是在用户态下进行的,而用户态只能访问用户空间(低2G空间)内的数据,需要将现场保存在用户空间。

Thinking 4.8

  • 减少对于内核态程序的调用,减少对于页表数据的修改,防止程序崩溃影响系统稳定。

Thinking 4.9

  • syscall_env_alloc中产生子进程并复制数据之前,需要对父进程的页表异常进行处理,防止子进程复制的数据出现异常,因此要在syscall_env_alloc之前调用set_pgfault_handler函数。

难点分析

本次实验中,我遇到的难点主要有以下几点:

  • 页表地址映射:实验中主要使用二级页表的结构,一级页表作为页框映射获得二级页表序号,二级页表作为页号映射获得页内容的真实物理地址。映射过程中的数据提取(该部分数据提取哪几位)及数据对应(这些数据又对应下一级数据地址的哪几位)难度较大,对于当前地址含义的判断也有一定难度。
  • mem的关联:在实验中,设立了sys_mem_map()sys_mem_unmap()函数用来处理进程关联。其中主要使用envid2env()函数,匹配envidenv环境,并将两个页面相匹配。
  • sys函数操作:本次实验中,有多个sys函数操作,涉及到内存的处理、子进程的申请等。这些函数多要调用env相关函数,接口设计与调用较有难度。

实验体会

Lab4主要让我们学习有关系统调用和申请子进程的问题,了解MIPS系统中虚拟地址与物理地址的对应关系、处理多种系统调用、为具体进程申请子进程并复制进程数据信息。本次实验涉及到的知识点很多很新,同时也有大量未知的需要自己阅读的宏定义和函数(在不知道使用目的与形参函数的含义情况下上手难度极大),继承Lab2和Lab3的函数与知识,逻辑简单,但实现难度较大,也花费了我很长一段时间来完成,但各函数与Lab2、Lab3中宏定义与自定义函数基本一致,有了Lab2、Lab3长时间的学习就会很好解决,也会很明白。同时,也十分感谢那些写博客的学长,看了他们的博客后真的是茅塞顿开。实验越往后走,陌生的东西越多,还是要摆正心态,世上无难事,只要肯攀登。