思路:
进程号是一个进程在用户空间的唯一标示,所以,根据pid可以从内核中得到一个进程的所有信息,
另外就是知道虚拟地址就可以通过内核物理地址映射到虚拟地址的逆运算就可以还原他的实际物理地址
以上便是虚拟地址转换成所对应的实际物理地址的思路。
大致的代码编写流程:
首先根据pid我们可以得到这个进程的task_struct,进而通过task_struct得到mm,通过mm得到pgd。
好了,现在我们有pgd和virtualaddress.
通过pgd和virtualaddress我们可以得到页表pte.
有了pte和virtualaddress,我们就可以计算物理地址了
phyaddress=(pte_val(pte)&PAGE_MASK)|(virtualladdress&~PAGE_MASK)
代码:
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
#include <asm/page.h>
static int v2p(int pid, unsigned long va)
{
unsigned long pa = 0;
struct task_struct *pcb_tmp;
pgd_t *pgd_tmp = NULL;
pud_t *pud_tmp = NULL;
pmd_t *pmd_tmp = NULL;
pte_t *pte_tmp = NULL;
printk(KERN_INFO"PAGE_OFFSET = 0x%lx\n",PAGE_OFFSET);
printk(KERN_INFO"PGDIR_SHIFT = %d\n",PGD