- 论坛徽章:
- 6
|
通过虚拟地址获取物理地址的代码
- #include <linux/module.h>
- #include <asm/pgtable.h>
- #include <linux/version.h>
- #include <asm/page.h>
- #include <linux/gfp.h>
- #include <linux/page-flags.h>
- #include <linux/sched.h>//find_task_by_vpid
- #include <linux/mm.h>//find_vma
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("CONVERT USER VIRTUAL ADDRESS TO PHYADDRESS");
- static int pid;
- static unsigned long va;
- module_param(pid,int,0644);
- module_param(va,ulong,0644);
- static int find_pgd_init(void)
- {
- unsigned long pa=0;
- struct task_struct *pcb_tmp=NULL;
- pgd_t *pgd_tmp=NULL;
- pud_t *pud_tmp=NULL;
- pmd_t *pmd_tmp=NULL;
- pte_t *pte_tmp=NULL;
- if(!(pcb_tmp=find_task_by_pid(pid)))
- {
- printk(KERN_ALERT "Can't find the task %d.\n",pid);
- return 0;
- }
- printk(KERN_ALERT "pgd=0x%p\n",pcb_tmp->mm->pgd);
- if(!find_vma(pcb_tmp->mm,va))
- {
- printk(KERN_ALERT "virt_addr 0x%lx not available.\n",va);
- return 0;
- }
- pgd_tmp=pgd_offset(pcb_tmp->mm,va);
- printk(KERN_ALERT "pgd_tmp=0x%p\n",pgd_tmp);
- printk(KERN_ALERT "pgd_val(*pgd_tmp)=0x%lx\n",pgd_val(*pgd_tmp));
- if(pgd_none(*pgd_tmp))
- {
- printk(KERN_ALERT "Not mapped in pgd.\n");
- return 0;
- }
- pud_tmp=pud_offset(pgd_tmp,va);
- pmd_tmp=pmd_offset(pud_tmp,va);
- /*FIXME:
- Do I need to check Large Page ? PSE bit.
- if(pmd_large(*pmd_tmp) == 1){
- pa = (pmd_val(*pmd_tmp) & PMD_MASK) | (va & ~PMD_MASK);
- }
- */
- pte_tmp=pte_offset_kernel(pmd_tmp,va);
- if(pte_none(*pte_tmp))
- {
- printk(KERN_ALERT "Not mapped in pte.\n");
- return 0;
- }
- if(!pte_present(*pte_tmp))
- {
- printk(KERN_ALERT "pte not in RAM,maybe swaped.\n");
- return 0;
- }
- pa=(pte_val(*pte_tmp)&PAGE_MASK)|(va&~PAGE_MASK);
- printk(KERN_ALERT "virt_addr 0x%lx in RAM is 0x%lx.\n",va,pa);
- printk(KERN_ALERT "content in 0x%lx is 0x%lx.\n",pa,*(unsigned long*)((char *)pa+PAGE_OFFSET));
- return 0;
- }
- static void find_pgd_exit(void)
- {
- printk(KERN_ALERT "Goodbey.\n");
- }
- module_init(find_pgd_init);
- module_exit(find_pgd_exit);
复制代码 |
|