diff options
Diffstat (limited to 'kernel/mem.c')
| -rw-r--r-- | kernel/mem.c | 88 |
1 files changed, 40 insertions, 48 deletions
diff --git a/kernel/mem.c b/kernel/mem.c index 7052e6c..79cfe9b 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -1,5 +1,6 @@ -#include <stdint.h> #include "kernel.h" +#include "mem.h" +#include <stdint.h> #include "multiboot.h" #define PMMNGR_BLOCKS_PER_BYTE 8 @@ -7,7 +8,7 @@ #define PMMNGR_MAX_BLOCKS 1048576 // 4096*1048576 = 2^32 bytes (maxium addressable memory ~4GB) #define PMMNGR_MAP_SIZE PMMNGR_MAX_BLOCKS/PMMNGR_BLOCKS_PER_BYTE/4 -// defined in linker.ld and multiboot.s +// defined in linker.ld and asm_start.s extern uint32_t kernel_start[]; extern uint32_t kernel_end[]; extern uint32_t stack_top[]; @@ -15,13 +16,12 @@ extern uint32_t stack_bottom[]; //memory map bit array. Each bit represents a 4KB memory block, //so uint32_t represents 8*4 blocks -static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE]; //32Kb +static uint32_t _mmngr_memory_map[PMMNGR_MAP_SIZE]; //128KiB +//track number of free blocks static uint32_t mem_free_blocks; //number of free blocks -static uint32_t mem_max_block; //index of highest usable block -static uint32_t mem_min_block; //index of lowset block available for alloc -char *memmap_type_to_string[]= +static char *memmap_type_to_string[]= { "Usable", "Reserved", @@ -30,30 +30,25 @@ char *memmap_type_to_string[]= "Bad Memory" }; -uint32_t mem_get_free_blocks_count() -{ - return mem_free_blocks; -} - // bit funcs! -void mmap_set(int bit) +static void mmap_set(int bit) { _mmngr_memory_map[bit / 32] |= (1 << (bit % 32)); } -void mmap_unset(int bit) +static void mmap_unset(int bit) { _mmngr_memory_map[bit / 32] &= ~ (1 << (bit % 32)); } -int mmap_test(int bit) +static int mmap_test(int bit) { return _mmngr_memory_map[bit / 32] & (1 << (bit % 32)); } // // By default, Set all of memory is in use -void pmmngr_init () +static void pmmngr_init () { mem_free_blocks=0; @@ -64,9 +59,9 @@ void pmmngr_init () } //find the first free bit -int mmap_first_free () +static int mmap_first_free () { - for (int i=0; i<mem_max_block ; i++) + for (int i=0; i<PMMNGR_MAP_SIZE; i++) if (_mmngr_memory_map[i] != 0xffffffff) for (int j=0; j<32; j++) { @@ -76,33 +71,38 @@ int mmap_first_free () return -1; } -void pmmngr_init_region (uint32_t base, uint32_t size) +// work with regions +static void pmmngr_init_region (uint32_t base, uint32_t size) { uint32_t align = base / PMMNGR_BLOCK_SIZE; - uint32_t blocks = size / PMMNGR_BLOCK_SIZE; + uint32_t end_align = (base+size-1) / PMMNGR_BLOCK_SIZE; + uint32_t blocks = end_align-align+1; for (; blocks>0; blocks--) { +// if(mmap_test(align))kpanic("already initialized"); mmap_unset (align++); mem_free_blocks++; } } -void pmmngr_deinit_region (uint32_t base, uint32_t size) +static void pmmngr_deinit_region (uint32_t base, uint32_t size) { uint32_t align = base / PMMNGR_BLOCK_SIZE; - uint32_t blocks = size / PMMNGR_BLOCK_SIZE; + uint32_t end_align = (base+size-1) / PMMNGR_BLOCK_SIZE; + uint32_t blocks = end_align-align+1; if(size%PMMNGR_BLOCK_SIZE)blocks++; for (; blocks>0; blocks--) { +// if(mmap_test(align))kpanic("already de-initialized"); mmap_set (align++); mem_free_blocks--; } } -void* pmmngr_alloc_block () +void* mem_alloc_block () { int frame = mmap_first_free (); @@ -122,7 +122,7 @@ void* pmmngr_alloc_block () } -void pmmngr_free_block (void* p) +void mem_free_block (void* p) { uint32_t addr = (uint32_t)(uint32_t*)p; int frame = addr / PMMNGR_BLOCK_SIZE; @@ -142,29 +142,33 @@ void pmmngr_free_block (void* p) //klog("free block (%d) 0x%08X)",frame,addr); } +uint32_t mem_get_free_blocks_count() +{ + return mem_free_blocks; +} -// returns index of first block outside of kerel-land +/** initialize physical memory manager */ uint32_t mem_init(multiboot_information *info) { + klog("markers in kernel binary:"); + klog("kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end); + klog("initial stack at: 0x%08X- 0x%08X",stack_top,stack_bottom); + fixme("check if kernel size does not exceed memory limits!"); - fixme("move stack"); + fixme("communicate pages to vmmem to identity map in kernel!"); if(info->flags&&1<<6) { - klog("memory map of length %d provided by bootloader",info->mmap_length); + klog("Memory map of length %d provided by bootloader",info->mmap_length); } else kpanic("Unable to continue without memory map, sorry!"); - pmmngr_init (); //clear memmap + pmmngr_init (); //mark all memory as used uint64_t memmap=info->mmap_addr; uint64_t length=info->mmap_length; - klog("kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end); - klog("initial stack at: 0x%08X- 0x%08X",stack_top,stack_bottom); - - // count available mem and track high_end of usable memory - uint32_t total_mem=0, highest_end; + uint32_t total_mem=0; // iterate : print memory map, calc blocks, deinit for(uint32_t mmap_addr=memmap;mmap_addr<memmap+length;) @@ -182,7 +186,6 @@ uint32_t mem_init(multiboot_information *info) if(mmap->type==1||mmap->type==3) { total_mem+=mem; - highest_end=mmap->base_addr+mmap->length-1; pmmngr_init_region(mmap->base_addr,mmap->length); } @@ -190,8 +193,8 @@ uint32_t mem_init(multiboot_information *info) mmap_addr+=mmap->size+4; } - uint32_t blocks=highest_end/4096+1; - mem_max_block=blocks/32+1; + // deinit first page (coz address=0 reserved for failure) + pmmngr_deinit_region(0,4096); // deinit modules memory if(info->flags&&1<<3) @@ -201,8 +204,6 @@ uint32_t mem_init(multiboot_information *info) { klog("mod 0x%08X-0x%08X : %s", mod->mod_start,mod->mod_end, mod->string); - - mem_min_block=mod->mod_end/PMMNGR_BLOCK_SIZE+1; pmmngr_deinit_region(mod->mod_start,((uint32_t)mod->mod_end-(uint32_t)mod->mod_start)+1); @@ -213,17 +214,8 @@ uint32_t mem_init(multiboot_information *info) // deinitialize kernel pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1); - // we deinit everything below mem_min_block anyway - //pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE); - - pmmngr_deinit_region(0,4096); // deinit first page (coz address=0 reserved for failure) - + klog("Free 4K blocks: %d",mem_free_blocks); klog("Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024); - klog( - "Free 4K blocks: %d (first free: %d)",mem_free_blocks,mem_min_block); - - return mem_min_block; + return 0; } - - |
