有兩種類型的虛擬地址的Linux內核使用:
- 你已經在該行的「內核內存(虛擬)直接 對應的物理內存提到什麼(只是0xC000_0000將 給予補償我們的實際地址)「。這映射到連續的物理地址。
- 使用vmalloc。
第一種是使用宏完成:
include/asm-x86/page_32.h
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
_pa(x)的確實的虛擬到物理轉換。請注意,這個翻譯是在編譯時內聯的。沒有頁面表翻譯發生。這最後一句話非常重要。
另一方面,使用第二種方法,您可以分配虛擬內存中連續的內存,但物理內存中可能不會這樣。現在,在這種情況下,當您第一次訪問虛擬地址時,需要整頁表格轉換。問題是這是誰?
在CISC機器(如x86)的情況下,MMU(硬件)在TLB未命中(首次訪問虛擬地址)的情況下執行該操作並更新頁表。對於內核虛擬地址(通過vmalloc獲取),它們保留爲TLB條目。它們被稱爲全局條目,當進程上下文切換髮生時,它們大多被忽略,而不像其他進程地址空間條目那樣被刷新。但是,當您執行vfree以釋放關聯的虛擬內存時,這些條目將被刪除。
在RISC機器(如MIPS)的情況下,頁面轉換由軟件處理。 TLB未命中後,硬件引發異常。陷阱句柄以內核模式運行以執行翻譯並使用特殊指令更新TLB。從陷阱處理程序返回後,運行相同的代碼行併發生TLB命中。
請參考:http://pages.cs.wisc.edu/~remzi/OSFEP/vm-tlbs.pdf
的底線是,並非所有的內核地址映射您所描述的方式。對於你的情況,物理地址是在編譯時本身生成的。那麼,爲什麼要添加一個TLB條目。對於來自vmalloc的地址,存在TLB條目。當進程之間發生上下文切換時,不需要刷新整個TLB,並且可以保留內核的vmalloc創建的全局條目。當你使用vfree時,相應的全局條目將被刷新。
ARM是一款RISC機器,我想它的工作方式與MIPS描述的相同。但我不確定。不過,我相信您的問題可以在不考慮處理器架構的情況下得到充分回答。 – trans1st0r
看起來像[ARM does硬件頁面漫遊](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0333h/I1029222.html)。除了TLB未命中開銷較低的顯而易見的優勢之外,這允許推測TLB預取,這對於軟件TLB未命中處理來說並不可行。另外http://stackoverflow.com/questions/28019266/arm-mmu-and-arm-linux-page-table-walk。我發現的ARM文檔提到了關於禁用頁面漫遊位的一些內容,所以也許ARM可以使用軟件頁面漫遊,而不像x86。 –