Linux 內核(Kernel)組成分析

一、Linux內核簡介

Linux 內核採用宏內核架構,即 Linux 大部分功能都會在內核中實現,如進程管理、內存管理、設備管理、文件管理以及網絡管理等功能,它們是運行在內核空間中(也可以稱之爲特權模式下運行)。

微內核,它僅僅是將內核的基本功能放入內核中,如進程管理、進程調度等,而其他的設備管理、文件管理等功能都放在內核空間之外(即運行在非特權模式下)。

Linux 內核組成 :

Linux 內核主要由 5 部分組成,分別爲:進程管理子系統,內存管理子系統,文件子系統,網絡子系統,設備子系統。

由系統調用層(系統調用子系統)進行統一管理,應用層通過系統調用層的函數接口與內核進行交互,用戶應用程序執行的

地方是用戶空間,用戶空間之下則是內核空間,Linux 內核正是位於內核空間中。

 

二、Linux內核組成

1、進程管理子系統

進程管理的核心就是進程的調度。在 Linux 內核中,進程調度的單元是進程,進程調度控制系統中的多個進程對 CPU 的訪問,從宏觀上看,系統中的進程在 CPU 中是併發執行的。此外內核通過系統調用提供了應用程序編程接口,例如:創建新進程(forkexec),結束進程(killexit),並且提供了控制進程,同步進程和進程間通信的接口。

(1)進程與程序的區別:

  • 程序:存放在磁盤上的一系列代碼和數據的可執行映像,是一個靜止的實體。
  • 進程:是一個執行中的程序,它是動態的實體。

(2)進程的四要素:

  • 有一段程序供其執行,這段程序不一定是某個進程所專有,可以與其他進程共用。
  • 有進程專有的系統堆棧空間(也可以稱之爲內核堆棧空間)。
  • 在內核中有一個 task_struct 數據結構,即進程控制塊。有了這個數據結構,進程才能被內核調度器識別並參與內核調度,除此之外它還記錄着進程所佔有的各項資源。
  • 除上述的專有的系統堆棧空間外,進程還需要有獨立的用戶堆棧空間,這就是 mm_struct 數據結構,該數據結構位於 task_struct 結構中,字段名稱爲 mm

(3)進程的堆棧:

  • 內核在創建一個新的進程(創建進程控制塊 task_struct) 時,爲進程創建堆棧。
  • 一個進程有 2 個堆棧,即用戶堆棧和系統堆棧;用戶堆棧的空間指向用戶地址空間,內核堆棧的空間指向內核地址空間。
  • 當進程在用戶態運行時,CPU 堆棧指針寄存器指向用戶堆棧地址,使用用戶堆棧。
  • 當進程運行在內核態時,CPU 堆棧指針寄存器指向的是內核堆棧空間地址,使用內核堆棧。
 

(4)進程與線程的區分:

  • 進程:四個要素是必要條件
  • 用戶線程:有共享的用戶空間
  • 內核線程:沒有用戶空間,即 mm_struct 爲 NULL
  • 簡單區分如圖所示:
 

(5)進程調度:

  • 進程調度是進程管理子系統中最重要的一個功能,是一個管理進程之間使用 CPU 資源的管理程序。
  • 進程調度器有效地爲各個進程分配其使用的 CPU 資源時間,同時又要達到良好的用戶體驗效果,此外調度器還需要解決一些互相沖突的情況,例如既要實現實時任務的最小化響應時間, 又要最大限度地提高 CPU的總體利用率等。
  • Linux2.6 版本之後,進程調度器使用新的進程調度算法——Completely Fair Scheduler,簡稱 CFS,即完全公平調度算法該算法會按所需分配的計算能力,向系統中每個進程提供最大的公正性,它負責將 CPU 資源,分配給正在執行的進程,目標在於最大化程式互動效能,最小化整體 CPU 的運用,這個算法使用紅黑樹來實現,算法效率爲 O(log(n))

(6)進程狀態:

 
 
 

就緒態 R

(TASK_RUNNING)

(可執行狀態)

該狀態的進程才能被允許參與調度器調度並且使用 CPU 資源,而同一時刻可能有多個進程處於就緒態,這些進程的 task_struct 結構(進程控制塊)被放入對應 CPU 的可執行隊列中(一個進程最多隻能出現在一個 CPU 的可執行隊列中)。
進程調度器的任務就是從各個 CPU 的可執行隊列中分別選擇一個進程在該 CPU 上運行。

運行態 R

(TASK_RUNNING)

進程正在使用 CPU 資源。
提示:很多操作系統的書將正在 CPU 上執行的進程定義爲 RUNNING 狀態、而將可執行但是尚未被調度執行的進程定義爲 READY 狀態,這兩種狀態在 linux 下統一爲 TASK_RUNNING 狀態

暫停態 T

(TASK_STOPPED or TASK_TRACED)

向進程發送 SIGSTOP 信號,進入 TASK_STOPPED 狀態
向進程發送 SIGCONT 信號,從 TASK_STOPPED 狀態恢復到 TASK_RUNNING 狀態,當進程正在被跟蹤時,它處於 TASK_TRACED 這個特殊的狀態。
”正在被跟蹤”指的是進程暫停下來,等待跟蹤它的進程對它進行操作。比如在 gdb 中對被跟蹤的進程下一個斷點,進程在斷點處停下來的時候就處於 TASK_TRACED 狀態。

可中斷睡眠態 S (TASK_INTERRUPTIBLE)

(睡眠態)

因爲等待某些事件的發生而進入睡眠狀態(比如等待 socket 連接、等待信號量等)。
當這些事件發生的時候進程將被喚醒,如產生一個硬件中斷、釋放進程正在等待的系統資源或是傳遞一個信號都可以是喚醒進程的條件。
系統的大多數進程都是處於這個狀態,在終端可以通過 ps –aux 命令查看系統進程狀態。

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

(深度睡眠態)

把信號傳遞到這種睡眠狀態的進程不能改變它的狀態,也就是說它不響應信號的喚醒,這種狀態一般由 IO 引起,同步 IO 在做讀或寫操作時(比如進程對某些硬件設備進行操作,等待磁盤 IO,等待網絡 IO),此時 CPU 不能做其它事情,只能處於這種狀態進行等待,這樣一來就能保證進程執行期間不被外部信號打斷。

僵死態 Z

(TASK_DEAD - EXIT_ZOMBIE)

殭屍態或者退出態

進程退出的過程中,除了 task_struct 數據結構(以及少數資源)以外,進程所佔有的資源將被系統回收,此時進程沒法繼續運行了,但它還有 task_struct 數據結構,所以被稱爲僵死態。
之所以保留 task_struct 數據結構,是因爲 task_struct 中保存了進程的退出碼、以及一些其他的信息,而其父進程很可能會關心這些信息,因此會暫時被保留下來。
 
 

2、內存管理子系統

  • 主要作用是保證系統安全訪問內存區域,且絕大部分 CPU 都是支持內存管理單元的(Memory Management Unit,MMU
  • 內存管理子系統負責管理每個進程完成從虛擬內存到物理內存的轉換,以及系統可用內存空間
  • 內存管理的硬件按照分頁方式管理內存,分頁就是把系統的物理內存按照相同大小等分,每個內存分片稱作內存頁,通常內存頁大小是 4KB。內存管理子系統要管理的不僅是 4KB 緩衝區,它提供了對 4KB 緩衝區的抽象,例如 slab 分配器。這種內存管理模式使用 4KB 緩衝區爲基數,然後從中分配管理結構,並跟蹤內存頁使用情況。系統就支持動態調整內存使用情況。
  • Linux 還支持內存交換,因爲 Linux 中使用的是虛擬內存,當物理內存不足時,內存管理子系統會將內存暫時移到磁盤中,在物理內存充裕時又將內存頁從磁盤移到物理內存中。
  • 32 位的系統上,每個進程都最大享有 4GB 的內存空間,因爲由於 32 位的系統尋址空間只有4G,當然這是虛擬內存,0~3GB 是屬於用戶內存空間,3~4GB 是屬於系統內存空間,實際上用戶的程序幾乎使用不完那麼大的用戶空間,一旦超出將無法正常運行,當然系統內存空間與用戶內存空間是可以調整的。
 

3、文件管理子系統

  • Linux 系統中一切皆文件,它把一切資源都看作是文件,包括硬件設備,通常稱爲設備文件。
  • Linux 的文件管理子系統主要實現了虛擬文件系統Virtual File SystemVFS),虛擬文件系統屏蔽了各種硬件上的差異以及具體實現的細節,爲所有的硬件設備提供統一的接口,即實現了設備無關性,同時文件管理系統還爲應用層提供統一的 API 接口。
  • Linux 的文件系統體系結構是對一個對複雜系統進行了抽象化,通過使用一組通用的 API 函數,Linux 可以在許多種存儲設備上支持多種文件系統,如 NTFSEXT2EXT3EXT4 FAT 等等;而用戶空間包含一些應用程序和 GNU C 庫(glibc),它們使用的 API 接口是由系統調用層提供(如打開、讀、寫和關閉等)。
  • 框架如圖所示:
 
 

4、網絡子系統

Linux 內核中,與網絡相關的代碼被 Linux 獨立開,形成一個相對獨立的子系統,稱爲網絡子系統,網絡子系統是一個層次化的結構,可分爲以下幾個層次:
  • Socket 層(也可以稱之爲協議無關層):Linux 在發展過程中,採用 BSD Socket API 作爲自己的網絡相關的 API 接口。同時,Linux 的目標又要能支持各種不同的協議族,而且這些協議族都可以使用 BSD Socket API 作爲應用層的編程接口,這樣一來將 Socket 層抽象出來就能屏蔽不同協議族之間的差異,不會對應用層的使用產生影響。
  • 協議層Linux 網絡子系統功能上相當完備,它不僅支持 INET 協議族(也就是通常所說的 TCP/IP 協議族),而且還支持其它很多種協議族,如 INET6DECnetROSENETBEUI 等,對於 INET 、INET6 協議族來說,又會進一步將協議族劃分爲傳輸層和網絡層以及鏈路層等。
  • 網絡設備層:網絡設備其實是設備驅動層的內容了,它抽象了網卡數據結構,在一個系統中可能存在多種網卡,屏蔽了不同硬件上的差異,這一層提供了一組通用函數供底層網絡設備驅動程序使用。
  • 框架如圖所示:

 

 

5、設備子系統

設備子系統又被稱之爲設備驅動,如 LCD、攝像頭、USB、音頻等都是屬於設備,且設備的廠商不同其驅動程序也是不同的,但是對於 Linux 來說,不可能去將每個設備都包含到內核,它只能抽象去描述某種設備。

系統調用層Linux 內核與應用程序之間的接口,而設備驅動則是 Linux 內核與硬件之間的接口,設備驅動程序爲應用程序屏蔽了硬件的細節,在應用程序看來,硬件設備只是一個設備文件,應用程序可以象操作普通文件一樣對硬件設備進行操作(打開、讀、寫和關閉)。

設備驅動程序是內核的一部分,主要功能:
  • 對設備初始化和釋放
  • 把數據從內核傳送到硬件和從硬件讀取數據
  • 讀取應用程序傳送給設備文件的數據和回送應用程序請求的數據
  • 檢測和處理設備出現的錯誤
根據設備的共性將設備分類:

字符設備、塊設備、網絡設備

  • 字符設備,是以字節爲單位傳輸的 IO 設備,可以提供連續的數據流,應用程序可以順序讀取,通常不支持隨機存取。這種字符傳輸的效率通常是比較低的,如鼠標、鍵盤、串口等都是字符設備。
  • 塊設備,是以塊爲單位進行傳輸的設備,應用程序可以隨機訪問塊設備中的數據,程序可以指定讀取數據的位置。磁盤就是一種常見的塊設備,應用程序可以尋址磁盤上的任何位置,並在這個位置讀取數據。塊設備讀取的數據只能以塊爲單位的倍數進行(通常是 512Byte 的整數倍),而不能與字符設備一樣以字節爲單位讀取。塊設備的傳輸速度是比較高的。
  • 網絡設備,其實就是網絡子系統中描述的網絡設備層,統一描述了不同的網卡設備,如 WIFI、以太網等。因爲網絡設備存在協議棧(協議族),它涉及了網絡層協議,所以 Linux 將網絡設備單獨分層一類設備。傳輸速率通常很高。
  • 框架如圖所示:
 
 
文章參照:[野火]i.MX Linux開發實戰指南 歸納總結筆記
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章