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
cr3 and page directory
Re:cr3 and page directory
Are you identity mapping you PTE and PDE, because if your not then when you enable paging, it will (tripple) fault. Try looking at: http://www.mega-tokyo.com/osfaq/HigherHalfWithGdt it uses a nice little trick so the kernel always thinks its at 0xC0000000 regardless of whether being paged there or not.
Peace
Peace
Re:cr3 and page directory
I already enable paging, and begin executing above 0xC0000000. Now I want to set pdes again, and reload cr3 because at the booting I only set and load the pdes of the first 8M address. Do I need to set some bit in some register or others......
Re:cr3 and page directory
I just edit the appropreate PTE-PDE entried and use the invlpg opcode if you using i386 (as opposed to i486 onwards) you should reloads cr3 instead.
Peace
Peace
Re:cr3 and page directory
My code can run in bochs with no problem, but can not run in VPC and VMware. In bochs My cr0=0x80000011, in VPC and VMware cr0=0x80000013, so I clear the MP flag and test again:VMware auto reseted, and VPC found a ramdom processor fault as before then reset, however bochs can execute successfully, I print the page directory and page table, found no difference......
I know I can init the whole address space at the beginning, then avoid this problem, but when I start coding threads and process I will meet cr3 again......
My full source code at
http://pickup.mofile.com/0120118765010663
I know I can init the whole address space at the beginning, then avoid this problem, but when I start coding threads and process I will meet cr3 again......
My full source code at
http://pickup.mofile.com/0120118765010663