Page 1 of 1

How to map more than 4MB?

Posted: Sun May 06, 2007 9:02 pm
by pcmattman
I have this setup for paging, from the tutorial on osdever.net. It's not the best tutorial in the world, because it only really teaches how to map the first 4MB.

I've got this:

Code: Select all

// initializes paging
void InitPaging()
{
	// necessary variables
	ulong_t address = 0;
	uint_t i;
	
	// map the first 4 MB, first 4K not available
	pagetab[0] = address | 2; // not present
	address += 4096;
	for( i = 1; i < 1024; i++ )
	{
		pagetab[i] = address | 3; // supervisor, r/w, present
		address += 4096; // 4 KB
	}
	
	// fill first entry of the page directory
	pagedir[0] = (unsigned int) pagetab;
	pagedir[0] = pagedir[0] | 3; // supervisor, r/w, present

	// null out the rest
	for( i = 1; i < 1024; i++ )
		pagedir[i] = 0 | 2; // not present

	// fill CR3 and CR0
	write_cr3( (unsigned int) pagedir ); // put page directory address into cr3
	write_cr0( read_cr0() | 0x80000000 ); // set paging bit to 1
}
The question is, how do I map the other entries in the page directory?

Posted: Sun May 06, 2007 11:23 pm
by DarkJarek
it's simple, you just must have another page table

Code: Select all

   pagetab1[0] = address | 2; // not present
   address = 0x400000;
   for( i = 0; i < 1024; i++ )
   {
      pagetab1[i] = address | 3; // supervisor, r/w, present
      address += 4096; // 4 KB
   }
   
   // fill first entry of the page directory
   pagedir[1] = (unsigned int) pagetab1;
   pagedir[1] = pagedir[1] | 3; // supervisor, r/w, present 

Posted: Sun May 06, 2007 11:49 pm
by pcmattman
What's the address of the second page table? 1024 higher than the first?

Posted: Sun May 06, 2007 11:57 pm
by DarkJarek
this's physical address of memory, in this case we start at 4MB, in your code should be

Code: Select all

pagetab[0] = address | 2; // not present
   address = 0;
   for( i = 1; i < 1024; i++ )
   {
      pagetab[i] = address | 3; // supervisor, r/w, present
      address += 4096; // 4 KB
   } 
not

Code: Select all

pagetab[0] = address | 2; // not present
   address += 4096;
   for( i = 1; i < 1024; i++ )
   {
      pagetab[i] = address | 3; // supervisor, r/w, present
      address += 4096; // 4 KB
   } 
of course if you start at begin of ram

Posted: Mon May 07, 2007 3:27 am
by jnc100
pcmattman wrote:What's the address of the second page table? 1024 higher than the first?
The second entry in the page directory is the physical address (+ flags etc) of the page table which provides page mappings for the second 4MB of virtual memory. Each page table is 4kB in length, and 4kB aligned. The way I do it is to get the physical memory for my page tables from my physical memory allocator, and then just write the value I get into the page directory. This means that the page tables can exist anywhere in physical memory, and are not necessarily contiguous.

Regards,
John.