summaryrefslogtreecommitdiff
path: root/kernel/mem.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-09-04 15:16:13 +0200
committerMichal Idziorek <m.i@gmx.at>2014-09-04 15:16:13 +0200
commit06e382afcbf199e5e4ec92574a3872ab04fb6e9e (patch)
tree08bb57d147d31cd4eefc26567849b1c6a2dbbe7f /kernel/mem.c
parent706d8edc5abf15960ff8bebf9a2a6dc76b23eeac (diff)
Improved physical memory manager and cleaning up.
Diffstat (limited to 'kernel/mem.c')
-rw-r--r--kernel/mem.c269
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);
+ }
+ }
}