linux 源 代码-fork.c 源 代码 /* * linux/kernel/fork.c * //--fork()用于创建子进程 * (C) 1991 Linus Torvalds */ /* * 'fork.c' contains the help-routines for the 'fork' system call * (see also system_call.s), and some misc functions ('verify_area'). * Fork is rather simple, once you get the hang of it, but the memory * management can be a bitch. See 'mm/mm.c': 'copy_page_tables()' */ #include
#include #include #include #include //--写页面验证,若页面不可写,则复制页面 extern void write_verify(unsigned long address); long last_pid=0; //--进程空间区域写前验证函数 void verify_area(void * addr,int size) { unsigned long start; start = (unsigned long) addr; size += start & 0xfff; start &= 0xfffff000; start += get_base(current->ldt[2]); //--逻辑地址到线性地址的转换 while (size>0) { size -= 4096; write_verify(start); start += 4096; } } 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) panic("We don't support separate I&D"); if (data_limit < code_limit) panic("Bad data_limit"); new_data_base = new_code_base = nr * TASK_SIZE; p->start_code = new_code_base; set_base(p->ldt[1],new_code_base); set_base(p->ldt[2],new_data_base); if (copy_page_tables(old_data_base,new_data_base,data_limit)) { //--复制页表 free_page_tables(new_data_base,data_limit); return -ENOMEM; } return 0; } /* * Ok, this is the main fork-routine. It copies the system ...