使用者態程序的虛擬位址如何轉換成實體地址

2021-06-18 17:14:24 字數 1757 閱讀 1396

使用者態程序的虛擬位址如何轉換成實體地址?

區分乙個程序,我們都知道最簡單就是程序的pid。我們就從(pid,virtualaddress)來看看如何將乙個程序的虛擬位址轉換為實體地址phyaddress。

首先根據pid我們可以得到這個程序的task_struct,進而通過task_struct得到mm,通過mm得到pgd。

好了,現在我們有pgd和virtualaddress.

通過pgd和virtualaddress我們可以得到頁表pte.

有了pte和virtualaddress,我們就可以計算實體地址了

phyaddress=(pte_val(pte)&page_mask)|(virtualladdress&~page_mask)

實體地址既然出來了,訪問這個位址的值就比較簡單了,只需要將實體地址轉換為核心線性位址就行。

*phyaddress=*((char *)phyaddress+page_offset)

uma和numa:

uma(uniform memory access),即一致性記憶體訪問。這種情況下,cpu訪問記憶體的任何位置,代價都是一樣的。

numa)(non uniform memory access),即非一致性記憶體訪問。這種情況下,cpu訪問不同位置的記憶體,代價是不一樣的。在多cpu情況下,對每個cpu來說有本地記憶體和遠端記憶體,訪問本地記憶體的代價比訪問遠端記憶體的代價小。確保cpu訪問記憶體代價最小,是非常重要的一點。

linux支援多種硬體體系結構,因此linux必須採用通用的方法來描述記憶體,以方便對記憶體進行管理。為此,linux有了記憶體節點、記憶體區、頁框的概念,這些概念也是一目了然的。

記憶體節點:主要依據cpu訪問代價的不同而劃分。多cpu下環境下,本地記憶體和遠端記憶體就是不同的節點。即使在單cpu環境下,訪問所有記憶體的代價都是一樣的,linux核心依然存在記憶體節點的概念,只不過只有乙個記憶體節點而已。核心以struct  pg_data_t來描述記憶體分割槽。

記憶體分割槽:linux對記憶體節點再進行劃分,分為不同的分割槽。核心以struct zone來描述記憶體分割槽。通常乙個節點分為dma、normal和high memory記憶體區,具體下面再介紹。

頁框:linux採用頁式記憶體管理,頁是物理記憶體管理的基本單位,每個記憶體分割槽又由大量的頁框組成。核心以struct page來描述頁框。頁框有很多屬性,這些屬性描述了這個頁框的狀態、用途等,例如是否被分配。

上圖中的zone_mem_map是乙個頁框的陣列,它記錄了乙個記憶體分割槽的所有頁框的使用情況。

dma記憶體區:即直接記憶體訪問分割槽,通常為物理記憶體的起始16m。主要是供一些外設使用,外設和記憶體直接訪問資料訪問,而無需系統cpu的參與。

normal記憶體區:從16m到896m記憶體區。

highmemory記憶體區:896m以後的記憶體區。

為什麼高階記憶體的邊界是896m?這是因為,32位linux虛擬記憶體空間為0-4g,其中0-3g用於使用者態,3g-4g用於核心態。這意味著核心只有1g的虛擬位址空間,如果物理記憶體超過1g,核心就無法映**。linux採取的策略是,核心位址空間的前896m採用固定對映,對映方法是:虛擬位址-3g = 實體地址,只能對映到實體地址的前896m。也就是說核心虛擬位址空間的3g到3g+896m這部分,頁表的對映是固定的,系統初始化時就建立起來。而虛擬位址空間的最後128m,也就是3g+896m到4g部分採用動態對映,也就是說頁表對映的實體地址可變的。在系統執行過程中,通過更新頁表,就可以對映到不同的實體地址,當然也包括高階物理記憶體。

使用者態程序的虛擬位址轉換到實體地址

看linux記憶體機制好幾遍了,總算是對記憶體機制有了基本的認識。下面就說乙個我剛看記憶體是的乙個問題 使用者態程序的虛擬位址如何轉換成實體地址?區分乙個程序,我們都知道最簡單就是程序的pid。我們就從 pid,virtualaddress 來看看如何將乙個程序的虛擬位址轉換為實體地址phyaddr...

程序的虛擬位址空間

linux程序虛擬位址空間是linux記憶體管理的乙個重要部分。總的虛擬位址空間通常按3 1的比例劃分,其中1g分給核心,3g分給使用者。由低位址到高位址分別為 唯讀段 該部分空間 只能讀,不可寫 包括 段 rodata 段 c常量字串和 define定義的常量 資料段 儲存全域性變數 靜態變數 的...

程序的虛擬位址空間劃分

虛擬位址 virtual address cpu啟動保護模式後,程式執行在虛擬位址空間中。注意,並不是所有的 程式 都是執行在虛擬位址中。cpu在啟動的時候是執行在實模式的,bootloader以及核心在初始化頁表之前並不使用虛擬位址,而是直接使用實體地址的。每乙個程序被給予它的非常私有的虛擬位址空...