Linux0.11內核剖析–內核體系結構
《Linux內核完全注釋》下載:http://files.cnblogs.com/files/HanBlogs/linux-kernel.pdf(進入pdf后要點擊右下角保存喔^_^)
一個完整可用的操作系統主要由 4 部分組成:硬件、操作系統內核、操作系統服務和用戶應用程序,如下圖所示:
用戶應用程序是指那些字處理程序、 Internet 瀏覽器程序或用戶自行編制的各種應用程序;
操作系統服務程序是指那些向用戶所提供的服務被看作是操作系統的部分功能的程序。
在 Linux 操作系統上,這些程序包括 X 窗口系統、 shell 命令解釋系統以及那些內核編程接口等系統程序;操作系統內核程序即是本書所感興趣的部分,它主要用於對硬件資源的抽象和訪問調度。
Linux 內核的主要用途就是為了與計算機硬件進行交互,實現對硬件部件的編程控制和接口操作,調度對硬件資源的訪問,並為計算機上的用戶程序提供一個高級的執行環境和對硬件的虛擬接口。在本文內容中,我們首先基於 Linux 0.11 版的內核源代碼,簡明地描述 Linux 內核的基本體系結構、主要構成模塊。然后對源代碼中出現的幾個重要數據結構進行說明。最后描述了構建 Linux 0.11 內核編譯實驗環境的方法。
1、Linux 內核模式
目前,操作系統內核的結構模式主要可分為整體式的單內核模式和層次式的微內核模式。而 Linux 0.11 內核,則是采用了單內核模式。
單內核模式的主要優點是內核代碼結構緊湊、執行速度快,不足之處主要是層次結構性不強。
在單內核模式的系統中,操作系統所提供服務的流程為:應用主程序使用指定的參數值執行系統調用指令(int x80),使 CPU 從用戶態( User Mode)切換到核心態( Kernel Model),然后操作系統根據具體的參數值調用特定的系統調用服務程序,而這些服務程序則根據需要再底層的一些支持函數以完成特定的功能。在完成了應用程序所要求的服務后,操作系統又從核心態切換回用戶態,返回到應用程序中繼續執行后面的指令。
因此概要地講,單內核模式的內核也可粗略地分為三個層次:調用服務的主程序層、執行系統調用的服務層和支持系統調用的底層函數。如下圖所示:
單內核模式的簡單結構模型
2、Linux 內核系統體系結構
Linux 內核主要由 5 個模塊構成,它們分別是:進程調度模塊、內存管理模塊、文件系統模塊、進程間通信模塊和網絡接口模塊。
進程調度模塊用來負責控制進程對 CPU 資源的使用。所采取的調度策略是各進程能夠公平合理地訪問 CPU,同時保證內核能及時地執行硬件操作。
內存管理模塊用於確保所有進程能夠安全地共享機器主內存區,同時,內存管理模塊還支持虛擬內存管理方式,使得 Linux 支持進程使用比實際內存空間更多大的內存容量。並可以利用文件系統把暫時不用的內存數據塊會被交換到外部存儲設備上去,當需要時再交換回來。
文件系統模塊用於支持對外部設備的驅動和存儲。虛擬文件系統模塊通過向所有的外部存儲設備提供一個通用的文件接口,隱藏了各種硬件設備的不同細節。從而提供並支持與其它操作系統兼容的多種文件系統格式。
進程間通信模塊子系統用於支持多種進程間的信息交換方式。
網絡接口模塊提供對多種網絡通信標准的訪問並支持許多網絡硬件。
這幾個模塊之間的依賴關系見圖 所示。其中的連線代表它們之間的依賴關系,虛線和虛框部分表示 Linux 0.11 中還未實現的部分(從 Linux 0.95 版才開始逐步實現虛擬文件系統,而網絡接口的支持到 0.96版才有)。
Linux 內核系統模塊結構及相互依賴關系:
若從單內核模式結構模型出發,我們還可以根據 linux 0.11 內核源代碼的結構將內核主要模塊繪制成下圖所示的框圖結構:
3、Linux 內核進程控制
對於 linux 0.11 內核來講, 系統最多可有 64 個進程同時存在。 系統除了第一個進程是“手工”建立以外, 其余的都是進程使用系統調用 fork 創建的新進程。內核程序使用進程標識號(process ID, pid)來標識每個進程。進程由可執行的指令代碼、數據和堆棧區組成。進程中的代碼和數據部分分別對應一個執行文件中的代碼段、數據段。每個進程只能執行自己的代碼和訪問自己的數據及堆棧區。進程之間相互之間的通信需要通過系統調用了進行。對於只有一個 CPU 的系統,在某一時刻只能有一個進程正在運行。內核通過調度程序分時調度各個進程運行。
Linux 系統中,一個進程可以在內核態( kernel mode)或用戶態( user mode)下執行,因此, linux 內核棧和用戶棧是分開的。用戶棧用於進程在用戶態下臨時保存調用函數的參數、局部變量等數據。內核棧則含有內核程序執行函數調用時的信息。內核程序是通過進程表對進程進行管理的,每個進程在進程表中占有一項。在 linux 系統中,進程表項是一個 task 結構。
當一個進程在執行時, CPU 的所有寄存器中的值、進程的狀態以及堆棧中的內容被稱為該進程的上下文。當內核需要切換( switch)至另一個進程時,它就需要保存當前進程的所有狀態,也即保存當前進程的上下文,以便在再次執行該進程時,能夠恢復到切換時的狀態執行下去。在發生中斷時,內核就在被中斷進程的上下文中,在內核態下執行中斷服務例程。但同時會保留所有需要用到的資源,以便中斷服務結束時能恢復被中斷進程的執行。
一個進程在其生存期內,可處於一組不同的狀態下,稱為進程狀態。見下圖所示:
當進程正在被 CPU 執行時,被稱為處於執行狀態( running)。當進程正在等待系統中的資源而處於等待狀態時,則稱其處於睡眠等待狀態。在 linux 系統中,還分為可中斷的和不可中斷的等待狀態。當系統資源已經可用時,進程就被喚醒而進入准備運行狀態,該狀態稱為就緒態。當進程已停止運行,但其父進程還沒有詢問其狀態時,則稱該進程處於僵死狀態。當進程被終止時,稱其處於停止狀態。只有當進程從“內核運行態”轉移到“睡眠狀態”時,內核才會進行進程切換操作。在內核態下運行的進程不能被其它進程搶占,而且一個進程不能改變另一個進程的狀態。為了避免進程切換時造成內核數據錯誤,內核在執行臨界區代碼時會禁止一切中斷。
4、Linux 內核對內存的使用方法
在 linux 0.11 內核中,為了有效地使用系統的物理內存,內存被划分成幾個功能區域,見下圖所示:
其中,linux 內核程序占據在物理內存的開始部分,接下來是用於供硬盤或軟盤等塊設備使用的高速緩沖區部分。當一個進程需要讀取塊設備中的數據時,系統會首先將數據讀到高速緩沖區中;當有數據需要寫到塊設備上去時,系統也是先將數據放到高速緩沖區中,然后由塊設備驅動程序寫到設備上。最后部分是供所有程序可以隨時申請使用的主內存區部分。內核程序在使用主內存區時,也同樣要首先向內核的內存管理模塊提出申請,在申請成功后方能使用。對於含有 RAM 虛擬盤的系統,主內存區頭部還要划去一部分,共虛擬盤存放數據。
由於計算機系統中所含的實際物理內存容量是有限制的。為了能有效地使用這些物理內存,Linux 采用了 Intel CPU 的內存分頁管理機制,使用虛擬線性地址與實際物理內存地址映射的方法讓所有同時執行的程序共同使用有限的內存。
內存分頁管理的基本原理是將整個主內存區域划分成 4096 字節為一頁的內存頁面。程序申請使用內存時,就以內存頁為單位進行分配。在使用這種內存分頁管理方法時,每個執行中的進程(任務)可以使用比實際內存容量大得多的線性地址空間。對於 Intel 80386 系統,其 CPU 可以提供多達 4G 的線性地址空間。對於 linux 0.11 內核,系統設置全局描述符表 GDT 中的段描述符項數最大為 256,其中 2 項空閑、 2 項系統使用,每個進程使用兩項。因此,此時系統可以最多容納(256-4)/2 + 1=127 個任務,並且虛擬地址范圍是 ((256-4)/2)* 64MB 約等於8G。 但 0.11 內核中人工定義最大任務數 NR_TASKS = 64 個, 每個進程虛擬地址(或線性地址)范圍是 64M,並且各個進程的虛擬地址起始位置是(任務號-1)*64MB。 因此所使用的虛擬地址空間范圍是 64MB*64 =4G,見下圖所示。 4G 正好與 CPU 的線性地址空間范圍或物理地址空間范圍相同,因此在 0.11 內核中比較容易混淆三種地址概念。
linux 0.11 中,在進行地址映射時,我們需要分清 3 種地址之間的變換: a. 進程虛擬地址,是從虛擬地址 0 開始計,最大 64M; b. CPU 的線性地址空間( 0--4G); c. 實際物理內存地址。進程的虛擬地址需要首先通過其局部段描述符變換為 CPU 整個線性地址空間中的地址,然后再使用頁目錄表 PDT(一級頁表)和頁表 PT(二級頁表)映射到實際物理地址頁上。因此兩種變換不能混淆。為了使用實際物理內存,每個進程的線性地址通過二級內存頁表動態地映射到主內存區域的不同內存頁上。因此每個進程最大可用的虛擬內存空間是 64MB。每個進程的邏輯地址通過加上任務號*64M,即可轉換為線性地址。不過在注釋中,我們通常將進程中的地址簡單地稱為線性地址。
5、Linux 內核源代碼的目錄結構
由於 Linux 內核是一種單內核模式的系統,因此,內核中所有的程序幾乎都有緊密的聯系,它們之間的依賴和調用關系非常密切。所以在閱讀一個源代碼文件時往往需要參閱其它相關的文件。因此有必要在開始閱讀內核源代碼之前,先熟悉一下源代碼文件的目錄結構和安排。
這里我們首先列出 Linux 內核完整的源代碼目錄,包括其中的子目錄。然后逐一介紹各個目錄中所包含程序的主要功能,使得整個內核源代碼的安排形式能在我們的頭腦中建立起一個大概的框架,以便於后面開始的源代碼閱讀工作。當我們使用 tar 命令將 linux-0.11.tar.gz 解開時,內核源代碼文件被放到了 linux 目錄中。其中的目錄結構為:
該內核版本的源代碼目錄中含有 14 個子目錄,總共包括 102 個代碼文件。下面逐個對這些子目錄中的內容進行描述。
1、內核主目錄 linux
linux 目錄是源代碼的主目錄,在該主目錄中除了包括所有的 14 個子目錄以外,還含有唯一的一個makefile 文件。該文件是編譯輔助工具軟件 make 的參數配置文件。 make 工具軟件的主要用途是通過識別哪些文件已被修改過,從而自動地決定在一個含有多個源程序文件的程序系統中哪些文件需要被重新編譯。因此, make 工具軟件是程序項目的管理軟件。linux 目錄下的這個 makefile 文件還嵌套地調用了所有子目錄中包含的 makefile 文件,這樣,當 linux 目錄(包括子目錄)下的任何文件被修改過時, make 都會對其進行重新編譯。因此為了編譯整個內核所有的源代碼文件,只要在 linux 目錄下運行一次 make 軟件即可。
2、引導啟動程序目錄 boot
boot 目錄中含有 3 個匯編語言文件,是內核源代碼文件中最先被編譯的程序。這 3 個程序完成的主要功能是當計算機加電時引導內核啟動,將內核代碼加載到內存中,並做一些進入 32 位保護運行方式前的系統初始化工作。 其中 bootsect.s 和 setup.s 程序需要使用 as86 軟件來編譯, 使用的是 as86 的匯編語言格式(與微軟的類似),而 head.s 需要用 GNU as 來編譯,使用的是 AT&T 格式的匯編語言。這兩種匯編語言在下一章的代碼注釋里以及代碼列表后面的說明中會有簡單的介紹。bootsect.s 程序是磁盤引導塊程序,編譯后會駐留在磁盤的第一個扇區中(引導扇區, 0 磁道(柱面),0 磁頭,第 1 個扇區)。在 PC 機加電 ROM BIOS 自檢后,將被 BIOS 加載到內存 0x7C00 處進行執行。setup.s 程序主要用於讀取機器的硬件配置參數,並把內核模塊 system 移動到適當的內存位置處。head.s 程序會被編譯連接在 system 模塊的最前部分,主要進行硬件設備的探測設置和內存管理頁面的初始設置工作。
3、文件系統目錄 fs
是文件系統實現程序的目錄,共包含 17 個 C 語言程序。這些程序之間的主要引用關系所示圖中每個方框代表一個文件,從上到下按基本按引用關系放置。其中各文件名均略去了后綴.c,虛框中是的程序文件不屬於文件系統,帶箭頭的線條表示引用關系,粗線條表示有相互引用關系。
由圖可以看出,該目錄中的程序可以划分成四個部分:高速緩沖區管理、低層文件操作、文件數據訪問和文件高層函數,對於文件系統,我們可以將它看成是內存高速緩沖區的擴展部分。所有對文件系統中數據的訪問,都需要首先讀取到高速緩沖區中。本目錄中的程序主要用來管理高速緩沖區中緩沖塊的使用分配和塊設備上的文件系統。
4、頭文件主目錄 include
頭文件目錄中總共有 32 個.h 頭文件。其中主目錄下有 13 個, asm 子目錄中有 4 個, linux 子目錄中有10 個, sys 子目錄中有 5 個:
<a.out.h> //a.out 頭文件,定義了 a.out 執行文件格式和一些宏。
<const.h> //常數符號頭文件,目前僅定義了 i 節點中 i_mode 字段的各標志位。
<ctype.h> //字符類型頭文件。定義了一些有關字符類型判斷和轉換的宏。
<errno.h> //錯誤號頭文件。包含系統中各種出錯號。 (Linus 從 minix 中引進的)。
<fcntl.h> //文件控制頭文件。用於文件及其描述符的操作控制常數符號的定義。
<signal.h> //信號頭文件。定義信號符號常量,信號結構以及信號操作函數原型。
<stdarg.h> //標准參數頭文件。以宏的形式定義變量參數列表。主要說明了 -個類型(va_list)和三個宏(va_start, va_arg 和 va_end),用於vsprintf、vprintf、vfprintf 函數
<stddef.h> //標准定義頭文件。定義了 NULL, offsetof(TYPE, MEMBER)。
<string.h> //字符串頭文件。主要定義了一些有關字符串操作的嵌入函數。
<termios.h> // 終端輸入輸出函數頭文件。主要定義控制異步通信口的終端接口。
<time.h> //時間類型頭文件。其中最主要定義了 tm 結構和一些有關時間的函數原形。
<unistd.h> //Linux 標准頭文件。定義了各種符號常數和類型,並申明了各種函數。如定義了__LIBRARY__,則還包括系統調用號和內嵌匯編_syscall0()等。
<utime.h> //用戶時間頭文件。定義了訪問和修改時間結構以及 utime()原型
體系結構相關頭文件子目錄 include/asm
這些頭文件主要定義了一些與 CPU 體系結構密切相關的數據結構、宏函數和變量。共 4 個文件。
<asm/io.h> //io 頭文件。以宏的嵌入匯編程序形式定義對 io 端口操作的函數。
<asm/memory.h> //內存拷貝頭文件。含有 memcpy()嵌入式匯編宏函數。
<asm/segment.h> // 段操作頭文件。定義了有關段寄存器操作的嵌入式匯編函數。
<asm/system.h> // 系統頭文件。定義了設置或修改描述符/中斷門等的嵌入式匯編宏。
Linux 內核專用頭文件子目錄 include/linux
<linux/config.h> //內核配置頭文件。定義鍵盤語言和硬盤類型( HD_TYPE)可選項。
<linux/fdreg.h> //軟驅頭文件。含有軟盤控制器參數的一些定義。
<linux/fs.h> //文件系統頭文件。定義文件表結構( file,buffer_head,m_inode 等)。
<linux/hdreg.h> //硬盤參數頭文件。定義訪問硬盤寄存器端口,狀態碼,分區表等信息。
<linux/head.h> //head 頭文件,定義了段描述符的簡單結構,和幾個選擇符常量。
<linux/kernel.h> //內核頭文件。含有一些內核常用函數的原形定義。
<linux/mm.h> //內存管理頭文件。含有頁面大小定義和一些頁面釋放函數原型。
<linux/sched.h> //調度程序頭文件,定義了任務結構 task_struct、初始任務 0 的數據,
//還有一些有關描述符參數設置和獲取的嵌入式匯編函數宏語句。
<linux/sys.h> //系統調用頭文件。含有 72 個系統調用 C 函數處理程序,以'sys_'開頭。
<linux/tty.h> //tty 頭文件,定義了有關 tty_io,串行通信方面的參數、常數。
系統專用數據結構子目錄 include/sys
<sys/stat.h> //文件狀態頭文件。含有文件或文件系統狀態結構 stat{}和常量。
<sys/times.h> //定義了進程中運行時間結構 tms 以及 times()函數原型。
<sys/types.h> //類型頭文件。定義了基本的系統數據類型。
<sys/utsname.h> //系統名稱結構頭文件。
<sys/wait.h> //等待調用頭文件。定義系統調用 wait()核 waitpid()及相關常數符號。
5、內核初始化程序目錄 init
該目錄中僅包含一個文件 main.c。用於執行內核所有的初始化工作,然后移到用戶模式創建新進程,並在控制台設備上運行 shell 程序。程序首先根據機器內存的多少對緩沖區內存容量進行分配,如果還設置了要使用虛擬盤,則在緩沖區內存后面也為它留下空間。之后就進行所有硬件的初始化工作,包括人工創建第一個任務( task 0),並設置了中斷允許標志。在執行從核心態移到用戶態之后,系統第一次調用創建進程函數 fork(),創建出一個用於運行 init()的進程,在該子進程中,系統將進行控制台環境設置,並且在生成一個子進程用來運行 shell程序。
6、內核程序主目錄 kernel
linux/kernel 目錄中共包含 12 個代碼文件和一個 Makefile 文件,另外還有 3 個子目錄。由於這些文件中代碼之間調用關系復雜,因此這里就不詳細列出各文件之間的引用關系圖,但仍然可以進行大概分類,如圖所示:
asm.s //程序是用於處理系統硬件異常所引起的中斷,對各硬件異常的實際處理程序則是在 traps.c 文件中,在各個中斷處理過程中,將分別調用traps.c 中相應的 C 語言處理函數
exit.c //程序主要包括用於處理進程終止的系統調用。包含進程釋放、會話(進程組)終止和程序退出處理函數以及殺死進程、終止進程、掛起進程等系統調用函數。
fork.c //程序給出了 sys_fork()系統調用中使用了兩個 C 語言函數: find_empty_process()和 copy_process()。
mktime.c //程序包含一個內核使用的時間函數 mktime(),用於計算從 1970 年 1 月 1 日 0 時起到開機當日的秒數,作為開機秒時間。僅在 init/main.c 中被調用一次。
panic. //程序包含一個顯示內核出錯信息並停機的函數 panic()。
printk.c //程序包含一個內核專用信息顯示函數 printk()。
sched.c //程序中包括有關調度的基本函數(sleep_on、 wakeup、 schedule 等)以及一些簡單的系統調用函數。另外還有幾個與定時相關的軟盤操作函數。
signal.c //程序中包括了有關信號處理的 4 個系統調用以及一個在對應的中斷處理程序中處理信號的函數 do_signal()。
sys.c //程序包括很多系統調用函數,其中有些還沒有實現。
system_call.s //程序實現了 linux 系統調用(int 0x80)的接口處理過程,實際的處理過程則包含在各系統調用相應的 C 語言處理函數中,這些處理函數分布在整個 linux 內核代碼中
vsprintf.c //程序實現了現在已經歸入標准庫函數中的字符串格式化函數。
塊設備驅動程序子目錄 kernel/blk_dev
通常情況下,用戶是通過文件系統來訪問設備的,因此設備驅動程序為文件系統實現了調用接口。在使用塊設備時,由於其數據吞吐量大,為了能夠高效率地使用塊設備上的數據,在用戶進程與塊設備之間使用了高速緩沖機制。在訪問塊設備上的數據時,系統首先以數據塊的形式把塊設備上的數據讀入到高速緩沖區中,然后再提供給用戶。 blk_dev 子目錄共包含 4 個 c 文件和 1 個頭文件。頭文件 blk.h 由於是塊設備程序專用的,所以與 C 文件放在一起。這幾個文件之間的大致關系,如圖所示:
blk.h //中定義了 3 個 C 程序中共用的塊設備結構和數據塊請求結構。
hd.c //程序主要實現對硬盤數據塊進行讀/寫的底層驅動函數,主要是 do_hd__request()函數;
floppy.c //程序中主要實現了對軟盤數據塊的讀/寫驅動函數,主要是 do_fd_request()函數。
ll_rw_blk.c //中程序實現了低層塊設備數據讀/寫函數 ll_rw_block(),內核中所有其它程序都是通過該函數對塊設備進行數據讀寫操作。
你將看到該函數在許多訪問塊設備數據的地方被調用,尤其是在高速緩沖區處理文件 fs/buffer.c 中。
字符設備驅動程序子目錄 kernel/chr_dev
字符設備程序子目錄共含有 4 個 C 語言程序和 2 個匯編程序文件。 這些文件實現了對串行端口 rs-232、串行終端、鍵盤和控制台終端設備的驅動。下圖(圖 2.12)是這些文件之間的大致調用層次關系:
tty_io.c //程序中包含 tty 字符設備讀函數 tty_read()和寫函數 tty_write(),為文件系統提供了上層訪問接
//口。另外還包括在串行中斷處理過程中調用的 C 函數 do_tty_interrupt(),該函數將會在中斷類型為讀字符
//的處理中被調用。
console.c //文件主要包含控制台初始化程序和控制台寫函數 con_write(),用於被 tty 設備調用。還包含
//對顯示器和鍵盤中斷的初始化設置程序 con_init()。
rs_io.s //匯編程序用於實現兩個串行接口的中斷處理程序。 該中斷處理程序會根據從中斷標識寄存器(端
//口 0x3fa 或 0x2fa)中取得的 4 種中斷類型分別進行處理,並在處理中斷類型為讀字符的代碼中調用do_tty_interrupt()。
serial.c //用於對異步串行通信芯片 UART 進行初始化操作,並設置兩個通信端口的中斷向量。
//另外還包括 tty 用於往串口輸出的 rs_write()函數。
tty_ioctl.c //程序實現了 tty 的 io 控制接口函數 tty_ioctl()以及對 termio(s)終端 io 結構的讀寫函數,並會
//在實現系統調用 sys_ioctl()的 fs/ioctl.c 程序中被調用。
keyboard.S //程序主要實現了鍵盤中斷處理過程 keyboard_interrupt。
協處理器仿真和操作程序子目錄 kernel/math
該子目錄中目前僅有一個 C 程序 math_emulate.c。其中的 math_emulate()函數是中斷 int7 的中斷處理程序調用的 C 函數。當機器中沒有數學協處理器,而 CPU 卻又執行了協處理器的指令時,就會引發該中斷。因此,使用該中斷就可以用軟件來仿真協處理器的功能。本書所討論的內核版本還沒有包含有關協處理器的仿真代碼。本程序中只是打印一條出錯信息,並向用戶程序發送一個協處理器錯誤信號 SIGFPE。
7、內核庫函數目錄 lib
內核庫函數主要用於用戶編程調用,是編譯系統標准庫的接口函數之一。其中共有 12 個 C 語言文件,除了一個由 tytso 編制的 malloc.c 程序較長以外,其它的程序很短,有的只有一二行代碼。
8、內存管理程序目錄 mm
該目錄包括 2 個代碼文件。主要用於管理程序對主內存區的使用,實現了進程邏輯地址到線性地址以及線性地址到主內存區中物理內存地址的映射,通過內存的分頁管理機制,在進程的虛擬內存頁與主內存區的物理內存頁之間建立了對應關系。
page.s 文件包括內存頁面異常中斷( int 14)處理程序,主要用於處理程序由於缺頁而引起的頁異常中斷和訪問非法地址而引起的頁保護。
memory.c 程序包括對內存進行初始化的函數 mem_init(),由 page.s 的內存處理中斷過程調用的do_no_page()和 do_wp_page()函數。在創建新進程而執行復制進程操作時,即使用該文件中的內存處理函數來分配管理內存空間。
9、編譯內核工具程序目錄 tools
該目錄下的 build.c 程序用於將 Linux 各個目錄中被分別編譯生成的目標代碼連接合並成一個可運行的內核映象文件 image。具體的功能后面詳細介紹
6、內核系統與用戶程序的關系
在 Linux 系統中,內核為應用程序提供了兩方面的接口。其一是系統調用接口,也即中斷調用 int 0x80;另一方面是通過內核庫函數,與內核進行信息交流。內核庫函數是基本 C 函數庫 libc 的組成部分。許多的系統調用是作為基本 C 語言函數庫的一部分實現的。系統調用主要是提供給系統軟件直接使用或用於庫函數的實現。而一般用戶開發的程序則是通過調用象 libc 等庫中的函數來訪問內核資源。通過調用這些庫中的程序,應用程序代碼能夠完成各種常用工作,例如,打開和關閉對文件或設備的訪問、進行科學計算、出錯處理以及訪問組和用戶標識號 ID 等系統信息。系統調用是內核與外界接口的最高層。在內核中,每個系統調用都有一個序列號(在include/linux/unistd.h 頭文件中定義),並常以宏的形式實現。