Page frame setup done, plus makefile changes.
Makefile now has VGA=2 to set the QEMU monitor to STDOUT. Nice for things like memory dumps. Can now parse the memory and create a bitmap of workable regions. Allocation soon(tm)
This commit is contained in:
parent
c45eb306df
commit
4ffc4692ae
4 changed files with 64 additions and 46 deletions
4
Makefile
4
Makefile
|
|
@ -35,6 +35,10 @@ ifeq ($(VGA), 0)
|
||||||
QEMU_FLAGS += -display none
|
QEMU_FLAGS += -display none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(VGA), 2)
|
||||||
|
QEMU_FLAGS += -monitor stdio
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(SERIAL), 1)
|
ifeq ($(SERIAL), 1)
|
||||||
QEMU_FLAGS += -serial stdio
|
QEMU_FLAGS += -serial stdio
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
#include "kmultiboot.h"
|
#include "kmultiboot.h"
|
||||||
|
|
||||||
#define PAGE_SIZE 0x1000
|
#define PAGE_SIZE 0x1000
|
||||||
#define MEM_MAX 0xFFFFFFFF
|
|
||||||
extern uint8_t* pmem_bitmap;
|
extern uint8_t* pmem_bitmap;
|
||||||
|
|
||||||
unsigned int build_bitmap(mb_mmap_entry_t* mmap, int mmap_size);
|
unsigned int build_bitmap(mb_mmap_entry_t* mmap, int mmap_size);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ 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);
|
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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,75 +3,90 @@
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
uint8_t* pmem_bitmap;
|
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 build_bitmap(mb_mmap_entry_t* mmap, int mmap_size) {
|
||||||
unsigned int pages_allocated = 0;
|
//rather important global pointer to the bitmap
|
||||||
//Set up a bitmap and set it all to 1
|
|
||||||
pmem_bitmap = &_kernel_end;
|
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;
|
*(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(;
|
for(;
|
||||||
(int)mmap < mmap_end;
|
(int)mmap < mmap_end;
|
||||||
mmap = (mb_mmap_entry_t*)((int)mmap + mmap->entry_size + sizeof(mmap->entry_size))) {
|
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.
|
||||||
printf(default_output,"__MMAP_ENTRY__:\nSTART_ADDR:%X\nSIZE:%X\nTYPE:%u\n",(uint32_t)mmap->addr, (uint32_t)mmap->mem_size, mmap->type);
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t* mem_bottom =(uint8_t*) (((uint32_t)mmap->addr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
|
uint8_t* mem_bottom =(uint8_t*) (((uint32_t)mmap->addr + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
|
||||||
|
|
||||||
|
//Is it usable mem?
|
||||||
if(mmap->type != 1) {
|
if(mmap->type != 1) {
|
||||||
//nah...
|
//nah...
|
||||||
continue;
|
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));
|
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.
|
||||||
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;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int page_count = (mem_top - mem_bottom) / PAGE_SIZE;
|
int page_count = (mem_top - mem_bottom) / PAGE_SIZE;
|
||||||
for(int i = 0; i < page_count; i++){
|
for(int i = 0; i < page_count; i++){
|
||||||
|
|
||||||
//OK which page is this
|
//OK which page is this
|
||||||
uint8_t* page_addr = mem_bottom + (PAGE_SIZE * i);
|
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) {
|
if((uint32_t)page_addr < bitmap_end) {
|
||||||
//bruh this is in lowmem or the kernel
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
//Looks good! Go ahead and free it.
|
||||||
//Available. Calculate the offset of the bit on the bitmap based on the page address
|
free_page((void*)page_addr);
|
||||||
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++;
|
pages_allocated++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages_allocated;
|
return pages_allocated;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue