分类:
2009-04-17 23:30:54
环境的数据结构:
struct Env {
struct Trapframe env_tf; // 切换时,在此保存寄存器
LIST_ENTRY(Env) env_link; //空闲链表指针
envid_t env_id; //环境id,唯一辨识
envid_t env_parent_id; // 父亲的id
unsigned env_status; // 环境的状态
uint32_t env_runs; //环境已运行次数
// Address space
pde_t *env_pgdir; // 页目录的虚拟地址
physaddr_t env_cr3; //页目录的物理地址
};
在i386_vm_init()中分配一个环境数组:envs指向大小为NENV的Env结构数组。
n = ROUNDUP(NENV*sizeof(struct Env), PGSIZE);
envs = (struct Env *)boot_alloc(n, PGSIZE);
在kern/env.c中实现如下函数,以完成对用户环境的管理:env_init()、env_setup_vm()、segment_alloc()、load_icode()、env_create()、env_run()。
1、 void env_init(void)函数:对在envs数组中的所有Env结构并把他们加入到env_free_list中。
2、 static int env_setup_vm(struct Env *e)函数:为新的环境分配一个页目录并且初始化内核部分的新环境地址空间
3、 static void segment_alloc(struct Env *e, void *va, size_t len)函数:为新的环境分配并映射一个物理内存
4、 static void load_icode(struct Env *e, uint8_t *binary, size_t size)函数:装载新环境的用户地址空间的内容,这与boot loader的功能一致。
5、 void env_create(uint8_t *binary, size_t size)函数:利用env_alloc()函数分配一个环境并掉用load_icode装载一个ELF
6、 void env_run(struct Env *e)函数:以用户态运行一个给定的环境。
实现中断与异常处理:
中断与异常的区别:中断处理异步事件(相对处理器是外部的),而异常是指处理器自己检测到的情况
在kern/trapentry.S中,使用宏TRAPHANDLER和TRAPHANDLER_NOEC定义和根据80386 Programmer's Manual的第九章对中断的描述定义中断处理程序的入口。在kern/trap.c中完成idt_init()
函数以实现初始化idt指向在trapentry.S定义的每个中断入口。完成_alltraps函数,其步骤如下:1)、将各个寄存器(如:ds、es)入栈,2)、将GD_KD载入ds、es,3)、esp入栈,4)、调用trap,5)、将入栈的信息出栈,6)、忽略中断数、错误信息并返回。