1. 程式人生 > >虛擬地址轉換為物理地址【轉】

虛擬地址轉換為物理地址【轉】

linux 目錄項 https 兼容 應用程序 數據結構 lan current get

轉自:https://blog.csdn.net/shuningzhang/article/details/38090621

應用程序只能提供一個虛擬地址,也可以通過如下方法獲取物理地址,當然得調用驅動。

Linux采用頁表的概念來管理虛擬空間,內核在處理虛擬地址時都必須將其轉換為物理地址,然後處理器才能夠訪問。虛擬地址可以通過Linux的頁表操作宏逐層查找到物理地址,簡單來說需要將虛擬地址分段,每段地址都作為索引指向頁表,最後一級頁表指向物理地址。
Linux在2.6.11以後版本為了兼容各種處理器,采用四級頁表結構:
? PGD:Page Global Directory,頁全局目錄,是頂級頁表。
? PUD:Page Upper Directory,頁上級目錄,是第二級頁表

? PMD:Page Middle Derectory,頁中間目錄,是第三級頁表。
? PTE:Page Table Entry,頁面表,最後一級頁表,指向物理頁面。
可以通過數據結構mm_struct訪問PGD找到物理頁面,如圖4-8,根據頁表尋找物理地址的流程見4-9。

圖 Linux采用的4級頁面


簡化的轉換代碼如下:
static int vir2phy(unsigned long va)
{
struct task_struct *pcb_tmp;
pcb_tmp = current;
pgd_tmp = pgd_offset(pcb_tmp->mm,va);
pud_tmp = pud_offset(pgd_tmp,va);
pmd_tmp = pmd_offset(pud_tmp,va);
pte_tmp = pte_offset_kernel(pmd_tmp,va);
pa = (pte_val(*pte_tmp) & PAGE_MASK) |(va & ~PAGE_MASK);
return pa;
}

pgd_offset(mm, addr) 接收內存描述符地址mm和線性地址addr作為參數。這個宏產生地址addr在頁全局目錄中相應表項的線性地址;
通過內存描述符mm內的一個指針可以找到這個頁全局目錄。

pud_offset(pgd, addr) 參數為指向頁全局目錄項的指針pgd和線性地址addr。這個宏產生頁上級目錄中目錄項addr對應的線性地址。在兩級或三級分頁系統中,該宏產生pgd,即一個頁全局目錄項的地址。

pmd_offset(pud, addr) 接收指向頁上級目錄項的指針pud和線性地址addr作為參數。這個宏產生目錄項addr在頁中間目錄中的偏移地址。在兩級或三級分頁系統中,它產生pud,即頁全局目錄項的地址。

pte_offset_kernel(dir, addr) 線性地址addr在頁中間目錄dir中有一個對應的項,該宏就產生這個對應項,即頁表的線性地址。另外,該宏只在主內核頁表上使用。

虛擬地址轉換為物理地址【轉】