summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-07-05 13:53:42 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-07-05 13:53:42 +0200
commitc55bc80baa51dc1028cbbae8a02540cfe4c56557 (patch)
treecc8f9e327d9e68eb6aee9ca781838c473074fa60 /src
parentb281252aac949fe54057608edb20cdfbe20eaed0 (diff)
downloadabaos-c55bc80baa51dc1028cbbae8a02540cfe4c56557.tar.gz
abaos-c55bc80baa51dc1028cbbae8a02540cfe4c56557.tar.bz2
'mem' command shows memory usage of kernel heap now
implemented a malloc/free and memory manager (simplest possible implementation, just allocating linearly and never freeing)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile7
-rw-r--r--src/kernel/kernel.c34
-rw-r--r--src/kernel/memorymanagement.c40
-rw-r--r--src/kernel/memorymanagement.h16
-rw-r--r--src/libc/stdio.c40
-rw-r--r--src/libc/stdio.h4
-rw-r--r--src/libc/stdlib.c19
-rw-r--r--src/libc/stdlib.h9
8 files changed, 141 insertions, 28 deletions
diff --git a/src/Makefile b/src/Makefile
index c256605..d8b279f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -33,11 +33,11 @@ kernel.bin: kernel.elf
kernel.sym: kernel.elf
$(OBJCOPY) --only-keep-debug kernel.elf kernel.sym
-kernel.elf: kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/mouse.o drivers/video/vga.o drivers/video/vga_font.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o
+kernel.elf: kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o kernel/memorymanagement.o kernel/tasks.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/mouse.o drivers/video/vga.o drivers/video/vga_font.o gui/widget.o gui/composite_widget.o gui/window.o gui/desktop.o gui/text_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o
$(LD) -o kernel.elf -N -n -Ttext 0x8800 --oformat elf32-i386 \
kernel/kernel.o kernel/kernel_asm.o \
kernel/console.o kernel/vgatext.o kernel/serial.o \
- kernel/tasks.o \
+ kernel/memorymanagement.o kernel/tasks.o \
hardware/port.o hardware/port_asm.o \
hardware/interrupts.o hardware/interrupts_asm.o \
hardware/pci.o \
@@ -72,6 +72,9 @@ kernel/vgatext.o: kernel/vgatext.c kernel/vgatext.h
kernel/serial.o: kernel/serial.c kernel/serial.h
$(CC) $(CFLAGS) -c -o kernel/serial.o kernel/serial.c
+kernel/memorymanagement.o: kernel/memorymanagement.c kernel/memorymanagement.h
+ $(CC) $(CFLAGS) -c -o kernel/memorymanagement.o kernel/memorymanagement.c
+
kernel/tasks.o: kernel/tasks.c kernel/tasks.h
$(CC) $(CFLAGS) -c -o kernel/tasks.o kernel/tasks.c
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index a9802e1..a6594f6 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -42,6 +42,7 @@ typedef struct {
vga_text_t vga_text;
driver_manager_t driver_manager;
task_manager_t task_manager;
+ memory_manager_t memory_manager;
vga_t vga;
mode_t mode;
mouse_t mouse;
@@ -60,6 +61,7 @@ static void refresh_screen( void );
static void switch_to_graphics_mode( global_context_t *global_context );
static void switch_to_text_mode( global_context_t *global_context );
static void print_task_status( global_context_t *global_context );
+static void print_memory_status( global_context_t *global_context );
// must be first entry in kernel.bin (0x8800) as stage 2 of
// the boot loader expects the entry point to be here!
@@ -78,13 +80,25 @@ void kernel_main( void )
console_init( &console );
console_add_vga_text_output( &console, &global_context.vga_text );
console_add_serial_output( &console, &serial );
-
+
// initialize the early console of the kernel
- stdio_set_console( &console );
+ __stdio_set_console( &console );
puts( "Started early kernel console" );
// TODO: get those values somehow from the boot loader
printf( "Kernel code and data is at 0x%X, kernel stack at 0x%X\n", 0x8800, 0x90000 );
+ // initialize memory management first, we may need it
+ // TODO: get memupper from multiboot header (but this needs
+ // a multiboot compliant entry function first) or use BIOS
+ // functions to determine size of memory, for now assume we
+ // have at least, for now use the memory above 1 MB, 64 MB
+ // heap is enough for what we are doing in the kernel
+ memory_manager_init( &global_context.memory_manager, 0x100000, 0xFFFF );
+ __stdlib_set_memory_manager( &global_context.memory_manager );
+ printf( "Kernel heap at 0x%X, size 0x%X\n", 0x100000, 0xFFFF );
+ void *test = malloc( 2048 );
+ free( test );
+
// exit point in case of kernel panic, do this as soon as
// possible, as soon we have an early console we can croak on
if( setjmp( panic_jmp_buf ) > 0 ) {
@@ -211,7 +225,7 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
} else if( strcmp( buf, "halt" ) == 0 ) {
longjmp( panic_jmp_buf, 0 );
} else if( strcmp( buf, "mem" ) == 0 ) {
- // TODO: print memory usage
+ print_memory_status( global_context );
} else if( strcmp( buf, "task" ) == 0 ) {
print_task_status( global_context );
} else if( strcmp( buf, "driver" ) == 0 ) {
@@ -411,3 +425,17 @@ static void print_task_status( global_context_t *global_context )
}
}
+static void print_memory_status( global_context_t *global_context )
+{
+ memory_manager_t *memory_manager = &global_context->memory_manager;
+
+ printf( "heap memory size: %d\n", memory_manager->size );
+ printf( "heap memory offset: 0x%X\n", memory_manager->offset );
+ printf( "heap memory in use: %d\n",
+ memory_manager->free_ptr - memory_manager->offset );
+ printf( "heap memory free: %d\n",
+ memory_manager->size - ( memory_manager->free_ptr - memory_manager->offset ) - 1 );
+
+}
+
+
diff --git a/src/kernel/memorymanagement.c b/src/kernel/memorymanagement.c
new file mode 100644
index 0000000..dc2d160
--- /dev/null
+++ b/src/kernel/memorymanagement.c
@@ -0,0 +1,40 @@
+#include "memorymanagement.h"
+
+#include "string.h"
+
+#include "kernel.h"
+
+void memory_manager_init( memory_manager_t *memory_manager, size_t offset, size_t size )
+{
+ memset( memory_manager, 0, sizeof( memory_manager_t ) );
+
+ memory_manager->offset = offset;
+ memory_manager->size = size;
+ memory_manager->free_ptr = offset;
+}
+
+void *memory_manager_allocate( memory_manager_t *memory_manager, size_t size )
+{
+ void *p = NULL;
+
+ if( memory_manager->free_ptr - memory_manager->offset + size > memory_manager->size ) {
+ kernel_panic( "Heap allocation out of memory (requested %d bytes, available %d)",
+ size, size - ( memory_manager->free_ptr - memory_manager->offset ) - 1 );
+ }
+
+ p = (void *)memory_manager->free_ptr;
+ memory_manager->free_ptr += size;
+
+ return p;
+}
+
+void memory_manager_deallocate( memory_manager_t *memory_manager, void **p )
+{
+ if( *p == NULL ) {
+ kernel_panic( "Double free of pointer 0x%X in heap", *p );
+ }
+
+ *p = NULL;
+}
+
+
diff --git a/src/kernel/memorymanagement.h b/src/kernel/memorymanagement.h
new file mode 100644
index 0000000..16f0b29
--- /dev/null
+++ b/src/kernel/memorymanagement.h
@@ -0,0 +1,16 @@
+#ifndef MEMORYMANAGEMENT_H
+#define MEMORYMANAGEMENT_H
+
+#include "stddef.h"
+
+typedef struct {
+ size_t offset;
+ size_t size;
+ uint32_t free_ptr;
+} memory_manager_t;
+
+void memory_manager_init( memory_manager_t *memory_manager, size_t offset, size_t size );
+void *memory_manager_allocate( memory_manager_t *memory_manager, size_t size );
+void memory_manager_deallocate( memory_manager_t *memory_manager, void **p );
+
+#endif // MEMORYMANAGEMENT_H
diff --git a/src/libc/stdio.c b/src/libc/stdio.c
index 1d53f7a..07a047e 100644
--- a/src/libc/stdio.c
+++ b/src/libc/stdio.c
@@ -3,16 +3,16 @@
#include "stdlib.h"
#include "string.h"
-console_t *global_console = NULL;
+console_t *stdio_console = NULL;
int puts( const char *s )
{
- if( global_console == NULL ) {
+ if( stdio_console == NULL ) {
return EOF;
}
- console_put_string( global_console, s );
- console_put_newline( global_console );
+ console_put_string( stdio_console, s );
+ console_put_newline( stdio_console );
return 1;
}
@@ -33,34 +33,34 @@ int vprintf( const char *format, va_list args )
const char *s = format;
int n = 0;
- if( global_console == NULL ) {
+ if( stdio_console == NULL ) {
return -1;
}
while( *s != '\0' ) {
switch( *s ) {
case '\n':
- console_put_newline( global_console );
+ console_put_newline( stdio_console );
n++;
break;
case '%':
s++;
if( *s == '\0' ) {
- console_put_string( global_console, "<truncated % found at end of format string>" );
- console_put_newline( global_console );
+ console_put_string( stdio_console, "<truncated % found at end of format string>" );
+ console_put_newline( stdio_console );
return -1;
}
switch( *s ) {
case '%':
- console_put_char( global_console, '%' );
+ console_put_char( stdio_console, '%' );
break;
case 'X': {
char buf[19];
itoa( va_arg( args, int ), (char *)buf, 16 );
- console_put_string( global_console, buf );
+ console_put_string( stdio_console, buf );
n += strlen( buf );
}
break;
@@ -68,30 +68,30 @@ int vprintf( const char *format, va_list args )
case 'd': {
char buf[19];
itoa( va_arg( args, int ), (char *)buf, 10 );
- console_put_string( global_console, buf );
+ console_put_string( stdio_console, buf );
n += strlen( buf );
}
break;
case 'c':
- console_put_char( global_console, va_arg( args, int ) );
+ console_put_char( stdio_console, va_arg( args, int ) );
break;
case 's':
- console_put_string( global_console, va_arg( args, const char * ) );
+ console_put_string( stdio_console, va_arg( args, const char * ) );
break;
default:
- console_put_string( global_console, "<illegal format string %" );
- console_put_char( global_console, *s );
- console_put_string( global_console, ">" );
- console_put_newline( global_console );
+ console_put_string( stdio_console, "<illegal format string %" );
+ console_put_char( stdio_console, *s );
+ console_put_string( stdio_console, ">" );
+ console_put_newline( stdio_console );
}
break;
default:
- console_put_char( global_console, *s );
+ console_put_char( stdio_console, *s );
n++;
}
s++;
@@ -100,7 +100,7 @@ int vprintf( const char *format, va_list args )
return n;
}
-void stdio_set_console( console_t *console )
+void __stdio_set_console( console_t *console )
{
- global_console = console;
+ stdio_console = console;
}
diff --git a/src/libc/stdio.h b/src/libc/stdio.h
index bc7fac0..dbf7ac7 100644
--- a/src/libc/stdio.h
+++ b/src/libc/stdio.h
@@ -9,12 +9,10 @@
#define EOF (-1)
-extern console_t *global_console;
-
int puts( const char *s );
int printf( const char *format, ... );
int vprintf( const char *format, va_list args );
-void stdio_set_console( console_t *console );
+void __stdio_set_console( console_t *console );
#endif //STDIO_H
diff --git a/src/libc/stdlib.c b/src/libc/stdlib.c
index 46bdce8..9150431 100644
--- a/src/libc/stdlib.c
+++ b/src/libc/stdlib.c
@@ -45,4 +45,23 @@ char *itoa( int v, char *s, int base )
return s;
}
+
+// TODO: we should have a global memory manager and one per
+// user process later
+static memory_manager_t *stdlib_memory_manager = NULL;
+void *malloc( size_t size )
+{
+ return memory_manager_allocate( stdlib_memory_manager, size );
+}
+
+void free( void *p )
+{
+ memory_manager_deallocate( stdlib_memory_manager, &p );
+}
+
+void __stdlib_set_memory_manager( memory_manager_t *memory_manager )
+{
+ stdlib_memory_manager = memory_manager;
+}
+
diff --git a/src/libc/stdlib.h b/src/libc/stdlib.h
index 331012e..ff6b67f 100644
--- a/src/libc/stdlib.h
+++ b/src/libc/stdlib.h
@@ -1,6 +1,15 @@
#ifndef STDLIB_H
#define STDLIB_H
+#include "stddef.h"
+
+#include "memorymanagement.h"
+
char *itoa( int v, char *s, int base );
+void *malloc( size_t size );
+void free( void *p );
+
+void __stdlib_set_memory_manager( memory_manager_t *memory_manager );
+
#endif // STDLIB_H