[Paging] How to figure out where to place pages in memory

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
padmalcom
Posts: 7
Joined: Tue Dec 14, 2010 6:27 am

[Paging] How to figure out where to place pages in memory

Post by padmalcom »

Hi, I'm struggeling with paging atm and run into a GP fault when I try to enable it.
I figured out that the physical address of my pages is responsible for this fault (from my point of view).

So my question is: How do I find out where to place my pages in memory?

My solution would be:
- Get the address of the end section from the linker script! (As done in JamesM's tutorial)

This would be for me: 0x1068a0 hex -> 1075360 byte -> 1.02554 mega byte

So with 32mb of physical memory set in my VM there should be no problem mapping 4mb by my paging routine.

Funny thing: When I start creating my pages at 0b it works (works = I can set the cr3 to my page_directory address)
but when I start putting my pages 1075360b (behind the "end" from the linker script) I get a GP fault
when setting the paging bit to 1.

Any ideas why this happens or any hints I might not have considered?

Thanks in advance :)

My paging code so far:

Code: Select all

#include "system.h"

unsigned long *page_directory = (unsigned long *) 0x9C000;
unsigned long *page_table = (unsigned long *) 0x9D000; // the page table comes right after the page directory

extern u32int end;

unsigned long address=(u32int)&end; // holds the physical address of where a page is <- This address does not work
unsigned int i;

void startPaging() {

	putfs("Addresses will be placed at: %p\n",address);
	// map the first 4MB of memory
	for(i=0; i<1024; i++)
	{
	page_table[i] = address | 3; // attribute set to: supervisor level, read/write, present(011 in binary)
	address = address + 4096; // 4096 = 4kb
	};

	// fill the first entry of the page directory
	page_directory[0] = page_table; // attribute set to: supervisor level, read/write, present(011 in binary)
	page_directory[0] = page_directory[0] | 3;

	for(i=1; i<1024; i++)
	{
	page_directory[i] = 0 | 2; // attribute set to: supervisor level, read/write, not present(010 in binary)
	};

	irq_install_handler(14, page_fault);
	
	asm volatile("mov %0, %%cr3":: "r"(page_directory));
    unsigned long cr0;
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 |= 0x80000000;
    //asm volatile("mov %0, %%cr0":: "r"(cr0));
}
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: [Paging] How to figure out where to place pages in memor

Post by gerryg400 »

You need to round 'end' up to the nearest page boundary.
If a trainstation is where trains stop, what is a workstation ?
azblue
Member
Member
Posts: 147
Joined: Sat Feb 27, 2010 8:55 pm

Re: [Paging] How to figure out where to place pages in memor

Post by azblue »

My solution would be:
- Get the address of the end section from the linker script! (As done in JamesM's tutorial)

This would be for me: 0x1068a0 hex -> 1075360 byte -> 1.02554 mega byte
You pages need to be on 4KB or 4 MB boundaries.
padmalcom
Posts: 7
Joined: Tue Dec 14, 2010 6:27 am

Re: [Paging] How to figure out where to place pages in memor

Post by padmalcom »

Okay, I put the following code at the beginning of startPaging:

Code: Select all

void startPaging() {

	// Align start address
	if (address & 0xFFFFF000)
    {
        address &= 0xFFFFF000;
        address += 0x1000;
    }
    ...
}
I got it from JamesM's tutorial but it results in a GP fault, as well. Is this piece of code
sufficient to align my adress to 4 KB boundaries?
padmalcom
Posts: 7
Joined: Tue Dec 14, 2010 6:27 am

Re: [Paging] How to figure out where to place pages in memor

Post by padmalcom »

Hey guys, thanks for the reply.

This code should aling my adress to 4kb:

Code: Select all

if ((address % 4096) != 0) {	
    address += 4096 - (address % 4096);
}
As berkus pointed out correctly this is - sadly - not the solution to my GP fault.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: [Paging] How to figure out where to place pages in memor

Post by Brendan »

Hi,
padmalcom wrote:This code should aling my adress to 4kb:
It's probably easier/better to do it without a conditional branch:

Code: Select all

    address = (address + 0x00000FFF) & 0xFFFFF000;
Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
padmalcom
Posts: 7
Joined: Tue Dec 14, 2010 6:27 am

Re: [Paging] How to figure out where to place pages in memor

Post by padmalcom »

Hi Brendan, thanks, this is really nice code.

Unfortunately, I did not find a solution to my problem ("which memory can I use to put my pages on").
User avatar
Jezze
Member
Member
Posts: 395
Joined: Thu Jul 26, 2007 1:53 am
Libera.chat IRC: jfu
Contact:

Re: [Paging] How to figure out where to place pages in memor

Post by Jezze »

I'm writing this from a phone so bare with me. If your ptables and pdirs are not dynamically allocated you can always use the aligned directive to automatically place your ptables and pdirectories on a correctly aligned address. Something like: struct page_directory {...} __attribute__ __aligned__((4096))); I'm not sure if that was correct but I hope the point came across.
Fudge - Simplicity, clarity and speed.
http://github.com/Jezze/fudge/
Tosi
Member
Member
Posts: 255
Joined: Tue Jun 15, 2010 9:27 am
Location: Flyover State, United States
Contact:

Re: [Paging] How to figure out where to place pages in memor

Post by Tosi »

You can place your page structures wherever you want, since it's your operating system.
Just make sure the address range you choose is usable RAM and is aligned on a page directory.
Whatever is causing a GPF might be somewhere else in the code.
Dario
Member
Member
Posts: 117
Joined: Sun Aug 31, 2008 12:39 pm

Re: [Paging] How to figure out where to place pages in memor

Post by Dario »

It would be nice to see your page structure. Also make sure that page directory/tables addresses are properly inserted into your page_dir/table structure(shift them right by 12 bits if necessary).
If you used bit fields to define your page structure, make sure that order of assignment are right.
Dump memory where these structures are located and check for their correctness.
I also have a short jump(jmp 1f) right after the enabling paging, although I don't think thats necessary.

EDIT: now I have actually red your code so you can ignore my post.
____
Dario
padmalcom
Posts: 7
Joined: Tue Dec 14, 2010 6:27 am

Re: [Paging] How to figure out where to place pages in memor

Post by padmalcom »

Hi, my page structure looks like:

Code: Select all

typedef struct page
{
    u32int present    : 1;   // Page present in memory
    u32int rw         : 1;   // Read-only if clear, readwrite if set
    u32int user       : 1;   // Supervisor level only if clear
    u32int accessed   : 1;   // Has the page been accessed since last refresh?
    u32int dirty      : 1;   // Has the page been written to since last refresh?
    u32int unused     : 7;   // Amalgamation of unused and reserved bits
    u32int frame      : 20;  // Frame address (shifted right 12 bits)
} page_t;
I did not make any progress with the chapter of JamesM about paging (I got my own paging
algorithm running but I cannot adopt it to the memory management of the following chapters
of JamesMs tutorial...).

So any help is still welcome!
Post Reply