COBE 0.1 ALPHA
|
00001 #include <pgng.h> 00002 #include <stdio.h> 00003 #include <pmm.h> 00004 #include <cmos.h> 00005 #include <multitasking.h> 00006 00007 struct paging_directory* kernel_map; //----------Legt den Kernel-Addressraum an---------- 00008 00009 extern const void start_kernel; //----------start_kernel und end_kernel sind Punkte, die im Linker-Script gekennzeichnet sind. Geben die Start und Endaddresse des Kernels an---------- 00010 extern const void end_kernel; 00011 extern new_task_t* current_task; 00012 00014 00015 void init_paging() { 00016 tick_counter = 0; 00017 uint32_t temp_cr0; 00018 kernel_map = paging_map(); //----------Die Kernel-Map wird vorbelegt und voll ausgestattet---------- 00019 for(int i = 0; i < 1024 * 4096; i += 0x1000) identity_mapping(kernel_map, i, i, ACCS_BIT | WRITE_BIT); //----------Vorläufig wird der Addressraum gleichgesetzt, phys. Addresse = virtuelle Addresse, alle Pages werden mit RING0 belegt---------- 00020 act_dir(kernel_map); //----------Der Kernel-Addressraum wird sofort aktiviert---------- 00021 00022 __asm("mov %%cr0, %0" : "=b"(temp_cr0)); //----------Beim Register cr0 wird das 31. Bit für Paging gesetzt, 1 = Paging, 0 = Kein Paging---------- 00023 temp_cr0 |= (1 << 31); 00024 __asm("mov %0, %%cr0" :: "b"(temp_cr0)); 00025 return; 00026 } 00027 00029 00030 void act_dir(struct paging_directory* pg_dr) { 00031 __asm volatile("mov %0, %%cr3" :: "r"(pg_dr->page_directory)); //----------Die Addresse vom PageDirectory wird in das Register cr3 geladen, cr3 beinhaltet immer die Addresse des aktuellen PageDirectory---------- 00032 return; 00033 } 00034 00036 00037 struct paging_directory* paging_map() { 00038 struct paging_directory* map_dr = pmm_alloc(); //----------Die Struktur des PageDirectory erhält einen eigenen Speicherbereich---------- 00039 map_dr->page_directory = pmm_alloc(); //----------Das PageDirectory erhält einen eigenen Speicherbereich---------- 00040 00041 for(int i = 0; i <1024; i++) 00042 { 00043 map_dr->page_directory[i] = 0; //----------Jeder PageDirectory-Eintrag wird mit 0 vorbelegt---------- 00044 } 00045 return map_dr; //----------Die Addresse des Speicherbereichs der Struktur wird zurückgegeben---------- 00046 } 00047 00049 00050 void identity_mapping(struct paging_directory* vmm, uint32_t virtaddr, uint32_t phyaddr, uint8_t flags) { 00051 uint32_t index = virtaddr / 4096; //----------Der Index wird erzeugt, virtuelle Addrese durch 0x1000---------- 00052 uint32_t dir_index = index / 1024; //----------Das PageDirectory-Index ist der Index durch 0x400---------- 00053 uint32_t table_index = index % 1024; //----------Der PageTable-Index ist der Index modulo 0x400---------- 00054 uint32_t* page_tbl; //----------Eine neue PageTable wird erzeugt---------- 00055 00056 if(vmm->page_directory[dir_index] & ACCS_BIT) page_tbl = (uint32_t*) (vmm->page_directory[dir_index] & ~0xFFF); //----------Wenn die PageTable bereits existiert, dann lösche alle Bits der PageTable---------- 00057 else { 00058 page_tbl = pmm_alloc(); //----------Erzeuge für die PageTable einen neuen Speicherbereich---------- 00059 for(int i = 0; i < 1024; i++) page_tbl[i] = 0; //----------Belege die PageTable mit 0---------- 00060 vmm->page_directory[dir_index] = (uint32_t) page_tbl | flags; //----------Setze den Deskriptor in der PageDirectory zur PageTable und setze die Flags---------- 00061 } 00062 page_tbl[table_index] = phyaddr | flags; //----------Setze die angegebene physische Addresse in der PageTable und setze die Flags---------- 00063 __asm volatile("invlpg %0" : : "m" (*(char*)virtaddr)); 00064 return; 00065 } 00066 00068 00069 void kernel_mapping(struct paging_directory* pd) { 00070 uint32_t start = (uint32_t) &start_kernel; 00071 while(start < (uint32_t) &end_kernel) { 00072 identity_mapping(pd, start, start, ACCS_BIT | WRITE_BIT); 00073 start += 0x1000; 00074 } 00075 identity_mapping(pd, 0xB8000, 0xB8000, ACCS_BIT | WRITE_BIT); 00076 return; 00077 } 00078 00080 00081 void* vmm_alloc() { 00082 uint32_t adr = 0; 00083 for(uint32_t i = 0; i < 32768; i++) { 00084 00085 identity_mapping(current_task->task_pd, adr, (uint32_t)pmm_alloc(), ACCS_BIT | WRITE_BIT | ALL_ACCS_BIT); 00086 } 00087 return (void*)adr; 00088 } 00089 00091 00092 void vmm_free(void* page) { 00093 00094 }