???????????????У????е?????????????????????????????????????????????????????????????????????????linux?????????????????д???????????????????????????????汾??0.11??
???????????PCB
????????????????????PCB??????????????????????????????????PCB??????????й????????????????洢??PCB?У????磬???????????????????????????????linux??PCB???y?task_struct???????????????????????task_struct????ɡ?
????????λ??linux/include/linux/Sched.h
????struct task_struct {
????long state; //????????????-1?????????У?0???????У?>0?????
????long counter;/* ????????????jiffs??????? */
????long priority; /* ??????????????????counter = priority????????????????????????????. */
????long signal;/* ???.?????λ???????bit??????????. */
????struct sigaction sigaction[32]; /* ??????????????? ?????????е??????????? */
????long blocked;   /* ?????????????(??????λ?) */
????/* various fields */
????int exit_code; /* ?????????????????丸?????? */
????unsigned long start_code??end_code??end_data??brk??start_stack;/* start_code????ε????end_code??????(byte)??
????end_data??????+???????(byte)??brk?????(byte)??start_stack????ε?? */
????long pid??father??pgrp??session??leader;/* ????????????? ????????????????????(??????)*/
????unsigned short uid??euid??suid;/* ???id ?????Ч??? id ?????????? id ??*/
????unsigned short gid??egid??sgid;/* ????? (??id)????Ч?? id?????????id */
????long alarm;/* ???????? (jiffs??) */
????long utime??stime??cutime??cstime??start_time;/* ??????????? (jiffs??)??
?????????????? (jiffs??)?????????????????????????????????????????????? */
????unsigned short used_math;/* ????????Э?????? */
????/* file system info */
????int tty;        /* ???????tty?????豸??. -1?????????? */
????unsigned short umask; /* ???????????????λ */
????struct m_inode * pwd; /* ????????? i???? */
????struct m_inode * root; /* ????i???? */
????struct m_inode * executable;/* ??????i???? */
????unsigned long close_on_exec; /* ?????????????λ????. */
????struct file * filp[NR_OPEN];
????/* ????????????32??. ???????????????????? */
????struct desc_struct ldt[3];
????/* ??????????????.0-???1-cs?Σ?2-Ds??Ss?? */
????struct tss_struct tss; /* ?????????????????? */
????};
????????????????
???????е????????????????fork()????????????????????fork????????????????????????
????1??????0×80?ж?
????????1???????0???fork??????????????е?fork???????£?
????init/main.c
????#define _syscall0(type??name) /  
????type name(void) / 
????{ / 
????long __res; / 
????__asm__ volatile ( "int $0x80" /    // ???????ж?0x80??  
????:"=a" (__res) /     // ???????eax(__res)??  
????:"0" (__NR_##name)); /           // ????????ж???ú?__NR_name??  
????if (__res >= 0) /      // ????????>=0??????????????  
????return (type) __res; errno = -__res; /    // ?????ó???????????-1??  
????return -1;}
???????????int 0×80?ж??????sys_fork?????????????????
????2??sys_fork()
????_sys_fork: 
????call _find_empty_process # ????find_empty_process()(kernel/fork.c??135)?? 
????testl %eax??%eax 
????js 1f 
????push %gs 
????pushl %esi 
????pushl %edi 
????pushl %ebp 
????pushl %eax 
????call _copy_process # ????C ????copy_process()(kernel/fork.c??68)?? 
????addl $20??%esp # ??????????????????? 
????1: ret
???????????λ???????????????????????????????????find_empty_process()????????????copy_process()????????????????fork.c?е?????????????????????????????????
????3??find_empty_process()
????// ????????ò??????????last_pid???????????????????е??????(????index)?? 
????int  find_empty_process (void) 
????{ 
????int i; 
????repeat: 
????if ((++last_pid) < 0) 
????last_pid = 1; 
????for (i = 0; i < NR_TASKS; i++) 
????if (task[i] && task[i]->pid == last_pid) 
????goto repeat; 
????for (i = 1; i < NR_TASKS; i++) // ????0 ??????? 
????if (!task[i]) 
????return i; 
????return -EAGAIN; 
????}
????find_empty_process????????????????????????????????????????????????last_pid??????????????????????????????????????????????????????????α???task[64]?????&&???????????last_pid?????????????????????++last_pid???????????μ??????????α???task[64]????????????е?i????????????????linux0.11?У????????????64????????????????????????????????-EAGAIN??
????4??copy_process()
??????y?????????Щ??????????????????copy_process()???ú?????????????μ??????
?????????????task_struct???????????task_struct???????????
???????????task_struct??tss??????????á?
?????????????????????????????????????????????????
???????????????????????
??????????????GDT?
?????????????????????????????????????????
????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) 
????{ 
????struct task_struct *p; 
????int i; 
????struct file *f; 
????p = (struct task_struct *) get_free_page ();  // ????????????????????? 
????if (!p)           // ??????????????????????????? 
????return -EAGAIN; 
????task[nr] = p;         // ????????????????????????С? 
????// ????nr ????????????find_empty_process()????? 
????*p = *current;        /* NOTE! this doesn't copy the supervisor stack */ 
????/* ????????????????????????? */ ???????????????????? 
????p->state = TASK_UNINTERRUPTIBLE; // ????????????????????ж??????? 
????p->pid = last_pid;     // ???????????????find_empty_process()????? 
????p->father = current->pid;   // ??????????? 
????p->counter = p->priority; 
????p->signal = 0;     // ???λ???0?? 
????p->alarm = 0; 
????p->leader = 0;     /* process leadership doesn't inherit */ 
????/* ??????????????е? */ 
????p->utime = p->stime = 0;    // ???????????????????? 
????p->cutime = p->cstime = 0;  // ??????????????????????? 
????p->start_time = jiffies;   // ????δ?????? 
????// ????????????????TSS ???????????μ??б????????? 
????p->tss.back_link = 0; 
????p->tss.esp0 = PAGE_SIZE + (long) p;    // ??????????????????p ??????1 ? 
????// ????棬??????esp0 ???????????????? 
????p->tss.ss0 = 0x10;     // ??????????????????Σ?[??]?? 
????p->tss.eip = eip;      // ????????? 
????p->tss.eflags = eflags;    // ?????????? 
????p->tss.eax = 0; 
????p->tss.ecx = ecx; 
????p->tss.edx = edx; 
????p->tss.ebx = ebx; 
????p->tss.esp = esp; 
????p->tss.ebp = ebp; 
????p->tss.esi = esi; 
????p->tss.edi = edi; 
????p->tss.es = es & 0xffff;   // ?μ??????16 λ??Ч?? 
????p->tss.cs = cs & 0xffff; 
????p->tss.ss = ss & 0xffff; 
????p->tss.ds = ds & 0xffff; 
????p->tss.fs = fs & 0xffff; 
????p->tss.gs = gs & 0xffff; 
????p->tss.ldt = _LDT (nr);    // ????????nr ??????????????????LDT ??????????GDT ?У??? 
????p->tss.trace_bitmap = 0x80000000;  
????// ???????????????Э????????????????????? 
????if (last_task_used_math == current) 
????__asm__ ("clts ; fnsave %0"::"m" (p->tss.i387)); 
????// ???????????????????λ??????????????????????????????????0??????λ?????????? 
????// ??????????????????????????? 
????if (copy_mem (nr?? p)) 
????{               // ??????0 ???????? 
????task[nr] = NULL; 
????free_page ((long) p); 
????return -EAGAIN; 
????} 
????// ???????????????????????????????????????1?? 
????for (i = 0; i < NR_OPEN; i++) 
????if (f = p->filp[i]) 
????f->f_count++; 
????// ???????????????????pwd?? root ??executable ???????????1?? 
????if (current->pwd) 
????current->pwd->i_count++; 
????if (current->root) 
????current->root->i_count++; 
????if (current->executable) 
????current->executable->i_count++; 
????// ??GDT ?????????????TSS ??LDT ?????????????task ??????? 
????// ???????л????????????tr ??CPU ???????? 
????set_tss_desc (gdt + (nr << 1) + FIRST_TSS_ENTRY?? &(p->tss)); 
????set_ldt_desc (gdt + (nr << 1) + FIRST_LDT_ENTRY?? &(p->ldt)); 
????p->state = TASK_RUNNING;   /* do this last?? just in case */ 
????/* ??????????????ó???????????????? */ 
????return last_pid;      // ??????????????????????????? 
????}