cr3 and page directory
Posted: Sat Sep 02, 2006 7:23 pm
I want to implement a linux like paging system, I read the source code, load the gdt, go into PM, and mapping first 8M to
0xC0000000, and start use virtual address, all work good. But when I set page directory(because I want to map all of the
address space),virtual machine(vmware, bochs, virtual pc) give a CPU fault, I find out I can read the content the page
directory, but can not
write!(virtual pc and vmware can write the empty entries, but bochs can not write the whole page directory). I takes 4 days
to test my code, at last I find I can reload the page directory, load the same page directory at different page, but can not
load a different page directory.........
void setup_paging()
{
unsigned long * pde;
unsigned long * pte;
unsigned long pde_idx, pte_idx, pfn;
unsigned long * pgd_base = page_dir; // page_dir address 0xC0107000
pde_idx = pgd_index(PAGE_OFFSET); // pde_idx = 0xC00
pfn = 0; // map all of the phy addr
pde = pgd_base + pde_idx; // pde address = 0xC0107C00
for (; pde_idx < 1024; pde++, pde_idx++) {
pte = allocate_page(); // get one page from kernel end to first 8M
*pde = ((unsigned long)pte) | 0x27; // << This program dead at this place
for (pte_idx = 0; pte_idx < 1024; pte++, pte_idx++, pfn++) {
if (pfn >= max_pfn) // max_pfn = 0x2000
goto out;
*pte = ((pfn<<12)+0xC0000000) | 0x63;
}
}
out:
load_cr3(pgd_base); // movl $0x107000, %ecx; movl %ecx, %cr3\n
__flush_tlb_all(); // movl %cr3, %eax; movl %eax, %cr3
printk("All of the page table init successfully!\n");
}
Before executing the function:
the page_dir is:
0x108000 # at offset 0x0
0x109000
.....
0x108000 # at offset 0xC00
0x109000
registers:
cr0:0x80000011
cr3:0x107000
My gdt:
gdt:
.fill GDT_ENTRY_BOOT_CS,8,0
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0x9A00 # system, read/exec
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0x9200 # system, read/write
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0xfa00 # user, read/exec
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0xf200 # user, read/write
.word 0x00CF # granularity=4K
The full source code at http://pickup.mofile.com/0120118765010663
0xC0000000, and start use virtual address, all work good. But when I set page directory(because I want to map all of the
address space),virtual machine(vmware, bochs, virtual pc) give a CPU fault, I find out I can read the content the page
directory, but can not
write!(virtual pc and vmware can write the empty entries, but bochs can not write the whole page directory). I takes 4 days
to test my code, at last I find I can reload the page directory, load the same page directory at different page, but can not
load a different page directory.........
void setup_paging()
{
unsigned long * pde;
unsigned long * pte;
unsigned long pde_idx, pte_idx, pfn;
unsigned long * pgd_base = page_dir; // page_dir address 0xC0107000
pde_idx = pgd_index(PAGE_OFFSET); // pde_idx = 0xC00
pfn = 0; // map all of the phy addr
pde = pgd_base + pde_idx; // pde address = 0xC0107C00
for (; pde_idx < 1024; pde++, pde_idx++) {
pte = allocate_page(); // get one page from kernel end to first 8M
*pde = ((unsigned long)pte) | 0x27; // << This program dead at this place
for (pte_idx = 0; pte_idx < 1024; pte++, pte_idx++, pfn++) {
if (pfn >= max_pfn) // max_pfn = 0x2000
goto out;
*pte = ((pfn<<12)+0xC0000000) | 0x63;
}
}
out:
load_cr3(pgd_base); // movl $0x107000, %ecx; movl %ecx, %cr3\n
__flush_tlb_all(); // movl %cr3, %eax; movl %eax, %cr3
printk("All of the page table init successfully!\n");
}
Before executing the function:
the page_dir is:
0x108000 # at offset 0x0
0x109000
.....
0x108000 # at offset 0xC00
0x109000
registers:
cr0:0x80000011
cr3:0x107000
My gdt:
gdt:
.fill GDT_ENTRY_BOOT_CS,8,0
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0x9A00 # system, read/exec
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0x9200 # system, read/write
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0xfa00 # user, read/exec
.word 0x00CF # granularity=4K
.word 0xFFFF # 4Gb
.word 0 # base address = 0
.word 0xf200 # user, read/write
.word 0x00CF # granularity=4K
The full source code at http://pickup.mofile.com/0120118765010663