fix/kernel: Fixed kfree to be more safe
This commit is contained in:
parent
d0e4149de5
commit
b41cc11e39
4 changed files with 81 additions and 36 deletions
|
@ -57,6 +57,7 @@ IMPLICIT_SRCS :=
|
||||||
ifneq ($(MAKECMDGOALS),menuconfig)
|
ifneq ($(MAKECMDGOALS),menuconfig)
|
||||||
ifeq ($(CONFIG_KERNEL_HEAP_FF),y)
|
ifeq ($(CONFIG_KERNEL_HEAP_FF),y)
|
||||||
IMPLICIT_SRCS += src/mm/heap/ff.c
|
IMPLICIT_SRCS += src/mm/heap/ff.c
|
||||||
|
CFLAGS += -DFF_POOL_SIZE=$(CONFIG_KERNEL_HEAP_POOL_SIZE)
|
||||||
else
|
else
|
||||||
$(error Error: No heap algorithm was defined. Please run "make menuconfig" and select one.)
|
$(error Error: No heap algorithm was defined. Please run "make menuconfig" and select one.)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,39 +1,54 @@
|
||||||
mainmenu "EMK Build Configuration"
|
mainmenu "EMK Build Configuration"
|
||||||
|
|
||||||
choice
|
menu "Build"
|
||||||
|
choice
|
||||||
prompt "Build Mode"
|
prompt "Build Mode"
|
||||||
default BUILD_MODE_DEBUG
|
default BUILD_MODE_DEBUG
|
||||||
|
|
||||||
config BUILD_MODE_DEBUG
|
config BUILD_MODE_DEBUG
|
||||||
bool "Debug"
|
bool "Debug"
|
||||||
help
|
help
|
||||||
Build with debug symbols and no optimizations.
|
Build with debug symbols and no optimizations.
|
||||||
|
|
||||||
config BUILD_MODE_RELEASE
|
config BUILD_MODE_RELEASE
|
||||||
bool "Release"
|
bool "Release"
|
||||||
help
|
help
|
||||||
Build with optimizations and no debug symbols.
|
Build with optimizations and no debug symbols.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
endmenu
|
||||||
|
|
||||||
choice
|
menu "Memory"
|
||||||
|
choice
|
||||||
prompt "Kernel Heap Algorithm"
|
prompt "Kernel Heap Algorithm"
|
||||||
default KERNEL_HEAP_FF
|
default KERNEL_HEAP_FF
|
||||||
|
|
||||||
config KERNEL_HEAP_FF
|
config KERNEL_HEAP_FF
|
||||||
bool "First-Fit"
|
bool "First-Fit"
|
||||||
help
|
help
|
||||||
Use the First-Fit memory allocation algorithm (ff.c).
|
Use the First-Fit memory allocation algorithm (ff.c).
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config ENABLE_FLANTERM
|
config KERNEL_HEAP_POOL_SIZE
|
||||||
bool "Enable Flanterm Support"
|
int "Pool Size (Pages)"
|
||||||
|
default 512
|
||||||
|
depends on KERNEL_HEAP_FF
|
||||||
help
|
help
|
||||||
Includes support for the Flanterm terminal emulator. Useful for debugging real hardware.
|
Set the pool size in pages for the First-Fit heap algorithm.
|
||||||
|
endmenu
|
||||||
|
|
||||||
config CC
|
menu "Toolchain"
|
||||||
|
config CC
|
||||||
string "C Compiler"
|
string "C Compiler"
|
||||||
default "gcc"
|
default "gcc"
|
||||||
help
|
help
|
||||||
Path to the C compiler to use for building.
|
Path to the C compiler to use for building.
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "Extras"
|
||||||
|
config ENABLE_FLANTERM
|
||||||
|
bool "Enable Flanterm Support"
|
||||||
|
help
|
||||||
|
Includes support for the Flanterm terminal emulator. Useful for debugging real hardware.
|
||||||
|
endmenu
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <boot/emk.h>
|
#include <boot/emk.h>
|
||||||
#include <util/align.h>
|
#include <util/align.h>
|
||||||
#include <sys/kpanic.h>
|
#include <sys/kpanic.h>
|
||||||
|
#include <util/log.h>
|
||||||
|
|
||||||
void *pool;
|
void *pool;
|
||||||
block_t *freelist = NULL;
|
block_t *freelist = NULL;
|
||||||
|
@ -18,6 +19,7 @@ void heap_init()
|
||||||
freelist = (block_t *)pool;
|
freelist = (block_t *)pool;
|
||||||
freelist->size = (FF_POOL_SIZE * PAGE_SIZE) - sizeof(block_t);
|
freelist->size = (FF_POOL_SIZE * PAGE_SIZE) - sizeof(block_t);
|
||||||
freelist->next = NULL;
|
freelist->next = NULL;
|
||||||
|
log_early("Initialized heap with a pool of %d pages (~%dMB)", FF_POOL_SIZE, DIV_ROUND_UP(FF_POOL_SIZE * PAGE_SIZE, 1024 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *kmalloc(size_t size)
|
void *kmalloc(size_t size)
|
||||||
|
@ -73,10 +75,35 @@ void kfree(void *ptr)
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* get block header */
|
|
||||||
block_t *block = (block_t *)((uint8_t *)ptr - sizeof(block_t));
|
block_t *block = (block_t *)((uint8_t *)ptr - sizeof(block_t));
|
||||||
|
|
||||||
/* insert freed block at head of freelist */
|
/* insert block sorted by address in freelist */
|
||||||
block->next = freelist;
|
block_t **cur = &freelist;
|
||||||
freelist = block;
|
while (*cur && *cur < block)
|
||||||
|
{
|
||||||
|
cur = &(*cur)->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
block->next = *cur;
|
||||||
|
*cur = block;
|
||||||
|
|
||||||
|
/* coalesce with next block if adjacent */
|
||||||
|
if (block->next && (uint8_t *)block + sizeof(block_t) + block->size == (uint8_t *)block->next)
|
||||||
|
{
|
||||||
|
block->size += sizeof(block_t) + block->next->size;
|
||||||
|
block->next = block->next->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* coalesce with previous block if adjacent */
|
||||||
|
if (cur != &freelist)
|
||||||
|
{
|
||||||
|
block_t *prev = freelist;
|
||||||
|
while (prev->next != block)
|
||||||
|
prev = prev->next;
|
||||||
|
if ((uint8_t *)prev + sizeof(block_t) + prev->size == (uint8_t *)block)
|
||||||
|
{
|
||||||
|
prev->size += sizeof(block_t) + block->size;
|
||||||
|
prev->next = block->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,9 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define FF_POOL_SIZE 512 // 2MB, in pages
|
#ifndef FF_POOL_SIZE
|
||||||
|
#define FF_POOL_SIZE 512
|
||||||
|
#endif // FF_POOL_SIZE
|
||||||
|
|
||||||
typedef struct block
|
typedef struct block
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue