Ich versuche, die Funktion Lookup-Adresse (http://lxr.free-electrons.com/source/arch/x86/mm/pageattr.c#L373) für Arm-Plattform (und nur für Kernel-Seitentabellen) zu emulieren.walkup Seitentabellen auf ARM
Der Punkt ist, ich bekomme die Adresse von swapper_pg_dir von TTBR1, und bis jetzt funktioniert das. Ich habe es mit GDB:
(gdb) file vmlinux
Reading symbols from vmlinux...done.
(gdb) p init_mm.pgd
$1 = (pgd_t *) 0xc0004000
(gdb)
und der Code von meinem Modul:
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 &= TTBR_MASK;
pgd = __va (ttb_reg);
pr_info ("get_global_pgd: %p\n", pgd);
return pgd;
}
und die Ausgabe:
bananapi kernel: [ 5665.358139] mod: get_global_pgd: c0004000
Bisher ist dies passend. Jetzt bin ich die Berechnung Adr des rechten pgd, tun:
pgd = get_global_pgd() + pgd_index (addr);
Und da (Adr >> 21) ist 0x600, ich 0xc0007000. Dann fahre ich fort mit:
pud = pud_offset (pgd, addr);
pr_info ("pud: 0x%0x - %p\n",pud_val (*pud), pud);
pmd = pmd_offset (pud, addr);
pr_info ("pmd: 0x%0x - %p\n", pmd_val (*pmd), pmd);
if (pmd == NULL || pmd_none (*pmd)) {
return NULL;
}
return pte_offset_kernel (pmd, addr);
Ausgang:
bananapi kernel: [ 5665.390391] mod: pud: 0x4001140e - c0007000
bananapi kernel: [ 5665.401603] mod: pmd: 0x4001140e - c0007000
bananapi kernel: [ 5665.423838] mod: pte: 0xe59f119c - c0011020
Das Problem ist, dass die pte ich scheint nicht in Ordnung zu sein, weil die Attribute des pte nicht übereinstimmen. Lassen Sie uns eine Adresse nehmen von/proc/kallsyms:
c0008054 t __create_page_tables
ich es mit GDB lesen:
(gdb) x/2x 0xc0008054
0xc0008054 <__create_page_tables>: 0xe2884901 0xe1a00004
(gdb)
Aber die pte ich von dieser Adresse erhalten, müssen nicht die vorliegende Flagge:
ich es mit der Überprüfung (diese pte ist diejenige, die ich von meinem lookup_address bekam):
ret = pte_present (*pte);
pr_info ("pte_present: %d\n", ret);
Das pte_present ist 0 (was das Flag L_PTE_PRESENT prüft, das include/asm/pgtable-2level.h definiert ist), aber sollte nicht 0 sein, solange ich es in GDB lesen kann.
Ich habe mit einigen anderen Adressen, zum Beispiel getestet: 0xc0035618:
c0035618 T __put_task_struct
Und für diesen einen großen der L_PTE_PRESENT gesetzt.
Ich bin mir ziemlich sicher, dass ich etwas vermisse, oder ich habe es falsch verstanden.
Vielen Dank im Voraus!
Die 'L_ *' Attribute sind Linux-spezifische, nicht unbedingt Hardware-Attribute. Es gibt bereits viele Fragen dazu, wie ARM Linux [eine zweite Gruppe von Schatten-Seitentabellen für diese unterhält] (http://lxr.free-electronics.com/source/arch/arm/include/asm/pgtable-2level). h). – Notlikethat
Ja, das weiß ich. Eigentlich denke ich, dass ARM diese Bits nicht zur Verfügung stellt, also musste Linux es umgehen, indem er diese Bits hinzufügte. Aber Linux prüft diese Bits, wenn ein Seitenfehler ausgelöst wird, also denke ich, dass sie die richtigen sind. Danke – leberus
Mögliches Duplikat von [Page table entry (PTE) -Deskriptor im Linux-Kernel für ARM] (http://stackoverflow.com/questions/16909101/page-table-entry-pte-descriptor-in-linux-kernel-for-- Arm) –