一個(gè)新進(jìn)程的誕生(六)fork 中進(jìn)程基本信息的復(fù)制

本系列作為?你管這破玩意叫操作系統(tǒng)源碼?的第三大部分,講述了操作系統(tǒng)第一個(gè)進(jìn)程從無(wú)到有的誕生過(guò)程,這一部分你將看到內(nèi)核態(tài)與用戶(hù)態(tài)的轉(zhuǎn)換、進(jìn)程調(diào)度的上帝視角、系統(tǒng)調(diào)用的全鏈路、fork 函數(shù)的深度剖析。
不要聽(tīng)到這些陌生的名詞就害怕,跟著我一點(diǎn)一點(diǎn)了解他們的全貌,你會(huì)發(fā)現(xiàn),這些概念竟然如此活靈活現(xiàn),如此順其自然且合理地出現(xiàn)在操作系統(tǒng)的啟動(dòng)過(guò)程中。
本篇章作為一個(gè)全新的篇章,需要前置篇章的知識(shí)體系支撐。
當(dāng)然,沒(méi)讀過(guò)的也問(wèn)題不大,我都會(huì)在文章里做說(shuō)明,如果你覺(jué)得有困惑,就去我告訴你的相應(yīng)章節(jié)回顧就好了,放寬心。
------- 第三部分目錄?-------
------- 正文開(kāi)始?-------

_sys_fork:
????call?_find_empty_process
????testl?%eax,%eax
????js?1f
????push?%gs
????pushl?%esi
????pushl?%edi
????pushl?%ebp
????pushl?%eax
????call?_copy_process
????addl?$20,%esp
1:??ret

struct?task_struct?{
????long?state;
????long?counter;
????long?priority;
????...
????struct?tss_struct?tss;
}
long?last_pid?=?0;
int?find_empty_process(void)?{
????int?i;
????repeat:
????????if?((++last_pid)<0)?last_pid=1;
????????for(i=0?;?i<64?;?i++)
????????????if?(task[i]?&&?task[i]->pid?==?last_pid)?goto?repeat;
????for(i=1?;?i<64;?i++)
????????if?(!task[i])
????????????return?i;
????return?-EAGAIN;
}
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;
????*p?=?*current;??/*?NOTE!?this?doesn't?copy?the?supervisor?stack?*/
????p->state?=?TASK_UNINTERRUPTIBLE;
????p->pid?=?last_pid;
????p->father?=?current->pid;
????p->counter?=?p->priority;
????p->signal?=?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;
????p->tss.back_link?=?0;
????p->tss.esp0?=?PAGE_SIZE?+?(long)?p;
????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;
????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);
????p->tss.trace_bitmap?=?0x80000000;
????if?(last_task_used_math?==?current)
????????__asm__("clts?;?fnsave?%0"::"m"?(p->tss.i387));
????if?(copy_mem(nr,p))?{
????????task[nr]?=?NULL;
????????free_page((long)?p);
????????return?-EAGAIN;
????}
????for?(i=0;?i????????if?(f=p->filp[i])
????????????f->f_count++;
????if?(current->pwd)
????????current->pwd->i_count++;
????if?(current->root)
????????current->root->i_count++;
????if?(current->executable)
????????current->executable->i_count++;
????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;
}
int?copy_process(int?nr,?...)?{
????struct?task_struct?p?=?
????????(struct?task_struct?*)?get_free_page();
????task[nr]?=?p;
????*p?=?*current;
????p->state?=?TASK_UNINTERRUPTIBLE;
????p->pid?=?last_pid;
????p->counter?=?p->priority;
????..
????p->tss.edx?=?edx;
????p->tss.ebx?=?ebx;
????p->tss.esp?=?esp;
????...
????copy_mem(nr,p);
????...
????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;
????return?last_pid;
}

int?copy_process(int?nr,?...)?{
????struct?task_struct?p?=?
????????(struct?task_struct?*)?get_free_page();
????task[nr]?=?p;
????*p?=?*current;
????...
}

int?copy_process(int?nr,?...)?{
????...
????p->state?=?TASK_UNINTERRUPTIBLE;
????p->pid?=?last_pid;
????p->counter?=?p->priority;
????..
????p->tss.edx?=?edx;
????p->tss.ebx?=?ebx;
????p->tss.esp?=?esp;
????...
????p->tss.esp0?=?PAGE_SIZE?+?(long)?p;
????p->tss.ss0?=?0x10;
????...
}

------- 關(guān)于本系列的完整內(nèi)容?-------
本系列的開(kāi)篇詞看這,開(kāi)篇詞
本系列的番外故事看這,讓我們一起來(lái)寫(xiě)本書(shū)?
本系列全局視角

最后,祝大家都能追更到系列結(jié)束,只要你敢持續(xù)追更,并且把每一回的內(nèi)容搞懂,我就敢讓你在系列結(jié)束后說(shuō)一句,我對(duì) Linux 0.11 很熟悉。
公眾號(hào)更新系列文章不易,閱讀量越來(lái)越低,希望大家多多傳播,不方便的話(huà)點(diǎn)個(gè)小小的在看我也會(huì)很開(kāi)心,我相信星火燎原的力量,謝謝大家咯。
另外,本系列完全免費(fèi),希望大家能多多傳播給同樣喜歡的人,同時(shí)給我的 GitHub 項(xiàng)目點(diǎn)個(gè) star,就在閱讀原文處,這些就足夠讓我堅(jiān)持寫(xiě)下去了!我們下回見(jiàn)。
