現在、私は研究関連のプログラムをいくつか開発しており、特定のアドレスのpte
が必要です。私の開発環境はJuno r1ボード(CPUはA53とA57)であり、arm64 Linuxカーネルを実行しています。Arm64 Linuxページテーブルウォーク
:
int find_physical_pte(void *addr)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pte_t *ptep;
unsigned long long address;
address = (unsigned long long)addr;
pgd = pgd_offset(current->mm, address);
printk(KERN_INFO "\npgd is: %p\n", (void *)pgd);
printk(KERN_INFO "pgd value: %llx\n", *pgd);
if (pgd_none(*pgd) || pgd_bad(*pgd))
return -1;
pud = pud_offset(pgd, address);
printk(KERN_INFO "\npud is: %p\n", (void *)pud);
printk(KERN_INFO "pud value: %llx\n", (*pud).pgd);
if (pud_none(*pud) || pud_bad(*pud))
return -2;
pmd = pmd_offset(pud, address);
printk(KERN_INFO "\npmd is: %p\n", (void *)pmd);
printk(KERN_INFO "pmd value: %llx\n",*pmd);
if (pmd_none(*pmd) || pmd_bad(*pmd))
return -3;
ptep = pte_offset_kernel(pmd, address);
printk(KERN_INFO "\npte is: %p\n", (void *)ptep);
printk(KERN_INFO "pte value: %llx\n",*ptep);
if (!ptep)
return -4;
return 1;
}
をプログラムがアドレス(0xffffffc0008b2000)のためpte
をチェックするときしかし、それは常に空pmd
を返します。
私の推測では、最初の手順で間違ったpgd
があるということです。私はTims Notesがcurrent->mm
を使用しているとpgd of TTBR0
(ユーザスペースpgd
)しか得られないと言いましたが、確認したアドレスはカーネルスペースアドレスですので、pgd of TTBR1
を取得してください。
私の質問は:カーネルスペースアドレスのpte
を取得したい場合は、pgd
を取得するのにcurrent->mm
を使用できますか?
私ができない場合は、代わりにやりたいことがありますか?
ご提案は大歓迎です!ありがとうございました。
サイモン
'TTBCR'を使用し、ターゲットアドレスに基づいて' TTBR0'または 'TTBR1'のいずれかを返すルーチンを記述してください。これは 'current-> mm'より優れていますが、Linuxの亜種とは違って物理的なARM PTE値を扱っています。 TTBR1は、カーネル空間(新しいLinuxバージョン〜3.xx +)で使用され、ユーザスペースのコンテキストスイッチ上で変更されることはありません。注意:Linux armv8は、TTBR0にEL0を使用し、TTBR1にEL1を使用します。 CP15のクエリ 'unsigned int pa;もあります。 \ t mrc p15、0、%0、c7、c4、0 \ n ":\ t" \ t mcr p15、0、%0、c7、c8、2 \ n " " \ t isb \ n " " "= r"(pa): "0"(0xffff0000)); '物理アドレスの場合。 –