Q: 爲什麼使用多級頁表能省內存?
A:
首先考慮一級頁表的情況。
內存虛擬空間是0~4G
按4K一頁的方式分頁。
那麼需要總共1024 * 1024個頁表項, 即1M個頁表項
其中每個頁表項爲32位整數。
爲什麼??
想想裏面需要存放什麼???
最主要的其實就是映射的頁表基地址。
假設0x12345678的虛擬地址, 映射的物理地址是0x56789678。
那我們頁表項主要記錄的就是0x56789這個基地址!!
最後12位是頁表的偏移地址/序列號。
所以頁表項就至少需要20位的空間了...所以用32位也就好理解了...
ok, cpu尋址0x1234 5678這個虛擬地址, 首先找到 mmu頁表的基地址, 這個在cp15協處理器寄存器中保存着。(當前進程 + 內核的頁表)
由於有1024*1024 1M個32位頁表項,
所以頁表空間需要4M,
假設起始地址是0xC100 0000,
最大範圍就是, 0xC140 0000,
所以我們基地址就是0xC1.....
ok, 我們取出了mmu頁表基地址0xC1,
具體偏移呢?? 根據前20位, 即0x12345尋址。
找到頁表項位置, 0xC10 8D14 (頁表項4字節對齊, 所以最後兩位是0)
假設尋找虛擬地址 0xFFF0 FFF0這個地址, 需要找第0xFFF0 F頁表項。
0xFFF0 F * 4 = 0x3FFC3C (頁表項最後兩位爲0, 即4字節對齊, 需左移兩位, 也即乘以4)
則需要找到 0xC13F FC3C 這一頁表項。
ok, 然後裏面存放這物理地址頁的基地址, 也即0x56789, 然後組合上頁偏移地址, 就可以了。
最後尋址 0x56789678成功。
ok, 迴歸正題, 爲什麼二級頁表比一級頁表省內存?
從以上可以, 4k分頁方式, 一級頁表每一個頁表項爲4byte, 總共需要1M個頁表項。
共需要內存4M。這樣才能將0~4G的虛擬內存空間全部覆蓋到。
否則 cpu 尋址未覆蓋的 區域, 直接就尋址出錯。 (像data abort和pre-fetch abort至少是尋址ok的, 取指出錯)
比如彙編指令 ldr r0 0x12345678, 直接尋址就出錯了...這個貌似不在arm的幾種異常裏面....
ok, 一級頁表4M空間。
假設用段1M, 頁4K的方式製作二級尋址頁表。
首先爲了0~4G空間全覆蓋, 1024個段空間是不能省的。
而具體每個段對應的二級頁表是否需要??
這個就不一定了....
通常我們寫代碼編譯完 代碼段 + 數據段也就是幾百K 到幾十M的範圍。
假設我們寫了段程序, 代碼段 + 數據段 也就4M以內。
由於代碼和數據的連續性,
所以我們可能也就只需要4個段就夠了。。。
如此, 我們只需要將四個段的映射做好就可以了。
1個段對應256個頁表。
所以我們4個段也就用1024個頁表就夠了。
最終, 這個進程使用的頁表內存大小, 就爲1024 * 4 + 1024 * 4,
即4K + 4K = 8K 就夠了。
和一級頁表比較下?
是否節省了很多內存??
是的, 奧妙就在這裏^^
* 如果和我們書本寫目錄那樣.... 那麼 目錄級別越多, 寫得字肯定越多啦^^
因爲書本每級目錄都是全映射的...