官术网_书友最值得收藏!

1.3 Linux內核

1.3.1 宏內核和微內核

操作系統屬于軟件的范疇,來負責管理系統的硬件資源,同時為應用程序開發和執行提供配套環境。操作系統必須具備如下兩大功能。

為多用戶和應用程序管理計算機上的硬件資源。

為應用程序提供執行環境。

除此之外,操作系統還需要具備如下一些特性。

并發性:操作系統必須具備執行多個線程的能力。從宏觀上看,多線程會并發執行,如在單CPU系統中運行多線程的程序。線程是獨立運行和獨立調度的基本單位。

虛擬性:多進程的設計理念就是讓每個進程都感覺有一個專門的處理器為它服務,這就是虛擬處理器技術。

操作系統內核的設計在歷史上存在兩大陣營,一個是宏內核,另一個是微內核。宏內核是指所有的內核代碼都編譯成一個二進制文件,所有的內核代碼都運行在一個大內核地址空間里,內核代碼可以直接訪問和調用,效率高并且性能好,如圖1.3所示。而微內核是指把操作系統分成多個獨立的功能模塊,每個功能模塊之間的訪問需要通過消息來完成,因此效率沒有那么高。比如,當時Linus學習的Minix就是微內核的典范。現代的一些操作系統(比如Windows)就采用微內核的方式,內核保留操作系統最基本的功能,比如進程調度、內存管理通信等模塊,其他的功能全部從內核移出,放到用戶態中實現,并以C/S模型為應用程序提供服務,如圖1.4所示。

圖1.3 宏內核架構

圖1.4 微內核架構

Linus 在設計之初并沒有使用當時學術界流行的微內核架構,而是采用實現方式比較簡單的宏內核架構,一方面是因為Linux在當時是業余作品,另一方面是因為Linus本人更喜歡宏內核的設計。宏內核架構的優點是設計簡潔和性能比較好,而微內核架構的優勢也很明顯,比如穩定性和實時性等。微內核架構最大的問題就是高度模塊化帶來的交互的冗余和效率的損耗。把所有的理論設計放到現實的工程實踐中都是一種折中的藝術。Linux在20多年的發展歷程中,形成了自己的工程理論,并且不斷融入了微內核的精華,如模塊化設計、搶占式內核、動態加載內核模塊等。

Linux 內核支持動態加載內核模塊。為了借鑒微內核的一些優點,Linux 內核在很早時就提出了內核模塊化的設計。Linux內核中很多核心的實現或者設備驅動的實現都可以編譯成一個個單獨的模塊。模塊是被編譯成的一個目標文件,并且可以在運行時的內核中動態加載和卸載。和微內核實現的模塊化不一樣,它不是作為一個特殊模塊來執行的,而是和靜態編譯的內核函數一樣,運行在內核態中。模塊的引入給Linux內核帶來了不少的優點,其中最大的優點就是很多內核的功能和設備驅動都可以編譯成動態加載和卸載的模塊,并且驅動開發者在編寫內核模塊時必須遵守定義好的接口來訪問內核核心,這也使得開發一個內核模塊變得容易很多。另一個優點是,很多內核模塊可以設計成和平臺無關的,比如文件系統等。相比微內核的模塊,還有一個優點就是繼承了宏內核的性能優勢。

1.3.2 Linux內核概貌

Linux內核從1991年至2018年已有近27年的發展過程,從原來不到1萬行代碼到現在已經超過2 000萬行代碼。對于如此龐大的項目,我們在學習的過程中首先需要了解其整體的概貌,再深入學習每個核心子模塊。

Linux內核總體的概貌如圖1.5所示,一個典型的Linux系統可以分成三部分。

硬件層:包括CPU、物理內存、主板、磁盤和相應的外設等。

內核空間:包括Linux內核的核心部件,比如arch抽象層、設備管理抽象層、內存管理、進程管理、總線設備、字符設備以及與應用程序交互的系統調用層。

用戶空間:這里包括的內容很豐富,如C語言庫、應用程序和虛擬機等。

圖1.5 Linux內核概貌

我們重點關注內核空間層中一些主要的部件。

(1)系統調用層

Linux內核把系統分成兩個空間:用戶空間和內核空間。CPU既可以運行在用戶空間,也可以運行在內核空間。一些體系結構的實現還有多種執行模式,如x86體系結構有ring0 ~ring3這4種不同的執行模式。但是Linux內核只使用了ring0和ring3兩種模式來實現內核態和用戶態。

Linux 內核為內核態和用戶態之間的切換設置了軟件抽象層,叫作系統調用(System Call)層,其實每個處理器體系結構設計中都提供了一些特殊的指令來實現內核態和用戶態之間的切換。Linux內核充分利用了這種硬件提供的機制來實現系統調用層。

系統調用層最大的目的是讓用戶進程看不到真實的硬件信息,比如當用戶需要讀取一個文件的內容時,編寫用戶進程的程序員不需要知道這個文件具體存放在磁盤的哪個扇區里,只需要調用open()、read()或mmap()等函數即可。

一個用戶進程大部分時間運行在用戶態,當需要向內核請求服務時,它會調用系統提供的接口進入內核態,比如上述例子中的open()函數。當內核完成了open()函數的調用之后會返回用戶態。

(2)處理器體系結構抽象層

Linux內核支持多種體系結構,比如現在最流行的x86和ARM,也包括MIPS、powerpc等。Linux最初的設計只支持x86體系結構,后來不斷擴展,到現在已經支持幾十種體系結構。為Linux內核添加一個新的體系結構不是一件很難的事情,如最新的Linux 4.15內核支持RISC-V體系結構。Linux內核為不同體系結構的實現做了很好的抽象和隔離,也提供了統一的接口來實現。比如,在內存管理方面,Linux內核把和體系結構相關部分的代碼都存放在arch/xx/mm目錄里,把和體系結構不相關的代碼都存放在mm目錄里,從而實現完好的分層。

(3)進程管理

進程是現代操作系統中非常重要的概念,包括上下文切換(Context Switch)以及進程調度(Scheduling)。每個進程運行時都感覺完全占有了全部的硬件資源,但是進程不會長時間占有硬件資源。操作系統利用進程調度器讓多個進程并發執行。Linux內核并沒有嚴格區分進程和線程,而常用task_struct數據結構來描述。Linux內核的調度器的發展經歷了好幾代,從很早的O(n)調度器到Linux 2.6內核中的O(1)調度器,再到現在的CFS公平算法調度器。目前比較熱門的討論是關于性能和功耗的優化,比如ARM陣營提出了大小核體系結構,至今在Linux內核實現中還沒有體現,因此類似EAS(Energy Awareness Scheduling)這樣的調度算法是一個研究熱點。

進程管理還包括進程的創建和銷毀、線程組管理、內核線程管理、隊列等待等內容。

(4)內存管理

內存管理模塊是 Linux 內核中最復雜的模塊,它涉及物理內存的管理和虛擬內存的管理。在一些小型的嵌入式 RTOS 中,內存管理不涉及虛擬內存的管理,比較簡單和簡潔。但是作為一個通用的操作系統,Linux內核的虛擬內存管理非常重要。虛擬內存有很多優點,比如多個進程可以并發執行、進程請求的內存可以比物理內存大、多個進程可以共享函數庫等,因此虛擬內存的管理也變得越來越復雜。在 Linux 內核中,關于虛擬內存的模塊有反向映射、頁面回收、KSM、Mmap 映射、缺頁中斷、共享內存、進程虛擬地址空間管理等。

物理內存的管理也比較復雜。頁面分配器(Page Allocator)是核心部件,它需要考慮當系統內存緊張時,如何回收頁面和繼續分配物理內存。其他比較重要的模塊有交換分區管理、頁面回收和OOM Killer等。

(5)中斷管理

中斷管理包含處理器的異常(Exception)處理和中斷(Interrupt)處理。異常通常是指如果處理器在執行指令時檢測到一個反常條件,處理器就必須暫停下來處理這些特殊的情況,如常見的缺頁異常(Page Fault)。而中斷異常一般是指外設通過中斷信號線路來請求處理器,處理器會暫停當前正在做的事情來處理外設的請求。Linux內核在中斷管理方面有上半部和下半部之分。上半部是在關閉中斷的情況下執行的,因此處理時間要求短、平、快;而下半部是在開啟中斷的情況下執行的,很多對執行時間要求不高的操作可以放到下半部來執行。Linux內核為下半部提供了多種機制,如軟中斷、Tasklet和工作隊列等。

(6)設備管理

設備管理對于任何的一個操作系統來說都是重中之重。Linux內核之所以這么流行,就是因為它支持的外設是所有開源操作系統中最多的。當很多大公司有新的芯片誕生時,第一個要支持的操作系統是Linux,也就是盡可能地在Linux內核社區里推送。

Linux內核的設備管理是一個很廣泛的概念,包含的內容很多,如ACPI、設備樹、設備模型kobject、設備總線(如PCI總線)、字符設備驅動、塊設備驅動、網絡設備驅動等。

(7)文件系統

一個優秀的操作系統必須包含優秀的文件系統,但是文件系統有不同的應用場合,如基于閃存的文件系統F2FS、基于磁盤存儲的文件系統ext4和XFS等。為了支持各種各樣的文件系統,Linux 抽象出了一個稱為虛擬文件系統(VFS)層的軟件層,這樣 Linux 內核就可以很方便地集成多種文件系統。

總之,Linux內核是一個龐大的工程,處處體現了抽象和分層的思想,其代碼的質量是值得我們深入學習的。

主站蜘蛛池模板: 金华市| 淮安市| 肇庆市| 肥城市| 淮北市| 鲁甸县| 游戏| 乳山市| 湄潭县| 报价| 英德市| 桃园市| 临泉县| 墨竹工卡县| 新昌县| 襄城县| 永胜县| 开封县| 岑巩县| 云阳县| 沙洋县| 全州县| 内乡县| 新兴县| 定南县| 龙山县| 买车| 加查县| 康定县| 蓝山县| 江陵县| 曲沃县| 突泉县| 彰武县| 淮阳县| 乌兰察布市| 客服| 湖南省| 白沙| 虹口区| 仲巴县|