我修改了我的内核并自己走了一下页面表来获取一个进程代码段的物理地址。我将(current->mm)->start_code
作为参数传递给了我的函数。下面列出了所述功能的代码:
unsigned long user_va_to_pa(unsigned long v) {
pgd_t *pgd = pgd_offset(current->mm, v);
printk("process id is %d\n",current->pid);
if (!pgd_none(*pgd)) {
pud_t *pud = pud_offset(pgd, v);
if (!pud_none(*pud)) {
pmd_t *pmd = pmd_offset(pud, v);
if (!pmd_none(*pmd)) {
pte_t *pte;
pte = pte_offset_map(pmd, v);
if (pte_present(*pte)){
unsigned long pa=pte_val(*pte) & PTE_PFN_MASK;
printk(KERN_ALERT "pte value is (in vatopa) %lx\n", pte_val(*pte));
pte_unmap(pte);
return pa; //return the real physical address(page aligned)
}
else {
printk(KERN_ALERT "cannot find pte\n");
}
}
else{
printk(KERN_ALERT "cannot find pmd\n");
}
}
else {
printk(KERN_ALERT "cannot find pud\n");
}
}
else {
printk(KERN_ALERT "cannot find PGD\n");
}
return 1;
}
然而,物理地址似乎经常出现在PCI内存孔中。我从一个用户应用程序调用我的函数作为系统调用。请注意,我的函数可以打印输出地址,如下所示:
pte value is (in vatopa) efe2d025
然后我按$ cat /proc/iomem
打开 iomem 。
我可以看到(显示部分):
20000000-201fffff : reserved
20200000-40003fff : System RAM
40004000-40004fff : reserved
40005000-ced2ffff : System RAM
ced30000-dae9efff : reserved
dae9f000-daf9efff : ACPI Non-volatile Storage
daf9f000-daffefff : ACPI Tables
dafff000-df9fffff : reserved
dfa00000-febfffff : PCI Bus 0000:00
e0000000-efffffff : 0000:00:02.0
f0000000-f03fffff : 0000:00:02.0
f0400000-f0bfffff : PCI Bus 0000:02
f0c00000-f13fffff : PCI Bus 0000:04
f1400000-f1bfffff : PCI Bus 0000:04
f1c00000-f1cfffff : PCI Bus 0000:03
f1c00000-f1c01fff : 0000:03:00.0
您可以看到地址efxxxxxx
完全在PCI内存孔中。但是,它应该驻留在系统RAM中,对吧?
这使我无法为该页面保留页面属性,因为它位于具有另一个属性的内存孔中。这很奇怪。
至于我的系统,我在具有8GB内存的Intel i5 Core机器上使用32位12.04 Ubuntu内核。