Linux內核的組成部分

1.進程、進程切換、調度

  • 系統中同時真正在運行的進程數目最多不超過CPU數目
  • 確定哪個進程運行多長時間的過程稱之爲調度

2.UNIX進程

  • init是進程樹的根,所有進程都直接或間接起源該進程
##@##>pstree
  • UNIX創建新進程的機制:分別是fork和exec
    (1)fork技術:寫時複製(copy on write),原理:將內存複製操作延遲到父進程或子進程向某內存頁面寫入數據之前,在只讀訪問的情況下父進程和子進程可以共用同一內存頁
    (2)exec將一個新程序加載到當前進程的內存中並執行。
    舊程序的內存頁將刷出,其內容將替換爲新數據,然後開始執行新程序。

  • 線程
    進程可以看作一個正在執行的程序,線程則是與主程序並行運行的程序函數或例程

  • 命名空間
    每個命名空間可以包含一個特定的PID集合

3.地址空間與特權級別

  • Linux將虛擬地址空間劃分爲2個部分,內核空間和用戶空間
    在這裏插入圖片描述

  • 地址空間的最大長度與實際可用的物理內存數量無關,因此被稱之爲虛擬地址空間

  • 各個系統進程的用戶空間是完全彼此分離的,而虛擬地址空間頂部的內核空間總是同樣的。

  • 特權級別
    在多處理器系統上,許多線程啓動時指定了CPU。並限制只能在某個特定的CPU上運行。從內核線程名稱之後的斜線和CPU編號可以看出這一點

[xxxx@xxxx ~]# ps fax
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:01 [kthreadd]
    3 ?        S      0:00  \_ [migration/0]
    4 ?        S      0:00  \_ [ksoftirqd/0]
    5 ?        S      0:00  \_ [migration/0]
    6 ?        S      0:00  \_ [watchdog/0]
    7 ?        S      0:00  \_ [migration/1]
    8 ?        S      0:00  \_ [migration/1]
  • 虛擬和物理地址空間,內核和CPU如何將實際可用的物理內存映射到虛擬地址空間的區域?
    (1)使用頁表來爲物理地址分配虛擬地址。
    虛擬地址關係到進程的用戶空間和內核空間,而物理地址則用來尋址實際可用的內存。
    進程A的虛擬內存頁1映射到物理內存頁A,而進程B的虛擬內存頁1映射到物理內存頁5。
    (2)物理內存頁經常稱作頁幀,頁則專指虛擬地址空間中的頁
    (3)由於內核負責將虛擬地址空間映射到物理地址空間,因此可以決定哪些內存區域在進程之間共享,哪些不共享。
    在這裏插入圖片描述

4.頁表

  • 用來將虛擬地址空間映射到物理地址空間的數據結構稱爲頁表
    爲什麼需要多級頁表?
    (1)若使用數組,對虛擬地址空間中的每一頁,都分配一個數組項,該數組項指向與之關聯的頁幀。若爲32bit的機器,使用4KB頁,在虛擬地址空間爲4GB的前提下,則需要包含100萬項的數組。因爲虛擬地址空間的大部分區域都沒有使用,因而也沒有關聯到頁幀,那麼就可以使用功能相同,但內存用量少的模型:多級頁表
    (2)全局頁目錄PGB(Page Global Directory),索引進程中的一個數組,每個進程僅有一個。PGD指向另一些數組PMD的起始地址
    中間頁目錄PMD(Page Middle Directory):其數組項是指針,指向下一級數組,稱之爲頁表或目錄
    (3)頁表數組PTE(Page Table Entry),用作頁表的索引。虛擬內存頁和頁幀之間的映射就此完成,頁表的數組項指向頁幀。
    (4)多級頁表節省了大量的內存。每次訪問內存,通過多級頁表(逐級訪問多個數組)才能將虛擬地址轉換爲物理地址。爲了加速該過程,CPU有2種方法:內存管理單元MMU(Memory Management Unit)優化內存訪問,地址轉換中最頻繁的地址保存到TLB(地址轉換後備緩衝器,Translation Lookaside Buffer)的CPU高速緩存中
    在這裏插入圖片描述
  • 內存映射:在內核中大量使用,也可應用於用戶應用程序
    映射方法可以將任意來源的數據傳輸到進程的虛擬地址空間,但任何修改都會自動傳輸到原數據源。

5.物理內存的分配

  • 在內核分配內存時,必須記錄頁幀的已分配或空閒狀態
    內核可以只分配完整的頁幀,委託用戶空間中的標準庫將內存劃分爲更小的部分,標準庫將來源於內核的頁幀拆分爲小的區域,並未進程分配內存
  • 夥伴系統:分配連續頁
    (1)內核對所有大小相同的夥伴(1,2,4,8。。。。)都放置到同一個列表中管理。各有8頁的一對夥伴也在相應的列表中.
    如果系統需要8個頁幀,則將16個頁幀組成的塊拆分爲2個夥伴,其中一塊用於滿足應用程序的請求,而剩餘的8個頁幀則放置到對應8頁大小內存塊的類表中。
    (2)如果下一個請求只需要2個連續頁幀,則由8頁組成的塊會分裂成2個夥伴,每個包含4個頁幀。
    其中一塊放置回夥伴列表中,而另一個再次分裂成2個夥伴,每個包含2頁。
    其中一個回到夥伴系統,另一個則傳遞給應用程序。
    在這裏插入圖片描述
  • slab緩存
    內核無法使用標準庫函數,但是需要比完整頁幀小得多的內存塊,所以使用了slab緩存
    (1)對頻繁使用的對象,內核定義了只包含了所需類型對象實例的緩存,slab緩存自動維護與夥伴系統的交互,在緩存用盡時會請求新的頁幀
    (2)內核針對不同大小的對象定義了一組slab緩存。
    與用戶空間編程不同的是,這些函數都增加了前綴k,eg:kmalloc,kfree
    (3)頁幀的分配由夥伴系統進行,slab分配器則負責分配小內存以及提供一般性的內核緩存
    在這裏插入圖片描述
  • 頁面交換和頁面回收
    (1)頁面交換:在內核需要更多內存時,不經常使用的頁可以寫入磁盤
    (2)頁面回收:用於將內存映射被修改的內容與底層的塊設備同步

6.系統調用

  • 對於所有的處理器來說,一個共同點是:用戶進程從用戶態切換到內核態,並將系統關鍵任務委派給內核執行,系統調用是必由之路

7.設備驅動程序、塊設備和字符設備

  • 對外設的訪問可利用/dev目錄下的設備文件來完成,程序對設備的處理完全類似於常規的文件
  • 外設可分爲以下2類:
    (1)字符設備
    提供連續的數據流,應用程序可以順序讀取,此類設備支持按字節/字符來讀寫數據
    (2)塊設備
    應用程序可以隨機訪問設備數據,程序可自行確定讀取數據的位置;
    硬盤是典型的塊設備,應用程序可以尋址磁盤上的任何位置,數據的讀寫只能以塊(通常是512B)的倍數進行。與字符設備不同,塊設備並不支持基於字符的尋址。
    編寫塊設備的驅動程序較字符設備要複雜得多,爲此內核廣泛使用緩存機制

8.網絡

  • 在發送數據時,內核必須首先根據各個協議層的要求打包數據,然後才能發送

9.文件系統

  • 虛擬文件系統層、文件系統實現和塊設備層之間的互操作
    在這裏插入圖片描述

10.模塊和熱拔插

  • 模塊用於在運行時,動態地向內核添加功能,如設備驅動程序、文件系統、網絡協議等
  • 模塊在本質上不過是普通的程序,只是在內核空間而不是用戶空間執行而已
  • 某些總線(eg:USB和FireWire)允許在系統運行時連接設備,而無需系統重啓。
    在系統檢測到新設備時,通過加載對應的模塊,可以將必須的驅動程序自動添加到內核

11.緩存

  • 由於內核是通過基於頁的內存映射來實現訪問塊設備的,因此緩存也是按頁組織的,也就是說整個頁都緩存起來了,故稱之爲頁緩存(page cache)
  • 塊緩存已經被頁緩存取代了

12.鏈表處理

  • 內核提供的標準鏈表可用於將任何類型的數據結構彼此鏈接起來。很明確,它不是類型安全的。

13.對象管理和引用計數

  • (1)一般性的內核對象
  • (2)對象集合
  • (3)引用計數
    引用計數用於檢測內核中有多少地方使用了某個對象

14.數據類型

  • (1)類型定義
    內核使用typedef來定義各種數據類型,以避免依賴於體系結構相關的特性,比如,各個處理器上標準數據類型的位長可能都不見得相同。

  • (2)字節序
    爲表示數字,現代計算機採用大端序( big endian)或小端序( little endian)格式

  • (3)per-cpu變量
    在有若干CPU的系統上,會爲每個CPU分別創建變量的一個實例。用於某個特定CPU的實例可以通過get_cpu(name, cpu)獲得,其中smp_processor_id()可以返回當前活動處理器的ID,用作前述的cpu參數。

  • (4)訪問用戶空間
    源代碼中的多處指針都標記爲__user,該標識符對用戶空間程序設計是未知的。
    這是因爲內存是通過頁表映射到虛擬地址空間的用戶空間部分的,而不是由物理內存直接映射的。因此內核需要確保指針所指向的頁幀確實存在於物理內存中

  • 參考:<深入Linux內核架構>

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