fork.c中含有fork的辅助子程序,其位置为Linux-0.11/kernel/frok.c.文件中主要包含了verify_area(),copy_mem(),copy_process(),find_empty_process()这几函数
首先分析verify_area()函数,源代码如下
void verify_area(void * addr,int size)
{
unsigned long start;
start = (unsigned long) addr;
size += start & 0xfff; //size=size+start%(4k),调整起始地址后的长度
start &= 0xfffff000; //重置开始地址,将地址整成整4k字节开始,即从整字节开始验证
start += get_base(current->ldt[2]);//下面把start 加上进程数据段在线性地址空间中的起始基址,
//变成系统整个线性空间中的地址位置。
while (size>0) {
size -= 4096; //一次验证一页内存
write_verify(start); //写页面验证。若页面不可写,则复制页面
start += 4096;
}
}
copy_mem()设置新任务的代码和数据段基址、限长并复制页表。 nr 为新任务号;p 是新任务数据结构的指针。
int copy_mem(int nr,struct task_struct * p)
{
unsigned long old_data_base,new_data_base,data_limit;
unsigned long old_code_base,new_code_base,code_limit;
code_limit=get_limit(0x0f); //取局部描述符表中代码段描述符项中段限长。
data_limit=get_limit(0x17); // 取局部描述符表中数据段描述符项中段限长。
old_code_base = get_base(current->ldt[1]);//取原代码段基值
old_data_base = get_base(current->ldt[2]);//去原数据段基值
if (old_data_base != old_code_base) //在0.11版本内核中代码段和数据段起始位置相同
panic("We don't support separate I&D");
if (data_limit < code_limit) //数据段一般位于代码后面,故而数据段限长不小于代码段
panic("Bad data_limit");
new_data_base = new_code_base = nr * 0