task_struct
結構的分配使用的是alloc_task_struct
巨集,該巨集就是簡單地呼叫kmem_cache_alloc()
從task_struct_cachep
快取中分配。接著會使用alloc_thread_info
巨集分配thread_info
結構。thread_info
結構儲存了特定於體系結構的組合語言**需要訪問的那部分程序資料,包括執行域、可搶占標誌和當前的cpu等資訊。在分配thread_info
結構的時,實際呼叫的是__get_free_pages()
,64位下分配的是2個物理頁(返回的是虛擬位址)。但是很顯然thread_info
結構是用不了2頁的,剩餘的記憶體其實是用作子程序的核心棧(不是stack_start
引數指定的使用者棧),可以通過end_of_stack()
來計算棧頂位置。在分配完必要的結構後,會呼叫arch_dup_task_struct()
拷貝父程序的task_struct
結構到子程序的task_struct
結構,如果父程序使用fpu或其他的cpu擴充套件暫存器,則要將這些暫存器的資訊(在prepare_to_copy()
中儲存的)拷貝到子程序的task_struct
結構中。
fork()系統呼叫對應的核心實現為sys_fork()
,sys_fork()
是對do_fork()
的簡單封裝,sys_fork()
的任務是從處理器暫存器中提取由使用者空間提供的資訊,do_fork()
負責程序的複製。fork()和clone()系統呼叫的入口點sys_vfork()
和sys_clone()
也是呼叫的do_fork()
。
而其中關係著程序建立的主要是copy_process
和copy_thread.copy_process()
函式有7個引數,其中我們需要關心的有clone_flags
、stack_start
和regs
。cone_flags
是乙個標誌集合,分為兩部分:最低的位元組指定了在子程序終止時傳送給父程序的訊號,其餘的高位位元組儲存了各種真正的複製標誌,如clone_fs
、clone_thread
等。在使用者層呼叫fork()時不能指定標誌,所以預設的clone_flags
的值為sigchld。
子程序的初始化:程序的使用者棧的起始位址儲存在task_struct
結構的stack_start
成員中,在初始化的時候使用的是父程序的使用者棧位址,所以在子程序建立時會和父程序使用相同的使用者棧,如果有任何一方修改棧的話,會重新拷貝乙份,這是基於cow技術,以避免無用的複製。建立子程序為排程器類提供了排程程序的乙個切入點,核心會呼叫sched_fork()
函式,以便使排程器有機會對新程序進行設定。sched_fork()
會初始化一些和排程相關的成員,並將程序設定為task_running狀態。不過此時新的程序還沒有放到cpu的執行佇列中,所以新的程序不會被排程到。
新程序是從ret_from_fork
處開始執行的。對於fork執行處理過程來說,父子程序共享同一段**空間,」一次呼叫,兩次返回「,其實對於呼叫fork的父程序來說,如果fork出來的子程序沒有得到 排程,那麼父程序從fork系統呼叫返回,同時分析sys_fork
知道,fork返回的是子程序的id。再看fork出來的子程序,由copy_process
函式可以看出,子程序的返回位址為ret_from_fork
(和父程序在同乙個**點上返回),返回值直接置為0。所以當子進 程得到排程的時候,也從fork返回,返回值為0。ret_from_fork()
呼叫schedule_tail()
函式,用存放在棧中的值再裝入所有暫存器,並強迫cpu返回到使用者態。這樣,eax暫存器就裝過兩個值,乙個是子程序的值0,乙個是父程序的值——子程序的pid。然後在fork()、vfork()或clone()返回時,新程序將開始執行。在不同的程序中返回不同的值。
1.配置環境,登入實驗樓**。
cd linuxkernel
刪除menu
然後從github上轉殖相應的mengning/menu.git
2.測試menuos,測試fork直接執行結果。
3.配置除錯系統,進入gdb除錯,利用file linux-3.18.6/vmlinux和target remote:1234來配置載入初始除錯環境.
4.在linux核心程序建立可能用到的點設定斷點分別為sys_clone,do_fork,dup_task_struct,copy_thread,copy_process和ret_from_fork.
linux中,fork、vfork和clone三個系統呼叫都是通過呼叫do_fork
來實現程序的建立,而fork()系統呼叫產生的子程序在系統呼叫處理過程中從ret_from_fork
處開始執行。fork會產生父子程序,在父程序中,返回值是子程序的程序號;在子程序中,返回值為0。因此可通過返回值來判斷當前程序是父程序還是子程序。使用fork函式得到的子程序是父程序的乙個複製品,它從父程序處複製了整個程序的位址空間,包括程序上下文,程序堆疊,記憶體資訊,開啟的檔案描述符,訊號控制設定,程序優先順序,程序組號,當前工作目錄,根目錄,資源限制,控制終端等。而子程序所獨有的只是它的程序號,資源使用和計時器等。可以看出,使用fork函式的代價是很大的,它複製了父程序中的**段,資料段和堆疊段裡的大部分內容,使得fork函式的執行速度並不快。
開發程序 第六周
請不要講本專案相關資料外洩,謝謝!在linux平台開發,使用語言,推薦python,也可以用c 請注意python的縮排格式!編譯器使用linux自帶的gredit,可以使用roboware來解決python的縮排問題。寫 時,請注意新增注釋,多使用函式型別,少使用全域性變數,注意ros的程式設計規...
第六周周總結
這一周,不管是生活上的還是學習上的,亦或是工作上的,都異常的忙碌,忙碌到心態會有些崩潰的地步,可能是性格原因,不願意說放棄就放棄,所以還是希望可以完成自己該做的,想做的事情。堅持不是一件容易的事情,可怕的是你都不知道自己的堅持到底對不對,不管正確與否,我都選擇,做下去。像長跑,原以為自己肯定跑不動,...
第六周周總結
在第六周中是忙碌的,對於高數,上課的內容也在快速的翻篇,我的大腦也在快速的運轉著,講概念的時候我很難理解過來,但是講習題的時候勉勉強強能聽的懂,每次在聽不懂的地方我都會打個問號,以便於自己下課後方便問同學,我覺得這也是初中以來養成的乙個好習慣吧,數學的作業真的太傷腦細胞了,往往要思考很久才能做出一題...