我修改了我的内核并自己遍历页表以获取一个进程代码段的物理地址。我(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
.
我可以看到(显示部分):
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 内核。