summaryrefslogtreecommitdiff
path: root/kernel/mem.c
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2015-05-14 14:05:54 +0200
committerMichal Idziorek <m.i@gmx.at>2015-05-14 14:05:54 +0200
commitce3968aa4a941e272171f8fcd389c4909a7a23a5 (patch)
treed3fd8fca72d0fe9f9b1d7f17a37a5fd3d2d44a16 /kernel/mem.c
parentdc7bf2f47d6f97407e3b50ae0b8ab59fd51079e5 (diff)
some clenup and recover after git-crash!
Diffstat (limited to 'kernel/mem.c')
-rw-r--r--kernel/mem.c176
1 files changed, 53 insertions, 123 deletions
diff --git a/kernel/mem.c b/kernel/mem.c
index f29c34f..f33b5d8 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -4,27 +4,28 @@
#include "config.h"
#include "multiboot.h"
-#include "lib/logger/log.h" // logger facilities
+#include "lib/logger/log.h"
-//! 8 blocks per byte
-#define PMMNGR_BLOCKS_PER_BYTE 8
-
-//! block size (4k)
+
+#define PMMNGR_BLOCKS_PER_BYTE 8
#define PMMNGR_BLOCK_SIZE 4096
-
-//! block alignment ??? TODO: what is this!?
-#define PMMNGR_BLOCK_ALIGN PMMNGR_BLOCK_SIZE
+#define PMMNGR_MAX_BLOCKS 1048576
+#define PMMNGR_MAP_SIZE PMMNGR_MAX_BLOCKS/PMMNGR_BLOCKS_PER_BYTE/4
+// defined in linker.ld and multiboot.s
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;
+//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];
+
+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 to userspace
char *memmap_type_to_string[]=
{
@@ -62,7 +63,7 @@ void pmmngr_init ()
{
mem_free_blocks=0;
- for(int i=0;i<mem_array_size;i++)
+ for(int i=0;i<PMMNGR_MAP_SIZE;i++)
{
_mmngr_memory_map[i]=0xffffffff;
}
@@ -71,7 +72,7 @@ void pmmngr_init ()
//find the first free bit
int mmap_first_free ()
{
- for (int i=0; i< mem_array_size ; i++)
+ for (int i=0; i<mem_max_block ; i++)
if (_mmngr_memory_map[i] != 0xffffffff)
for (int j=0; j<32; j++)
{
@@ -81,31 +82,10 @@ int mmap_first_free ()
return -1;
}
-/*
-//find the first free consecutive x bits
-int mmap_first_free_s (uint32_t x)
-{
- int found=0;
-
- for (int i=0; i< mem_array_size; i++)
- if (_mmngr_memory_map[i] != 0xffffffff)
- for (int j=0; j<32; j++)
- {
- if(!mmap_test(32*i+j))found++;
- else found=0;
- if(found==x)return 32*i+j;
- }
-
- return -1;
-}
-*/
-
void pmmngr_init_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 -1;
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init blocks: 0x%08X 0x%08X",base,size);
+ uint32_t align = base / PMMNGR_BLOCK_SIZE;
+ uint32_t blocks = size / PMMNGR_BLOCK_SIZE;
for (; blocks>0; blocks--)
{
@@ -116,10 +96,10 @@ 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 -1; // TODO: calc properly
- uint32_t blocks = size / PMMNGR_BLOCK_SIZE +2;
+ uint32_t align = base / PMMNGR_BLOCK_SIZE;
+ uint32_t blocks = size / PMMNGR_BLOCK_SIZE;
- //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"%08X, %08X -> deinit %d blocks",base,size,blocks);
+ if(size%PMMNGR_BLOCK_SIZE)blocks++;
for (; blocks>0; blocks--)
{
@@ -146,30 +126,7 @@ void* pmmngr_alloc_block ()
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; i<size; i++)
- {
- mmap_set (frame+i);
- mem_free_blocks--;
- }
-
- uint32_t addr = frame * PMMNGR_BLOCK_SIZE;
-
- return (void*)addr;
-}
-*/
void pmmngr_free_block (void* p)
{
@@ -192,18 +149,26 @@ void pmmngr_free_block (void* p)
}
-void mem_init(uint32_t memmap,uint32_t length)
+void mem_init(multiboot_information *info)
{
+ if(info->flags&&1<<6)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"memory map of length %d provided by bootloader",info->mmap_length);
+ }
+ else panic(FOOLOS_MODULE_NAME,"Unable to continue without memory map, sorry!");
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end);
+ pmmngr_init (); //clear memmap
+
+ uint64_t memmap=info->mmap_addr;
+ uint64_t length=info->mmap_length;
- // we will place the memory map directly after the kernel for now (TODO: move somewehere else, so modules are not overwritten!)
- _mmngr_memory_map=kernel_end;
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"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;
- // iterate : print memory map and calc blocks.
+ // iterate : print memory map, calc blocks, deinit
for(uint32_t mmap_addr=memmap;mmap_addr<memmap+length;)
{
multiboot_mmap *mmap=mmap_addr;
@@ -222,6 +187,7 @@ void mem_init(uint32_t memmap,uint32_t length)
{
total_mem+=mem;
highest_end=mmap->base_addr+mmap->length-1;
+ pmmngr_init_region(mmap->base_addr,mmap->length);
}
//next
@@ -229,69 +195,33 @@ void mem_init(uint32_t memmap,uint32_t length)
}
uint32_t blocks=highest_end/4096+1;
- mem_array_size=blocks/32+1;
+ mem_max_block=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_addr<memmap+length;)
+ // deinit modules memory
+ if(info->flags&&1<<3)
{
- multiboot_mmap *mmap=mmap_addr;
-
- //reclaimable OR usable
- if(mmap->type==1||mmap->type==3)
+ multiboot_mod *mod=info->mods_addr;
+ for(int i=0;i<info->mods_count;i++)
{
- pmmngr_init_region(mmap->base_addr,mmap->length);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"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);
+
+ mod++;
}
-
- //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);
+ // deinitialize kernel
+ pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1);
- 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];
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024);
-
- }
- }
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,
+ "Free 4K blocks: %d (first free: %d)",mem_free_blocks,mem_min_block);
}
+