Problem while mapping my memory-bitmap
Posted: Wed Mar 04, 2009 2:34 pm
Hello,
I have a problem with the initialization of paging.
The problem is, that the first entry in the first table of my kernel-directory does not set zero as value.
I do not know why the error exists.
If I manipulate the first entry by hand, I get a triple fault of qemu.
Here is the code:
Can you find the problem?
Thank you.
cu
rizor
I have a problem with the initialization of paging.
The problem is, that the first entry in the first table of my kernel-directory does not set zero as value.
I do not know why the error exists.
If I manipulate the first entry by hand, I get a triple fault of qemu.
Here is the code:
Code: Select all
void paging_init(){
size_t size;
krn_dir = (directory_table_t)palloc(PAGING_KERNEL_DIR_SIZE * sizeof(directory_table_t) / PAGING_PAGESIZE);
memset(krn_dir , EMPTY , PAGING_KERNEL_DIR_SIZE);
//map the kernel
size = ((uint32_t)kernel_end - (uint32_t)kernel_start) / PAGING_PAGESIZE;
puts("\tMapped the kernel ");
map_init(kernel_start , kernel_mem_start , size);
//map the txt-video-memory
size = 80 * 25 * 2 / PAGING_PAGESIZE + 1;
puts("\tMapped the video-memory ");
map_init((phys_t)0xB8000 , (virt_t)0xB8000 , size);
//map the kernel_directory
puts("\tMapped the kernel-directory ");
map_init(krn_dir , krn_dir , 1);
//map the bitmap
size = bitmap_size / PAGING_PAGESIZE;
puts("\tMapped the bitmap ");
map_init(bitmap_entry, bitmap_entry , size);
//activate paging
//_write_cr3((uint32_t)kernel_dir);
//_write_cr0((_read_cr0() | PAGING_ENABLE));
syscall_register(SYSCALL_MAP_PAGE , map_pages_user , NULL , 1);
syscall_register(SYSCALL_UNMAP_PAGE , unmap_pages_user , NULL , 2);
}
Code: Select all
void map_init(phys_t paddr , virt_t vaddr , size_t size){
size_t i , c , offset , overflow = 0;
size_t start_table , start_page;
uint32_t phys;
page_table_t table;
offset = ((uint32_t)vaddr >> PAGING_SHIFT_TABLE) % PAGING_TABLE_SIZE;
if(size > PAGING_TABLE_SIZE - offset){
if(krn_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1] == EMPTY)
create_table(krn_dir , (uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1);
table = (page_table_t)((uint32_t)krn_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY + 1] & PAGING_REMOVEFLAGS);
overflow = size - PAGING_TABLE_SIZE + offset;
for(i = 0; i < overflow; i++){
phys = (uint32_t)paddr + PAGING_TABLE_SIZE - offset + i * PAGING_PAGESIZE;
if(table[i] != EMPTY)
panic("Tried to map a mapped page");
table[i] = phys | PAGING_KERNEL;
}
}
if(krn_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY] == EMPTY)
create_table(krn_dir , (uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY);
table = (page_table_t)(krn_dir[(uint32_t)vaddr >> PAGING_SHIFT_DIRECTORY] & PAGING_REMOVEFLAGS);
for(i = 0; i < size - overflow; i++){
phys = (uint32_t)paddr + i * PAGING_PAGESIZE;
if(table[i + offset] != EMPTY)
panic("Tried to map a mapped page");
table[i + offset] = phys | PAGING_KERNEL;
}
puts("from %p to %p\n" , vaddr , (vaddr + size * PAGING_PAGESIZE));
}
Code: Select all
void create_table(directory_table_t directory , size_t dir_offset){
page_table_t table;
table = (page_table_t)palloc(PAGING_TABLE_SIZE * sizeof(page_table_t) / PAGING_PAGESIZE);
if(table == EMPTY)
//TODO call swapping
panic("Not enough physical memory");
memset(table , EMPTY , PAGING_TABLE_SIZE);
if(dir_offset >= PAGING_KERNEL_DIR_SIZE)
directory[dir_offset] = (uint32_t)table | PAGING_USER;
else
directory[dir_offset] = (uint32_t)table | PAGING_KERNEL;
table[0] = EMPTY; //TODO first element of the first table is wrong
}
Thank you.
cu
rizor