COBE 0.1 ALPHA
|
00001 #include <pmm.h> 00002 #include <stdint.h> 00003 #include <stdio.h> 00004 #include <panic.h> 00005 00006 #define SIZE_OF_MAP 32768 00007 00008 extern const void start_kernel; 00009 extern const void end_kernel; 00010 00011 uint32_t MemoryMap[SIZE_OF_MAP]; //----------Erzeugt eine MemoryMap---------- 00012 00014 00015 void init_pmm(multiboot_info_t* mbinfo) { 00016 00017 memory_map_t* mmap = (void*)mbinfo->mmap_addr; //----------Erzeugt die MemoryMap von GRUB---------- 00018 memory_map_t* mmap_end = (void*) ((uintptr_t)mbinfo->mmap_addr + mbinfo->mmap_length); //----------Die Addresse des Ende der Map ist die Start-Addresse plus der Länge der MemoryMap---------- 00019 kmemset(MemoryMap, 0, sizeof(MemoryMap)); //----------Belege die MemoryMap mit 0, damit alle Blöcke als belegt makiert sind---------- 00020 00021 //----------Alle als frei angezeigten Blöcke in der MemoryMap von GRUB werden freigegeben---------- 00022 while(mmap < mmap_end) 00023 { 00024 if(mmap->type == 1) 00025 { 00026 uintptr_t m_address = mmap->base; 00027 uintptr_t m_end = m_address + mmap->length; 00028 while(m_address < m_end) 00029 { 00030 pmm_free((void*)m_address); 00031 m_address += 0x1000; 00032 } 00033 } 00034 mmap++; 00035 } 00036 00037 //----------Sperre die Speicherblöcke, in denen der Kernel liegt---------- 00038 00039 uintptr_t kstart = (uintptr_t)&start_kernel; //----------start_kernel ist die Start-Addresse des Kernels, deklariert im Linker-Script---------- 00040 while(kstart < (uintptr_t) &end_kernel) //----------end_kernel ist die End-Addresse des Kernels, deklariert im Linker-Script---------- 00041 { 00042 pmm_mark_used((void*)kstart); //----------Sperrt die angegebene Addresse---------- 00043 kstart += 0x1000; 00044 } 00045 00046 //----------Die Strukturen werden auch als belegt makiert---------- 00047 module_t* grub_modules = (void*)mbinfo->mods_addr; 00048 pmm_mark_used(grub_modules); 00049 pmm_mark_used(mbinfo); 00050 00051 //----------Die Module werden als belegt makiert, immerhin sollen diese nicht überschrieben werden---------- 00052 for(int i = 0; i < mbinfo->mods_count; i++) 00053 { 00054 uintptr_t addr = grub_modules[i].mod_start; 00055 while(addr < grub_modules[i].mod_end) 00056 { 00057 pmm_mark_used((void*)addr); 00058 addr += 0x1000; 00059 } 00060 } 00061 return; 00062 } 00063 00065 00066 void* pmm_alloc() { 00067 for(int i = 0; i < SIZE_OF_MAP; i++) { //----------Führe das alles pro Block aus---------- 00068 if(MemoryMap[i] != 0) //----------Wenn dieser Block nicht 0 ist, also irgendein Bit gesetzt ist, prüfe weiter---------- 00069 { 00070 for(int k = 0; k < 32; k++) //----------Führe dies für alle 32 Bits aus---------- 00071 { 00072 if(MemoryMap[i] & (1 << k)) //----------Finde das gesetzte Bit---------- 00073 { 00074 MemoryMap[i] &= ~(1 << k); //----------Lösche das gesetzte Bit(Block als belegt markieren) und gebe die aktuelle Addresse des Speicherblocks zurück---------- 00075 return (void*) ((i * 32 + k) * 4096); 00076 } 00077 } 00078 } 00079 } 00080 kernel_panic(1,0); //----------Wenn alle Blöcke belegt sind, führe die Kernel-Panic Nummer 1 aus---------- 00081 return 0; 00082 } 00083 00085 00086 void pmm_free(void* pmm_page) { 00087 uintptr_t i = (uintptr_t)pmm_page / 0x1000; 00088 MemoryMap[i / 32] |= (1 << (i % 32)); //----------Setze das Bit zum freigeben des angegebenen Blocks---------- 00089 } 00090 00092 00093 void pmm_mark_used(void* pmm_page) { 00094 uintptr_t i = (uintptr_t)pmm_page / 0x1000; 00095 MemoryMap[i / 32] &= ~(1 << (i % 32)); //----------Lösche das Bit zum sperren des angegebenen Blocks---------- 00096 }