主要内容
进程的介绍
进程的创建
一
要想简单的了解进程,可以用一个比喻:把工作的人比作系统,人要做的工作就是进程,每种工作相对独立,有自己特有的工具和方法,同一时间,一个人只能做一样工作,但可以把各个工作轮换着做。进程也类似,有进程调度模块,有自己要用的资源,代码,数据,对进程的调度,就好比一个人轮换着做不同的工作。
二
1.以时钟中断为例,一个运行的进程运行到一半,时钟中断发生,保存进程状态,特权级变化后开始执行时钟中断处理程序,中断处理程序调用进程调用模块,指定下一个运行的进程(在这里让进程运行在ring1,进程切换运行在ring0)。
2.同一时间,一个CPU只能运行一个进程,而其他的进程就处于“休息”状态,所以对于休息状态的进程要记录他休息前的状态(各项数据保留)以便再次运行时,可以从上次的间断处继续运行。
3.我们使用进程表(PCB)来保存进程的状态,因为我们会有很多进程,所以要有一个进程表数组
4.通过pushad命令保存寄存器的值到进程表中,并把esp指针指向专门的内核栈区域,之后利用iretd指令恢复。
内核栈示意
5.关于进程表,进程体,GDT和TSS的关系
进程表和GDT:进程表中的LDT 选择子对应GDT中的一个描述符,这个描述符指向的内存空间位于进程表内。
进程表和进程:进程表是进程的描述,进程运行时如果被中断,各个寄存器的值会被保存在进程表中。
GDT和TSS:GDT需要有一个描述符对应TSS。
三
1.做一个简单的时钟中断程序
ALIGN 16
hwint00: ; Interrupt routine for irq 0 (the clock).
iretd
2.初始化包括进程表,进程体,GDT,TSS
2.1准备一个进程体
void TestA()
{
int i = 0;
while(1){
disp_str("A");
disp_int(i++);
disp_str(".");
delay(1);
}
}
2.2初始化进程表
typedef struct s_stackframe {
u32 gs; /* \ */
u32 fs; /* | */
u32 es; /* | */
u32 ds; /* | */
u32 edi; /* | */
u32 esi; /* | pushed by save() */
u32 ebp; /* | */
u32 kernel_esp; /* <- 'popad' will ignore it */