Linux 操作系統(tǒng)原理內(nèi)核態(tài)與用戶態(tài)

      網(wǎng)友投稿 986 2025-04-03

      目錄


      文章目錄

      目錄

      linux 的內(nèi)核態(tài)與用戶態(tài)

      系統(tǒng)調(diào)用(System Call)

      Shell

      用戶態(tài)和內(nèi)核態(tài)的切換

      進(jìn)程的用戶空間和內(nèi)核空間的內(nèi)存布局

      內(nèi)核空間

      用戶空間

      linux 的內(nèi)核態(tài)與用戶態(tài)

      我們常說的 Linux 嚴(yán)格來說指代的是 Linux Kernel,泛指使用或裁剪標(biāo)準(zhǔn) Linux Kernel 并在此基礎(chǔ)之上實(shí)現(xiàn)各種應(yīng)用程序解決方案的操作系統(tǒng)發(fā)行版本(e.g. RHEL、SUSE 和 Ubuntu)。一個(gè)完整的 Linux 操作系統(tǒng)體系架構(gòu)通常由下列幾個(gè)核心層級(jí)組成:

      Applications:在操作系統(tǒng)上安裝并運(yùn)行的用戶態(tài)應(yīng)用程序

      Shell:支持編程的命令行解析器

      Libs:操作系統(tǒng)標(biāo)準(zhǔn)庫函數(shù)

      System Calls:暴露給用戶態(tài)的內(nèi)核態(tài)系統(tǒng)調(diào)用接口

      Kernel:操作系統(tǒng)的核心,真正對(duì)接硬件平臺(tái)的軟件程序

      Linux Kernel 本質(zhì)上看是一種軟件,實(shí)現(xiàn)了進(jìn)程管理器、內(nèi)存管理器、文件系統(tǒng)、設(shè)備驅(qū)動(dòng)以及網(wǎng)絡(luò)管理組件來負(fù)責(zé)對(duì)接、管理計(jì)算機(jī)硬件平臺(tái),并通過系統(tǒng)調(diào)用(System Calls)為上層應(yīng)用程序暴露硬件資源以提供程序運(yùn)行環(huán)境。

      以系統(tǒng)調(diào)用為邊界將 Linux 操作系統(tǒng)的體系架構(gòu)分為用戶態(tài)和內(nèi)核態(tài)(包括系統(tǒng)調(diào)用)。

      操作系統(tǒng)的用戶態(tài)和內(nèi)核態(tài)實(shí)際上對(duì)應(yīng)了 CPU 指令集中的非特權(quán)指令和特權(quán)指令的執(zhí)行狀態(tài),CPU 劃分了不同的執(zhí)行級(jí)別來執(zhí)行具有相應(yīng)特權(quán)的指令。例如:Intel x86 CPU 具有四種不同的執(zhí)行級(jí)別 [RING0, RING1, RING2, RING3],Linux 操作系統(tǒng)只使用了其中的 RING0 和 RING3 分別表示內(nèi)核態(tài)與用戶態(tài)。處于 RING3 狀態(tài)的用戶態(tài)代碼不能直接訪問處于 RING0 的內(nèi)核態(tài)代碼的地址空間(包括代碼和數(shù)據(jù))。

      我們知道有些 CPU 特權(quán)指令的操作實(shí)際是比較危險(xiǎn)的,比如:寫入系統(tǒng)配置文件、殺掉其他用戶的進(jìn)程或重啟系統(tǒng)。所以在操作系統(tǒng)的設(shè)計(jì)中,為了保障操作系統(tǒng)的穩(wěn)定性,尤其是在多用戶環(huán)境中的可靠性,操作系統(tǒng)根據(jù) CPU 的指令類型來抽象并實(shí)現(xiàn)了用戶態(tài)和內(nèi)核態(tài)兩種代碼運(yùn)行模式,兩種運(yùn)行模式之間的切換也成為模式切換。用戶態(tài)的代碼被限制了可以執(zhí)行的操作以及可以訪問的資源范圍,而內(nèi)核態(tài)的代碼則可以執(zhí)行任何操作并且沒有資源使用上的限制。

      所以,**為什么要?jiǎng)澐趾诵膽B(tài)和用戶態(tài)?**簡(jiǎn)單來說:

      禁止用戶程序和底層硬件平臺(tái)直接交互。

      禁止用戶程序直接訪問任意內(nèi)存地址空間。

      Linux 進(jìn)程擁有 4GB 內(nèi)存地址空間,其中 3-4G 部分是內(nèi)核態(tài)的地址空間,存放了整個(gè)內(nèi)核的代碼,所有內(nèi)核模塊以及內(nèi)核所維護(hù)的數(shù)據(jù)。隨便多說一句,這就是所謂的操作系統(tǒng)副本,無論是 SMP 還是 NUMA 實(shí)現(xiàn)的都是「單操作系統(tǒng)與數(shù)據(jù)庫系統(tǒng)副本」,而 MPP 海量并行處理體系結(jié)構(gòu)實(shí)現(xiàn)的是多操作系統(tǒng)與數(shù)據(jù)庫系統(tǒng)副本,但 MPP 一般只常見于大型機(jī)。運(yùn)行在 RING3 的用戶程序代碼可以通過系統(tǒng)調(diào)用主動(dòng)訪問 RING0 的內(nèi)核代碼來實(shí)現(xiàn)從用戶態(tài)帶內(nèi)核態(tài)的切換。當(dāng)進(jìn)程陷入內(nèi)核態(tài)時(shí),被執(zhí)行的內(nèi)核代碼會(huì)直接使用進(jìn)程的內(nèi)核棧資源。

      例如:用戶運(yùn)行一個(gè)程序,該程序創(chuàng)建的進(jìn)程開始運(yùn)行在用戶態(tài),如果程序要執(zhí)行諸如文件操作,網(wǎng)絡(luò)數(shù)據(jù)發(fā)送操作等內(nèi)核態(tài)操作的話,就必須通過系統(tǒng)調(diào)用中的 Write,Send 等功能單元完成,根本是通過調(diào)用內(nèi)核代碼完成的。此時(shí),運(yùn)行該進(jìn)程的處理器會(huì)從 RING3 切換到 RING0 級(jí)別,然后進(jìn)入 3-4GB 內(nèi)核地址空間中完成內(nèi)核代碼的執(zhí)行。執(zhí)行完成后,處理器再?gòu)?RING0 切換回 RING3,進(jìn)程也回到用戶態(tài)。

      用戶態(tài)的應(yīng)用程序可以通過三種方式來訪問內(nèi)核態(tài)的資源:

      系統(tǒng)調(diào)用。

      庫函數(shù)。

      Shell 腳本。

      系統(tǒng)調(diào)用(System Call)

      系統(tǒng)調(diào)用是操作系統(tǒng)的最小功能單位,具有原子性,這些系統(tǒng)調(diào)用根據(jù)不同的應(yīng)用場(chǎng)景可以進(jìn)行擴(kuò)展和裁剪,現(xiàn)在各種版本的 Unix 實(shí)現(xiàn)都提供了不同數(shù)量的系統(tǒng)調(diào)用,如 Linux 的不同版本提供了 240-260 個(gè)系統(tǒng)調(diào)用,F(xiàn)reeBSD 大約提供了 320 個(gè)(reference:UNIX 環(huán)境高級(jí)編程)。

      庫函數(shù)正是為了將程序員從復(fù)雜的細(xì)節(jié)中解脫出來而提出的一種有效方法。它實(shí)現(xiàn)對(duì)系統(tǒng)調(diào)用的封裝,將簡(jiǎn)單的業(yè)務(wù)邏輯接口呈現(xiàn)給用戶,方便用戶調(diào)用。顯然,這樣的庫函數(shù)依據(jù)不同的標(biāo)準(zhǔn)也可以有不同的實(shí)現(xiàn)版本,如 ISO C 標(biāo)準(zhǔn)庫,POSIX 標(biāo)準(zhǔn)庫等。

      Shell

      Shell 是一個(gè)特殊的應(yīng)用程序,俗稱命令行,本質(zhì)上是一個(gè)命令解釋器,它下通系統(tǒng)調(diào)用,上通各種應(yīng)用,通常充當(dāng)著一種“膠水”的角色,來連接各個(gè)小功能程序,讓不同程序能夠以一個(gè)清晰的接口協(xié)同工作,從而增強(qiáng)各個(gè)程序的功能。

      同時(shí),Shell 是可編程的,它可以執(zhí)行符合 Shell 語法的文本,這樣的文本稱為 Shell 腳本,通常短短的幾行 Shell 腳本就可以實(shí)現(xiàn)一個(gè)非常大的功能,原因就是這些 Shell 語句通常都對(duì)系統(tǒng)調(diào)用做了一層封裝。為了方便用戶和系統(tǒng)交互,一般的,一個(gè) Shell 對(duì)應(yīng)一個(gè)終端,終端是一個(gè)硬件設(shè)備,呈現(xiàn)給用戶的是一個(gè)圖形化窗口。我們可以通過這個(gè)窗口輸入或者輸出文本。這個(gè)文本直接傳遞給 Shell 進(jìn)行分析解釋,然后執(zhí)行。

      用戶態(tài)和內(nèi)核態(tài)的切換

      因?yàn)椴僮飨到y(tǒng)的資源是有限的,如果訪問資源的操作過多,必然會(huì)消耗過多的資源,而且如果不對(duì)這些操作加以區(qū)分,很可能造成資源訪問的沖突。

      所以,為了減少有限資源的訪問和使用沖突,Unix/Linux 的設(shè)計(jì)哲學(xué)之一就是:對(duì)不同的操作賦予不同的執(zhí)行等級(jí),就是所謂特權(quán)的概念。簡(jiǎn)單說就是有多大能力做多大的事,與系統(tǒng)相關(guān)的一些特別關(guān)鍵的操作必須由最高特權(quán)的程序來完成。Intel 的 X86 架構(gòu)的 CPU 提供了 0 到 3 四個(gè)特權(quán)級(jí),數(shù)字越小,特權(quán)越高。

      Linux 操作系統(tǒng)中主要采用了 0 和 3 兩個(gè)特權(quán)級(jí),分別對(duì)應(yīng)的就是內(nèi)核態(tài)和用戶態(tài)。運(yùn)行于用戶態(tài)的進(jìn)程可以執(zhí)行的操作和訪問的資源都會(huì)受到極大的限制,而運(yùn)行在內(nèi)核態(tài)的進(jìn)程則可以執(zhí)行任何操作并且在資源的使用上沒有限制。

      很多程序開始時(shí)運(yùn)行于用戶態(tài),但在執(zhí)行的過程中,一些操作需要在內(nèi)核權(quán)限下才能執(zhí)行,這就涉及到一個(gè)從用戶態(tài)切換到內(nèi)核態(tài)的過程。比如C函數(shù)庫中的內(nèi)存分配函數(shù) malloc(),它具體是使用 sbrk() 系統(tǒng)調(diào)用來分配內(nèi)存,當(dāng)malloc() 調(diào)用 sbrk() 的時(shí)候就涉及一次從用戶態(tài)到內(nèi)核態(tài)的切換,類似的函數(shù)還有 printf(),調(diào)用的是 wirte() 系統(tǒng)調(diào)用來輸出字符串,等等。

      用戶程序除了通過系統(tǒng)調(diào)用主動(dòng)觸發(fā)模式切換之外,還可能會(huì)被動(dòng)的進(jìn)行??偟膩碚f模式切換有兩種觸發(fā)手段:

      (軟中斷)系統(tǒng)調(diào)用:這時(shí)用戶態(tài)進(jìn)程要傳遞很多變量或參數(shù)值給內(nèi)核,內(nèi)核態(tài)運(yùn)行時(shí)也要保存用戶進(jìn)程的一些寄存器值和變量等等。所謂的「進(jìn)程上下文」,可以看作是用戶進(jìn)程傳遞給內(nèi)核的這些參數(shù)以及內(nèi)核要保存的那一整套的變量和寄存器值以及運(yùn)行環(huán)境等。

      (硬中斷)外圍設(shè)備中斷:硬件可以通過觸發(fā)中斷信號(hào)令內(nèi)核調(diào)用中斷處理程序從而進(jìn)入內(nèi)核空間。這個(gè)過程中,硬件的一些變量和參數(shù)也要傳遞給內(nèi)核,內(nèi)核通過這些參數(shù)進(jìn)行中斷處理。所謂的「中斷上下文」,就是硬件傳遞過來的這些參數(shù)和內(nèi)核需要保存的當(dāng)前被中斷執(zhí)行的進(jìn)程環(huán)境。

      由此可見,處理器總處于以下狀態(tài)中的一種:

      運(yùn)行進(jìn)程上下文的內(nèi)核態(tài),內(nèi)核代表進(jìn)程運(yùn)行在內(nèi)核地址空間。

      運(yùn)行中斷上下文的內(nèi)核態(tài),內(nèi)核代表硬件運(yùn)行在內(nèi)核地址空間。

      用戶態(tài),運(yùn)行在用戶地址空間。

      發(fā)生從用戶態(tài)到內(nèi)核態(tài)的切換,一般存在以下三種情況:

      系統(tǒng)調(diào)用。

      異常事件: 當(dāng) CPU 正在執(zhí)行運(yùn)行在用戶態(tài)的程序時(shí),突然發(fā)生某些預(yù)先不可知的異常事件,這個(gè)時(shí)候就會(huì)觸發(fā)從當(dāng)前用戶態(tài)執(zhí)行的進(jìn)程轉(zhuǎn)向內(nèi)核態(tài)執(zhí)行相關(guān)的異常事件,典型的如缺頁異常。

      外設(shè)的中斷:當(dāng)外圍設(shè)備完成用戶的請(qǐng)求操作后,會(huì)向 CPU 發(fā)出中斷信號(hào),此時(shí),CPU 就會(huì)暫停執(zhí)行下一條即將要執(zhí)行的指令,轉(zhuǎn)而去執(zhí)行中斷信號(hào)對(duì)應(yīng)的處理程序,如果先前執(zhí)行的指令是在用戶態(tài)下,則自然就發(fā)生從用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)換。

      注意:系統(tǒng)調(diào)用的本質(zhì)其實(shí)也是中斷,相對(duì)于外圍設(shè)備的硬中斷,這種中斷稱為軟中斷,這是操作系統(tǒng)為用戶特別開放的一種中斷,如 Linux int 80h 中斷。所以,從觸發(fā)方式和效果上來看,這三種切換方式是完全一樣的,都相當(dāng)于是執(zhí)行了一個(gè)中斷響應(yīng)的過程。但是從觸發(fā)的對(duì)象來看,系統(tǒng)調(diào)用是進(jìn)程主動(dòng)請(qǐng)求切換的,而異常和硬中斷則是被動(dòng)的。

      進(jìn)程的用戶空間和內(nèi)核空間的內(nèi)存布局

      內(nèi)核空間

      內(nèi)核空間總是駐留在內(nèi)存中,它是為操作系統(tǒng)的內(nèi)核保留的。應(yīng)用程序是不允許直接在該區(qū)域進(jìn)行讀寫或直接調(diào)用內(nèi)核代碼定義的函數(shù)的。

      上圖左側(cè)區(qū)域?yàn)閮?nèi)核進(jìn)程對(duì)應(yīng)的虛擬內(nèi)存,按訪問權(quán)限可以分為進(jìn)程私有和進(jìn)程共享兩塊區(qū)域:

      進(jìn)程私有的虛擬內(nèi)存:每個(gè)進(jìn)程都有單獨(dú)的內(nèi)核棧、頁表、task 結(jié)構(gòu)以及 mem_map 結(jié)構(gòu)等。

      進(jìn)程共享的虛擬內(nèi)存:屬于所有進(jìn)程共享的內(nèi)存區(qū)域,包括物理存儲(chǔ)器、內(nèi)核數(shù)據(jù)和內(nèi)核代碼區(qū)域。

      用戶空間

      每個(gè)普通的用戶進(jìn)程都有一個(gè)單獨(dú)的用戶空間,處于用戶態(tài)的進(jìn)程不能訪問內(nèi)核空間中的數(shù)據(jù),也不能直接調(diào)用內(nèi)核函數(shù)的 ,因此要進(jìn)行系統(tǒng)調(diào)用的時(shí)候,就要將進(jìn)程切換到內(nèi)核態(tài)才行。

      用戶空間包括以下幾個(gè)內(nèi)存區(qū)域:

      Linux 操作系統(tǒng)原理 — 內(nèi)核態(tài)與用戶態(tài)

      運(yùn)行時(shí)棧:由編譯器自動(dòng)釋放,存放函數(shù)的參數(shù)值,局部變量和方法返回值等。每當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),該函數(shù)的返回類型和一些調(diào)用的信息被存儲(chǔ)到棧頂,調(diào)用結(jié)束后調(diào)用信息會(huì)被彈出并釋放掉內(nèi)存。棧區(qū)是從高地址位向低地址位增長(zhǎng)的,是一塊連續(xù)的內(nèi)在區(qū)域,最大容量是由系統(tǒng)預(yù)先定義好的,申請(qǐng)的??臻g超過這個(gè)界限時(shí)會(huì)提示溢出,用戶能從棧中獲取的空間較小。

      運(yùn)行時(shí)堆:用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,位于 BSS 和棧中間的地址位。由卡發(fā)人員申請(qǐng)分配(malloc)和釋放(free)。堆是從低地址位向高地址位增長(zhǎng),采用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。頻繁地 malloc/free 造成內(nèi)存空間的不連續(xù),產(chǎn)生大量碎片。當(dāng)申請(qǐng)堆空間時(shí),庫函數(shù)按照一定的算法搜索可用的足夠大的空間。因此堆的效率比棧要低的多。

      代碼段:存放 CPU 可以執(zhí)行的機(jī)器指令,該部分內(nèi)存只能讀不能寫。通常代碼區(qū)是共享的,即其他執(zhí)行程序可調(diào)用它。假如機(jī)器中有數(shù)個(gè)進(jìn)程運(yùn)行相同的一個(gè)程序,那么它們就可以使用同一個(gè)代碼段。

      未初始化的數(shù)據(jù)段:存放未初始化的全局變量,BSS 的數(shù)據(jù)在程序開始執(zhí)行之前被初始化為 0 或 NULL。

      已初始化的數(shù)據(jù)段:存放已初始化的全局變量,包括靜態(tài)全局變量、靜態(tài)局部變量以及常量。

      內(nèi)存映射區(qū)域:例如將動(dòng)態(tài)庫,共享內(nèi)存等虛擬空間的內(nèi)存映射到物理空間的內(nèi)存,一般是 mmap 函數(shù)所分配的虛擬內(nèi)存空間。

      Linux Shell 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:wps文字怎么排版?
      下一篇:請(qǐng)問ppt里插入表格如何自動(dòng)美化表格?之前會(huì)自動(dòng)跳出來美化表格的按鈕,現(xiàn)在沒有了
      相關(guān)文章
      激情亚洲一区国产精品| 亚洲国产成a人v在线观看| 色天使亚洲综合在线观看| 亚洲AV永久无码区成人网站| 亚洲综合另类小说色区| 亚洲第一区精品日韩在线播放| 亚洲高清乱码午夜电影网| 亚洲欧美日韩中文无线码| 亚洲色少妇熟女11p| 亚洲欧美黑人猛交群| 亚洲av无码专区国产不乱码| 亚洲AV综合永久无码精品天堂| 伊人久久亚洲综合影院首页| 中文字幕亚洲码在线| 亚洲日韩国产二区无码| 老子影院午夜伦不卡亚洲| 亚洲精品456播放| 国产亚洲AV手机在线观看| 亚洲精品乱码久久久久66| 亚洲av最新在线网址| 少妇中文字幕乱码亚洲影视 | jzzijzzij在线观看亚洲熟妇| 亚洲av永久无码天堂网| 日韩精品亚洲专区在线观看| 亚洲精品动漫人成3d在线| 亚洲欧洲国产精品香蕉网| 久久精品国产亚洲香蕉| 亚洲精品动漫在线| 亚洲人成小说网站色| 色欲色欲天天天www亚洲伊| 成人亚洲网站www在线观看| 久久久久久亚洲精品不卡| 亚洲精品午夜无码电影网| 亚洲福利在线观看| 亚洲欧洲国产经精品香蕉网| 亚洲AV成人噜噜无码网站| 亚洲avav天堂av在线网毛片| 国产成人亚洲影院在线观看| 精品亚洲成α人无码成α在线观看| 亚洲va中文字幕无码久久| 亚洲视频网站在线观看|