Triple Fault While Enabling Paging
Posted: Fri Aug 05, 2016 4:40 am
Hi,
I have a kernel loaded on 0x10000 (1mb) and I'm using grub 0.97 as bootloader.
I have a physical memory management just like brokenthorn os development series;
In this method we will divide memory into 4k blocks. if we have a (4GB) 0xFFFFFFFF memory then we have 0x1000 blocks of 4kb.
So to represent if a block is in use or it is free to use, we just need to one bit of data. we used an array of 32768 elements of uint32 for it.
the next step was to init or deinit used or unused memory.
all functions worked fine and everything was good
--------------------------------------------------------------------------------
So I have started to add Virtual memory management to my kernel.
in Virtual memory management we have a PDT that contains 1024 elements of Page tables.
and each page table contains 1024 elements of Pages.
so an 32 bit virtual address will be translated to a physical address in this way :
PDT [ 10 highest bit of 32 bit address ] [ next 10 higher bit of 32 bit address ] + 12 lower bit as offset in the page.
------------------------------------------------- ------------------------------------------------------
Page Table Index Page Index
my problem comes from vmmngr_initialize() where i have defined an identity paging for the first 4mb of memory and then i have mapped 4mb of (address 0xC0000000 or 3GB) higher half to the second 4mb of main memory.
in debugging affords i saw that everything works right before pmmngr_paging_enable ()
this function is written in inline assmebly :
can you help me to find its problem ?
I have a kernel loaded on 0x10000 (1mb) and I'm using grub 0.97 as bootloader.
I have a physical memory management just like brokenthorn os development series;
In this method we will divide memory into 4k blocks. if we have a (4GB) 0xFFFFFFFF memory then we have 0x1000 blocks of 4kb.
So to represent if a block is in use or it is free to use, we just need to one bit of data. we used an array of 32768 elements of uint32 for it.
the next step was to init or deinit used or unused memory.
all functions worked fine and everything was good
--------------------------------------------------------------------------------
So I have started to add Virtual memory management to my kernel.
in Virtual memory management we have a PDT that contains 1024 elements of Page tables.
and each page table contains 1024 elements of Pages.
so an 32 bit virtual address will be translated to a physical address in this way :
PDT [ 10 highest bit of 32 bit address ] [ next 10 higher bit of 32 bit address ] + 12 lower bit as offset in the page.
------------------------------------------------- ------------------------------------------------------
Page Table Index Page Index
my problem comes from vmmngr_initialize() where i have defined an identity paging for the first 4mb of memory and then i have mapped 4mb of (address 0xC0000000 or 3GB) higher half to the second 4mb of main memory.
Code: Select all
void vmmngr_initialize () {
// physical memory allocations are 4kb aligned
//! allocate default page table
ptable* table = (ptable*) pmmngr_alloc_block ();
if (!table)
return;
//! allocates 3gb page table
ptable* table2 = (ptable*) pmmngr_alloc_block ();
if (!table2)
return;
//! clear page table
memset (table, 0, sizeof (ptable));
//! 1st 4mb are idenitity mapped
for (int i=0, frame=0x0, virt=0x00000000; i<1024; i++, frame+=4096, virt+=4096) {
//! create a new page
pt_entry page=0;
pt_entry_add_attrib (&page, I86_PTE_PRESENT);
pt_entry_set_frame (&page, frame);
//! ...and add it to the page table
table2->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
}
//! map 1mb to 3gb (where we are at)
for (int i=0, frame=0x100000, virt=0xc0000000; i<1024; i++, frame+=4096, virt+=4096) {
//! create a new page
pt_entry page=0;
pt_entry_add_attrib (&page, I86_PTE_PRESENT);
pt_entry_set_frame (&page, frame);
//! ...and add it to the page table
table->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
}
//! create default directory table
pdirectory* dir = (pdirectory*) pmmngr_alloc_blocks (3);
if (!dir)
return;
//! clear directory table and set it as current
memset (dir, 0, sizeof (pdirectory));
//! get first entry in dir table and set it up to point to our table
pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (0xc0000000) ];
pd_entry_add_attrib (entry, I86_PDE_PRESENT);
pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
pd_entry_set_frame (entry, (physical_addr)table);
pd_entry* entry2 = &dir->m_entries [PAGE_DIRECTORY_INDEX (0x00000000) ];
pd_entry_add_attrib (entry2, I86_PDE_PRESENT);
pd_entry_add_attrib (entry2, I86_PDE_WRITABLE);
pd_entry_set_frame (entry2, (physical_addr)table2);
//! store current PDBR
_cur_pdbr = (physical_addr) &dir->m_entries;
//! switch to our page directory
vmmngr_switch_pdirectory (dir);
//! enable paging
pmmngr_paging_enable ();
}
this function is written in inline assmebly :
Code: Select all
void pmmngr_paging_enable ()
{
__asm__ __volatile__ ("movl %%cr0,%%eax":::"%eax");
__asm__ __volatile__ ("orl $0x80000000,%%eax":::"%eax");
__asm__ __volatile__ ("movl %%eax,%%cr0":::"%eax");
}