Using global variable causes page fault
Posted: Sun Dec 10, 2006 9:06 am
Hi,
In my OS I am currently writing the memory manager, which is being run as a seperate module (and process!) from the kernel, and is loaded using the GRUB module command. It is mapped into address space at 0x8000,0000 (upper two gigabytes), by using the multiboot information that grub gives about the memory locations to which it was loaded. All works perfectly (including task switching to it), until I try to access a global variable (an array for allocating memory), which causes a page fault. Can anyone suggest what I am doing wrong? There's not really much I can think of checking - any point in the array seems to do this, so I haven't defined it too small!
I'll post more code later if need be, for now here's the linker script and module loading code:
Linker Script:
Module mapping:
I've left out stack, etc mapping code to make it more readable, and to the best of my knowledge the page table manipulation functions work fine.
Thanks,
OScoder
In my OS I am currently writing the memory manager, which is being run as a seperate module (and process!) from the kernel, and is loaded using the GRUB module command. It is mapped into address space at 0x8000,0000 (upper two gigabytes), by using the multiboot information that grub gives about the memory locations to which it was loaded. All works perfectly (including task switching to it), until I try to access a global variable (an array for allocating memory), which causes a page fault. Can anyone suggest what I am doing wrong? There's not really much I can think of checking - any point in the array seems to do this, so I haven't defined it too small!
I'll post more code later if need be, for now here's the linker script and module loading code:
Linker Script:
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY (_loader)
SECTIONS
{
. = 0x80000000;
.text :
{
*(.text)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss ALIGN (0x1000):
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
Code: Select all
ushort modules_init(ulong mods_addr)
{
ulong module_size;
ulong module_start;
ulong module_eip;
ulong i; /*counter*/
module_t *mod;
/*Work out MM's properties*/
mod = (module_t*)mods_addr;
module_size = mod->mod_end - mod->mod_start + 1;
module_start = mod->mod_start;
module_eip = V_USERSPACE;
_print("MM Properties evaluated...",0x01,4);
/*Map memory manager to 0x80000000 (2Gb)*/
change_page_table( 0, _USERSPACE_FIRST_TABLE, /*set up the MM's page table*/
_MM_PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT);
for(i=0; i<=(module_size/PAGE_SIZE); i+=PAGE_SIZE) /*set up MM's pages to point to it's physical address*/
change_page( 0, _USERSPACE_FIRST_TABLE, i,
((module_start+i)&0xFFFFF000) | PAGE_WRITEABLE | PAGE_PRESENT);
_print("MM mapped in...",0x01,4);
Thanks,
OScoder