写自己的内核模块——获取一个进程的物理地址

首先,根据一个虚拟地址是可以得到物理地址的,这个内核模块是可以做到的。
大概就以下这几步:
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;

在运行这个代码的时候,要导出一些内核函数。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值