linux內核學習筆記(一)——內核體系結構

Linux進程控制

系統最多可以有64個進程同時運行,除第一個進程爲手工建立,其他進程均使用系統調用fork創建。
內核使用進程標識號(process ID,pid)標識進程。
進程由可致性的指令代碼、數據和堆棧區組成。

任務數據結構

內核通過進程表對進程進行管理,每個進程在進程表中佔有一項,進程表項是一個task_struct任務結構指針,定義在include/linux/sched.h中。
當一個進程在執行時,CPU的所有寄存器中的值、進程的狀態以及堆棧中的內容被稱爲該進程的上下文。

進程運行狀態

一個進程在其生存期內,可處於一組不同的狀態下,稱爲進程狀態。

  • 運行狀態(TASK_RUNNING)

    當進程正在被CPU執行,或已經準備就緒隨時可由調度程序執行,則稱該進程處於運行狀態(running)。當系統資源已經可用時,進程就被喚醒而進入準備運行狀態,該狀態被稱爲就緒態

  • 可中斷睡眠狀態(TASK_INTERRUPTIBLE)

    當進程處於可中斷狀態時,系統不會調度該進程執行。當系統產生一個終端或者釋放進程正在等待的資源,或者進程收到一個信號,都可以喚醒進程轉換到就緒狀態(運行狀態)

  • 不可中斷睡眠狀態(TASK_UNINTERRUPTIBLE)

    與可中斷睡眠狀態類似。但處於該狀態的進程只有被使用wake_up()函數明確喚醒時才能轉換到可運行的就緒狀態。

  • 暫停狀態(TASK_STOPPED)

    當進程收到信號SIGSTOP、SIGTSTP、SIGTTIN和SIGTTOU時就會進入暫停狀態。可向其發送SIGCONT信號讓進程轉換到可運行狀態。

  • 僵死狀態(TASK_ZOMBIE)

    當進程已經停止運行,但其父進程還沒詢問其狀態時,則稱該進程處於僵死狀態

只有當進程從“內核運行態”轉移到“睡眠狀態”時,內核纔會進行進程切換操作。在內核態下運行的進程不能被其他進程搶佔,而且一個進程不能改變另一個進程的狀態。爲了避免切換時造成內核數據錯誤,內核在執行臨界區代碼時會禁止一切中斷。

進程調度

Linux進程是搶佔式的,被搶佔的進程仍然處於TASK_RUNNING狀態,只是暫時沒有被CPU運行,進程的搶佔發生在進程處於用戶態執行階段,在內核態執行時是不能被搶佔的。Linux 0.11中採用基於優先級排隊的調度策略。

對內存的使用方法

  1. 邏輯地址(Logical Address)是指程序產生的與段相關的偏移地址部分。
  2. 線性地址(Linear Address)是邏輯地址到物理地址變換之間的中間層。
  3. 物理地址(Physical Address)是指出現在CPU外部地址總線上的尋址物理內存的地址信號,是地址變換的最終結果地址。
  4. 虛擬內存(Virtual Memory)是指計算機呈現出要比實際擁有的內存大得多的內存量。

Linux內核源代碼的目錄結構

引導啓動程序目錄boot

boot目錄包含3個彙編文件,是內核源代碼文件中最先被編譯的程序

  1. bootsect.s : 磁盤引導塊程序,編譯後會駐留在磁盤的第一個扇區中
  2. setup.s : 用於讀取機器的硬件配置參數,並把內核模塊system移動到適當的內存位置處
  3. head.s : 會被編譯連接在system模塊的最前部分,主要進行硬件設備的探測設置和內存管理頁面的初始設置工作

文件系統目錄fs


圖中每個方框代表一個文件,從上到下按基本引用關係放置,虛框中的程序文件不屬於文件系統,帶箭頭的線條表示引用關係,粗線條表示有相互引用關係。

文件系統目錄中可以劃分爲四個部分:高速緩衝區管理、低層文件操作、文件數據訪問和文件高層函數。

管理高速緩衝區的程序是buffer.c,其他程序則主要用於文件系統管理。

file_table.c中,目前只定義了一個文件句柄(描述符)結構數組。

ioctl.c文件將引用kernel/chr_drv/tty_ioctl.c中的函數,實現字符設備的io控制功能。

exec.c主要包含一個執行程序函數do_execve(),它是所有exec()函數簇中的主要函數。

fcntl.c程序用於實現文件i/o控制的系統調用函數。

read_write.c程序用於實現文件讀/寫和定位三個系統調用函數。

stat.c程序中實現了兩個獲取文件狀態的系統調用函數。

open.c程序主要包含實現修改文件屬性和創建與關閉文件的系統調用函數。

char_dev.c主要包含字符設備獨寫函數rw_char()

pipe.c程序中包含管道讀寫函數和創建管道的系統調用。

file_dev.c程序中包含基於i幾點和描述符結構的文件獨寫函數。

namei.c程序主要包括文件系統中目錄名和文件名的操作函數和系統調用函數。

block_dev.c程序包含塊數據讀和寫函數。

inode.c程序中包含針對文件系統i節點操作的函數。

truncate.c程序用於在刪除文件時釋放文件所佔用的設備數據空間。

bitmap.c程序用於處理文件系統中i系欸但和邏輯數據塊的位圖。

super.c程序中包含對文件系統超級塊的處理函數。

頭文件目錄include

頭文件目錄中一共含有32個.h頭文件。主目錄下13個,asm目錄下4個,linux目錄中有10個,sys子目錄中有5個。

內核初始化程序目錄init

用於執行內核所有的初始化工作,然後移到用戶模式創建新進程,並在控制檯設備上運行shell程序。

內核程序主目錄kernel

內核庫函數目錄lib

內核庫函數用於爲內核初始化程序init/main.c運行在用戶態的進程(進程0、1)提供調用支持,與普通靜態庫的實現方法完全一樣。

內存管理程序目錄mm

主要用於管理程序對主內存區的使用,實現了進程邏輯地址到線性地址以及線性地址到主內存區中物理內存地址的映射,通過內存的分頁管理機制,在進程的虛擬內存頁與主內存區的物理內存頁之間建立了對應關係。

編譯內核工具程序目錄tools

用於將Linux各個目錄中被分別編譯生成的目標代碼連接合併成一個可運行的內核映像文件image。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章