Hi all,
for learning purposes, I wanted to emulate "lookup_address" function for ARM platforms, but I'm having some troubles which I don't know how to get over them.Cannot access memory at address 0xc0004000
(gdb) p init_mm.pgd
$5 = (pgd_t *) 0xc0004000
(gdb)
And from my code:
static pgd_t *get_global_pgd (void)
{
pgd_t *pgd;
unsigned int ttb_reg;
asm volatile (
" mrc p15, 0, %0, c2, c0, 1"
: "=r" (ttb_reg));
ttb_reg &= ~0x3fff;
pgd = phys_to_virt (ttb_reg);
return pgd;
}
and the output:
kernel: [18604.342604] mod: get_global_pgd: 0x0 - c0004000
So far, it's ok, but now the fun begins.
I'm walking the page table to get the PTE related to an X address:
static pte_t *lookup_address (unsigned long addr)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
pgd = get_global_pgd() + pgd_index (addr);
pud = pud_offset (pgd, addr);
pmd = pmd_offset (pud, addr);
if (pmd == NULL || pmd_none (*pmd)) {
pr_info ("%s: pmd == NULL\n", r2_devname);
return NULL;
}
return pte_offset_kernel (pmd, addr);
}
After that, I'd to check if the PTE has the PRESENT flag. Since ARM processor doesn't provide those flags Linux had to workaround that by adding
these flags: (f.i: http://lxr.free-electrons.com/source/arch/arm/include/asm/pgtable-2level.h#L123 )
I'm checking the flags with
pte_present
or
pte_write
But I think I'm getting the wrong PTE's because I've tried with some address from /proc/kallsyms, and it's saying that the page is not present, and I'm getting diferent values for different pages
in the same range.
For instance:
for: 0xc0009244:
bananapi kernel: [18604.419142] mod: pte_present: 0
bananapi kernel: [18604.428025] mod: pte_write: 0
bananapi kernel: [18604.436592] mod: pte_young: 2
bananapi kernel: [18604.445318] mod: pte_dirty: 0
and for 0xc0012904:
bananapi kernel: [18883.095749] r2k: pte_present: 0
bananapi kernel: [18883.104607] r2k: pte_write: 1
bananapi kernel: [18883.113159] r2k: pte_young: 0
bananapi kernel: [18883.121670] r2k: pte_dirty: 0
It's saying that is not present, but I can read from those addresses with gdb:
(gdb) x/2x 0xc0009244
0xc0009244 <vfp_flush_hwstate>: 0xe92d4010 0xe1a04000
(gdb) x/2x 0xc0012904
0xc0012904 <__readwrite_bug>: 0xe1a01000 0xe30505ec
(gdb)
What am I doing wrong?
Thanks in advance
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies