#define FOOLOS_MODULE_NAME "mem" #include #include "config.h" #include "multiboot.h" #include "lib/logger/log.h" // logger facilities //! 8 blocks per byte #define PMMNGR_BLOCKS_PER_BYTE 8 //! block size (4k) #define PMMNGR_BLOCK_SIZE 4096 //! block alignment ??? TODO: what is this!? #define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE extern uint32_t kernel_start[]; extern uint32_t kernel_end[]; extern uint32_t stack_top[]; extern uint32_t stack_bottom[]; //memory map bit array. Each bit represents a 4KB memory block static uint32_t *_mmngr_memory_map; static uint32_t mem_free_blocks; static uint32_t mem_array_size; char *memmap_type_to_string[]= { "Usable", "Reserved", "ACPI reclaimable", "ACPI NVS", "Bad Memory" }; uint32_t mem_get_free_blocks_count() { return mem_free_blocks; } // bit funcs! void mmap_set(int bit) { _mmngr_memory_map[bit / 32] |= (1 << (bit % 32)); } void mmap_unset(int bit) { _mmngr_memory_map[bit / 32] &= ~ (1 << (bit % 32)); } 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 () { mem_free_blocks=0; for(int i=0;i0; blocks--) { mmap_unset (align++); mem_free_blocks++; } } void pmmngr_deinit_region (uint32_t base, uint32_t size) { uint32_t align = base / PMMNGR_BLOCK_SIZE -1; // TODO: calc properly uint32_t blocks = size / PMMNGR_BLOCK_SIZE +2; //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%08X, %08X -> deinit %d blocks",base,size,blocks); for (; blocks>0; blocks--) { mmap_set (align++); mem_free_blocks--; } } void* pmmngr_alloc_block () { int frame = mmap_first_free (); if (frame == -1) { panic(FOOLOS_MODULE_NAME,"OUT OF MEMORY (alloc_block)"); return 0; //out of memory } mmap_set (frame); mem_free_blocks--; uint32_t addr = frame * PMMNGR_BLOCK_SIZE; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"alloc block (%d) 0x%08X)",frame,addr); return (void*)addr; } /* void* pmmngr_alloc_blocks (uint32_t size) { int frame = mmap_first_free_s (size); if (frame == -1) { panic(FOOLOS_MODULE_NAME,"OUT OF MEMORY (alloc_blocks)"); return 0; //out of memory } for (int i=0; ibase_addr; uint64_t mem_end=mmap->base_addr+mmap->length; #ifdef MEM_PRINT_MEMORYMAP log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%08X - %08X / type: %s, (size: %d)", (uint32_t)mem_start, (uint32_t)mem_end, memmap_type_to_string[mmap->type-1], mmap->size); #endif uint32_t mem=mmap->length; //reclaimable OR usable if(mmap->type==1||mmap->type==3) { total_mem+=mem; highest_end=mmap->base_addr+mmap->length-1; } //next mmap_addr+=mmap->size+4; } uint32_t blocks=highest_end/4096+1; mem_array_size=blocks/32+1; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Init bitmap for %d blocks (array size: %d bytes)",blocks,mem_array_size*4); pmmngr_init (); //clear memmap // iterate : initialize memory for(uint32_t mmap_addr=memmap;mmap_addrtype==1||mmap->type==3) { pmmngr_init_region(mmap->base_addr,mmap->length); } //next mmap_addr+=mmap->size+4; } // deinitialize kernel + memory (TODO: modules) pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)); pmmngr_deinit_region(_mmngr_memory_map,mem_array_size*4+PMMNGR_BLOCK_SIZE); pmmngr_deinit_region(0,0x700000); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Usable Mem: %d (0x%X) bytes. (~%d MB)",total_mem,total_mem,total_mem/1024/1024); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Currently Free 4K blocks: %d blocks.",mem_free_blocks); // mmap_show_free(); } // analytics void mmap_show_free () { int last_pos=0; uint32_t last=_mmngr_memory_map[0]; for (int i=1; i< mem_array_size ; i++) { if (_mmngr_memory_map[i] != last||i==mem_array_size-1) { if(last==0) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d -%d free",last_pos*32,i*32); } else if(last==0xffffffff) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d -%d full",last_pos*32,i*32); } else { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%d -%d some free",last_pos*32,i*32); } last_pos=i; last=_mmngr_memory_map[i]; } } }