寫自己的內核模塊——獲取一個進程的物理地址

首先,根據一個虛擬地址是可以得到物理地址的,這個內核模塊是可以做到的。
大概就以下這幾步:
1、得到當前進程的task_struct結構體(類似於current宏的實現)
2、得到進程的mm_struct結構體
3、搞一個虛擬地址(一個變量的地址或者一個函數的地址)
4、先得到pgd,然後根據pgd找到pud,根據pud找到pte,噹噹噹當,你得到了該變量(或者函數)所在頁面的頁表表項地址,意味着你得到了偏移量。
5、現在要做的就是根據頁表的到頁面的物理地址,和偏移量相加。done,物理地址得到。
實現代碼如下:

 int i = 1;              
//得到了一個虛擬地址
unsigned long addr = (unsigned long)(&i);
unsigned long real_addr;
unsigned long *pte_addr;
//得到個當前進程的task_struct結構體
struct task_struct *curr= get_current();        


//得到當前進程的mm_struct結構體
struct mm_struct *mm = curr->mm;
struct pgd_t  *pgd = pgd_offset(mm,addr);
if(!pgd)
{
     printk("pgd error!\n");
     return 0;
}
struct pud_t *pud = pud_offset(pgd,addr);
struct pmd_t *pmd = pmd_offset(pud,addr);
if(!pmd)
{
    printk("pmd error!\n");
    return 0;     }                                                       
//得到頁表項地址    
unsigned long pte = pte_offset(pmd,addr);           

if(!pte)
{
     printk("pte error\n");
     return 0;
}
//得到頁內偏移量(線性地址的後12位)
real_addr = addr&0x00000fff;        

pte_addr = pte;
//頁表表項內容後20位填充的是頁框起始地址
real_addr += (*pte_addr)&0x000fffff;               


printk("\t虛擬地址爲%ld\n",addr);
printk("\t物理地址爲%ld\n",real_addr);
return 0;

在運行這個代碼的時候,要導出一些內核函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章