Page 1 of 1

paging problem

Posted: Sun Aug 17, 2014 12:24 pm
by Mohsen
Hi guys, I am currently trying to enable paging for my kernel but I am facing a strange problem, if I use the code in the wiki for paging it works just fine but this code is really simple so I tried to enable paging using the code from jamesMolly tutorial but when I enable paging using the code from the tutorial my OS crashes and restarts in qemu I checked the value laoded to cr3 register many times and it is right, this in my case is 0x10e000 contains a pointer to the first page table at address 0x111000 and the pages are set up right I verified that using gdb debugger, This is my code:

Code: Select all

kernel_directory = (page_directory_t *)kmalloc(sizeof(page_directory_t),1);
memset(kernel_directory,0,sizeof(page_directory_t));

	uint32 i = 0;
	while(i<placement_address){
		alloc_frame(get_page(i,1,kernel_directory),0,0);
		i+= 0x1000;
	}

asm volatile("mov %0,%%cr3"::"b"(kernel_directory));

uint32 cr0;
asm volatile("mov %%cr0, %0": "=b"(cr0));
cr0 |= 0x80000000; // Enable paging!
asm volatile("mov %0, %%cr0":: "b"(cr0));


void alloc_frame(page_t *page,uint8 is_kernel,uint8 is_writable){
	if(page->frame != 0)
		return;
uint32 addr = first_frame();
set_frame(addr);
page->present = 1;
page->rw = (is_writable)?1:0;
page->user = (is_kernel)?0:1;
page->frame = addr/0x1000;
}


page_t *get_page(uint32 address, int make, page_directory_t *dir)
{
    // Turn the address into an index.
    address /= 0x1000;
    // Find the page table containing this address.
    uint32 table_idx = address / 1024;
    if (dir->tables[table_idx]) // If this table is already assigned
    {
        return &dir->tablesAddr[table_idx]->pages[address%1024];
    }
    else if(make)
    {
	uint32 tmp;
    dir->tablesAddr[table_idx] = (page_table_t *)kmalloc_ap(sizeof(page_table_t), &tmp);
	memset(&dir->tablesAddr[table_idx]->pages[address%1024],0,sizeof(page_table_t));
    dir->tables[table_idx] = tmp| 0x7; // PRESENT, RW, US.
    return &dir->tablesAddr[table_idx]->pages[address%1024];
    }
    else
    {
        return 0;
    }
}


typedef struct page{
	uint32 present	:1;
	uint32 rw	:1;
	uint32 user	:1;
	uint32 accessed	:1;
	uint32 dirty	:1;
	uint32 unused	:1;
	uint32 frame	:20;
}page_t;

typedef struct page_table{
	page_t pages[1024];
}page_table_t;

typedef struct page_directory{
	uint32 tables[1024];

	page_table_t *tablesAddr[1024];
}page_directory_t;
Please help I really have no idea why this code doesn't work and the code in the wiki works despite that it forms the same structures in memory.

Re: paging problem

Posted: Sun Aug 17, 2014 2:10 pm
by Nable
1. Bochs has very good debugging messages and facilities.
2. http://wiki.osdev.org/James_Molloy%27s_ ... Known_Bugs
3. Your code is causing light form of eye-bleeding. Those random indentation, absence of packing attribute/pragma, custom type names instead of stdint.h's ones...

Re: paging problem

Posted: Sun Aug 17, 2014 2:14 pm
by Mohsen
thanks I figured out the error, it is in the definition of page_t struct the number of unused bits is 7 not one.

Re: paging problem

Posted: Mon Aug 18, 2014 8:36 am
by hometue
I would agree with Nable, while I am not the best to comment about code tidiness (since I code really bad code, which cost me a lot), it is best you develop your own coding style (how code looks like). An example would be something like this https://www.kernel.org/doc/Documentation/CodingStyle. You don't have to follow it exactly, it is just an example, but you would need to have a consistent coding style. For example, in your code, I see things like this

Code: Select all

if(page->frame != 0)
      return;
And this a little down the code

Code: Select all

else
    {
        return 0;
    }
Both which are one line returns but having a different look (with me not being able to tell what you are returning in the first one in the first glance). Perhaps you want to standardize this along with other things which can be very messy (like what Nable mentioned, indentations). Remember that good code will help you a lot in the future when you look back to understand what the code does. (something I learnt looking at my old code) Or while you are trying to debug for that matter, so I do suggest spending some time looking around and standardizing your code style.