(26)TLB
一、為什么需要TLB?TLB是什么?
TLB(Translation Lookaside Buffer)
當程序訪問一個線性地址,需要先查PDPT,然后查PDT,然后查頁表PTT(一直沒搞懂第三個T是什么的縮寫),最后才是訪問物理頁。這期間多次訪問內存,效率非常低。于是TLB就被設計出來了。
TLB 是CPU內部的表,一個CPU有一張TLB表,用來緩存線性地址和物理地址的映射關系,以及屬性和訪問次數。
LA,PA是線性地址到物理地址的映射,LRU是最近最久未使用的意思,用來控制替換的優先級,當TLB表填滿了,就會根據LRU刪除優先級低的項,以騰出空間給其他項。ATTR是屬性,如果是10-10-12分頁,那么就是PDE和PTE的屬性邏輯與,如果是2-9-9-12分頁,那么就是PDPE,PDE,PTE的屬性邏輯與。
進程切換時,CR3改變,TLB就會隨之刷新,這是因為相同的線性地址通過不同的CR3會映射到不同的物理地址。
操作系統的高2G映射基本不變,如果Cr3改了,TLB刷新,重建高2G以上很浪費。
所以PDE和PTE中有個G標志位,如果G位為1刷新TLB時將不會刷新 PDE/PTE的
G位為1的頁,當TLB滿了,根據統計信息將不常用的地址廢棄,最近最常用的保留.
二、TLB的種類
TLB在X86體系的CPU里的實際應用最早是從Intel的486CPU開始的,在X86體系的CPU里邊,一般都設有如下4組TLB:
第一組:緩存一般頁表(4K字節頁面)的指令頁表緩存(Instruction-TLB);
第二組:緩存一般頁表(4K字節頁面)的數據頁表緩存(Data-TLB);
第三組:緩存大尺寸頁表(2M/4M字節頁面)的指令頁表緩存(Instruction-TLB);
第四組:緩存大尺寸頁表(2M/4M字節頁面)的數據頁表緩存(Instruction-TLB)
三、實驗
體驗TLB的存在
編寫程序,在R0給NULL掛一個物理頁,并寫入數據,然后修改NULL的物理頁,然后讀NULL,發現讀取了之前寫入的值,這證明第二次訪問NULL的時候是從TLB中取的物理地址,證明了TLB的存在。
// TLB.cpp : Defines the entry point for the console application. //#include "stdafx.h" #include <windows.h>DWORD TempVal = 0;void __declspec(naked) R0Function() {__asm{pushadpushfd // 1.給NULL掛物理頁(修改PTE,這里概率藍屏)0x01234867(G=0) 0x01234967(G=1)mov dword ptr ds:[0xc0000000],0x01234867// 2.寫NULL指針,生成TLB記錄mov dword ptr ds:[0],0x12345678// 3.再次修改物理頁mov dword ptr ds:[0xc0000000],0x02345867// 4.讀NULL,發現讀了之前賦的值,證明了TLB的存在mov eax,dword ptr ds:[0]mov TempVal,eaxpopfdpopad iretd} }int _tmain(int argc, _TCHAR* argv[]) {printf("在IDT表構建中斷門,請在windbg中執行下面的指令:\n");printf("eq 8003f500 %04xee00`0008%04x\n",(DWORD)R0Function>>16,(DWORD)R0Function & 0x0000FFFF);getchar();__asm int 0x20printf("%08X\n", TempVal);getchar();return 0; }全局頁的意義
G=1,即為全局頁,進程(CR3)切換時,TLB中的記錄不會被刷新。
在上一個實驗的基礎上修改,首先,我們在讀取NULL之前,切換一下CR3:
實驗結果證明,進程切換會刷新G=0的TLB記錄。
接下來,修改代碼,讓NULL的PTE的G=1,即,NULL的物理頁是全局頁,再看看結果有什么不同:
void __declspec(naked) R0Function() {__asm{pushadpushfd // 1.給NULL掛物理頁(修改PTE,這里概率藍屏)0x01234867(G=0) 0x01234967(G=1)mov dword ptr ds:[0xc0000000],0x01234967// 2.寫NULL指針,生成TLB記錄mov dword ptr ds:[0],0x12345678// 3.再次修改物理頁mov dword ptr ds:[0xc0000000],0x02345867// 模擬進程切換mov eax,cr3mov cr3,eax// 4.讀NULL,讀取到 0x01234867,證明G=1的物理頁不刷新TLBmov eax,dword ptr ds:[0]mov TempVal,eaxpopfdpopad iretd} }實驗結果證明G=1時,TLB不刷新。
INVLPG指令的意義
INVLPG 是特權指令,需要在R0執行,作用是清除某個線性地址在TLB中的記錄。
在上面的代碼基礎上修改:
發現讀取不到先前寫入的數據了,這是因為TLB記錄被刪除了,需要重新解析線性地址,讀取到新物理頁的值了。
總結
- 上一篇: (25)2-9-9-12分页(下)
- 下一篇: (27)TLB番外篇——ShadowWa