Hallo,
beim Initialisieren der Pagingstrukturen gibt es ein Problem. Der Eintrag in die PML4 Table wird zwar richtig geschrieben, aber dann, wenn setPDP aufgerufen wird, ist die PML4 wieder auf null zurückgesetzt und ich weis nicht wieso.
Die Funktionen (paging.c):
void setPML4Entry(uint8_t i, uint8_t Present, uint8_t RW, uint8_t US, uint8_t PWT,
uint8_t PCD, uint8_t A, uint16_t AVL, uint8_t NX, uint64_t Address)
{
PML4.PML4E[i] = 0;
PML4.PML4E[i] = (Present & 1);
PML4.PML4E[i] |= (RW & 1) << 1;
PML4.PML4E[i] |= (US & 1) << 2;
PML4.PML4E[i] |= (PWT & 1) << 3;
PML4.PML4E[i] |= (PCD & 1) << 4;
PML4.PML4E[i] |= (A & 1) << 5;
PML4.PML4E[i] |= (AVL & 0x7LL) << 9;
PML4.PML4E[i] |= (Address & 0xFFFFFFFFFFLL) << 12;
PML4.PML4E[i] |= ((AVL >> 3) & 0x7FFLL) <<52;
PML4.PML4E[i] |= (NX & 1LL) << 63;
}
void setPDPEntry(uint8_t i, PDP_t *PDP, uint8_t Present, uint8_t RW, uint8_t US, uint8_t PWT,
uint8_t PCD, uint8_t A, uint16_t AVL, uint8_t NX, uint64_t Address)
{
PDP->PDPE[i] = 0;
PDP->PDPE[i] = (Present & 1);
PDP->PDPE[i] |= (RW & 1) << 1;
PDP->PDPE[i] |= (US & 1) << 2;
PDP->PDPE[i] |= (PWT & 1) << 3;
PDP->PDPE[i] |= (PCD & 1) << 4;
PDP->PDPE[i] |= (A & 1) << 5;
PDP->PDPE[i] |= (AVL & 0x7LL) << 9;
PDP->PDPE[i] |= (Address & 0xFFFFFFFFFFLL) << 12;
PDP->PDPE[i] |= ((AVL >> 3) & 0x7FFLL) <<52;
PDP->PDPE[i] |= (NX & 1LL) << 63;
}
void setPDEntry(uint8_t i, PD_t *PD, uint8_t Present, uint8_t RW, uint8_t US, uint8_t PWT,
uint8_t PCD, uint8_t A, uint16_t AVL, uint8_t NX, uint64_t Address)
{
PD->PDE[i] = 0;
PD->PDE[i] = (Present & 1);
PD->PDE[i] |= (RW & 1) << 1;
PD->PDE[i] |= (US & 1) << 2;
PD->PDE[i] |= (PWT & 1) << 3;
PD->PDE[i] |= (PCD & 1) << 4;
PD->PDE[i] |= (A & 1) << 5;
PD->PDE[i] |= (AVL & 0x7LL) << 9;
PD->PDE[i] |= (Address & 0xFFFFFFFFFFLL) << 12;
PD->PDE[i] |= ((AVL >> 3) & 0x7FFLL) <<52;
PD->PDE[i] |= (NX & 1LL) << 63;
}
void setPTEntry(uint8_t i, PT_t *PT, uint8_t Present, uint8_t RW, uint8_t US, uint8_t PWT,
uint8_t PCD, uint8_t A, uint8_t D, uint8_t G, uint16_t AVL,
uint8_t PAT, uint8_t NX, uint64_t Address)
{
PT->PTE[i] = 0;
PT->PTE[i] = (Present & 1);
PT->PTE[i] |= (RW & 1) << 1;
PT->PTE[i] |= (US & 1) << 2;
PT->PTE[i] |= (PWT & 1) << 3;
PT->PTE[i] |= (PCD & 1) << 4;
PT->PTE[i] |= (A & 1) << 5;
PT->PTE[i] |= (D & 1) << 6;
PT->PTE[i] |= (PAT & 1) << 7;
PT->PTE[i] |= (G & 1LL) << 8;
PT->PTE[i] |= (AVL & 0x7LL) << 9;
PT->PTE[i] |= (Address & 0xFFFFFFFFFFLL) << 12;
PT->PTE[i] |= ((AVL >> 3) & 0x7FFLL) << 52;
PT->PTE[i] |= (NX & 1LL) << 63;
}
Die Definitionen (paging.h):
#define MAP 3 //Anzahl der zu mappenden MBs. Mehrfaches von 2MB, d.h. 3*2MB werden gemappt; Max 1GB
#define PAGE_ENTRIES 512
static struct{
uint64_t PML4E[PAGE_ENTRIES];
}PML4;
typedef struct{
uint64_t PDPE[PAGE_ENTRIES];
}PDP_t;
typedef struct{
uint64_t PDE[PAGE_ENTRIES];
}PD_t;
typedef struct{
uint64_t PTE[PAGE_ENTRIES];
}PT_t;
Und hier die Intialisierung (im Hauptprogramm):
static PDP_t PDP;
static PD_t PD;
static PT_t PT[MAP];
//Erste 6MB mappen
setPML4Entry(0, 1, 1, 0, 1, 0, 0, 0, 0, (uint64_t)&PDP);
for(i = 1; i < PAGE_ENTRIES; i++)
setPML4Entry(i, 0, 0, 0, 0, 0, 0, 0, 0, 0);
setPDPEntry(0, &PDP, 1, 1, 0, 1, 0, 0, 0, 0, (uint64_t)&PD);
for(i = 1; i < PAGE_ENTRIES; i++)
setPDPEntry(i, &PDP, 0, 0, 0, 0, 0, 0, 0, 0, 0);
for(i = 0; i < MAP; i++)
setPDEntry(i, &PD, 1, 1, 0, 1, 0, 0, 0, 0, (uint64_t)&PT[i]);
for(i = MAP; i < PAGE_ENTRIES; i++) //Rest mit nullen auffüllen
setPDEntry(i, &PD, 0, 0, 0, 0, 0, 0, 0, 0, 0);
register int j;
for(i = 0; i < MAP; i++)
for(j = 0; j < PAGE_ENTRIES; j++)
setPTEntry(j, &PT[i], 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, (j * 4096) + (i * 512 * 4096));
asm(
"mov %0,%%eax;"
"mov %%eax,%%cr3;"
: : "r" (&PML4)
);
Ich hoffe ihr könnt mir helfen.