Page 1 of 1

Paging issuses.

Posted: Sat Dec 27, 2008 11:52 am
by eXeCuTeR
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:

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
my paging code: (PHYS_MEMORY_SIZE = 16MB, PAGE_SIZE = 4KB, 0x1000)

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(&registers, "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);
}
control registers input & output:

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
and the bochs output:
http://pastebin.com/mb1a656c

Please help! thanks.

Re: Paging issuses.

Posted: Sat Dec 27, 2008 12:26 pm
by eXeCuTeR
Nevermind, got it working :P
I didn't map the VGA frame buffer.