Paging issuses.
Posted: Sat Dec 27, 2008 11:52 am
I've been trying to enable paging on my kernel for the last 2 days and I'm almost done but I don't know why, bochs keeps REBOOTING(restarting) after I enable paging (writing the page directory to the cr3 and ORing the cr0)
A good friend of mine told me that it is the stack the occur a page fault because it's located somewhere grub choose, but I make the stack appear in a specific location!
boot.asm:
my paging code: (PHYS_MEMORY_SIZE = 16MB, PAGE_SIZE = 4KB, 0x1000)
control registers input & output:
and the bochs output:
http://pastebin.com/mb1a656c
Please help! thanks.
A good friend of mine told me that it is the stack the occur a page fault because it's located somewhere grub choose, but I make the stack appear in a specific location!
boot.asm:
Code: Select all
STACKSIZE equ 0x4000
PAGE_ALIGN equ 1<<0
MEM_INFO equ 1<<1
HEADER_MAGIC equ 0x1BADB002 ; grub magic word
HEADER_FLAGS equ PAGE_ALIGN | MEM_INFO
CHECKSUM equ -(HEADER_MAGIC + HEADER_FLAGS)
global mbheader
extern code, bss, end
mbheader:
dd HEADER_MAGIC
dd HEADER_FLAGS
dd CHECKSUM
dd mbheader
dd code
dd bss
dd end
dd start
global start
extern main
start:
mov esp, stack+STACKSIZE
push eax
push ebx
call main
jmp $
section .bss
align 32
stack:
resb STACKSIZE
Code: Select all
#include <common.h>
#include <screen.h>
#include <physical_mm.h>
#include <page.h>
#include <desc_tables.h>
extern unsigned int start, end; // linker script
extern unsigned int current_addr;
unsigned int *page_bitmap, pages_num; /* with the assistances of this array, i will be checking whether there's a free space so i can allocate page on it.
i treat each page as one bit (this is a bitmap) while '1' marks an allocated spot, and '0' marks a free spot. */
extern void writeto_cr3(unsigned int);
extern unsigned int readfrom_cr3(void);
extern void writeto_cr0(unsigned int);
extern unsigned int readfrom_cr0(void);
extern unsigned int readfrom_cr2(void);
extern int_handler int_handlers[NUM_INTERRUPTS];
void initialize_page_bitmap(void)
{
pages_num = PHYS_MEMORY_SIZE/PAGE_SIZE; // each page is 0x1000KB big
page_bitmap = (unsigned int *)malloc((pages_num/32), 0, 0);
memset(page_bitmap, 0, pages_num/32); // no pages are in the frame now
}
int checkfor_empty_space(void) /* loop through the page bitmap and look for an empty spot */
{
unsigned int i = 0, j;
for(;i<pages_num/32/*page_bitmap is an array of integers(32bits) and every page is counted as 1 bit*/;i++)
for(j=0;j<32;j++)
if((page_bitmap[i] & (0x1 << j)) == 0)
return i*32+j; // return the number of the page
return -1; // no empty space
}
void mark_page_in_bitmap(unsigned int addr)
{
/* we divide the address by 0x1000 to get the page number (index+offset, i*32+j),
* we /32 to get the index in the page bitmap
* we %32 to get the offset of the page */
unsigned int page_number = addr/PAGE_SIZE;
page_bitmap[page_number/32] |= (0x1 << (page_number%32)); // mark that this place is now allocated by some page
}
void delete_page_from_bitmap(unsigned int addr)
{
unsigned int page_number = addr/PAGE_SIZE;
page_bitmap[page_number/32] &= ~(0x1 << (page_number%32)); // now this place is not marked as allocated and it is marked as free
}
void allocate_page(unsigned int *entry, int writable, int user_mode)
{
int page_number = checkfor_empty_space();
if(page_number == -1)
{
// PANIC(0, "[phys_allocate_page] says: out of memory, no more room for any more pages.\n");
// puts("[phys_allocate_page] says: out of memory, no more room for any more pages.");
return;
}
mark_page_in_bitmap(page_number*PAGE_SIZE); /*multiply by 0x1000 to make it an address because each page is 4KB big*/
/* present: 1<<0,
* rw (writable): 1<<1,
* user/supervisor(usermode page): 1<<2 */
unsigned int attribute = 0x1; // this page is now present in physical memory
attribute |= (writable)?(0x1<<1):0; // is this a writable page?
attribute |= (user_mode)?(0x1<<2):0; // is this a usermode page?
attribute |= page_number*PAGE_SIZE; // the frame address of the page
*entry = attribute;
}
int is_page_free(unsigned int addr)
{
unsigned int page_number = addr/PAGE_SIZE;
return (page_bitmap[page_number/32] & (0x1 << (page_number%32)))?1:0;
}
void enable_paging(unsigned int *pde)
{
writeto_cr3((unsigned int)pde);
unsigned int temp = readfrom_cr0();
writeto_cr0(temp|0x80000000);
}
void free_page(unsigned int addr)
{
addr /= PAGE_SIZE;
if((page_bitmap[addr/32] & (0x1 << addr%32)) != 0)
{
delete_page_from_bitmap(addr*PAGE_SIZE);
addr &= KPAGE_ENTRY_ATTR; // remove the frame address
}
}
void page_fault(registers_state registers)
{
PANIC(®isters, "Page fault.\n");
asm volatile("hlt");
}
void initialize_paging(void)
{
unsigned int *kernel_directory = (unsigned int *)malloc(1024*sizeof(unsigned int), 0, 1);
memset(kernel_directory, 0, 1024*sizeof(unsigned int));
initialize_page_bitmap();
// creating 128 page tables for the kernel directory
unsigned int i=0;
for(;i<128;i++)
{
void *ptr = malloc(1024*sizeof(unsigned int), 0, 1);
kernel_directory[i] = (unsigned int)ptr | KPAGE_ENTRY_ATTR;
memset(ptr, 0, 1024*sizeof(unsigned int));
}
// map the kernel
unsigned int kernel_start = (unsigned int)&start & ~0xFFF,
kernel_end = ((unsigned int)&end + 4095) & ~0xFFF;
for(i=kernel_start;i<kernel_end;i+=0x1000)
{
unsigned int *page_table = (unsigned int *)((unsigned int)kernel_directory[i/(PAGE_SIZE*1024)] & (~KPAGE_ENTRY_ATTR));
page_table[(i/PAGE_SIZE)%1024] = i | KPAGE_ENTRY_ATTR;
// allocate_page(&page_table[(i/PAGE_SIZE)%1024], 1, 0);
}
int_handlers[14/*page fault*/] = page_fault;
// check if the mapping was done wrong:
unsigned int *pagetable = (void *)(kernel_directory[0] & ~0xFFF);
unsigned int address = pagetable[0x105] & ~0xFFF;
if (address != 0x105000)
{
puts("Mapping broken.\n");
putdec(address);
}
enable_paging(kernel_directory);
}
Code: Select all
global writeto_cr3
writeto_cr3:
mov eax, [esp+4]
mov cr3, eax
ret
global readfrom_cr3
readfrom_cr3:
mov eax, cr3
ret
global writeto_cr0
writeto_cr0:
mov eax, [esp+4]
mov cr0, eax
ret
global readfrom_cr0
readfrom_cr0:
mov eax, cr0
ret
global readfrom_cr2 ; for page faults
readfrom_cr2:
mov eax, cr2
ret
http://pastebin.com/mb1a656c
Please help! thanks.