Linux核心的整體架構

tinylaker發表於2018-10-18

本文轉載自 http://www.wowotech.net/linux_kenrel/11.html

1.前言

本文是“Linux核心分析”系列文章的第一篇,會以核心的核心功能為出發點,描述Linux核心的整體架構,以及架構之下主要的軟體子系統。之後,會介紹Linux核心原始檔的目錄結構,並和各個軟體子系統對應。

注:本文和其它的“Linux核心分析”文章都基於如下約定:

a) 核心版本為Linux 3.10.29(該版本是一個long term的版本,會被Linux社群持續維護至少2年),可以從下面的連結獲取:https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.10.29.tar.xz

b) 鑑於嵌入式系統大多使用ARM處理器,因此涉及到體系結構部分的內容,都以ARM為分析物件

2.Linux核心的核心功能

如下圖所示,Linux核心只是Linux作業系統一部分。對下,它管理系統的所有硬體裝置;對上,它通過系統呼叫,向Library Routine(例如C庫)或者其它應用程式提供介面。

因此,其核心功能就是:管理硬體裝置,供應用程式使用。而現代計算機(無論是PC還是嵌入式系統)的標準組成,就是CPU、Memory(記憶體和外存)、輸入輸出裝置、網路裝置和其它的外圍裝置。所以為了管理這些裝置,Linux核心提出瞭如下的架構。

image

3.Linux核心的整體架構

3.1 整體架構和子系統劃分

image

上圖說明了Linux核心的整體架構。根據核心的核心功能,Linux核心提出了5個子系統,分別負責如下的功能:

  • Process Scheduler,也稱作程式管理、程式排程。負責管理CPU資源,以便讓各個程式可以以儘量公平的方式訪問CPU。

  • Memory Manager,記憶體管理。負責管理Memory(記憶體)資源,以便讓各個程式可以安全地共享機器的記憶體資源。另外,記憶體管理會提供虛擬記憶體的機制,該機制可以讓程式使用多於系統可用Memory的記憶體,不用的記憶體會通過檔案系統儲存在外部非易失儲存器中,需要使用的時候,再取回到記憶體中。

  • VFS(Virtual File System),虛擬檔案系統。Linux核心將不同功能的外部裝置,例如Disk裝置(硬碟、磁碟、NAND Flash、Nor Flash等)、輸入輸出裝置、顯示裝置等等,抽象為可以通過統一的檔案操作介面(open、close、read、write等)來訪問。這就是Linux系統“一切皆是檔案”的體現(其實Linux做的並不徹底,因為CPU、記憶體、網路等還不是檔案,如果真的需要一切皆是檔案,還得看貝爾實驗室正在開發的”Plan 9”的)。

  • Network,網路子系統。負責管理系統的網路裝置,並實現多種多樣的網路標準。

  • IPC(Inter-Process Communication),程式間通訊。IPC不管理任何的硬體,它主要負責Linux系統中程式之間的通訊。

3.2 程式排程(Process Scheduler)

程式排程是Linux核心中最重要的子系統,它主要提供對CPU的訪問控制。因為在計算機中,CPU資源是有限的,而眾多的應用程式都要使用CPU資源,所以需要“程式排程子系統”對CPU進行排程管理。

程式排程子系統包括4個子模組(見下圖),它們的功能如下:

scheduler

  • Scheduling Policy,實現程式排程的策略,它決定哪個(或哪幾個)程式將擁有CPU。

  • Architecture-specific Schedulers,體系結構相關的部分,用於將對不同CPU的控制,抽象為統一的介面。這些控制主要在suspend和resume程式時使用,牽涉到CPU的暫存器訪問、彙編指令操作等。

  • Architecture-independent Scheduler,體系結構無關的部分。它會和“Scheduling Policy模組”溝通,決定接下來要執行哪個程式,然後通過“Architecture-specific Schedulers模組”resume指定的程式。

  • System Call Interface,系統呼叫介面。程式排程子系統通過系統呼叫介面,將需要提供給使用者空間的介面開放出去,同時遮蔽掉不需要使用者空間程式關心的細節。

3.3 記憶體管理(Memory Manager, MM)

記憶體管理同樣是Linux核心中最重要的子系統,它主要提供對記憶體資源的訪問控制。Linux系統會在硬體實體記憶體和程式所使用的記憶體(稱作虛擬記憶體)之間建立一種對映關係,這種對映是以程式為單位,因而不同的程式可以使用相同的虛擬記憶體,而這些相同的虛擬記憶體,可以對映到不同的實體記憶體上。

記憶體管理子系統包括3個子模組(見下圖),它們的功能如下:

mman

  • Architecture Specific Managers,體系結構相關部分。提供用於訪問硬體Memory的虛擬介面。

  • Architecture Independent Manager,體系結構無關部分。提供所有的記憶體管理機制,包括:以程式為單位的memory mapping;虛擬記憶體的Swapping。

  • System Call Interface,系統呼叫介面。通過該介面,向使用者空間程式應用程式提供記憶體的分配、釋放,檔案的map等功能。

3.4 虛擬檔案系統(Virtual Filesystem, VFS)

傳統意義上的檔案系統,是一種儲存和組織計算機資料的方法。它用易懂、人性化的方法(檔案和目錄結構),抽象計算機磁碟、硬碟等裝置上冰冷的資料塊,從而使對它們的查詢和訪問變得容易。因而檔案系統的實質,就是“儲存和組織資料的方法”,檔案系統的表現形式,就是“從某個裝置中讀取資料和向某個裝置寫入資料”。

隨著計算機技術的進步,儲存和組織資料的方法也是在不斷進步的,從而導致有多種型別的檔案系統,例如FAT、FAT32、NTFS、EXT2、EXT3等等。而為了相容,作業系統或者核心,要以相同的表現形式,同時支援多種型別的檔案系統,這就延伸出了虛擬檔案系統(VFS)的概念。VFS的功能就是管理各種各樣的檔案系統,遮蔽它們的差異,以統一的方式,為使用者程式提供訪問檔案的介面。

我們可以從磁碟、硬碟、NAND Flash等裝置中讀取或寫入資料,因而最初的檔案系統都是構建在這些裝置之上的。這個概念也可以推廣到其它的硬體裝置,例如記憶體、顯示器(LCD)、鍵盤、串列埠等等。我們對硬體裝置的訪問控制,也可以歸納為讀取或者寫入資料,因而可以用統一的檔案操作介面訪問。Linux核心就是這樣做的,除了傳統的磁碟檔案系統之外,它還抽象出了裝置檔案系統、記憶體檔案系統等等。這些邏輯,都是由VFS子系統實現。

VFS子系統包括6個子模組(見下圖),它們的功能如下:

vfs

  • Device Drivers,裝置驅動,用於控制所有的外部裝置及控制器。由於存在大量不能相互相容的硬體裝置(特別是嵌入式產品),所以也有非常多的裝置驅動。因此,Linux核心中將近一半的Source Code都是裝置驅動,大多數的Linux底層工程師(特別是國內的企業)都是在編寫或者維護裝置驅動,而無暇估計其它內容(它們恰恰是Linux核心的精髓所在)。

  • Device Independent Interface, 該模組定義了描述硬體裝置的統一方式(統一裝置模型),所有的裝置驅動都遵守這個定義,可以降低開發的難度。同時可以用一致的形勢向上提供介面。

  • Logical Systems,每一種檔案系統,都會對應一個Logical System(邏輯檔案系統),它會實現具體的檔案系統邏輯。

  • System Independent Interface,該模組負責以統一的介面(快裝置和字元裝置)表示硬體裝置和邏輯檔案系統,這樣上層軟體就不再關心具體的硬體形態了。

  • System Call Interface,系統呼叫介面,向使用者空間提供訪問檔案系統和硬體裝置的統一的介面。

3.5 網路子系統(Net)

網路子系統在Linux核心中主要負責管理各種網路裝置,並實現各種網路協議棧,最終實現通過網路連線其它系統的功能。在Linux核心中,網路子系統幾乎是自成體系,它包括5個子模組(見下圖),它們的功能如下:

net

  • Network Device Drivers,網路裝置的驅動,和VFS子系統中的裝置驅動是一樣的。

  • Device Independent Interface,和VFS子系統中的是一樣的。

  • Network Protocols,實現各種網路傳輸協議,例如IP, TCP, UDP等等。

  • Protocol Independent Interface,遮蔽不同的硬體裝置和網路協議,以相同的格式提供介面(socket)。

  • System Call interface,系統呼叫介面,向使用者空間提供訪問網路裝置的統一的介面。

至於IPC子系統,由於功能比較單純,這裡就不再描述了。

4.Linux核心原始碼的目錄結構

Linux核心原始碼包括三個主要部分:

  1. 核心核心程式碼,包括第3章所描述的各個子系統和子模組,以及其它的支撐子系統,例如電源管理、Linux初始化等
  2. 其它非核心程式碼,例如庫檔案(因為Linux核心是一個自包含的核心,即核心不依賴其它的任何軟體,自己就可以編譯通過)、韌體集合、KVM(虛擬機器技術)等
  3. 編譯指令碼、配置檔案、幫助文件、版權說明等輔助性檔案

下圖示使用ls命令看到的核心原始碼的頂層目錄結構,具體描述如下。

kernel_src_tree

include/ ---- 核心標頭檔案,需要提供給外部模組(例如使用者空間程式碼)使用。

kernel/ ---- Linux核心的核心程式碼,包含了3.2小節所描述的程式排程子系統,以及和程式排程相關的模組。

mm/ ---- 記憶體管理子系統(3.3小節)。

fs/ ---- VFS子系統(3.4小節)。

net/ ---- 不包括網路裝置驅動的網路子系統(3.5小節)。

ipc/ ---- IPC(程式間通訊)子系統。

arch// ---- 體系結構相關的程式碼,例如arm, x86等等。 
    arch//mach- ---- 具體的machine/board相關的程式碼。 
    arch//include/asm ---- 體系結構相關的標頭檔案。 
    arch//boot/dts ---- 裝置樹(Device Tree)檔案。

init/ ---- Linux系統啟動初始化相關的程式碼。 
block/ ---- 提供塊裝置的層次。 
sound/ ---- 音訊相關的驅動及子系統,可以看作“音訊子系統”。 
drivers/ ---- 裝置驅動(在Linux kernel 3.10中,裝置驅動佔了49.4的程式碼量)。

lib/ ---- 實現需要在核心中使用的庫函式,例如CRC、FIFO、list、MD5等。 
crypto/ ----- 加密、解密相關的庫函式。 
security/ ---- 提供安全特性(SELinux)。 
virt/ ---- 提供虛擬機器技術(KVM等)的支援。 
usr/ ---- 用於生成initramfs的程式碼。 
firmware/ ---- 儲存用於驅動第三方裝置的韌體。

samples/ ---- 一些示例程式碼。 
tools/ ---- 一些常用工具,如效能剖析、自測試等。

Kconfig, Kbuild, Makefile, scripts/ ---- 用於核心編譯的配置檔案、指令碼等。

COPYING ---- 版權宣告。 
MAINTAINERS ----維護者名單。 
CREDITS ---- Linux主要的貢獻者名單。 
REPORTING-BUGS ---- Bug上報的指南。

Documentation, README ---- 幫助、說明文件。

5.附錄

5.1 參考資料

相關文章