第一部分
程序控制塊pcb-task_struct資料結構
圖 1 task_struct
為了管理程序,核心必須對每個程序進行清晰的描述,程序描述符提供了核心所需了解的程序資訊。task_struct資料結構龐大,包含以下:
1、程序狀態
#define task_running 0
#define task_interruptible 1
#define task_uninterruptible 2
#define __task_stopped 4
#define __task_traced 8
/* in tsk->exit_state */
#define exit_dead 16
#define exit_zombie 32
#define exit_trace (exit_zombie | exit_dead)
/* in tsk->state again */
#define task_dead 64
#define task_wakekill 128
#define task_waking 256
#define task_parked 512
#define task_state_max 1024
linux程序的狀態與作業系統原理中的描述的程序狀態似乎有所不同,比如就緒狀態和執行狀態都是task_running,是否處於執行狀態,取決是否獲得cpu的控制權。
2、程序的pid
3、所有程序雙向鍊錶 struct list_head tasks
4、程序父子關係
5、linux為每個程序分配乙個8kb大小的記憶體區域,用於存放該程序兩個不同的資料結構:thread_info和程序的核心堆疊。
6、struct thread_struct thread,cpu相關的狀態。
7、檔案系統和檔案描述符
8、記憶體管理——程序的位址空間
9、開啟的檔案符列表
等等第二部分
分析fork函式對應的核心處理過程sys_clone,理解建立乙個新程序如何建立。
圖2 fork函式執行流程
fork、vfork和clone三個系統呼叫都可以建立乙個新程序,而且都是通過呼叫do_fork來實現程序的建立。
(1)do_fork
建立新程序是通過複製當前程序實現的。
do_fork主要是複製了父程序的task_struct,然後修改必要的資訊,從而得到子程序的task_struct。
呼叫copy_process,將當前程序複製乙份出來給子程序,並且為子程序設定相應地上下文資訊。
呼叫wake_up_new_task,將子程序放入排程器的佇列中,此時的子程序就可以被排程程序選中執行。
(2)copy_process
建立程序描述符以及子程序所需要的其他所有資料結構,為子程序準備執行環境。呼叫dup_task_struct複製乙份task_struct結構體,作為子程序的程序描述符,複製所有的程序資訊。呼叫copy_thread,設定子程序的堆疊資訊,為子程序分配乙個pid。
(3)dup_ task_ struct
先呼叫alloc_task_struct_node分配乙個task_struct結構體。
呼叫alloc_thread_info_node,分配了乙個union。這裡分配了乙個thread_info結構體,還分配了乙個stack陣列。返回值為ti,實際上就是棧底。
tsk->stack = ti將棧底的位址賦給task的stack變數。最後為子程序分配了核心棧空間。
執行完dup_task_struct之後,子程序和父程序的task結構體,除了stack指標之外,完全相同。
(4)copy_thread
獲取子程序暫存器資訊的存放位置,對子程序的thread.sp賦值,將來子程序執行,這就是子程序的esp暫存器的值。
將子程序的eax暫存器值設定為0,所以fork呼叫在子程序中的返回值為0。
子程序從ret_from_fork開始執行,所以它的位址賦給thread.ip,也就是將來的eip暫存器。
(5)執行新程序
新的子程序從ret_from_fork處開始執行。
dup_task_struct中為其分配了新的堆疊。
copy_process中呼叫了sched_fork,將其置為task_running
copy_thread中將父程序的暫存器上下文複製給子程序,這是非常關鍵的一步,這裡保證了父子程序的堆疊資訊是一致的。
第三部分
使用gdb跟蹤分析fork函式執行
圖3 為menuos中的fork函式執行效果
圖4 在sys_clone處設定斷點
圖5 在do_fork處設定斷點
圖6 在copy_process處設定斷點
圖7 在dup_task_struct處設定斷點
圖8 在copy_thread處設定斷點
圖9 ret_from_fork
聊聊Linux核心建立新程序
計算機是一種精密的儀器,有一點錯誤都是不能成功執行的,計算機軟體是靠乙個個程式組成的,而程式又是一系列指令所組成。通過執行這樣的一條條指令,計算機就能完成乙個個任務了。這裡有兩個概念比較容易混淆,平時我們在學習計算機的時候也是這樣,那就是程序和程式的區別,這也是這篇部落格的主要內容,程序。簡單點講,...
實驗六 分析Linux核心建立乙個新程序的過程
1 首先進入虛擬機器,開啟終端,這命令列依次敲入以下命令 cd linuxkernel 一切正常的話,這時候我們簡易的核心系統就啟動起來了,輸入help,就可以看到新新增的命令fork,輸入fork,2.gdb上述的fork命令 關閉qemu視窗,中命令列中輸入 qemu kernel linux ...
Linux建立新程序
在linux系統中,建立新程序涉及到兩個系統呼叫api 分別是fork 和exec 首先,在當前程序中,呼叫fork 複製出自身的乙個拷貝,此時主要涉及到核心中與程序上下文相關的資料複製操作,而使用者 和資料則採用寫時複製技術共享同乙份資源。當乙個程序複製後,原程序稱為父程序,新程序則稱為子程序.然...