カーネルを変更し、自分でページテーブルを歩いて、1つのプロセスのコードセクションの物理アドレスを取得しました。(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
それから私はによってiomem$ 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のメモリを搭載したInteli5Coreマシンで32ビットの12.04Ubuntuカーネルを使用しています。