#include "physmem.h" #include #include uint8_t* pmem_bitmap; uint32_t bitmap_size; void free_page(void* addr) { //Available. Calculate the offset of the bit on the bitmap based on the page address unsigned int pagenumber = (unsigned int)addr / PAGE_SIZE; uint8_t* bitmap_byte = pmem_bitmap + (pagenumber / 8); int bitmap_bit = pagenumber % 8; //ok now set the bit to unused *bitmap_byte &= ~(0x80 >> bitmap_bit); } unsigned int build_bitmap(mb_mmap_entry_t* mmap, int mmap_size) { //rather important global pointer to the bitmap pmem_bitmap = (&_kernel_end); //some variables int mmap_end = (uint32_t)mmap + mmap_size; unsigned int pages_allocated = 0; uint32_t max_memory = 0; //How much memory do we even have? Find the highest usable mmap region, and that'll be our bitmap size. for(mb_mmap_entry_t* mmap_walk = mmap; (int)mmap_walk < mmap_end; mmap_walk = (mb_mmap_entry_t*)((int)mmap_walk + mmap_walk->entry_size + sizeof(mmap_walk->entry_size))) { if(mmap_walk->type != 1) //lol lmao continue; uint32_t section_upper = (uint32_t)mmap_walk->addr + (uint32_t)mmap_walk->mem_size; if(section_upper > max_memory) { max_memory = section_upper; } } //Now that we know the bitmap size, we can define it a bit bitmap_size = max_memory / (PAGE_SIZE*8); uint32_t bitmap_end = (uint32_t)pmem_bitmap + bitmap_size; //Now we'll Fill out our bitmap with 1s. for(unsigned int i = 0; i < bitmap_size; i++) { *(pmem_bitmap + i) = 0xFF; } //Time to actually fill it out. Iterate the memory map, and for every VALID memory region, set their bits to 0. for(; (int)mmap < mmap_end; mmap = (mb_mmap_entry_t*)((int)mmap + mmap->entry_size + sizeof(mmap->entry_size))) { //The bottom of our memory, rounded up to the nearest page boundary. uint8_t* mem_bottom =(uint8_t*) (((uint32_t)mmap->addr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)); //Is it usable mem? if(mmap->type != 1) { //nah... continue; } //Top of our memory, rounded UP this time. uint8_t* mem_top = (uint8_t*) (((uint32_t)mmap->addr + (uint32_t)mmap->mem_size) & ~(PAGE_SIZE - 1)); //Iterating through our pages in the memory region. Free the ones that meet our criteria. int page_count = (mem_top - mem_bottom) / PAGE_SIZE; for(int i = 0; i < page_count; i++){ //OK which page is this uint8_t* page_addr = mem_bottom + (PAGE_SIZE * i); //Is it in an invalid region? skip this page if so. if((uint32_t)page_addr < bitmap_end) { continue; } //Looks good! Go ahead and free it. free_page((void*)page_addr); pages_allocated++; } } return pages_allocated; }