[JOS笔记]Lab3--env分析
2009-02-12 22:31 hyddd 阅读(1867) 评论(0) 编辑 收藏 举报在JOS里面,它用“environment”(环境)去代替"process"(进程)这一概念,我的理解是:你大概可以认为,一个进程对应一个env结构体,切换进程即是切换env。
下面我们来看一下Env结构体:
/*
* inc/env.h里,定义了Env结构体
*/
struct Env {
struct Trapframe env_tf; // Saved registers
LIST_ENTRY(Env) env_link; // Free list link pointers
u_int env_id; // Unique environment identifier
u_int env_parent_id; // env_id of this env's parent
u_int env_status; // Status of the environment
// Address space
pde_t *env_pgdir; // Kernel virtual address of page dir ("typedef uint32_t pde_t")
u_int env_cr3; // Physical address of page dir
};
* inc/env.h里,定义了Env结构体
*/
struct Env {
struct Trapframe env_tf; // Saved registers
LIST_ENTRY(Env) env_link; // Free list link pointers
u_int env_id; // Unique environment identifier
u_int env_parent_id; // env_id of this env's parent
u_int env_status; // Status of the environment
// Address space
pde_t *env_pgdir; // Kernel virtual address of page dir ("typedef uint32_t pde_t")
u_int env_cr3; // Physical address of page dir
};
从上面看到,Env包含下面几个部分:
1.struct Trapframe env_tf:env_tf是一个Trapframe结构,下面首先看看Trapframe结构体:
/*
* inc/trap.h里面,有Trapfame的定义
*/
struct Trapframe {
struct PushRegs tf_regs;
uint16_t tf_es;
uint16_t tf_padding1;
uint16_t tf_ds;
uint16_t tf_padding2;
uint32_t tf_trapno;
/* below here defined by x86 hardware */
uint32_t tf_err;
uintptr_t tf_eip;
uint16_t tf_cs;
uint16_t tf_padding3;
uint32_t tf_eflags;
/* below here only when crossing rings, such as from user to kernel */
uintptr_t tf_esp;
uint16_t tf_ss;
uint16_t tf_padding4;
};
struct PushRegs {
/* registers as pushed by pusha */
uint32_t reg_edi;
uint32_t reg_esi;
uint32_t reg_ebp;
uint32_t reg_oesp; /* Useless */
uint32_t reg_ebx;
uint32_t reg_edx;
uint32_t reg_ecx;
uint32_t reg_eax;
};
* inc/trap.h里面,有Trapfame的定义
*/
struct Trapframe {
struct PushRegs tf_regs;
uint16_t tf_es;
uint16_t tf_padding1;
uint16_t tf_ds;
uint16_t tf_padding2;
uint32_t tf_trapno;
/* below here defined by x86 hardware */
uint32_t tf_err;
uintptr_t tf_eip;
uint16_t tf_cs;
uint16_t tf_padding3;
uint32_t tf_eflags;
/* below here only when crossing rings, such as from user to kernel */
uintptr_t tf_esp;
uint16_t tf_ss;
uint16_t tf_padding4;
};
struct PushRegs {
/* registers as pushed by pusha */
uint32_t reg_edi;
uint32_t reg_esi;
uint32_t reg_ebp;
uint32_t reg_oesp; /* Useless */
uint32_t reg_ebx;
uint32_t reg_edx;
uint32_t reg_ecx;
uint32_t reg_eax;
};
Trapframe用于存储各种寄存器的值,因为切换进程时,我们需要保护进程现场,所谓现场,可以粗略地认为就是各种存储器的值。
2. LIST_ENTRY(Env) env_link:先看看LIST_ENTRY的结构:
/*
* inc/queue.h
*
* Use this inside a structure "LIST_ENTRY(type) field" to use
* x as the list piece.
*
* The le_prev points at the pointer to the structure containing
* this very LIST_ENTRY, so that if we want to remove this list entry,
* we can do *le_prev = le_next to update the structure pointing at us.
*/
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* ptr to ptr to this element */ \
}
嗯~很好,说明说得很清楚,那么现在可以看出env_link是一个env的链表,至于作用是什么先放一下。* inc/queue.h
*
* Use this inside a structure "LIST_ENTRY(type) field" to use
* x as the list piece.
*
* The le_prev points at the pointer to the structure containing
* this very LIST_ENTRY, so that if we want to remove this list entry,
* we can do *le_prev = le_next to update the structure pointing at us.
*/
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* ptr to ptr to this element */ \
}
3.env_id:env在env数组里的唯一标识。
4.env_parent_id:创建这个env的env的env_id(很绕口-_-),通过它你可以还原整个进程的创建族谱。
5.env_status:标记这个env的状态,它的值见下面代码:
// Values of env_status in struct Env
#define ENV_FREE 0 //表明这个env是inactive的,这时它将会存储在env_free_list
#define ENV_RUNNABLE 1 //表明这个是一个active的env,正等待运行!
#define ENV_NOT_RUNNABLE 2 //也是一个active的env,但是现在还不能运行,因为它正在等待另一个进程的通信
#define ENV_FREE 0 //表明这个env是inactive的,这时它将会存储在env_free_list
#define ENV_RUNNABLE 1 //表明这个是一个active的env,正等待运行!
#define ENV_NOT_RUNNABLE 2 //也是一个active的env,但是现在还不能运行,因为它正在等待另一个进程的通信
6.env_pgdir:pgdir很熟悉的字眼,它是指向env页目录的虚拟地址指针。
7.env_cr3:存储本env对应的pgdir的物理首地址。
OK~现在我们在来看一下kern/env.c
struct Env *envs = NULL; // All environments
struct Env *curenv = NULL; // The current env
static struct Env_list env_free_list; // Free list
struct Env *curenv = NULL; // The current env
static struct Env_list env_free_list; // Free list
这样一看,又清晰了很多了,这个对应了刚才上面所说的env_status的3种状态。
作者:hyddd
出处:http://www.cnblogs.com/hyddd/
本文版权归作者所有,欢迎转载,演绎或用于商业目的,但是必须说明本文出处(包含链接)。