diff options
| author | Michal Idziorek <m.i@gmx.at> | 2014-09-04 15:16:13 +0200 |
|---|---|---|
| committer | Michal Idziorek <m.i@gmx.at> | 2014-09-04 15:16:13 +0200 |
| commit | 06e382afcbf199e5e4ec92574a3872ab04fb6e9e (patch) | |
| tree | 08bb57d147d31cd4eefc26567849b1c6a2dbbe7f /kernel/mem.c | |
| parent | 706d8edc5abf15960ff8bebf9a2a6dc76b23eeac (diff) | |
Improved physical memory manager and cleaning up.
Diffstat (limited to 'kernel/mem.c')
| -rw-r--r-- | kernel/mem.c | 269 |
1 files changed, 107 insertions, 162 deletions
diff --git a/kernel/mem.c b/kernel/mem.c index 9899822..0b9dab7 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -1,9 +1,9 @@ +#define FOOLOS_MODULE_NAME "mem" #define MEM_PRINT_MEMORYMAP #include "lib/int/stdint.h" #include "lib/logger/log.h" // logger facilities -#define FOOLOS_MODULE_NAME "mem" //! 8 blocks per byte #define PMMNGR_BLOCKS_PER_BYTE 8 @@ -14,14 +14,11 @@ //! block alignment #define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE -#define MEM_BITMAP_SIZE 32768 -//#define MEM_BITMAP_SIZE 327 - -// memory map bit array. Each bit represents a memory block -//uint32_t _mmngr_memory_map[MEM_BITMAP_SIZE]; -uint32_t _mmngr_memory_map[MEM_BITMAP_SIZE]; +//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; // bit funcs! void mmap_set(int bit) @@ -39,127 +36,79 @@ int mmap_test(int bit) return _mmngr_memory_map[bit / 32] & (1 << (bit % 32)); } -void mmap_show_free () +void pmmngr_init () { - - int last_pos=0; - uint32_t last=_mmngr_memory_map[0]; - - for (int i=1; i< MEM_BITMAP_SIZE ; i++) + // By default, all of memory is in use + for(int i=0;i<mem_array_size;i++) { - if (_mmngr_memory_map[i] != last||i==MEM_BITMAP_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]; - - - } + _mmngr_memory_map[i]=0xffffffff; } - } -// int mmap_first_free () { - //! find the first free bit uint32_t i; int j; - for (i=0; i< MEM_BITMAP_SIZE ; i++) + for (i=0; i< mem_array_size ; i++) if (_mmngr_memory_map[i] != 0xffffffff) for (j=0; j<32; j++) { //! test each bit in the dword - int bit = 1 << j; if (! (_mmngr_memory_map[i] & bit) ) return i*4*8+j; } return -1; - } - -void pmmngr_init () +void pmmngr_init_region (uint32_t base, uint32_t size) { - //! By default, all of memory is in use - // memset (_mmngr_memory_map, 0xf, 128 ); - int i; + uint32_t align = base / PMMNGR_BLOCK_SIZE; + uint32_t blocks = size / PMMNGR_BLOCK_SIZE; - for(i=0;i<MEM_BITMAP_SIZE;i++) + for (; blocks>0; blocks--) { - _mmngr_memory_map[i]=0xffffffff; + mmap_unset (align++); + mem_free_blocks++; } - - } -void pmmngr_init_region (uint32_t base, uint32_t size) +void pmmngr_deinit_region (uint32_t base, uint32_t size) { - - uint32_t align = base / PMMNGR_BLOCK_SIZE; uint32_t blocks = size / PMMNGR_BLOCK_SIZE; for (; blocks>0; blocks--) { - // hack to lock first ~4MB of memory - if(align<1000) - { - align++; - continue; - } - - - mmap_unset (align++); - mem_free_blocks++; - //_mmngr_used_blocks--; + mmap_set (align++); + mem_free_blocks--; } - //mmap_set (0); //first block is always set. This insures allocs cant be 0 } void* pmmngr_alloc_block () { - int frame = mmap_first_free (); - + if (frame == -1) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"OUT OF MEMORY"); return 0; //out of memory } -// scr_put_string_nl("MEM ALLOC OK!"); -// scr_put_hex32(frame); - // scr_put_string_nl(""); - mmap_set (frame); - + uint32_t addr = frame * PMMNGR_BLOCK_SIZE; mem_free_blocks--; - + return (void*)addr; } -void pmmngr_free_block (void* p) { - +void pmmngr_free_block (void* p) +{ uint32_t addr = (uint32_t*)p; int frame = addr / PMMNGR_BLOCK_SIZE; @@ -168,125 +117,121 @@ void pmmngr_free_block (void* p) { mmap_unset (frame); mem_free_blocks++; } - } -/* -void mem_test_3() +void mem_init(uint16_t *memmap,uint16_t entries) { - uint32_t *addr; - addr=pmmngr_alloc_block(); - scr_put_string("alloc 1: "); - scr_put_hex32(addr); - scr_put_string_nl(""); + // init free blocks counter + mem_free_blocks=0; - addr=pmmngr_alloc_block(); - scr_put_string("alloc 2: "); - scr_put_hex32(addr); - scr_put_string_nl(""); -} + // count available mem + uint32_t total_mem=0, highest_end=0, high_end_low=0; -void mem_test_2() -{ - //crossing 512MB boundary! - // (do not do this in real, coz it probably is reserved) - //mem_test(0x1fee1000,0x2000f000,0x800); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"the memory map contains %d entries.",entries); - int cnt=-1; - uint32_t *addr; - uint32_t *lastaddr; + // preserve pointer + uint16_t save=memmap; - do{ - lastaddr=addr; - addr=pmmngr_alloc_block(); - cnt++; - }while(addr!=0); + //print memory map and calc blocks. + for(int i=0;i<entries;i++) + { + uint32_t low_end=(((uint32_t)memmap[1])<<16)+memmap[0]; + uint32_t high_end=(((uint32_t)memmap[1])<<16)+memmap[0]-1 + +(((uint32_t)memmap[5])<<16)+memmap[4]; + #ifdef MEM_PRINT_MEMORYMAP + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"type: %02d / range: 0x%08x - 0x%08x", + memmap[8],low_end,high_end); + #endif - scr_put_string("no mem after : "); - scr_put_hex32(cnt); - scr_put_string_nl(""); + if(memmap[8]==1) + { + total_mem+=memmap[4]+(memmap[5]<<16); + } - pmmngr_free_block(lastaddr); + if(memmap[8]==1) + { + if(high_end>highest_end){ + highest_end=high_end; + high_end_low=low_end; + } + } + memmap+=12; + + } + // restore pointer + memmap=save; - cnt=-1; - do{ - lastaddr=addr; - addr=pmmngr_alloc_block(); - cnt++; - }while(addr!=0); + int blocks=highest_end/4096+1; + mem_array_size=blocks/32+1; - scr_put_string("no mem after : "); - scr_put_hex32(cnt); - scr_put_string_nl(""); -} - -void mem_test(int start, int end, int steps) -{ - int *p=start; - for(;p<end;p+=steps) + if(highest_end-high_end_low<mem_array_size*4) { - scr_put_string("testing memory at "); - scr_put_hex32(p); - - // - *p=p; - volatile x=*p; - if(x==p) scr_put_string(" OK"); - // - - scr_put_string_nl(""); + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Highest end area: 0x%08X - 0x%08X",high_end_low,highest_end); + panic(FOOLOS_MODULE_NAME,"not enough space at high end :( sorry."); } -} -*/ - -void mem_init(uint16_t *memmap,uint16_t entries) -{ - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Initializing bitmap at: %08X",_mmngr_memory_map); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"the memory map contains %d entries.",entries); + _mmngr_memory_map=highest_end-mem_array_size*4; + log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Initializing bitmap for 0x%X blocks at 0x%08X",blocks,_mmngr_memory_map); - // hardcoded memory bitmap!!??! - // todo: fix! - //_mmngr_memory_map=0x80000; - mem_free_blocks=0; pmmngr_init (); - // count available memory - uint32_t avail_mem=0; - int i; - //print memory map and init regions! - for(i=0;i<entries;i++) + for(int i=0;i<entries;i++) { + if(memmap[8]==1) + { + pmmngr_init_region(memmap[0]+(memmap[1]<<16),memmap[4]+((memmap[5])<<16)); + } + memmap+=12; + } + + // here is somewhere our kernel stuff ;) // todo!! better. + pmmngr_deinit_region(0x0,0xfffff); -// if(memmap[8]==0)break; + // and here is the memory map that we JUST created! + pmmngr_deinit_region(_mmngr_memory_map,mem_array_size*4); + + 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); -#ifdef MEM_PRINT_MEMORYMAP - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"type: %02d / range: 0x%08x - 0x%08x", - memmap[8], - (((uint32_t)memmap[1])<<16)+memmap[0], - (((uint32_t)memmap[1])<<16)+memmap[0]-1 - +(((uint32_t)memmap[5])<<16)+memmap[4]); -#endif +} + +// analytics +void mmap_show_free () +{ + int last_pos=0; + uint32_t last=_mmngr_memory_map[0]; - if(memmap[8]==1) + for (int i=1; i< mem_array_size ; i++) + { + if (_mmngr_memory_map[i] != last||i==mem_array_size-1) { - avail_mem+=memmap[4]+(memmap[5]<<16); - pmmngr_init_region(memmap[0]+(memmap[1]<<16),memmap[4]+((memmap[5])<<16)); - } - memmap+=12; - - } + 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]; + - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Available Mem: %d bytes. (~%d MB)",avail_mem,avail_mem/1024/1024); - log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Available 4K blocks: %d blocks.",mem_free_blocks); + } + } } |
