HigherHalfBareBones
HigherHalfWithGdt
I have tested HigherHalfWithGdt.
Her is how it setup paging.
Code: Select all
// Declare the page directory and a page table, both 4kb-aligned
unsigned long kernelpagedir[1024] __attribute__ ((aligned (4096)));
unsigned long lowpagetable[1024] __attribute__ ((aligned (4096)));
// This function fills the page directory and the page table,
// then enables paging by putting the address of the page directory
// into the CR3 register and setting the 31st bit into the CR0 one
void init_paging()
{
// Pointers to the page directory and the page table
void *kernelpagedirPtr = 0;
void *lowpagetablePtr = 0;
int k = 0;
kernelpagedirPtr = (char *)kernelpagedir + 0x40000000; // Translate the page directory from
// virtual address to physical address
lowpagetablePtr = (char *)lowpagetable + 0x40000000; // Same for the page table
// Counts from 0 to 1023 to...
for (k = 0; k < 1024; k++)
{
lowpagetable[k] = (k * 4096) | 0x3; // ...map the first 4MB of memory into the page table...
kernelpagedir[k] = 0; // ...and clear the page directory entries
}
// Fills the addresses 0...4MB and 3072MB...3076MB of the page directory
// with the same page table
kernelpagedir[0] = (unsigned long)lowpagetablePtr | 0x3;
kernelpagedir[768] = (unsigned long)lowpagetablePtr | 0x3;
// Copies the address of the page directory into the CR3 register and, finally, enables paging!
asm volatile ( "mov %0, %%eax\n"
"mov %%eax, %%cr3\n"
"mov %%cr0, %%eax\n"
"orl $0x80000000, %%eax\n"
"mov %%eax, %%cr0\n" :: "m" (kernelpagedirPtr));
}
At the beginning of the file this two is decleared, this is the real storage place for the pagedir and pagetable (or have I missed something?) this two would then have a vaddr (virtual address) I gess in the higher half where the kernel is mapped
Code: Select all
unsigned long kernelpagedir[1024] __attribute__ ((aligned (4096)));
unsigned long lowpagetable[1024] __attribute__ ((aligned (4096)));
Code: Select all
kernelpagedirPtr = (char *)kernelpagedir + 0x40000000;
lowpagetablePtr = (char *)lowpagetable + 0x40000000;
Code: Select all
lowpagetable[k] = (k * 4096) | 0x3;
Code: Select all
kernelpagedir[k] = 0;
Code: Select all
kernelpagedir[0] = (unsigned long)lowpagetablePtr | 0x3;
kernelpagedir[768] = (unsigned long)lowpagetablePtr | 0x3;
Then there is the ASM code that actually do the magic.
So now paging is enabled, and if I use any address after this that address would be a virtual address and the MMU will look into the pagedir/pagetables to find the physical address and then read/write to that address even though the application thinks it writing to another place.. valid virtual addresses would be addresses below 4mb and between 3072 and 3076mb altough they actually are the same place in the physical memory.
if I have understand everything ok why can't I remove the line where I map the first 4mb and leave that part unmapped?
edit: or if I can what can't I do if I remove that line?
edit 2: I can access videomem at both 0xB8000 and 0xC00B8000 isn't that a result of the mapping above that these two vaddr points to the same paddr.