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