实验完善代码 LAB2-4下载链接 提取码:79t8
0、下载lab3 的源代码
[root@xxx lab]# git add .
[root@xxx lab]# git commit -am 'changes to lab2 after handin'
2 files changed, 139 insertions(+), 24 deletions(-)
create mode 100644 kern/test.cc
[root@xxx lab]# git pull
Already up-to-date.
[root@xxx lab]# git checkout -b lab3 origin/lab3
Branch lab3 set up to track remote branch lab3 from origin.
Switched to a new branch 'lab3'
[root@xxx lab]# git merge lab2
Auto-merging kern/pmap.c
Merge made by the 'recursive' strategy.
kern/pmap.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
kern/test.cc | 0
2 files changed, 139 insertions(+), 24 deletions(-)
create mode 100644 kern/test.cc
LAB2 的主要实现在pmap.c 文件中,我们可以将LAB2 和 LAB3这两个文件的内容对比,
[root@xxx tmp]# diff -u pmap2.c pmap3.c > test.txt
1、实验目标
LAB3 的目标是在LAB2 的基础上实现进程管理和中断的功能。程序的几乎所有代码都集中在env.c 和 trap.c 文件中,实验可以分为两部分:进程环境和中断处理(包括系统调用)。前者通过设置进程控制块(PCB)和编写进程创建、进程中止 和进程调度程序,实现如何对进程进行管理;后者通过设置中断描述符表IDT,编写通用中断派发程序,实现如何管理中断等。
- 进程管理需要完善的函数
env_init()
env_setup_vm()
segment_alloc()
load_icode()
env_create()
env_run() - 中断处理需要完善的函数
trapentry.S
trap_dispatch()
idt_init()
syscall()
2、背景知识
通过LAB2 我们知道,JOS 在启动之后开启了内存分页管理,在LAB2 的主要函数i386_init() 函数之后,并没有进入循环,而是响应的对进程结构进行初始化和中断初始化,i386_init() 函数最后会调用env_run(&envs[0]) ;运行一个进程。一个进程的执行不能对内核和其他进程产生干扰,当进程执行特权指令的时候,需要处理器产生中断,从用户态切换到内核态,完成任务后中断返回到用户态。
从用户态切换到内核态的唯一方法是异常。 异常可以分为4类
- 中断:来自处理器外部的IO设备的信号,不是由指令造成的,异步发生的。
- 陷阱:有意的异常,是执行指令的结果,陷阱最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,叫 系统调用 .执行syscall 会导致一个到异常处理程序的陷阱,这个处理程序对参数进行解码,调用相应的内核程序。
- 故障:由错误情况引起,可能会终止程序。
- 终止:是不可修复的错误造成的结果。
3、进程管理的实现
这个实验中,主要是建立合理的数据结构对进程进行管理,并对进程分配空间,然后将给定的二进制存储的ELF 文件重新映射到进程空间中分配好的内存空间中,运行初始化完毕的进程。
(1)进程管理
在JOS 系统中,对于进程的管理和对物理页面的管理是一样的,也是通过链表进行管理的。在讨论进程管理之前,有几个常识性的问题需要先澄清一下。首先,进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配的独立单位,又称为任务。系统为了管理进程设置了一个专门的数据结构:进程控制块(PCB),用它来记录进程的外部特征,描述进程的运动变化工程(又称为进程描述符)。
- 进程结构
实验中进程的结构是在 inc/env.h 文件中定义的,操作系统内核使用数据结构Env 来记录每个进程的信息。
在kern/env.c 文件中我们可以看到操作系统维护了三个重要的和进程相关的全局变量:
struct Env *envs = NULL; // All environments
struct Env *curenv = NULL; // The current env
static struct Env *env_free_list; // Free environment list
一旦JOS 启动,envs 指针便指向一个Env 结构体链表,表示系统中所有的进程,JOS内核将支持同一时刻最多NENV 个活跃的进程。系统会为每个活跃的进程在envs 链表中 维护一个Env 结构体。
系统也将不活跃的进程用env_free_list连接起来,这种设计方式非常方便资源的分配和回收。
struct Env {
struct Trapframe env_tf; // Saved registers
struct Env *env_link; // Next free Env
envid_t env_id; // Unique environment identifier
envid_t env_parent_id; // env_id of this env's parent
enum EnvType env_type; // Indicates special system environments
unsigned env_status; // Status of the environment
uint32_t env_runs; // Number of times environment has run