This is how I thaught to do it:
First I will break down the highest possible memory address (Provided by GRUB) into its component parts (as if it were a virtual PAGED address), telling me how many Page Directory Entries are used and how many Page Table Entries (In the final Page Directory) are used to reach this address.
Code: Select all
EndAddress = Memory Length (in bytes)
DirectoryEntries = bits 22-32 of EndAddrees
TableEntries = bits 12-22 of EndAddress
All of my Page Table Entries will be stored in a single array with my Page Directory situated just before it:
NOTE: PageDirectory and PageTable, both 4Kb aligned
Code: Select all
unsigned long *PageDirectory = (unsigned long *)0x400000;
unsigned long *PageTable = (unsigned long *)0x401000;
Code: Select all
i=0, address=0;
for(i=0;i<=((DirectoryEntries*0x400)+TableEntries);i++) {
PageTable[i]= address | 3;
Address=(Address+0x1000); // 4Kb in HEX
}
NOTE: See above for definition of DirectoryEntries
Code: Select all
i=0;
for(i=0;i<=DirectoryEntries;i++) {
PageDirectory[i]=PageTable[i*0x400];
PageDirectory[i]=PageDirectory[i] | 3;
}
for(i=DirectoryEntries;i<=0x400;i++) {
PageDirectory[i]=0 | 2;
}
Code: Select all
Set CR3 to address of PageDirectory
Set PE bit in CR0
I have tried and something is wrong.
I just can't figure out the problem