1.Linux 的體系結(jié)構(gòu)
User Space 是用戶空間即應(yīng)用程序執(zhí)行的地方。Kernel Space 是內(nèi)核空間,分為 3 層:① 最上層實(shí)系統(tǒng)調(diào)用接口,即內(nèi)核向用戶提供服務(wù)的接口,例如 io read 和 write。應(yīng)用程序通過軟件中斷后,調(diào)用系統(tǒng)內(nèi)核提供的功能。② 內(nèi)核程序。③ 最下層是體系結(jié)構(gòu)的代碼,通常稱為 BSP。

Linux 內(nèi)核簡(jiǎn)介:
內(nèi)核是操作系統(tǒng)最基本的部分,提供了安全訪問計(jì)算機(jī)硬件的基本能力。這種訪問是有限的,并且內(nèi)核決定應(yīng)用程序在什么時(shí)候?qū)δ巢糠钟布僮鞫嚅L(zhǎng)時(shí)間。內(nèi)核負(fù)責(zé)管理系統(tǒng)的進(jìn)程、內(nèi)存、設(shè)備驅(qū)動(dòng)程序、文件和網(wǎng)絡(luò)系統(tǒng),決定著系統(tǒng)的性能和穩(wěn)定性。
問題 1:內(nèi)核的實(shí)質(zhì)是什么?
答:內(nèi)核的實(shí)質(zhì)也是一種應(yīng)用程序,只不過它是直接操作硬件的。內(nèi)核直接面對(duì)硬件,調(diào)用硬件接口即硬件廠商提供的指令集。內(nèi)核是直接面向硬件的,故可用資源權(quán)限很大,但內(nèi)核是工作在有限地址空間內(nèi)的,例如 Linux 的32位系統(tǒng)在線性地址空間中,內(nèi)核只認(rèn)為自己有 1G 的空間,剩下的 3G 給用戶態(tài)的應(yīng)用程序。
說明:編寫內(nèi)核級(jí)應(yīng)用程序的時(shí)候,為了避免過于底層,因此內(nèi)核可以動(dòng)態(tài)編譯后,重啟加載該程序,例如驅(qū)動(dòng)程序通過動(dòng)態(tài)編譯生成可執(zhí)行文件,然后系統(tǒng)重啟后加載該驅(qū)動(dòng)就可以使用相應(yīng)的設(shè)備。
問題 2:從動(dòng)態(tài)角度如何分析 Linux 主機(jī)的運(yùn)行狀態(tài)
答:用戶態(tài)的應(yīng)用程序邏輯上是運(yùn)行在內(nèi)核,但實(shí)際是直接工作在硬件上的。簡(jiǎn)單來說,任意應(yīng)用程序數(shù)據(jù)都在內(nèi)存中,數(shù)據(jù)處理都是在 CPU,只是應(yīng)用程序不能隨意使用這些硬件資源,需要接受內(nèi)核的管理。當(dāng)用戶態(tài)的應(yīng)用程序需要訪問硬件資源時(shí),首先通過系統(tǒng)調(diào)用接口向 CPU 發(fā)起特權(quán)請(qǐng)求,一旦 CPU 收到特權(quán)請(qǐng)求就會(huì)喚醒內(nèi)核,從而執(zhí)行內(nèi)核中的某段代碼,然后將結(jié)果返回給應(yīng)用程序。接著內(nèi)核代碼退出,內(nèi)核程序暫停。
問題 3:CPU 占用與內(nèi)核的關(guān)系
答:內(nèi)核將 CPU 虛擬化提供給進(jìn)程,使得內(nèi)存中每一個(gè)進(jìn)程都以為直接是獨(dú)占 CPU。內(nèi)核將 CPU 切成時(shí)間片,隨著時(shí)間流逝完成了在進(jìn)程之間分配計(jì)算能力,即內(nèi)核把 CPU 以時(shí)間的方式提供了計(jì)算能力。
2.內(nèi)核的整體架構(gòu)與子系統(tǒng)

- Process Scheduler 進(jìn)程管理:負(fù)責(zé)管理 CPU 資源,使得讓各個(gè)進(jìn)程以時(shí)間片的方式使用 CPU 資源
- Memory Manager 內(nèi)存管理:負(fù)責(zé)管理 Memory(內(nèi)存)資源,是的各個(gè)進(jìn)程可以安全地共享機(jī)器的內(nèi)存資源。另外,內(nèi)存管理會(huì)提供虛擬內(nèi)存的機(jī)制,可以讓進(jìn)程使用多于系統(tǒng)可用的 Memory,不用的內(nèi)存會(huì)通過文件系統(tǒng)保存在外部非易失存儲(chǔ)器中,需要使用的時(shí)候再取回到內(nèi)存中。
- VFS(Virtual File System)虛擬文件系統(tǒng):將不同功能的外部設(shè)備,例如 Disk 設(shè)備(硬盤、磁盤、NAND Flash、Nor Flash 等)、輸入輸出設(shè)備、顯示設(shè)備等,抽象為可以通過統(tǒng)一的文件操作接口(open、close、read、write等)來訪問。
- Network 網(wǎng)絡(luò)系統(tǒng):負(fù)責(zé)管理系統(tǒng)的網(wǎng)絡(luò)設(shè)備,并實(shí)現(xiàn)多種多樣的網(wǎng)絡(luò)標(biāo)準(zhǔn)。
- IPC(Inter-Process Communication)進(jìn)程間通信:不管理任何的硬件,主要負(fù)責(zé) Linux 系統(tǒng)中進(jìn)程之間的通信
2.1 Process Scheduler 進(jìn)程管理
進(jìn)程調(diào)度是 Linux 內(nèi)核中最重要的子系統(tǒng),主要提供對(duì) CPU 的訪問控制。進(jìn)程調(diào)度子系統(tǒng)的 4 個(gè)模塊,如下圖所示。

- System Call Interface 系統(tǒng)調(diào)用接口:系統(tǒng)調(diào)用接口將需要提供給用戶空間的接口開放出去,同時(shí)屏蔽掉不需要用戶空間程序關(guān)心的細(xì)節(jié)。例如應(yīng)用程序的主進(jìn)程可以利用系統(tǒng)調(diào)用接口,創(chuàng)建、暫停和恢復(fù)子線程。
- Architecture-independent Scheduler 模塊:體系結(jié)構(gòu)無關(guān)的部分,即與 CPU、內(nèi)存等硬件無關(guān)的模塊。它與 Scheduling Policy 模塊溝通決定接下來要執(zhí)行哪個(gè)進(jìn)程,最后通過 Architecture-specific Schedulers 模塊 resume 指定的進(jìn)程。
- Scheduling Policy 進(jìn)程調(diào)度策略:決定哪個(gè)或哪幾個(gè)的進(jìn)程將擁有 CPU 切片時(shí)間。
- Architecture-specific Schedulers 模塊:體系結(jié)構(gòu)相關(guān)的部分,即與 CPU、內(nèi)存等硬件相關(guān)聯(lián)的模塊。將對(duì)不同 CPU 的控制抽象為統(tǒng)一的接口,主要在 suspend 和 resume 進(jìn)程時(shí)使用,牽涉到CPU的寄存器訪問、匯編指令操作等。
2.2 Memory Manager 內(nèi)存管理
內(nèi)存管理也是 Linux 內(nèi)核中最重要的子系統(tǒng),主要提供對(duì)內(nèi)存資源的訪問控制。Linux 系統(tǒng)會(huì)在硬件物理內(nèi)存和進(jìn)程所使用的內(nèi)存(虛擬內(nèi)存)之間建立一種映射關(guān)系。這種映射是以進(jìn)程為單位,不同的進(jìn)程可以使用相同的虛擬內(nèi)存,而這些相同的虛擬內(nèi)存,可以映射到不同的物理內(nèi)存上。內(nèi)存管理子系統(tǒng)包括 3 個(gè)子模塊,如下圖所示。

- System Call Interface 系統(tǒng)調(diào)用接口:通過該接口向用戶態(tài)的應(yīng)用程序提供內(nèi)存的分配、釋放,文件的 map 等功能。
- Architecture-independent Scheduler 模塊:提供所有的內(nèi)存管理機(jī)制,包括以進(jìn)程為單位的 memory mapping、虛擬內(nèi)存的 Swapping 等。
- Architecture-specific Schedulers 模塊:提供用于訪問內(nèi)存硬件的虛擬接口。
2.3 VFS 虛擬文件系統(tǒng)
虛擬文件系統(tǒng) VFS 就是管理各種各樣的文件系統(tǒng),屏蔽其差異,以統(tǒng)一的方式為用戶程序提供訪問文件的。VFS 子系統(tǒng)包括 6 個(gè)子模塊,如下圖所示。

- System Independent Interface 模塊:負(fù)責(zé)以統(tǒng)一的接口表示硬件設(shè)備和邏輯文件系統(tǒng),包括快設(shè)備和字符設(shè)備。
- Logical Systems 模塊:每一種文件系統(tǒng)都會(huì)對(duì)應(yīng)一個(gè) Logical System 邏輯文件系統(tǒng),實(shí)現(xiàn)了具體的文件系統(tǒng)邏輯。
- Device Independent Interface 模塊:定義了硬件設(shè)備的統(tǒng)一方式即統(tǒng)一設(shè)備模型,所有的設(shè)備驅(qū)動(dòng)都遵守這個(gè)定義,可以降低開發(fā)的難度。
- Device Drivers 模塊:設(shè)備驅(qū)動(dòng)模塊用于控制所有的外部設(shè)備及控制器。由于存在大量不能相互兼容的硬件設(shè)備,特別是嵌入式產(chǎn)品,所以也有非常多的設(shè)備驅(qū)動(dòng)。因此,Linux 內(nèi)核中將近一半的 Source Code 都是設(shè)備驅(qū)動(dòng)。
2.4 Network 網(wǎng)絡(luò)系統(tǒng)
網(wǎng)絡(luò)子系統(tǒng)在 Linux 內(nèi)核中主要負(fù)責(zé)管理各種網(wǎng)絡(luò)設(shè)備,并實(shí)現(xiàn)各種網(wǎng)絡(luò)協(xié)議棧,最終實(shí)現(xiàn)通過網(wǎng)絡(luò)連接其它系統(tǒng)的功能,包括 5 個(gè)子模塊,如下圖所示。

- Protocol Independent Interface 模塊:屏蔽不同的硬件設(shè)備和網(wǎng)絡(luò)協(xié)議,以相同的格式提供接口即 Socket
- Network Protocols 模塊:實(shí)現(xiàn)各種網(wǎng)絡(luò)傳輸協(xié)議,例如 IP、TCP、UDP 等
- Device Independent Interface 模塊:定義了硬件設(shè)備的統(tǒng)一方式即統(tǒng)一設(shè)備模型,所有的設(shè)備驅(qū)動(dòng)都遵守這個(gè)定義,可以降低開發(fā)的難度。
- Network Device Drivers 模塊:網(wǎng)絡(luò)設(shè)備的驅(qū)動(dòng),類似 VFS 子系統(tǒng)中的設(shè)備驅(qū)動(dòng)。
3.內(nèi)核源代碼的目錄結(jié)構(gòu)
Linux 內(nèi)核源代碼包括三個(gè)主要部分。
- 內(nèi)核核心代碼:上面所描述的各個(gè)子系統(tǒng)和子模塊,以及其它的支撐子系統(tǒng),例如電源管理、Linux初始化等
- 其它非核心代碼:例如庫文件(因?yàn)長(zhǎng)inux內(nèi)核是一個(gè)自包含的內(nèi)核,即內(nèi)核不依賴其它的任何軟件,自己就可以編譯通過)、固件集合、KVM(虛擬機(jī)技術(shù))等
- 編譯腳本、配置文件、幫助文檔、版權(quán)說明等輔助性文件
include/ ---- 內(nèi)核頭文件,需要提供給外部模塊(例如用戶空間代碼)使用。
kernel/ ---- Linux 內(nèi)核的核心代碼,包含了 2.1 小節(jié)所描述的進(jìn)程調(diào)度子系統(tǒng),以及和進(jìn)程調(diào)度相關(guān)的模塊
mm/ ---- 內(nèi)存管理子系統(tǒng) 2.2 小節(jié)
fs/ ---- VFS 子系統(tǒng) 2.3 小節(jié)。
net/ ---- 不包括網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)的網(wǎng)絡(luò)子系統(tǒng) 2.4 小節(jié))。
ipc/ ---- IPC(進(jìn)程間通信)子系統(tǒng)。
arch// ---- 體系結(jié)構(gòu)相關(guān)的代碼,例如arm, x86等等。
arch//mach- ---- 具體的machine/board相關(guān)的代碼。
arch//include/asm ---- 體系結(jié)構(gòu)相關(guān)的頭文件。
arch//boot/dts ---- 設(shè)備樹(Device Tree)文件。
init/ ---- Linux系統(tǒng)啟動(dòng)初始化相關(guān)的代碼。
block/ ---- 提供塊設(shè)備的層次。
sound/ ---- 音頻相關(guān)的驅(qū)動(dòng)及子系統(tǒng),可以看作“音頻子系統(tǒng)”。
drivers/ ---- 設(shè)備驅(qū)動(dòng)(在Linux kernel 3.10中,設(shè)備驅(qū)動(dòng)占了49.4的代碼量)。
lib/ ---- 實(shí)現(xiàn)需要在內(nèi)核中使用的庫函數(shù),例如CRC、FIFO、list、MD5等。
crypto/ ----- 加密、解密相關(guān)的庫函數(shù)。
security/ ---- 提供安全特性(SELinux)。
virt/ ---- 提供虛擬機(jī)技術(shù)(KVM等)的支持。
usr/ ---- 用于生成initramfs的代碼。
firmware/ ---- 保存用于驅(qū)動(dòng)第三方設(shè)備的固件。
samples/ ---- 一些示例代碼。
tools/ ---- 一些常用工具,如性能剖析、自測(cè)試等。
Kconfig, Kbuild, Makefile, scripts/ ---- 用于內(nèi)核編譯的配置文件、腳本等。
COPYING ---- 版權(quán)聲明。
MAINTAINERS ----維護(hù)者名單。
CREDITS ---- Linux主要的貢獻(xiàn)者名單。
REPORTING-BUGS ---- Bug上報(bào)的指南。
Documentation, README ---- 幫助、說明文檔。