1. 程式人生 > >《Linux核心原理與分析》第七週作業

《Linux核心原理與分析》第七週作業

課本:第六章 程序的描述和程序的建立

  • 作業系統核心實現作業系統的三大管理功能
    • 程序管理
    • 記憶體管理
    • 檔案系統
  • 在作業系統原理中,通過程序控制塊PCB描述程序;在Linux核心中,通過一個數據結構struct task_struct來描述程序。
  • 在作業系統原理中,程序有就緒態、執行態和阻塞態;在Linux核心中,就緒態和執行態都是相同的TASK_RUNNING狀態另加上一個阻塞態。在Linux核心中,當程序是TASK_RUNNING狀態時,它是可執行的,就是就緒態,是否在執行取決於它有沒有獲得CPU的控制權。
  • 對於一個正在執行的程序,呼叫使用者態庫函式exit()會陷入核心執行該核心函式do_exit(),程序會進入TASK_ZOMBIE狀態,即中止狀態,Linux核心會在適當的時候把該程序處理掉,後釋放程序描述符。一個正在執行的程序在等待特定事件或資源時會進入阻塞態,阻塞態分為兩種:TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE。前者可以被訊號和wake_up()喚醒,後者只能被wake_up()喚醒。程序狀態轉換圖如下圖所示:
  • 在程序描述符中用pid和tgid標識程序。
  • 在程序的建立時,0號程序init_task的初始化是通過硬編碼方式固定下來的,除此之外,所有其他程序的初始化都是通過do_fork複製父程序的方式初始化的。
  • Linux核心中,資料結構struct thread_struct用來儲存程序上下文中CPU相關的一些狀態資訊,其內部最關鍵的是sp和ip,在x86-32位系統中,sp用來儲存程序上下文中的ESP暫存器狀態,ip用來儲存程序上下文中的EIP暫存器狀態。
  • fork系統呼叫把當前程序又複製了一個子程序,也就一個程序變成了兩個程序,兩個程序執行相同的程式碼,只是fork系統呼叫在父程序和子程序中的返回值不同。
  • fork、vfork和clone這三個系統呼叫和kernel_thread核心函式都可以建立一個新程序,而且都是通過do_fork函式來建立程序的,只不過傳遞的引數不同。
  • do_fork函式的引數:
    • clone_flags:子程序建立相關標誌,通過此標誌可以對父程序的資源進行有選擇的複製。
    • stack_start:子程序使用者態堆疊的地址。
    • regs:指向pt_regs結構體的指標。當發生系統呼叫時,int指令和SAVE_ALL儲存現場等會將CPU暫存器中的值按順序壓入核心棧。為了便於訪問操作,這部分資料被定義為pt_regs結構體。
    • stack_size:使用者態棧的大小,通常不必要,設定為0。
    • parent_tidptr和child_tidptr:父程序、子程序使用者態下的pid地址。
  • 程序的建立中幾個關鍵函式:
    • do_fork():建立程序
    • copy_process():建立程序內容
    • dup_task_struct():複製程序描述符、資訊檢查、初始化、更改程序狀態、複製其他程序資源、呼叫copy_thread初始化子程序核心棧、設定子程序pid等
    • copy_thread():核心棧關鍵資訊初始化

實驗:分析Linux核心建立一個新程序的過程