Paging problem. (Problem Solved)
Posted: Sun Sep 30, 2007 2:54 am
Hey all,
Sorry for this, but I have a problem with the paging I have in my kernel. When I try to get it enabled then Bochs panics which means that there is something wrong when I try to enable it but I don't know what is wrong with it tough.
I use djgpp, ld and NASM on Windows XP to compile the kernel and I use Grub 0.97 as bootsector.
Here is the code where it normally gets enabled:
If I comment __asm__ __volatile__ ("mov %0, %%cr0":: "r"(cr0)); then the kernel doesn't crash. The same thing if I don't initialize the paging so I can still use my kernel but not something like the paging.
I am thinking that it has to do with the kernel_directory. If you need anymore code then you can just ask.
Thank you already.
Regards, Stephan J.R. van Schaik.
Sorry for this, but I have a problem with the paging I have in my kernel. When I try to get it enabled then Bochs panics which means that there is something wrong when I try to enable it but I don't know what is wrong with it tough.
I use djgpp, ld and NASM on Windows XP to compile the kernel and I use Grub 0.97 as bootsector.
Here is the code where it normally gets enabled:
Code: Select all
void switch_page_directory(mpage_directory *dir) {
current_directory = dir;
__asm__ __volatile__ ("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
unsigned int cr0;
__asm__ __volatile__ ("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
__asm__ __volatile__ ("mov %0, %%cr0":: "r"(cr0));
}
Code: Select all
void initialize_paging() {
// The size of physical memory. For the moment we
// assume it is 16MB big.
unsigned int mem_end_page = 0x1000000;
nframes = mem_end_page / 0x1000;
frames = (unsigned int*)kmalloc(INDEX_FROM_BIT(nframes));
memset(frames, 0, INDEX_FROM_BIT(nframes));
// Let's make a page directory.
kernel_directory = (mpage_directory*)kmalloc_a(sizeof(mpage_directory));
memset(kernel_directory, 0, sizeof(mpage_directory));
current_directory = kernel_directory;
// Map some pages in the kernel heap area.
// Here we call get_page but not alloc_frame. This causes page_table_t's
// to be created where necessary. We can't allocate frames yet because they
// they need to be identity mapped first below, and yet we can't increase
// placement_address between identity mapping and enabling the heap!
int i = 0;
for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000)
get_page(i, 1, kernel_directory);
// We need to identity map (phys addr = virt addr) from
// 0x0 to the end of used memory, so we can access this
// transparently, as if paging wasn't enabled.
// NOTE that we use a while loop here deliberately.
// inside the loop body we actually change placement_address
// by calling kmalloc(). A while loop causes this to be
// computed on-the-fly rather than once at the start.
// Allocate a lil' bit extra so the kernel heap can be
// initialised properly.
i = 0;
while (i < placement_address + 0x1000) {
// Kernel code is readable but not writeable from userspace.
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
i += 0x1000;
}
// Now allocate those pages we mapped earlier.
for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += 0x1000)
alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
// Before we enable paging, we must register our page fault handler.
irq_install_handler(14, page_fault);
// Now, enable paging!
switch_page_directory(kernel_directory); // bug here!
// Initialise the kernel heap.
//kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0); // commented for debug reasons.
}
Thank you already.
Regards, Stephan J.R. van Schaik.