Linux0.11内核剖析--内核体系结构
一個完整可用的操作系統(tǒng)主要由 4 部分組成:硬件、操作系統(tǒng)內(nèi)核、操作系統(tǒng)服務(wù)和用戶應(yīng)用程序,如下圖所示:
用戶應(yīng)用程序是指那些字處理程序、 Internet 瀏覽器程序或用戶自行編制的各種應(yīng)用程序;
操作系統(tǒng)服務(wù)程序是指那些向用戶所提供的服務(wù)被看作是操作系統(tǒng)的部分功能的程序。
在 Linux 操作系統(tǒng)上,這些程序包括 X 窗口系統(tǒng)、 shell 命令解釋系統(tǒng)以及那些內(nèi)核編程接口等系統(tǒng)程序;操作系統(tǒng)內(nèi)核程序即是本書所感興趣的部分,它主要用于對硬件資源的抽象和訪問調(diào)度。
Linux 內(nèi)核的主要用途就是為了與計算機硬件進行交互,實現(xiàn)對硬件部件的編程控制和接口操作,調(diào)度對硬件資源的訪問,并為計算機上的用戶程序提供一個高級的執(zhí)行環(huán)境和對硬件的虛擬接口。在本文內(nèi)容中,我們首先基于 Linux 0.11 版的內(nèi)核源代碼,簡明地描述 Linux 內(nèi)核的基本體系結(jié)構(gòu)、主要構(gòu)成模塊。然后對源代碼中出現(xiàn)的幾個重要數(shù)據(jù)結(jié)構(gòu)進行說明。最后描述了構(gòu)建 Linux 0.11 內(nèi)核編譯實驗環(huán)境的方法。
本文地址:http://www.cnblogs.com/archimedes/p/linux011-architecture.html,轉(zhuǎn)載請注明源地址。
1、Linux 內(nèi)核模式
目前,操作系統(tǒng)內(nèi)核的結(jié)構(gòu)模式主要可分為整體式的單內(nèi)核模式和層次式的微內(nèi)核模式。而?Linux 0.11 內(nèi)核,則是采用了單內(nèi)核模式。
單內(nèi)核模式的主要優(yōu)點是內(nèi)核代碼結(jié)構(gòu)緊湊、執(zhí)行速度快,不足之處主要是層次結(jié)構(gòu)性不強。
在單內(nèi)核模式的系統(tǒng)中,操作系統(tǒng)所提供服務(wù)的流程為:應(yīng)用主程序使用指定的參數(shù)值執(zhí)行系統(tǒng)調(diào)用指令(int x80),使 CPU 從用戶態(tài)( User Mode)切換到核心態(tài)( Kernel Model),然后操作系統(tǒng)根據(jù)具體的參數(shù)值調(diào)用特定的系統(tǒng)調(diào)用服務(wù)程序,而這些服務(wù)程序則根據(jù)需要再底層的一些支持函數(shù)以完成特定的功能。在完成了應(yīng)用程序所要求的服務(wù)后,操作系統(tǒng)又從核心態(tài)切換回用戶態(tài),返回到應(yīng)用程序中繼續(xù)執(zhí)行后面的指令。
因此概要地講,單內(nèi)核模式的內(nèi)核也可粗略地分為三個層次:調(diào)用服務(wù)的主程序?qū)印?zhí)行系統(tǒng)調(diào)用的服務(wù)層和支持系統(tǒng)調(diào)用的底層函數(shù)。如下圖所示:
單內(nèi)核模式的簡單結(jié)構(gòu)模型
2、Linux 內(nèi)核系統(tǒng)體系結(jié)構(gòu)
Linux 內(nèi)核主要由 5 個模塊構(gòu)成,它們分別是:進程調(diào)度模塊、內(nèi)存管理模塊、文件系統(tǒng)模塊、進程間通信模塊和網(wǎng)絡(luò)接口模塊。
進程調(diào)度模塊用來負責(zé)控制進程對 CPU 資源的使用。所采取的調(diào)度策略是各進程能夠公平合理地訪問 CPU,同時保證內(nèi)核能及時地執(zhí)行硬件操作。
內(nèi)存管理模塊用于確保所有進程能夠安全地共享機器主內(nèi)存區(qū),同時,內(nèi)存管理模塊還支持虛擬內(nèi)存管理方式,使得 Linux 支持進程使用比實際內(nèi)存空間更多大的內(nèi)存容量。并可以利用文件系統(tǒng)把暫時不用的內(nèi)存數(shù)據(jù)塊會被交換到外部存儲設(shè)備上去,當需要時再交換回來。
文件系統(tǒng)模塊用于支持對外部設(shè)備的驅(qū)動和存儲。虛擬文件系統(tǒng)模塊通過向所有的外部存儲設(shè)備提供一個通用的文件接口,隱藏了各種硬件設(shè)備的不同細節(jié)。從而提供并支持與其它操作系統(tǒng)兼容的多種文件系統(tǒng)格式。
進程間通信模塊子系統(tǒng)用于支持多種進程間的信息交換方式。
網(wǎng)絡(luò)接口模塊提供對多種網(wǎng)絡(luò)通信標準的訪問并支持許多網(wǎng)絡(luò)硬件。
這幾個模塊之間的依賴關(guān)系見圖 所示。其中的連線代表它們之間的依賴關(guān)系,虛線和虛框部分表示 Linux 0.11 中還未實現(xiàn)的部分(從 Linux 0.95 版才開始逐步實現(xiàn)虛擬文件系統(tǒng),而網(wǎng)絡(luò)接口的支持到 0.96版才有)。
Linux 內(nèi)核系統(tǒng)模塊結(jié)構(gòu)及相互依賴關(guān)系:
若從單內(nèi)核模式結(jié)構(gòu)模型出發(fā),我們還可以根據(jù) linux 0.11 內(nèi)核源代碼的結(jié)構(gòu)將內(nèi)核主要模塊繪制成下圖所示的框圖結(jié)構(gòu):
3、Linux 內(nèi)核進程控制
對于 linux 0.11 內(nèi)核來講, 系統(tǒng)最多可有 64 個進程同時存在。 系統(tǒng)除了第一個進程是“手工”建立以外, 其余的都是進程使用系統(tǒng)調(diào)用 fork 創(chuàng)建的新進程。內(nèi)核程序使用進程標識號(process ID, pid)來標識每個進程。進程由可執(zhí)行的指令代碼、數(shù)據(jù)和堆棧區(qū)組成。進程中的代碼和數(shù)據(jù)部分分別對應(yīng)一個執(zhí)行文件中的代碼段、數(shù)據(jù)段。每個進程只能執(zhí)行自己的代碼和訪問自己的數(shù)據(jù)及堆棧區(qū)。進程之間相互之間的通信需要通過系統(tǒng)調(diào)用了進行。對于只有一個 CPU 的系統(tǒng),在某一時刻只能有一個進程正在運行。內(nèi)核通過調(diào)度程序分時調(diào)度各個進程運行。
Linux 系統(tǒng)中,一個進程可以在內(nèi)核態(tài)( kernel mode)或用戶態(tài)( user mode)下執(zhí)行,因此, linux 內(nèi)核棧和用戶棧是分開的。用戶棧用于進程在用戶態(tài)下臨時保存調(diào)用函數(shù)的參數(shù)、局部變量等數(shù)據(jù)。內(nèi)核棧則含有內(nèi)核程序執(zhí)行函數(shù)調(diào)用時的信息。內(nèi)核程序是通過進程表對進程進行管理的,每個進程在進程表中占有一項。在 linux 系統(tǒng)中,進程表項是一個 task 結(jié)構(gòu)。
當一個進程在執(zhí)行時, CPU 的所有寄存器中的值、進程的狀態(tài)以及堆棧中的內(nèi)容被稱為該進程的上下文。當內(nèi)核需要切換( switch)至另一個進程時,它就需要保存當前進程的所有狀態(tài),也即保存當前進程的上下文,以便在再次執(zhí)行該進程時,能夠恢復(fù)到切換時的狀態(tài)執(zhí)行下去。在發(fā)生中斷時,內(nèi)核就在被中斷進程的上下文中,在內(nèi)核態(tài)下執(zhí)行中斷服務(wù)例程。但同時會保留所有需要用到的資源,以便中斷服務(wù)結(jié)束時能恢復(fù)被中斷進程的執(zhí)行。
一個進程在其生存期內(nèi),可處于一組不同的狀態(tài)下,稱為進程狀態(tài)。見下圖所示:
當進程正在被 CPU 執(zhí)行時,被稱為處于執(zhí)行狀態(tài)( running)。當進程正在等待系統(tǒng)中的資源而處于等待狀態(tài)時,則稱其處于睡眠等待狀態(tài)。在 linux 系統(tǒng)中,還分為可中斷的和不可中斷的等待狀態(tài)。當系統(tǒng)資源已經(jīng)可用時,進程就被喚醒而進入準備運行狀態(tài),該狀態(tài)稱為就緒態(tài)。當進程已停止運行,但其父進程還沒有詢問其狀態(tài)時,則稱該進程處于僵死狀態(tài)。當進程被終止時,稱其處于停止狀態(tài)。只有當進程從“內(nèi)核運行態(tài)”轉(zhuǎn)移到“睡眠狀態(tài)”時,內(nèi)核才會進行進程切換操作。在內(nèi)核態(tài)下運行的進程不能被其它進程搶占,而且一個進程不能改變另一個進程的狀態(tài)。為了避免進程切換時造成內(nèi)核數(shù)據(jù)錯誤,內(nèi)核在執(zhí)行臨界區(qū)代碼時會禁止一切中斷。
4、Linux 內(nèi)核對內(nèi)存的使用方法
在 linux 0.11 內(nèi)核中,為了有效地使用系統(tǒng)的物理內(nèi)存,內(nèi)存被劃分成幾個功能區(qū)域,見下圖所示:
其中,linux 內(nèi)核程序占據(jù)在物理內(nèi)存的開始部分,接下來是用于供硬盤或軟盤等塊設(shè)備使用的高速緩沖區(qū)部分。當一個進程需要讀取塊設(shè)備中的數(shù)據(jù)時,系統(tǒng)會首先將數(shù)據(jù)讀到高速緩沖區(qū)中;當有數(shù)據(jù)需要寫到塊設(shè)備上去時,系統(tǒng)也是先將數(shù)據(jù)放到高速緩沖區(qū)中,然后由塊設(shè)備驅(qū)動程序?qū)懙皆O(shè)備上。最后部分是供所有程序可以隨時申請使用的主內(nèi)存區(qū)部分。內(nèi)核程序在使用主內(nèi)存區(qū)時,也同樣要首先向內(nèi)核的內(nèi)存管理模塊提出申請,在申請成功后方能使用。對于含有 RAM 虛擬盤的系統(tǒng),主內(nèi)存區(qū)頭部還要劃去一部分,共虛擬盤存放數(shù)據(jù)。
由于計算機系統(tǒng)中所含的實際物理內(nèi)存容量是有限制的。為了能有效地使用這些物理內(nèi)存,Linux 采用了 Intel CPU 的內(nèi)存分頁管理機制,使用虛擬線性地址與實際物理內(nèi)存地址映射的方法讓所有同時執(zhí)行的程序共同使用有限的內(nèi)存。
內(nèi)存分頁管理的基本原理是將整個主內(nèi)存區(qū)域劃分成 4096 字節(jié)為一頁的內(nèi)存頁面。程序申請使用內(nèi)存時,就以內(nèi)存頁為單位進行分配。在使用這種內(nèi)存分頁管理方法時,每個執(zhí)行中的進程(任務(wù))可以使用比實際內(nèi)存容量大得多的線性地址空間。對于 Intel 80386 系統(tǒng),其 CPU 可以提供多達 4G 的線性地址空間。對于 linux 0.11 內(nèi)核,系統(tǒng)設(shè)置全局描述符表 GDT 中的段描述符項數(shù)最大為 256,其中 2 項空閑、 2 項系統(tǒng)使用,每個進程使用兩項。因此,此時系統(tǒng)可以最多容納(256-4)/2 + 1=127 個任務(wù),并且虛擬地址范圍是 ((256-4)/2)* 64MB 約等于8G。 但 0.11 內(nèi)核中人工定義最大任務(wù)數(shù) NR_TASKS = 64 個, 每個進程虛擬地址(或線性地址)范圍是 64M,并且各個進程的虛擬地址起始位置是(任務(wù)號-1)*64MB。 因此所使用的虛擬地址空間范圍是 64MB*64 =4G,見下圖所示。 4G 正好與 CPU 的線性地址空間范圍或物理地址空間范圍相同,因此在 0.11 內(nèi)核中比較容易混淆三種地址概念。
linux 0.11 中,在進行地址映射時,我們需要分清 3 種地址之間的變換: a. 進程虛擬地址,是從虛擬地址 0 開始計,最大 64M; b. CPU 的線性地址空間( 0--4G); c. 實際物理內(nèi)存地址。進程的虛擬地址需要首先通過其局部段描述符變換為 CPU 整個線性地址空間中的地址,然后再使用頁目錄表 PDT(一級頁表)和頁表 PT(二級頁表)映射到實際物理地址頁上。因此兩種變換不能混淆。為了使用實際物理內(nèi)存,每個進程的線性地址通過二級內(nèi)存頁表動態(tài)地映射到主內(nèi)存區(qū)域的不同內(nèi)存頁上。因此每個進程最大可用的虛擬內(nèi)存空間是 64MB。每個進程的邏輯地址通過加上任務(wù)號*64M,即可轉(zhuǎn)換為線性地址。不過在注釋中,我們通常將進程中的地址簡單地稱為線性地址。
5、Linux 內(nèi)核源代碼的目錄結(jié)構(gòu)
由于 Linux 內(nèi)核是一種單內(nèi)核模式的系統(tǒng),因此,內(nèi)核中所有的程序幾乎都有緊密的聯(lián)系,它們之間的依賴和調(diào)用關(guān)系非常密切。所以在閱讀一個源代碼文件時往往需要參閱其它相關(guān)的文件。因此有必要在開始閱讀內(nèi)核源代碼之前,先熟悉一下源代碼文件的目錄結(jié)構(gòu)和安排。
這里我們首先列出 Linux 內(nèi)核完整的源代碼目錄,包括其中的子目錄。然后逐一介紹各個目錄中所包含程序的主要功能,使得整個內(nèi)核源代碼的安排形式能在我們的頭腦中建立起一個大概的框架,以便于后面開始的源代碼閱讀工作。當我們使用 tar 命令將 linux-0.11.tar.gz 解開時,內(nèi)核源代碼文件被放到了 linux 目錄中。其中的目錄結(jié)構(gòu)為:
該內(nèi)核版本的源代碼目錄中含有 14 個子目錄,總共包括 102 個代碼文件。下面逐個對這些子目錄中的內(nèi)容進行描述。
1、內(nèi)核主目錄 linux
linux 目錄是源代碼的主目錄,在該主目錄中除了包括所有的 14 個子目錄以外,還含有唯一的一個makefile 文件。該文件是編譯輔助工具軟件 make 的參數(shù)配置文件。 make 工具軟件的主要用途是通過識別哪些文件已被修改過,從而自動地決定在一個含有多個源程序文件的程序系統(tǒng)中哪些文件需要被重新編譯。因此, make 工具軟件是程序項目的管理軟件。linux 目錄下的這個 makefile 文件還嵌套地調(diào)用了所有子目錄中包含的 makefile 文件,這樣,當 linux 目錄(包括子目錄)下的任何文件被修改過時, make 都會對其進行重新編譯。因此為了編譯整個內(nèi)核所有的源代碼文件,只要在 linux 目錄下運行一次 make 軟件即可。
2、引導(dǎo)啟動程序目錄 boot
boot 目錄中含有 3 個匯編語言文件,是內(nèi)核源代碼文件中最先被編譯的程序。這 3 個程序完成的主要功能是當計算機加電時引導(dǎo)內(nèi)核啟動,將內(nèi)核代碼加載到內(nèi)存中,并做一些進入 32 位保護運行方式前的系統(tǒng)初始化工作。 其中 bootsect.s 和 setup.s 程序需要使用 as86 軟件來編譯, 使用的是 as86 的匯編語言格式(與微軟的類似),而 head.s 需要用 GNU as 來編譯,使用的是 AT&T 格式的匯編語言。這兩種匯編語言在下一章的代碼注釋里以及代碼列表后面的說明中會有簡單的介紹。bootsect.s 程序是磁盤引導(dǎo)塊程序,編譯后會駐留在磁盤的第一個扇區(qū)中(引導(dǎo)扇區(qū), 0 磁道(柱面),0 磁頭,第 1 個扇區(qū))。在 PC 機加電 ROM BIOS 自檢后,將被 BIOS 加載到內(nèi)存 0x7C00 處進行執(zhí)行。setup.s 程序主要用于讀取機器的硬件配置參數(shù),并把內(nèi)核模塊 system 移動到適當?shù)膬?nèi)存位置處。head.s 程序會被編譯連接在 system 模塊的最前部分,主要進行硬件設(shè)備的探測設(shè)置和內(nèi)存管理頁面的初始設(shè)置工作。
3、文件系統(tǒng)目錄 fs
是文件系統(tǒng)實現(xiàn)程序的目錄,共包含 17 個 C 語言程序。這些程序之間的主要引用關(guān)系所示圖中每個方框代表一個文件,從上到下按基本按引用關(guān)系放置。其中各文件名均略去了后綴.c,虛框中是的程序文件不屬于文件系統(tǒng),帶箭頭的線條表示引用關(guān)系,粗線條表示有相互引用關(guān)系。
由圖可以看出,該目錄中的程序可以劃分成四個部分:高速緩沖區(qū)管理、低層文件操作、文件數(shù)據(jù)訪問和文件高層函數(shù),對于文件系統(tǒng),我們可以將它看成是內(nèi)存高速緩沖區(qū)的擴展部分。所有對文件系統(tǒng)中數(shù)據(jù)的訪問,都需要首先讀取到高速緩沖區(qū)中。本目錄中的程序主要用來管理高速緩沖區(qū)中緩沖塊的使用分配和塊設(shè)備上的文件系統(tǒng)。
4、頭文件主目錄 include
頭文件目錄中總共有 32 個.h 頭文件。其中主目錄下有 13 個, asm 子目錄中有 4 個, linux 子目錄中有10 個, sys 子目錄中有 5 個:
體系結(jié)構(gòu)相關(guān)頭文件子目錄 include/asm
這些頭文件主要定義了一些與 CPU 體系結(jié)構(gòu)密切相關(guān)的數(shù)據(jù)結(jié)構(gòu)、宏函數(shù)和變量。共 4 個文件。
Linux 內(nèi)核專用頭文件子目錄 include/linux
<linux/config.h> //內(nèi)核配置頭文件。定義鍵盤語言和硬盤類型( HD_TYPE)可選項。 <linux/fdreg.h> //軟驅(qū)頭文件。含有軟盤控制器參數(shù)的一些定義。 <linux/fs.h> //文件系統(tǒng)頭文件。定義文件表結(jié)構(gòu)( file,buffer_head,m_inode 等)。 <linux/hdreg.h> //硬盤參數(shù)頭文件。定義訪問硬盤寄存器端口,狀態(tài)碼,分區(qū)表等信息。 <linux/head.h> //head 頭文件,定義了段描述符的簡單結(jié)構(gòu),和幾個選擇符常量。 <linux/kernel.h> //內(nèi)核頭文件。含有一些內(nèi)核常用函數(shù)的原形定義。 <linux/mm.h> //內(nèi)存管理頭文件。含有頁面大小定義和一些頁面釋放函數(shù)原型。 <linux/sched.h> //調(diào)度程序頭文件,定義了任務(wù)結(jié)構(gòu) task_struct、初始任務(wù) 0 的數(shù)據(jù),//還有一些有關(guān)描述符參數(shù)設(shè)置和獲取的嵌入式匯編函數(shù)宏語句。 <linux/sys.h> //系統(tǒng)調(diào)用頭文件。含有 72 個系統(tǒng)調(diào)用 C 函數(shù)處理程序,以'sys_'開頭。 <linux/tty.h> //tty 頭文件,定義了有關(guān) tty_io,串行通信方面的參數(shù)、常數(shù)。系統(tǒng)專用數(shù)據(jù)結(jié)構(gòu)子目錄 include/sys
<sys/stat.h> //文件狀態(tài)頭文件。含有文件或文件系統(tǒng)狀態(tài)結(jié)構(gòu) stat{}和常量。 <sys/times.h> //定義了進程中運行時間結(jié)構(gòu) tms 以及 times()函數(shù)原型。 <sys/types.h> //類型頭文件。定義了基本的系統(tǒng)數(shù)據(jù)類型。 <sys/utsname.h> //系統(tǒng)名稱結(jié)構(gòu)頭文件。 <sys/wait.h> //等待調(diào)用頭文件。定義系統(tǒng)調(diào)用 wait()核 waitpid()及相關(guān)常數(shù)符號。5、內(nèi)核初始化程序目錄 init
該目錄中僅包含一個文件 main.c。用于執(zhí)行內(nèi)核所有的初始化工作,然后移到用戶模式創(chuàng)建新進程,并在控制臺設(shè)備上運行 shell 程序。程序首先根據(jù)機器內(nèi)存的多少對緩沖區(qū)內(nèi)存容量進行分配,如果還設(shè)置了要使用虛擬盤,則在緩沖區(qū)內(nèi)存后面也為它留下空間。之后就進行所有硬件的初始化工作,包括人工創(chuàng)建第一個任務(wù)( task 0),并設(shè)置了中斷允許標志。在執(zhí)行從核心態(tài)移到用戶態(tài)之后,系統(tǒng)第一次調(diào)用創(chuàng)建進程函數(shù) fork(),創(chuàng)建出一個用于運行 init()的進程,在該子進程中,系統(tǒng)將進行控制臺環(huán)境設(shè)置,并且在生成一個子進程用來運行 shell程序。
6、內(nèi)核程序主目錄 kernel
linux/kernel 目錄中共包含 12 個代碼文件和一個 Makefile 文件,另外還有 3 個子目錄。由于這些文件中代碼之間調(diào)用關(guān)系復(fù)雜,因此這里就不詳細列出各文件之間的引用關(guān)系圖,但仍然可以進行大概分類,如圖所示:
塊設(shè)備驅(qū)動程序子目錄 kernel/blk_dev
通常情況下,用戶是通過文件系統(tǒng)來訪問設(shè)備的,因此設(shè)備驅(qū)動程序為文件系統(tǒng)實現(xiàn)了調(diào)用接口。在使用塊設(shè)備時,由于其數(shù)據(jù)吞吐量大,為了能夠高效率地使用塊設(shè)備上的數(shù)據(jù),在用戶進程與塊設(shè)備之間使用了高速緩沖機制。在訪問塊設(shè)備上的數(shù)據(jù)時,系統(tǒng)首先以數(shù)據(jù)塊的形式把塊設(shè)備上的數(shù)據(jù)讀入到高速緩沖區(qū)中,然后再提供給用戶。 blk_dev 子目錄共包含 4 個 c 文件和 1 個頭文件。頭文件 blk.h 由于是塊設(shè)備程序?qū)S玫?#xff0c;所以與 C 文件放在一起。這幾個文件之間的大致關(guān)系,如圖所示:
你將看到該函數(shù)在許多訪問塊設(shè)備數(shù)據(jù)的地方被調(diào)用,尤其是在高速緩沖區(qū)處理文件 fs/buffer.c 中。
字符設(shè)備驅(qū)動程序子目錄 kernel/chr_dev
字符設(shè)備程序子目錄共含有 4 個 C 語言程序和 2 個匯編程序文件。 這些文件實現(xiàn)了對串行端口 rs-232、串行終端、鍵盤和控制臺終端設(shè)備的驅(qū)動。下圖(圖 2.12)是這些文件之間的大致調(diào)用層次關(guān)系:
協(xié)處理器仿真和操作程序子目錄 kernel/math
該子目錄中目前僅有一個 C 程序 math_emulate.c。其中的 math_emulate()函數(shù)是中斷 int7 的中斷處理程序調(diào)用的 C 函數(shù)。當機器中沒有數(shù)學(xué)協(xié)處理器,而 CPU 卻又執(zhí)行了協(xié)處理器的指令時,就會引發(fā)該中斷。因此,使用該中斷就可以用軟件來仿真協(xié)處理器的功能。本書所討論的內(nèi)核版本還沒有包含有關(guān)協(xié)處理器的仿真代碼。本程序中只是打印一條出錯信息,并向用戶程序發(fā)送一個協(xié)處理器錯誤信號 SIGFPE。
7、內(nèi)核庫函數(shù)目錄 lib
內(nèi)核庫函數(shù)主要用于用戶編程調(diào)用,是編譯系統(tǒng)標準庫的接口函數(shù)之一。其中共有 12 個 C 語言文件,除了一個由 tytso 編制的 malloc.c 程序較長以外,其它的程序很短,有的只有一二行代碼。
8、內(nèi)存管理程序目錄 mm
該目錄包括 2 個代碼文件。主要用于管理程序?qū)χ鲀?nèi)存區(qū)的使用,實現(xiàn)了進程邏輯地址到線性地址以及線性地址到主內(nèi)存區(qū)中物理內(nèi)存地址的映射,通過內(nèi)存的分頁管理機制,在進程的虛擬內(nèi)存頁與主內(nèi)存區(qū)的物理內(nèi)存頁之間建立了對應(yīng)關(guān)系。
page.s 文件包括內(nèi)存頁面異常中斷( int 14)處理程序,主要用于處理程序由于缺頁而引起的頁異常中斷和訪問非法地址而引起的頁保護。
memory.c 程序包括對內(nèi)存進行初始化的函數(shù) mem_init(),由 page.s 的內(nèi)存處理中斷過程調(diào)用的do_no_page()和 do_wp_page()函數(shù)。在創(chuàng)建新進程而執(zhí)行復(fù)制進程操作時,即使用該文件中的內(nèi)存處理函數(shù)來分配管理內(nèi)存空間。
9、編譯內(nèi)核工具程序目錄 tools
該目錄下的 build.c 程序用于將 Linux 各個目錄中被分別編譯生成的目標代碼連接合并成一個可運行的內(nèi)核映象文件 image。具體的功能后面詳細介紹
6、內(nèi)核系統(tǒng)與用戶程序的關(guān)系
在 Linux 系統(tǒng)中,內(nèi)核為應(yīng)用程序提供了兩方面的接口。其一是系統(tǒng)調(diào)用接口,也即中斷調(diào)用 int 0x80;另一方面是通過內(nèi)核庫函數(shù),與內(nèi)核進行信息交流。內(nèi)核庫函數(shù)是基本 C 函數(shù)庫 libc 的組成部分。許多的系統(tǒng)調(diào)用是作為基本 C 語言函數(shù)庫的一部分實現(xiàn)的。系統(tǒng)調(diào)用主要是提供給系統(tǒng)軟件直接使用或用于庫函數(shù)的實現(xiàn)。而一般用戶開發(fā)的程序則是通過調(diào)用象 libc 等庫中的函數(shù)來訪問內(nèi)核資源。通過調(diào)用這些庫中的程序,應(yīng)用程序代碼能夠完成各種常用工作,例如,打開和關(guān)閉對文件或設(shè)備的訪問、進行科學(xué)計算、出錯處理以及訪問組和用戶標識號 ID 等系統(tǒng)信息。系統(tǒng)調(diào)用是內(nèi)核與外界接口的最高層。在內(nèi)核中,每個系統(tǒng)調(diào)用都有一個序列號(在include/linux/unistd.h 頭文件中定義),并常以宏的形式實現(xiàn)。
參考資料
Linux內(nèi)核完全注釋(趙炯)
轉(zhuǎn)載于:https://www.cnblogs.com/wuyudong/p/linux011-architecture.html
總結(jié)
以上是生活随笔為你收集整理的Linux0.11内核剖析--内核体系结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Visio进行UML建模
- 下一篇: Linux下Tomcat设置自动启动