一. 进程1的创建
进程1是由进程0创建的,创建过程如下:
main() { fork() } ---> _syscall0(int,fork) ---> int 0x80中断进入系统调用(特权级由3切换到0) ---> _sys_call --->sys_fork() ---> find_empty_process()为进程申请一个可用的进程号pid ---> copy_process(),在该函数中初始化创建的进程1的TSS结构,将tss段插入到gdt描述符表中,并设置好TSS的段基址和段长度。
进程1的创建主要是通过copy_process()函数来完成,copy_process()函数主要完成以下任务:
(1)调用get_free_page()函数,在主内存申请一个空闲页面,并将申请的空闲页面清零,用于进程1的task_struct及内核栈。
(2)将父进程0的task_struct的内容复制给进程1的task_struct
(3)为进程1的task_struct、tss做个性化设置:特别要注意,将进程1的tss.eip设置为创建过程中int 0x80中断程序执行时,保护现场压入栈中的EIP了,这一点会影响后面轮转后,进程1的执行。
(4)为进程1创建第一个页表,将进程0的页表项内容赋给这个页表
(5)进程1共享进程0的文件
(6)设置进程1的GDT项
(7)最后将进程1设置为就绪状态,使其可以参与进程间的轮转
代码如下:
int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,
long ebx,long ecx,long edx,
long fs,long es,long ds,
long eip,long cs,long eflags,long esp,long ss)
//参数是int 0x80、system_call、sys_fork调用时多次累积压栈的结果
{
struct task_struct *p;
int i;
struct file *f;
p = (struct task_struct *) get_free_page();
if (!p)
return -EAGAIN;
task[nr] = p;
//将父进程的task_struct内容拷贝到子进程
*p = *current; /* NOTE! this doesn't copy the supervisor stack */ //curent是task_struct类型,并未包含task_union联合体中的stack部分,此处的赋值相当于拷贝内容
//设置子进程
p->state = TASK_UNINTERRUPTIBLE;
p->pid = last_pid;
p->father = current->pid;
p->counter = p->priority;
p->s