call graph:
- start (kern/entry.S)
- i386_init (kern/init.c)
- cons_init
- mem_init
- env_init
- trap_init (still incomplete at this point)
- env_create
- env_run
- env_pop_tf
类似 Unix 中的process概念,JOS 把thread 和address space的概念组合在一次.thread 主要由当前的寄存器值定义(由env_tf字段维护), address space由page directory和page table(被env_pgdir维护)定义. 要想运行某个环境,内核必须为 CPU 设置当前环境的寄存器值和合适的地址空间.
JOS中的struct Env与 xv6 中的struct proc类似. 它们都维护着当前环境/进程的用户模式的寄存器状态(在Trapframe中).在 JOS 中,每个环境没有维护各自的内核栈.而 xv6 中的进程是维护的. 在 JOS 中,任意时刻只有一个 env,所以 jos 只需要一个内核栈.
练习 1 修改mem_init, 申请并映射env数组. 此数组包含整整NENV个Env结构的实例.申请方式类似pages.保存envs的内存也应该映射至UENVS. 所以用户进程可以从这里读取.
现在开始写一些为了运行用户环境而必需的的代码. 由于尚未建立文件系统,我们首先令内核加载一个与 kernel 本身绑定的静态二进制镜像.
Lab 3 的GNUmakefile生成了若干二进制文件,并放置到了/obj/user/目录中.
CPL : Current Privilege Level, 当前进程的权限级别
DPL : Descriptor Privilege Level,
PCB : Process Control Block 进程控制表