程序2的建立與執行

2021-07-24 18:37:32 字數 4730 閱讀 5439

程序1第一次執行,完成設定硬碟資訊、格式化虛擬盤(根裝置)、載入根檔案系統後會回到下面語句:

if(!fork())        

//***********************************== 分隔符 ****************************************==

----init();

1.開啟終端裝置檔案

----open("/dev/tty0",o_rdwr,0); //建立標準輸入裝置,其中/dev/tty0是該檔案的路徑名

----sys_open("/dev/tty0",o_rdwr,0); //通過int 0x80中斷進行系統呼叫

----open_namei("/dev/tty0",o_rdwr,0,&inode);獲取檔案tty0的i節點,儲存在inode中

----dir_namei("/dev/tty0",&namelen,&basename); //獲取枝梢i節點,namelen為tty0的長度,basename指向tty0的第乙個字母't'

----get_dir("/dev/tty0"); //遍歷整個檔案路徑"/dev/tty0",獲取枝梢i節點(即獲取dev目錄檔案的i節點)

----find_entry(&inode,thisname,namelen,&de); //根據根i節點和dev來查詢dev目錄項,此時thisname為dev,namelen=3

----iget(idev,inr); //根據dev的i節點號獲取dev的i節點

----find_entry(&dir,basename,namelen,&de); //根據dev的i節點和"tty0"來查詢tty0的目錄項,de指向tty0目錄項

----//檢查tty0檔案的i節點屬性,確定它是乙個字元裝置檔案

----//設定file_table[0]

//至此程序1的current->filp[0]存放的file_table第乙個元素位址,file_table第乙個元素,又存放著inode的位址,f_count為1,完成標準輸入裝置/dev/tty0的建立

2.開啟標準輸出、標準錯誤輸出檔案

----(void)dup(0); //複製控制代碼,構建標準輸出裝置

----(void)dup(0); //繼續複製控制代碼,構建標準錯誤輸出裝置

----sys_dup(0); //dup對應的系統呼叫函式

----dupfd(0,0); //執行複製控制代碼

//執行兩次dup(0),將flip[0]中儲存的tty0檔案指標複製進flip[1]和filp[2],並將file_table[0]中的f_count檔案引用計數自增1(兩次累加後,f_count為3)

//至此,建立shell所需要的終端標準輸入裝置檔案、標準輸出裝置檔案和標準錯誤輸出裝置檔案讀已經開啟

3.程序1建立程序2並切換到程序2

----if(!pid=fork()) //程序1建立程序2(執行過程參考程序1的建立與輪**程序2建立完畢後,fork()函式返回2,不會執行if中的語句,跳到wait(&i)執行

----wait(&i) //程序1等待子程序退出,最終會切換到程序2執行

----sys_waitpid(pid_t pid,unsigned long * stat_addr, int options); //先遍歷所有程序,找出程序1的子程序,即程序2,再對程序2進行分析,確定程序2並不準備退出,於是設定flag標誌為1,該標誌將導致程序切換

----schedule(); //在呼叫schedule()函式之前,先將程序1設為可中斷狀態,然後呼叫schedule()切換到程序2取執行

----close(0); //切換到程序2執行(程序1的建立與輪**確定if(!(pid=fork())這條語句為真後,呼叫close(0)函式來關閉標準輸入輸出裝置檔案,並用rc檔案代替

----sys_close(0); //sys_close(0)是close(0)的系統呼叫,close(0)就是要將filp[20]第一項清空(就是關閉標準輸入裝置檔案tty0),並遞減file_table[64]中f_count的引用計數

----open("/etc/rc",o_edonly,0); //rc檔案代替tty0裝置檔案

----execve("/bin/sh",argv_rc,envp_rc); //載入shell程式

----sys_execve(); //execve()的系統呼叫

----do_execve() //do_execve是載入shell程式的主體函式,其路徑:fs/exec.c,執行過程參考

....

4.執行shell程式

do_execve()函式執行完後,sys_execve便會中斷返回,去執行shell程式。由於在do_execve中清空了頁目錄表和對應頁表,所以會產生乙個"頁異常"中斷,此中斷會進一步呼叫"缺頁中斷"處理程式來分配該頁面,並載入一頁shell程式

//**路徑:mm/page.s

---- _page_fault: //頁異常處理函式入口

----do_no_page(); //呼叫"缺頁中斷"處理程式來分配該頁面,並載入一頁shell程式

----get_free_page(); //為shell程式申請一頁新的記憶體

----nr[i] = bmap(current->executable,block); //得到執行的**所在的塊號

----bread_page(page,current->executable->i_dev,nr); //讀取4個邏輯塊(1頁)的shell程式內容進記憶體頁面

----put_page(page,address); //物理位址對映到線性位址,建立頁目錄表--->頁表--->頁表--->頁面的**對映管理關係

5.切換到shell程序執行,建立update程序(程序3)

sheel程式開始執行後,要讀取標準輸入裝置檔案上的資訊,即task_struct中filp[20]第一項對應的檔案資訊。參考前面分析知道,此時filp[20]中第一項對應檔案是rc而非tty0,因此shell先讀取rc

----read(); //shell程式呼叫read()讀取rc檔案上的內容

----sys_read();read()函式的系統呼叫

----file_read(inode,file,buf,count); //rc是普通檔案,讀取結束後,返回值是-error,會導致shell程序退出,退出將執行exit()

---- /etc/update & ... //建立乙個新程序update,並載入update程式,update程序完成:將快取區中的資料同步到外設,由於資料交換速度遠低於資料處理速度,資料不是直接寫到外設,而是先寫入快取區再同步到外設,

//因此每隔一段時間,update就會被喚醒,然後完成一次資料同步,沒有同步任務時,update程序會被休眠

.....

---- echo "/dev/hd1">/etc/mtab //將"/dev/hd1"這一字串寫入虛擬盤中/etc/mtab中

----exit();

----sys_exit();

----do_exit(); //為shell退出做善後工作:釋放shell程序**段和資料段所占用的記憶體頁面、將update程序的父程序設定為程序1、解除shell程序與其他程序、檔案、終端等的關係、將當前程序(程序2)設定為僵死狀態

//給程序1發資訊,通知它shell程序即將退出、程序切換

----free_page_tables(); //釋放shell程序**段和資料段所占用的記憶體頁面

----tell_father(current->father); //給程序1發資訊,通知它shell程序即將退出

----schedule(); //程序切換

----sys_waitpid(); //程序1是執行sys_waitpid()函式時呼叫schedule()函式切換到程序2的,所以shell程序退出時執行schedule,會最終回到sys_waitpid(),繼續shell程序退出的善後工作

//sys_waitpid()執行完後最終會回到init(),因建立完程序2後,pid=2,而sys_wait返回值也是2,即wait()返回值為2,while迴圈條件為假,跳出while迴圈。

6.重建shell

程序1回到init()繼續執行,準備重建shell

----init(); //回到init()中,準備重建shell

----pid=fork(); //程序1建立程序4,即重建shell程序

----close(0);close(1);close(2); //關閉所有開啟檔案

----setsid(); //建立新的會話

----(void) open("/dev/tty0",o_rdwr,0); //重新開啟標準輸入裝置檔案

----(void) dup(0); //重新開啟標準輸出裝置檔案

----(void) dup(0); //重新開啟標準錯誤輸出裝置檔案

----_exit(execve("/bin/sh",argv,envp)); //載入shell程序

.... ----sys_read(); //shell讀取的tty0檔案為字元裝置檔案

----rw_char(); //進入shell程序,shell程序將被設定為可中斷等待狀態,這樣所有的程序全部都處於可中斷等待狀態,再次切換到程序0取執行,系統實現怠速

----while(1)

if(pid == wait(&i)) //程序1等待子程序退出

break;

程序建立和執行

簡單的說,每個應用在執行時就會產生乙個程序,這個程序就對這個應用負責,掌握這個應用的執行狀態。可是為什麼還要用乙個程序來控制乙個應用呢,下面將會簡單的解釋一下。現在的應用對於資源的要求都是獅子大開口,開口就是幾個g,一台電腦的記憶體一般也就幾個g,總不能一台電腦就跑這乙個應用吧。為了解決這個問題,作...

程序建立與執行緒建立

1.程序建立fork asmlinkage int sys fork struct pt regs regs long do fork unsigned long clone flags,unsigned long stack start,struct pt regs regs,unsigned l...

主程序與子程序的執行順序

from multiprocessing import process import time deftask name print s start name time.sleep 3 print s stop name if name main p process target task,args...