Paging
Posted: Sun May 09, 2021 3:37 am
Hi, I try to enable paging but it doesn't work. When I enable it system just stops. It doesn't even print info about what interrupt caused the system to stop although it should.
My kernel is loaded at 0x400000 so when initializing paging I'm identity mapping two first page Directories (8MiB).
That's the code I try to enable paging with. paging_init() is called:
I don't know what's the problem can you help me with that?
Also, I try to compile this function but it gives an error. Do you know what's the problem with this assembly?
My kernel is loaded at 0x400000 so when initializing paging I'm identity mapping two first page Directories (8MiB).
That's the code I try to enable paging with. paging_init() is called:
Code: Select all
typedef uint32_t PTE; // Page Table Entry
typedef uint32_t PDE; // Page Directory Entry
// page table
struct pTable
{
PTE entries[1024];
} __attribute__((packed)); // make sure it's not alligned by compiler
typedef struct pTable pTable;
// page directory
struct pDirectoryTable
{
PDE entries[1024];
} __attribute__((packed)); // make sure it's not alligned by compiler
typedef struct pDirectoryTable pDirectoryTable;
// ...
static void paging_set_pDirectoryTable( pDirectoryTable *dir )
{
Paging.currPDirectoryTable = dir;
__asm("mov %0, %%cr3" : : "r" (dir));
}
static void enable_paging()
{
uint32_t cr0;
__asm("mov %%cr0, %0" : "=r" (cr0));
cr0 |= 0x80000001;
__asm("mov %0, %%cr0" : : "r" (cr0));
/*__asm("mov %%cr0, %%eax" : : : "%eax");
__asm("or $0x80000000, %%eax" : : : "%eax");
__asm("mov %%eax, %%cr0");*/
}
//_________________________________________________________________________________________
void paging_init()
{
// 0-4 MiB (identity mapped)
pTable *table1 = (pTable *)memory_alloc_block();
if (!table1)
{
terminal_print(debugTerminal, "paging.c, paging_initialize(): initialization failed no space for Paging Table 1");
return;
}
memsetk(table1, (uint8_t)0x00, sizeof(pTable));
// 4 MiB - 8MiB (identity mapped)
pTable *table2 = (pTable *)memory_alloc_block();
if (!table2)
{
terminal_print(debugTerminal, "paging.c, paging_initialize(): initialization failed no space for Paging Table 2");
return;
}
memsetk(table2, (uint8_t)0x00, sizeof(pTable));
//! 1st 4mb are idenitity mapped
for (int i=0, frame=0x0; i<1024; i++, frame+=4096)
{
// create a new page
PTE page = 0;
PTE_set_adress(&page, frame);
PTE_set_present_flag(&page, true); // present
PTE_set_rw_flag(&page, true); // writable
PTE_set_usm_flag(&page, false); // supervisor mode
// ...and add it to the page table
table1->entries[i] = page;
}
for (int i=0, frame=0x400000; i<1024; i++, frame+=4096)
{
// create a new page
PTE page = 0;
PTE_set_adress (&page, frame);
PTE_set_present_flag(&page, true); // present
PTE_set_rw_flag(&page, true); // writable
PTE_set_usm_flag(&page, false); // supervisor mode
// ...and add it to the page table
table2->entries[i] = page;
}
// create default directory table
pDirectoryTable *dir = (pDirectoryTable *) memory_alloc_block(); // memory_alloc_block() returns 4096 alligned pointer
if (!dir)
{
terminal_print(debugTerminal, "paging.c, paging_initialize(): initialization failed no space for Paging Directory Table");
return;
}
memsetk(dir, 0, sizeof (pDirectoryTable));
PDE *entry = &dir->entries[0];
PDE_set_adress(entry, (uint32_t)table1);
PDE_set_present_flag(entry, true);
PDE_set_rw_flag(entry, true);
PDE_set_usm_flag(entry, false); // supervisor mode
entry = &dir->entries[1];
PDE_set_adress(entry, (uint32_t)table2);
PDE_set_present_flag(entry, true);
PDE_set_rw_flag(entry, true);
PDE_set_usm_flag(entry, false); // supervisor mode
//! switch to our page directory
paging_set_pDirectoryTable(dir);
//! enable paging
enable_paging();
terminal_print(debugTerminal, "Paging initialized and enabled!\n");
}
Also, I try to compile this function but it gives an error. Do you know what's the problem with this assembly?
Code: Select all
void paging_flush_tlb_entry( uint32_t addr )
{
disable_interrupts();
__asm("invlpg %0" : : "r"(addr));
enable_interrupts();
}