Hey guys, I'm working on implementing paging and had a question. Where do I actually place the page tables and directories?
I've seen some tutorials that place it in the lower memory, but I can't really figure out why (other than random choice). Should it be in lower as opposed to higher memory? I looked at the x86 memory map on the wiki and saw that there is space in lower memory, but only if the ram is available. How do I check this if I'm using GRUB as my boot loader? I've tried reading data out of the multiboot header, but it gives me garbage.
Also, when first starting paging, does some virtual space HAVE to be mapped to identical physical space so that the computer can still keep running it self properly? i.e Do I have to be under 1 MB?
Thanks guys!
Where to place page tables, directories, etc
Where to place page tables, directories, etc
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
- gzaloprgm
- Member
- Posts: 141
- Joined: Sun Sep 23, 2007 4:53 pm
- Location: Buenos Aires, Argentina
- Contact:
Re: Where to place page tables, directories, etc
To know the memory map using grub (to avoid placing something in a unavailable address), I suggest you to read http://wiki.osdev.org/How_Do_I_Determin ... p_Via_GRUB
Yes, the GDT must be present if you are working in protected mode and the IDT and ISRs if you wanna use interrupts. And of course, the code after setting paging must be mapped correctly.
Cheers,
Gonzalo
Yes, the GDT must be present if you are working in protected mode and the IDT and ISRs if you wanna use interrupts. And of course, the code after setting paging must be mapped correctly.
Cheers,
Gonzalo
Last edited by gzaloprgm on Mon Jan 05, 2009 5:50 pm, edited 1 time in total.
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
Re: Where to place page tables, directories, etc
They can be placed anywhere in physical memory (However page tables must be aligned at 4K addresses. This does not apply to page directories though but may be a small performance hit if it is not.) I recommend storing it above 1MB though in physical memory and mapping the physical location to a virtual address somewhere in the high memory area in kernel land.Hey guys, I'm working on implementing paging and had a question. Where do I actually place the page tables and directories?
Yes. The reason is because the format of your physical addresses are treated very different when paging is enabled. More specifically, as soon as paging is enabled, all addresses become virtual and are treated as such. This is guaranteed to #GPF as none of the page tables refer to valid physical addresses yet.Also, when first starting paging, does some virtual space HAVE to be mapped to identical physical space so that the computer can still keep running it self properly? i.e Do I have to be under 1 MB?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: Where to place page tables, directories, etc
Thanks neon, that helped!
However, I'm still a little confused. In the first part you recommend putting everything above 1MB, yet in the 2nd part you recommend putting stuff under 1 MB. I'm probably not reading it right, can you clarify some?
Also, I don't understand this part:
However, I'm still a little confused. In the first part you recommend putting everything above 1MB, yet in the 2nd part you recommend putting stuff under 1 MB. I'm probably not reading it right, can you clarify some?
Also, I don't understand this part:
Is this referring to storing the directories or the tables or both above the 1 MB part?I recommend storing it above 1MB though in physical memory and mapping the physical location to a virtual address somewhere in the high memory area in kernel land
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
Re: Where to place page tables, directories, etc
Perhaps I didnt word it right. I recommend storing it above 1MB physical memory.However, I'm still a little confused. In the first part you recommend putting everything above 1MB, yet in the 2nd part you recommend putting stuff under 1 MB. I'm probably not reading it right, can you clarify some?
Both.Is this referring to storing the directories or the tables or both above the 1 MB part?
I try not putting anything below 1MB as that can be used for real mode programs and data. I personally map my kernel to 2GB virtual address and store my memory management tables above 2GB in kernel land so no user mode app can touch them in any way. The physical address that this virtual address refers to can be anything, but do recommend above the kernel over the 1MB physical address mark.
Keep in mind that this is only opinion
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: Where to place page tables, directories, etc
Here's another opinion
When I go to PMode, my page frame allocator is one of the first things that goes online. I do not plan to use any real mode code at all and have a 32/64 bit kernel.
Page directories and page tables are allocated just as any other memory - there is no special case. Because I do not use legacy ISA DMA, I do not need to keep any memory under 1MiB especially for this. I use a stack page frame allocator and build the stack from the base of memory upwards. For this reason, chances are that pages used for the initial page directory and page tables will come from high memory somewhere.
As for identity mapping - the code you are currently running needs to be identity mapped (and stack, and the data), but remember that CR3, PDE's and PTE's always refer to physical addresses. I generally map the PD and PT's (and in 64 bit mode PDPT and PML4) in to a contiguous range in the high virtual address range (above my kernel). If you have a lower-half kernel, you may want to consider something different!
Cheers,
Adam
When I go to PMode, my page frame allocator is one of the first things that goes online. I do not plan to use any real mode code at all and have a 32/64 bit kernel.
Page directories and page tables are allocated just as any other memory - there is no special case. Because I do not use legacy ISA DMA, I do not need to keep any memory under 1MiB especially for this. I use a stack page frame allocator and build the stack from the base of memory upwards. For this reason, chances are that pages used for the initial page directory and page tables will come from high memory somewhere.
As for identity mapping - the code you are currently running needs to be identity mapped (and stack, and the data), but remember that CR3, PDE's and PTE's always refer to physical addresses. I generally map the PD and PT's (and in 64 bit mode PDPT and PML4) in to a contiguous range in the high virtual address range (above my kernel). If you have a lower-half kernel, you may want to consider something different!
Cheers,
Adam
Re: Where to place page tables, directories, etc
Hey guys, so I've been working on my paging implementation and I'm having some trouble again.
So far, I've allocated 512 page tables, 1024 4kb pages each inside of 1 page directory. As such, shouldn't I be able to be able to access any address up to 2gb? However, the way things are now, my OS page faults when I access an address past 0x1FFFF000 (512mb-4kb).
Additionally, my code is very slow, due to the massive for loop in the code. Can anyone suggest ways to improve this?
Below is my code, can someone give me some pointers as to what I'm doing wrong? Thanks!
So far, I've allocated 512 page tables, 1024 4kb pages each inside of 1 page directory. As such, shouldn't I be able to be able to access any address up to 2gb? However, the way things are now, my OS page faults when I access an address past 0x1FFFF000 (512mb-4kb).
Additionally, my code is very slow, due to the massive for loop in the code. Can anyone suggest ways to improve this?
Below is my code, can someone give me some pointers as to what I'm doing wrong? Thanks!
Code: Select all
// give kmalloc a starting point
placementAddress = (unsigned int)&end; // defined in linker script
placementAddress &= 0xFFFFF000; // align it on 4kb
placementAddress += 0x1000;
unsigned long* kernelDirectory = (unsigned long*)kmalloc_a(sizeof(unsigned long) * 1024); // array of tables - 1024 tables, 4 kb
memset((unsigned char*)kernelDirectory, 0, sizeof(unsigned long)*1024);
unsigned long* kernelTables = (unsigned long*)kmalloc_a(sizeof(unsigned long) * 1024 * 512); // 0x8000; // array of pages - 512 pages per table, 512kb
memset((unsigned char*)kernelTables, 0, sizeof(unsigned long)*1024*1024);
unsigned long physicalAddress = 0x0;
unsigned int i;
for(i=0; i<1024*512-1; i++) // 512b * 1kb = 512 kb
{
kernelTables[i] = (physicalAddress) | 3;
physicalAddress = physicalAddress + 4096;
if(physicalAddress <= 0)
{
monitorWriteUDec(i);
PANIC("OVERFLOW!");
}
}
monitorWriteUHex(physicalAddress);
// for the kernel directory, we have 512 tables * 1024 pages each = 2G available space
// this means we need 512KB to store the directory
// we need to put 2G into low space for the kernel
for(i=0; i<512; i++)
{
kernelDirectory[i] = (unsigned long)(kernelTables + i * 1024 * sizeof(unsigned long));
kernelDirectory[i] = kernelDirectory[i] | 3;
}
for(i=512; i<1024; i++)
{
kernelDirectory[i] = 0 | 2; // not present, rw, supervisor
}
// now actually enable the paging code
write_cr3((unsigned long)kernelDirectory); // put that page directory address into CR3
write_cr0(read_cr0() | 0x80000000); // set the paging bit in CR0 to 1
// set up page fault interrupts
register_interrupt_handler(14, page_fault);
}
Hexciting: An open source hex editor for the command line.
https://sourceforge.net/projects/hexciting/
https://sourceforge.net/projects/hexciting/
- carbonBased
- Member
- Posts: 382
- Joined: Sat Nov 20, 2004 12:00 am
- Location: Wellesley, Ontario, Canada
- Contact:
Re: Where to place page tables, directories, etc
This may, or may not, be useful to you, but I always found it useful to hex dump my page directory, and all defined page tables inside my core exception handlers (at least the ones which can't be handled, and kill the system).
From there, you have a good set of info to debug paging problems. It's tedious, but you get better at it, the more you do it.
Your performance can be improved by only mapping pages as required. Don't map everything at once; map what you need, and incrementally map as requested.
--Jeff
From there, you have a good set of info to debug paging problems. It's tedious, but you get better at it, the more you do it.
Your performance can be improved by only mapping pages as required. Don't map everything at once; map what you need, and incrementally map as requested.
--Jeff