用戶虛擬地址轉化成物理地址,物理地址轉換成內核虛擬地址,內核虛擬地址轉換成物理地址,虛擬地址和對應頁的關系

文章目錄

  • 1. 用戶虛擬地址轉換成物理地址
  • 2. 內核虛擬地址轉換成物理地址
  • 3. 物理地址轉換成內核虛擬地址
  • 4 內核虛擬地址和對應頁
  • 5 根據進程號獲取進程描述符

1. 用戶虛擬地址轉換成物理地址

static void get_pgtable_macro(void)
{printk("PAGE_OFFSET = 0x%lx\n", PAGE_OFFSET);printk("PGDIR_SHIFT = %d\n", PGDIR_SHIFT);printk("PUD_SHIFT = %d\n", PUD_SHIFT);printk("PMD_SHIFT = %d\n", PMD_SHIFT);printk("PAGE_SHIFT = %d\n", PAGE_SHIFT);printk("PTRS_PER_PGD = %d\n", PTRS_PER_PGD);printk("PTRS_PER_PUD = %d\n", PTRS_PER_PUD);printk("PTRS_PER_PMD = %d\n", PTRS_PER_PMD);printk("PTRS_PER_PTE = %d\n", PTRS_PER_PTE);printk("PAGE_MASK = 0x%lx\n", PAGE_MASK);
}
static unsigned long vaddr2paddr(unsigned long vaddr)
{pgd_t *pgd;pud_t *pud;pmd_t *pmd;pte_t *pte;unsigned long paddr = 0;unsigned long page_addr = 0;unsigned long page_offset = 0;pgd = pgd_offset(current->mm, vaddr);printk("pgd_val = 0x%lx\n", pgd_val(*pgd));printk("pgd_index = %lu\n", pgd_index(vaddr));if (pgd_none(*pgd)) {printk("not mapped in pgd\n");return -1;}pud = pud_offset(pgd, vaddr);printk("pud_val = 0x%lx\n", pud_val(*pud));if (pud_none(*pud)) {printk("not mapped in pud\n");return -1;}pmd = pmd_offset(pud, vaddr);printk("pmd_val = 0x%lx\n", pmd_val(*pmd));printk("pmd_index = %lu\n", pmd_index(vaddr));if (pmd_none(*pmd)) {printk("not mapped in pmd\n");return -1;}pte = pte_offset_kernel(pmd, vaddr);printk("pte_val = 0x%lx\n", pte_val(*pte));printk("pte_index = %lu\n", pte_index(vaddr));if (pte_none(*pte)) {printk("not mapped in pte\n");return -1;}//頁框物理地址機制 | 偏移量page_addr = pte_val(*pte) & PAGE_MASK;page_offset = vaddr & ~PAGE_MASK;paddr = page_addr | page_offset;printk("page_addr = %lx, page_offset = %lx\n", page_addr, page_offset);printk("vaddr = %lx, paddr = %lx\n", vaddr, paddr);return paddr;
}
static int __init v2p_init(void)
{unsigned long vaddr = 0;printk("vaddr to paddr module is running..\n");get_pgtable_macro();printk("\n");vaddr = (unsigned long)vmalloc(1000 * sizeof(char));if (vaddr == 0) {printk("vmalloc failed..\n");return 0;}printk("vmalloc_vaddr=0x%lx\n", vaddr);vaddr2paddr(vaddr);printk("\n\n");vaddr = __get_free_page(GFP_KERNEL);if (vaddr == 0) {printk("__get_free_page failed..\n");return 0;}printk("get_page_vaddr=0x%lx\n", vaddr);vaddr2paddr(vaddr);return 0;
}
static void __exit v2p_exit(void)
{printk("vaddr to paddr module is leaving..\n");vfree((void *)vaddr);free_page(vaddr);
}

整個程序的結構如下:

get_pgtable_macro()打印當前系統分頁機制中的一些宏。

通過vmalloc()在內核空間中分配內存,調用vaddr2paddr()將虛擬地址轉化成物理地址。

通過__get_free_pages()在內核空間中分配頁框,調用vaddr2paddr()將虛擬地址轉化成物理地址。

分別通過vfree()和free_page()釋放申請的內存空間。

vaddr2paddr()的執行過程如下:

  1. 通過pgd_offset計算頁全局目錄項的線性地址pgd,傳入的參數為內存描述符mm和線性地址vaddr。接著打印pgd所指的頁全局目錄項。

  2. 通過pud_offset計算頁上級目錄項的線性地址pud,傳入的參數為頁全局目錄項的線性地址pgd和線性地址vaddr。接著打印pud所指的頁上級目錄項。

  3. 通過pmd_offset計算頁中間目錄項的線性地址pmd,傳入的參數為頁上級目錄項的線性地址pud和線性地址vaddr。接著打印pmd所指的頁中間目錄項。

  4. 通過pte_offset_kernel計算頁表項的線性地址pte,傳入的參數為頁中間目錄項的線性地址pmd和線性地址vaddr。接著打印pte所指的頁表項。

  5. pte_val(*pte)先取出頁表項,與PAGE_MASK相與的結果是得到要訪問頁的物理地址;vaddr&~PAGE_MASK用來得到線性地址offset字段;兩者或運算得到最終的物理地址。

2. 內核虛擬地址轉換成物理地址

__pa():將物理內核虛擬地址轉換成物理虛擬地址

#include <asm/page.h>
#define __pa(x)		__phys_addr((unsigned long)(x))

3. 物理地址轉換成內核虛擬地址

__va()將物理地址轉換成內核虛擬地址:

#include <asm/page.h>
#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))

4 內核虛擬地址和對應頁

struct page *virt_to_page(void *kaddr); 
//將內核邏輯地址轉換為響應的page結構指針。
struct page *pfn_to_page(int pfn);
//針對給定的頁幀號,返回page結構指針。
void *page_address(struct page *page); 
//如果地址存在的話,則返回頁的內核虛擬地址

5 根據進程號獲取進程描述符

struct task_struct * task = pid_task(find_vpid(target_pid), PIDTYPE_PID);

find_vpid:此函數根據提供的局部進程號獲取對應的進程描述符

struct pid *find_vpid(int nr)

pid_task:此函數獲取任務的任務描述符信息,此任務在進程pid的使用鏈表中,并且搜索的鏈表的起始元素的下標為參數type的值。

struct task_struct *pid_task(struct pid *pid, enum pid_type)enum pid_type
{PIDTYPE_PID,     //進程的進程號PIDTYPE_PGID,    //進程組領頭進程的進程號PIDTYPE_SID,     //會話領頭進程的進程號PIDTYPE_MAX
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/379488.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/379488.shtml
英文地址,請注明出處:http://en.pswp.cn/news/379488.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單三層架構(登錄)

1&#xff0c;首先導包 dao //獲取數據String username request.getParameter("username");String password request.getParameter("password");//傳遞到Service層UserService service new UserService();//這里的UserService 需要創建到service包下Use…

通過隱藏option實現select的聯動效果

開始的時候需求是根據一定條件隱藏一部分<option>標簽&#xff0c;類似聯動效果&#xff0c;但是目前的html規范并沒有為<option>提供隱藏的效果&#xff0c;因此常用的設置display或者visibility無效。網上大部分解決方案是刪除<option>節點或<option>…

Java SimpleTimeZone setEndRule()方法與示例

SimpleTimeZone類setEndRule()方法 (SimpleTimeZone Class setEndRule() method) Syntax: 句法&#xff1a; public void setEndRule(int en_mm, int en_dd, int en_time);public void setEndRule(int en_mm, int en_dd, int en_dow, int en_time);public void setEndRule(int…

Linux設備驅動開發--- DMA

文章目錄1 設置DMA映射緩存一致性和DMADMA映射一致映射流式DMA映射2 完成的概念3 DMA引擎API分配DMA從通道設置從設備和控制器指定參數獲取事務描述符提交事務發布待處理DMA請求并等待回調通知4 程序單緩沖區映射分散聚集映射DMA是計算機系統的一項功能&#xff0c;它允許設備在…

類加載器

一、類加載器 1&#xff0c;什么是類加載器&#xff1f; 類加載器就是用來加載字節碼文件 2&#xff0c;類加載器的種類有哪些&#xff1f; 1&#xff09;BootStrap&#xff1a;引導類加載器&#xff1a;加載都是最基礎的文件 2&#xff09;ExtClassLoader&#xff1a;擴展類加…

一個用java讀取XML文件的簡單方法(轉)

XML文件 book.xml <book> <person> <first>Kiran</first> <last>Pai</last> <age>22</age> </person> <person> <first>Bill</first> <last>Gates</last> <age>46</age&g…

Java ObjectStreamField getName()方法與示例

ObjectStreamField類的getName()方法 (ObjectStreamField Class getName() method) getName() method is available in java.io package. getName()方法在java.io包中可用。 getName() method is used to get the name of this ObjectStreamField field. getName()方法用于獲取…

【css】CSS中折疊margin的問題

為什么要翻譯這篇說明&#xff1f;css2本有人已翻譯過&#xff0c;但看一下&#xff0c;很粗糙&#xff08;不是說自己就怎么怎么樣啊&#xff0c;翻譯者真的是很值得敬佩的&#xff01;&#xff09;&#xff0c;近來跟css與xhtml接觸得越來越多&#xff0c;但接觸得越多&#…

算法---鏈表

文章目錄反轉鏈表合并兩個有序鏈表刪除重復元素反轉鏈表 反轉鏈表包括兩種&#xff0c;反轉全部元素或者反轉部分元素。在這里&#xff0c;我們約定&#xff1a;數據元素類型是struct LinkNode&#xff0c;要反轉鏈表的第一個節點是head&#xff0c;head的前面一個節點是pre&a…

SSM

二、環境設置&#xff08;MyEclipse&#xff09; 1&#xff0c;字體設置 window–>Preference->General->Appearance->Colors and Fonts->Basic Text->Font 2&#xff0c;workspace字符集設置 window–>Preference->General->Appearance->W…

IOS NSArray,NSDictionary

小結&#xff1a; NSArray有序的集合&#xff1b; NSDictionary無序的集合&#xff0c;可排序&#xff1b; 增刪改查 ------NSArray----------- create : 1)NSArray *array [NSArray arrayWithObjects:"Henry","Jones", "Susan", "Smith&q…

Java PropertyPermission equals()方法與示例

PropertyPermission類equals()方法 (PropertyPermission Class equals() method) equals() method is available in java.util package. equals()方法在java.util包中可用。 equals() method is used to check whether this object and the given object (ob) are equal or not…

c#配合oracle快速導入excel方法--原創(6萬條記錄5分鐘左右)

原理&#xff1a;用c#采用讀取Excel數據源方式將數據讀入c#的datatable,循環datatable,將datatable中的數據用stringbuilder拼成insert into (字段名) valus (值);每5條插入一個符號&#xff08;作用是將sql字符串限制在4000字符以內&#xff09;&#xff0c;然后將拼成的字符串…

English最俗語法大全

一、先分析兩個長難句 1,It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. 人們公認這樣一個事實&#xff0c;一個有錢的單身男人一定想要娶一個妻子。 in want of want 想要 university widely 廣泛的…

tfs 內網和外網切換的方法。

C:\Windows\System32\drivers\etc的hosts文件配置一個123.67.128.109 geo-dept-3轉載于:https://www.cnblogs.com/lwflt/archive/2012/07/23/2604731.html

observable_Java Observable countObservers()方法與示例

observable可觀察的類countObservers()方法 (Observable Class countObservers() method) countObservers() method is available in java.util package. countObservers()方法在java.util包中可用。 countObservers() method is used to count the number of observers exists…

設計模式--Strategy 策略模式

所謂策略模式(Strategy Pattern)&#xff0c;就是將策略 (算法) 封裝為一個對象&#xff0c;易于相互替換&#xff0c;如同 USB 設備一樣可即插即用&#xff1b;如果將策略、具體的算法和行為&#xff0c;編碼在某個類或客戶程序內部&#xff0c;將導至事后的修改和擴展不易。 …

HDU-1518 Square dfs+剪枝

該題問給定的棍子能否組成一個正方形。首先我們要判定是否總長度是4的倍數&#xff0c;然后再決定是否存在某條邊大于組合邊長。 搜索的過程中也是可以進行剪枝了。 首先將邊排序&#xff0c;我們可以假定所有的組合邊由大小遞減的邊組成&#xff0c;那么我們在搜索的時候就不用…

英語思維黃金法則

一、謂語單一原則 英文的句子當中&#xff0c;有且只有一套謂語結構。 要想使用多個謂語&#xff0c;有以下三種方法&#xff1a; 1&#xff0c;利用連詞將不同謂語并列起來 2&#xff0c;把其中的一些動詞給降級&#xff08;v-ing v-ed 非謂語動詞&#xff09; 3&#xff0c;…

java getname_Java文件類字符串getName()方法(帶示例)

java getname文件類字符串getName() (File Class String getName()) This method is available in package java.io.File.getName(). 軟件包java.io.File.getName()中提供了此方法。 This method is used to retrieve or return the filename or directory name and represente…