Nabend zusammen,
habe gerade ein Problem mit der MMU.
Ich habe mir eine VMM geschrieben, die sich der MMU anpasst und verscuhe das System gerade an der i386-MMU.
Leider fliegt mir der Code, sobald ich Paging aktiviere (genau nach dem Befehl).
Habe mir alle Einträge angeschaut.
Die sehen gut aus.
Die Tabellen sind mit den Flags 0x3 gemappt und die Pages mit 0x103.
Müssten so ja stimmen für den Kernel-Space.
Hier mal der Code, der die Tabellen aufbaut:
index = kernel_space / level_info[1].managed_mem;
entries = 1;
//count the number of L1-table-entries to map the L1-table as a table
while((entries * level_info[1].level_entries) < level_info[0].level_entries)
entries++;
//map the L1-table as a table
for(i = 0; i < entries; i++){
l1_table[index - entries + i] =
((uint32_t)l1_table + i * level_info[1].managed_mem) | level_info[0].masks[FLAG_KRN_RW];
}
level_info[1].mapped_level_start = (void*)((index - entries) * level_info[1].managed_mem);
index -= entries + 1;
//create the table to map the L1-table
phys = (uint32_t)pmm_alloc((level_info[1].level_entries * sizeof(vmm_table_t)) / page_size , &errno);
//could not find enough memory for the table
if(errno == ERR_PMM_NO_FREE_MEM){
kprintf("PANIC: Could not find %#x, bytes for the L2-table to map the L1-table" , level_info[1].level_entries * sizeof(vmm_table_t));
while(1);
}
//FIXME: write code which supports unaligned memory
if((phys != 0) && ((phys % level_info[1].alignment) != 0)){
kprintf("PANIC: The VMM does not support wrong aligned memory\n");
kprintf("Tried to create the L2-table to map the L1-table\n");
kprintf("address: %p alignment: %#x" , phys , level_info[1].alignment);
while(1);
}
memset((void*)phys , EMPTY , level_info[1].level_entries * sizeof(vmm_table_t));
l1_table[index] = phys | level_info[0].masks[FLAG_KRN_RW];
entries = 1;
while((entries * page_size) < (level_info[0].level_entries * sizeof(vmm_table_t)))
entries++;
for(i = 0; i < entries; i++){
((vmm_table_p)phys)[level_info[1].level_entries - entries + i] =
((uint32_t)l1_table + i * page_size) | level_info[1].masks[FLAG_KRN_RW];
}
level_info[0].mapped_level_start = (void*)((level_info[1].level_entries - entries) * page_size + (index * level_info[1].managed_mem));
#ifdef CONFIG_MAX_BOOT_STATUS
kprintf("\tmapped the L1-table at %p\n" , level_info[0].mapped_level_start);
kprintf("\tmapped the L2-table at %p\n" , level_info[1].mapped_level_start);
#endif /* CONFIG_MAX_BOOT_STATUS */
//create all tables
for(i = 0; i < index; i++){
phys = (uint32_t)pmm_alloc((level_info[1].level_entries * sizeof(vmm_table_t)) / page_size , &errno);
//could not find enough memory for the table
if(errno == ERR_PMM_NO_FREE_MEM){
kprintf("PANIC: Could not find %#x, bytes for the L2-table.\n" , level_info[1].level_entries * sizeof(vmm_table_t));
kprintf("Tried to map address %p -> %p" , level_info[1].managed_mem * i , level_info[1].managed_mem * i + level_info[1].managed_mem);
while(1);
}
//FIXME: write code which supports unaligned memory
if((phys != 0) && ((phys % level_info[1].alignment) != 0)){
kprintf("PANIC: The VMM does not support wrong aligned memory\n");
kprintf("Tried to create the L2-table to map the L1-table\n");
kprintf("address: %p alignment: %#x" , phys , level_info[1].alignment);
while(1);
}
memset((void*)phys , EMPTY , level_info[1].level_entries * sizeof(vmm_table_t));
l1_table[i] = phys | level_info[0].masks[FLAG_KRN_RW];
Der Code mappt die L1- und L2-Tabellen und erstellt die Tabellen für den Kernel-Space.
Der folgende Code mappt einzelne Seiten:
//get the index of the L1-table
index = mmu_table_index((void*)((uint32_t)virt + i * page_size) , L1_TABLE , &errno);
//the L1-table is not supported
if(errno == ERR_MMU_UNSUPPORTED_TABLE){
kprintf("PANIC: the MMU does not support the L1-table");
while(1);
}
//it is not inside of the kernel space
if(l1_table[index] == EMPTY){
kprintf("PANIC: tried to map memory outside of the kernel-space\n");
kprintf("address: %p" , index * level_info[1].managed_mem + mmu_table_index((void*)((uint32_t)virt + i * page_size) , L2_TABLE , &errno) * page_size);
while(1);
}
l2_table = (vmm_table_p)(l1_table[index] & level_info[0].masks[FLAG_PHYS_ADDR]);
//get the index of the L2-table
index = mmu_table_index((void*)((uint32_t)virt + i * page_size) , L2_TABLE , &errno);
//the L2-table is not supported
if(errno == ERR_MMU_UNSUPPORTED_TABLE){
kprintf("PANIC: the MMU does not support the L2-table");
while(1);
}
l2_table[index] = ((uint32_t)phys + i * page_size) | level_info[1].masks[FLAG_KRN_RW];
Die index-Variable ist immer richtig gesetzt.
Woran kann es noch liegen, dass der Code fliegt?
Danke.
Gruß,
rizor