diff --git a/Makefile b/Makefile index 4b0de63..59dc864 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,10 @@ ifeq ($(VGA), 0) QEMU_FLAGS += -display none endif +ifeq ($(VGA), 2) + QEMU_FLAGS += -monitor stdio +endif + ifeq ($(SERIAL), 1) QEMU_FLAGS += -serial stdio endif diff --git a/include/physmem.h b/include/physmem.h index 32a24c3..72a6226 100644 --- a/include/physmem.h +++ b/include/physmem.h @@ -4,7 +4,6 @@ #include "kmultiboot.h" #define PAGE_SIZE 0x1000 -#define MEM_MAX 0xFFFFFFFF extern uint8_t* pmem_bitmap; unsigned int build_bitmap(mb_mmap_entry_t* mmap, int mmap_size); diff --git a/src/main.c b/src/main.c index 57c6608..bd24d37 100644 --- a/src/main.c +++ b/src/main.c @@ -58,8 +58,8 @@ void kern_main(uint32_t multiboot_magic, mb_info_t* multiboot_info) unsigned int pages_allocated = build_bitmap((mb_mmap_entry_t*)multiboot_info->mmap_addr, multiboot_info->mmap_length); - printf(default_output, "Available mem:%d Pages | %dK", pages_allocated, pages_allocated * PAGE_SIZE); - - + printf(default_output, "Available mem:%d Pages | %dK", pages_allocated, pages_allocated * 4); + + } diff --git a/src/physmem.c b/src/physmem.c index 14cae69..67426af 100644 --- a/src/physmem.c +++ b/src/physmem.c @@ -3,75 +3,90 @@ #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) { - unsigned int pages_allocated = 0; - //Set up a bitmap and set it all to 1 + //rather important global pointer to the bitmap pmem_bitmap = &_kernel_end; - uint32_t bitmap_end = (uint32_t)pmem_bitmap + (MEM_MAX / (PAGE_SIZE*8)); - printf(default_output, "bitmap at: %X", pmem_bitmap); - for(unsigned int i = 0; i < bitmap_end; i++) { + + + + //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; } - int mmap_end = (uint32_t)mmap + mmap_size; + //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))) { - - - printf(default_output,"__MMAP_ENTRY__:\nSTART_ADDR:%X\nSIZE:%X\nTYPE:%u\n",(uint32_t)mmap->addr, (uint32_t)mmap->mem_size, mmap->type); - - + + //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; } - - //round the starting address of the map to the nearest page boundary so we don't mark half used pages as free + + //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)); - - printf(default_output, "lowerpage:%X|upper:%X\n", mem_bottom, mem_top); - - //ok lets set the bitmap - /* bullshit dont use it - for(uint8_t* i = mem_bottom; i < mem_top; i+=4096) { - - //Watch out for cutting up kernelspace - if((unsigned int)mem_bottom + (unsigned int)i < bitmap_end) - continue; - - //ok we can just say this whole chunk is available - *(pmem_bitmap + (unsigned int)i) = 0; - } - */ + //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) { - //bruh this is in lowmem or the kernel continue; } - - //Available. Calculate the offset of the bit on the bitmap based on the page address - unsigned int pagenumber = (unsigned int)page_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); - pages_allocated++; + //Looks good! Go ahead and free it. + free_page((void*)page_addr); + pages_allocated++; } - } - return pages_allocated; - }