summaryrefslogtreecommitdiff
path: root/kernel/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/mem.c')
-rw-r--r--kernel/mem.c88
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;
}
-
-