羽夏看Linux內核——中斷與分頁相關入門知識
寫在前面
??此系列是本人一個字一個字碼出來的,包括示例和實驗截圖。如有好的建議,歡迎反饋。碼字不易,如果本篇文章有幫助你的,如有閑錢,可以打賞支持我的創(chuàng)作。如想轉載,請把我的轉載信息附在文章后面,并聲明我的個人信息和本人博客地址即可,但必須事先通知我。
你如果是從中間插過來看的,請仔細閱讀 羽夏看Linux系統內核——簡述 ,方便學習本教程。
中斷
??中斷通常是由CPU外部的輸入輸出設備(硬件)所觸發(fā)的,供外部設備通知CPU有事情需要處理,因此又叫中斷請求,英文為Interrupt Request。中斷請求的目的是希望CPU暫時停止執(zhí)行當前正在執(zhí)行的程序,轉去執(zhí)行中斷請求所對應的中斷處理例程,中斷處理程序由哪有IDT表決定。
??80x86有兩條中斷請求線:非屏蔽中斷線,NMI,全稱NonMaskable Interrupt和可屏蔽中斷線,INTR,全稱Interrupt Require。
不可屏蔽中斷
??什么是不可屏蔽中斷?CPU的EFLAG之中有一個位,它是IF位。如果它被置0。如果有可屏蔽中斷告訴CPU有中斷來了,你能先執(zhí)行我的代碼呢?可是IF位是0,對不起,我聽不見。左耳朵進,右耳朵出。反之,我會處理。常見的不可屏蔽中斷有電腦長按關機、鍵盤輸入等等。當非可屏蔽中斷產生時,CPU在執(zhí)行完當前指令后會里面進入中斷處理程序,非可屏蔽中斷不受那個位的影響,一旦發(fā)生,CPU必須處理。為了方便觀看,給個EFLAG圖解:
??那么CPU是如何處理我們的不可屏蔽中斷呢?我們先來看如下表格:
| (IDT表)中斷號 | NMI | 說明 |
|---|---|---|
| 0x2 | 不可屏蔽中斷 | 80x86 中固定為 0x2 |
??如果處理不可屏蔽中斷,CPU會調用2號中斷。涉及的IDT表和中斷門的知識如果忘卻請查看前面的教程。
可屏蔽中斷
??什么是可屏蔽中斷,我就不贅述了。在硬件級,可屏蔽中斷是由一塊專門的芯片來管理的,通常稱為中斷控制器。它負責分配中斷資源和管理各個中斷源發(fā)出的中斷請求.為了便于標識各個中斷請求,中斷管理器通常用IRQ,全稱為Interrupt Request,后面加上數字來表示不同的中斷。
??那么CPU是如何處理我們的可屏蔽中斷呢?我們先來看如下表格:
| (IDT表)中斷號 | IRQ | 說明 |
|---|---|---|
| 0x30 | IRQ0 | 時鐘中斷 |
| 0x31-0x3F | IRQ1-IRQ15 | 其他硬件設備的中斷 |
??如果自己的程序執(zhí)行時不希望CPU去處理這些中斷,可以用CLI指令清空EFLAG寄存器中的IF位,用STI指令設置EFLAG寄存器中的IF位。
??硬件中斷與IDT表中的對應關系并非固定不變的,可以參考白皮書的Chapter 10 Advanced Programmable Interrupt Controller(APIC)進行了解。
異常
??異常通常是CPU在執(zhí)行指令時檢測到的某些錯誤,比如除0、訪問無效頁等。中斷與異常之間有一些相似之處,但它們是不一樣的:中斷來自于外部設備,是中斷源(比如鍵盤)發(fā)起的,CPU是被動的;而異常來自于CPU本身,是CPU主動產生的。INT N雖然被稱為“軟件中斷”,但其本質是異常,EFLAG的IF位對INT N是無效。
異常處理
??無論是由硬件設備觸發(fā)的中斷請求還是由CPU產生的異常,處理程序都在IDT表。常見的異常處理程序如下表所示:
| 錯誤類型 | (IDT表)中斷號 |
|---|---|
| 頁錯誤 | 0xE |
| 段錯誤 | 0xD |
| 除零錯誤 | 0x0 |
| 雙重錯誤 | 0x8 |
控制寄存器
??控制寄存器用于控制和確定CPU的操作模式。控制寄存器有Cr0、Cr1、Cr2、Cr3、Cr4。Cr1被保留了,Cr3用于頁目錄表基址,其他的將繼續(xù)詳細講解。
Cr0
??Cr0是一個十分重要的寄存器,可以說它是總開關的集合體。如下圖所示:
??PE位是啟用保護模式(Protection Enable)標志。若PE = 1是開啟保護模式,反之為實地址模式。這個標志僅開啟段級保護,而并沒有啟用分頁機制。若要啟用分頁機制,那么PE和PG標志都要置位。
??PG位是啟用分頁機制。在開啟這個標志之前必須已經或者同時開啟PE標志。PG = 0且PE = 0,處理器工作在實地址模式下。PG = 0且PE = 1,處理器工作在沒有開啟分頁機制的保護模式下。PG = 1且PE = 0,在PE沒有開啟的情況下無法開啟PG。PG = 1且PE = 1,處理器工作在開啟了分頁機制的保護模式下。
??WP位對于Intel 80486或以上的CPU,是寫保護(Write Proctect)標志。當設置該標志時,處理器會禁止超級用戶程序(例如特權級0的程序)向用戶級只讀頁面執(zhí)行寫操作;當CPL < 3的時候,如果WP = 0可以讀寫任意用戶級物理頁,只要線性地址有效。如果WP = 1可以讀取任意用戶級物理頁,但對于只讀的物理頁,則不能寫。
Cr2
??當CPU訪問某個無效頁面時,會產生缺頁異常,此時,CPU會將引起異常的線性地址存放在CR2中,如下圖所示:
Cr4
??Cr4的結構如下圖所示:
??VME用于虛擬8086模式。PAE用于確認是哪個分頁,PAE = 1,是2-9-9-12分頁,PAE = 0是10-10-12分頁。PSE是大頁是否開啟的總開關,如果置0,就算PDE中設置了大頁你也得是普通的頁。至于分頁到底是什么,將會之后進行講解。
中斷小節(jié)
??有些結構的位我并沒有詳細介紹,詳情請查看白皮書的控制寄存器的篇章,如下圖所示:
??如果對分頁不了解看不懂沒關系,接下來將會介紹相關知識。
分頁
??在講解分頁基礎之前,我們先大體了解CPU是如何在保護模式下訪問數據的,如下圖所示:
??比如我們執(zhí)行mov eax,ds:[0x12345678]這句匯編指令的時候,0x12345678這個線性地址會傳遞給CPU,先查詢TLB和緩存有沒有,有的話直接取出來返回;如果沒有,經過MMU(內存管理單元)處理得到物理地址,通過固定的分頁模式直接找到,取出數據返回。
??前面的教程講解了段的機制,接下來將介紹頁的機制。CPU為了方便管理物理內存,按照頁的方式進行管理內存。可用的所有內存可以類比為一本書,而所有的內存被分為這本書的一個頁。對于32位來說,它有10-10-12分頁和2-9-9-12分頁。其中10-10-12分頁最為簡單,故拿其作為詳細講解,作為分頁講解的基礎。
??我們都了解一個進程都有4GB的虛擬地址空間,它們并不是真正的地址,而是個索引。它通過某種方式進行轉換,從而指向真正的物理地址,示意圖如下所示:
??而虛擬地址也被稱作線性地址。舉個例子,比如某個進程里面我想讀取一個0x12345678,它就是線性地址,通過一些轉換,找到了對應的物理地址0x10101010,如下圖所示:
??每個進程都有一個CR3,準確的說是都一個CR3的值。CR3本身是個寄存器,一核一套。CR3里面放的是一個真正的物理地址,指向一個物理頁,一共4096字節(jié),如下圖所示:
??對于10-10-12分頁來說,線性地址對應的物理地址是有對應關系的,它被分成了三個部分,每個部分都有它具體的含義。線性地址分配的結構如下圖所示:
??第一個部分指的是PDE在PDT的索引,第二部分是PTE在PTT的索引,第三個部分是在PTE指向的物理頁的偏移。PDT被稱為頁目錄表,PTT被稱為頁表。PDE和PTE分別是它們的成員,大小為4個字節(jié)。我們接下來將詳細介紹每一個部分是咋用的。
10-10-12 分頁整體結構
??通過實驗我們了解了它們的結構,接下來將詳細介紹了。根據實驗結果的體驗,可以給出如下圖:
??分頁并不是由操作系統決定的,而是由CPU決定的。只是操作系統遵守了CPU的約定來實現的。物理頁是什么?物理頁是操作系統對可用的物理內存的抽象,按照4KB的大小進行管理(Intel是按照這個值做的,別的CPU就不清楚了),和真實硬件層面上的內存有一層的映射關系,這個不是保護模式的范疇,故不介紹。
PDE 與 PTE
??前面我們簡單了解PDE和PTE,接下來將學習它們的屬性結構,結構如下:
P 位
??表示PDE或者PTE是否有效,如果有效為1,反之為0。
R/W 位
??如果R/W = 0,表示是只讀的,反之為可讀可寫。
U/S 位
??如果U/S = 0,則為特權用戶(super user),即非3環(huán)權限。反之,則為普通用戶,即為3環(huán)權限。
PS位
??這個位只對PDE有意義。如果PS == 1,則PDE直接指向物理頁,不再指向PTE,低22位是頁內偏移。它的大小為4MB,俗稱“大頁”。
A 位
??是否被訪問,即是否被讀或者寫過,如果被訪問過則置1。
D 位
??臟位,指示是否被寫過。若沒有被寫過為0,被寫過為1。
注意,下面的三個位的講解將涉及 TLB 和控制寄存器相關知識,為了保證文章的完整性,故先介紹。之后將會詳細講解。
G 位
??表示是否為全局頁。它的作用是什么呢?舉個例子,操作系統的進程的高2G映射基本不變,如果Cr3改了,TLB刷新重建高2G以上很浪費。所以PDE和PTE中有個G位,如果為1,刷新TLB時將不會刷新它指向的頁。
PWT 位
??當PWT = 1,寫緩存的時候也要將數據寫入內存中。
PCD 位
??當PCD = 1時,禁止某個頁寫入緩存,直接寫內存。比如,做頁表用的頁,已經存儲在TLB中了,可能不需要再緩存了。
注意事項
PTE可以沒有物理頁,且只能對應一個物理頁。- 多個
PTE也可以指向同一個物理頁。 PDE和PTE重合的屬性共同決定著最終物理頁的屬性。比如P位,如果有一個是0,那么最終的物理頁就是無效的。但是PDE和PTE它們的屬性的影響范圍是不一樣的。數值上:物理頁的屬性 = PDE屬性 & PTE屬性。
PAE 分頁
??PAE分頁是啥,其實他就是2-9-9-12分頁的英文縮寫。為什么要有2-9-9-12分頁,其實還是物理頁不夠用了,需要擴展。但想要足夠的物理頁,位數在那里,你想大也大不了。那么我就需要擴展物理頁地址的位數,于是乎2-9-9-12分頁誕生了,它整體分頁的結構如下:
??與10-10-12分頁不同的地方就是,多了一層名為頁目錄指針表的東西,英文縮寫為PDPTT。每個PDE和PTE被擴展為8個字節(jié),物理地址描述的位數擴展為24位,故可以描述更多的物理頁,但個數減半,變成了512個。下面詳細查看它們的結構。
??首先看PDPTT的結構。由2-9-9-12的2可知第一部分由兩位二進制組成,那么最多有4種結果。也就是為什么有五個成員,它的結構如下圖所示:
??然后是PDE,既然學過了10-10-12分頁,直接看下面的結構示意圖吧:
非大頁
大頁
??然后是PTE,同理不多說了:
??我們之前做一道作業(yè)題目知道,我寫的shellcode寫到一個頁上,它并沒有執(zhí)行權限,但它不是代碼,仍然可以被我執(zhí)行。為了彌補這個漏洞,Intel給我們補了一個硬件層面上的漏洞,它是一個位,處于PDE和PTE的最高位,如下圖所示:
??如果最高位是1,說明被保護。如果這個是數據,且這個X位被置為1,則會被報出異常不能執(zhí)行。反之,和正常的10-10-12分頁沒什么兩樣。
??一個進程的線性地址仍是4GB的線性空間,有再多的物理頁有啥用呢?在10-10-12分頁下,假設進程一啟動,就把所有的物理頁都掛上,且沒有任何交換。那么只能啟動一個;如果在2-9-9-12分頁下,同樣的情況,它可以啟動4個進程。這個就是2-9-9-12分頁的意義。
TLB
??CPU通過頁的方式對物理內存進行了,需要通過某種運算方式才能訪問真正的內存。但是,如果頻繁訪問某一個線性地址,每次都得通過推算到真正的物理地址然后進行讀寫操作,是不是挺浪費效率的?Intel就考慮到性能的問題,提供了TLB這一個機制,提供緩存提高讀寫效率。
??TLB的全稱為Translation Lookaside Buffer,它的結構如下:
| LA(線性地址) | PA(物理地址) | ATTR(屬性) | LRU(統計) |
|---|
??對于TLB,給出如下說明:
??1. ATTR(屬性):如果是2-9-9-12分頁,屬性是PDPE、PDE、PTE三個屬性共同決定的。如果是10-10-12分頁就是PDE和PTE共同決定。
??2. 不同的CPU這個表的大小不一樣。
??3. 只要Cr3變了,TLB立馬刷新,一核一套TLB。
??如果Cr3改了,TLB刷新重建高2G以上很浪費。所以PDE和PTE中有個G標志位,如果G位為1刷新TLB時將不會刷新PDE/PTE的G位為1的頁,當TLB滿了,根據統計信息將不常用的地址廢棄,最近最常用的保留。
??TLB有不同的種類,用于不同的緩存目的,它在X86體系里的實際應用最早是從Intel的486CPU開始的,在X86體系的CPU里邊,一般都設有如下4組TLB:
??第一組:緩存一般頁表(4K字節(jié)頁面)的指令頁表緩存:Instruction-TLB
??第二組:緩存一般頁表(4K字節(jié)頁面)的數據頁表緩存:Data-TLB
??第三組:緩存大尺寸頁表(2M/4M字節(jié)頁面)的指令頁表緩存:Instruction-TLB
??第四組:緩存大尺寸頁表(2M/4M字節(jié)頁面)的數據頁表緩存:Data-TLB
CPU緩存
??CPU緩存是位于CPU與物理內存之間的臨時存儲器,它的容量比內存小的多但是交換速度卻比內存要快得多。它可以做的很大,但不是TLB,它們有很大的不同。TLB存的是線性地址與物理地址的對應關系,CPU緩存存的是物理地址與內容對應關系。
??更多的細節(jié)請參考白皮書的Chapter 11 Memory Cache Control,本篇教程主要是針對內核安全層面,就不再贅述了。
PWT 與 PCD
??PWT全稱為Page Write Through,PWT = 1時,寫Cache的時候也要將數據寫入內存中。
??PCD全稱為Page Cache Disable,PCD = 1時,禁止某個頁寫入緩存,直接寫內存。比如,做頁表用的頁,已經存儲在TLB中了,可能不需要再緩存了。
下一篇
本文來自博客園,作者:寂靜的羽夏 ,一個熱愛計算機技術的菜鳥
轉載請注明原文鏈接:http://www.rzrgm.cn/wingsummer/p/16564726.html



浙公網安備 33010602011771號