summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-07-02 21:39:09 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-07-02 21:39:09 +0200
commite6efe69c614d7781d18a7189831e8243abf57664 (patch)
tree44292f2913f52bee038b7c27c1551c3e6ed755f1 /src
parent2c8aa7c2fa92aabf5ac277606fba1e6b5c6b3ed9 (diff)
downloadabaos-e6efe69c614d7781d18a7189831e8243abf57664.tar.gz
abaos-e6efe69c614d7781d18a7189831e8243abf57664.tar.bz2
started to add task scheduling
Diffstat (limited to 'src')
-rw-r--r--src/Makefile6
-rw-r--r--src/drivers/driver.c2
-rw-r--r--src/kernel/kernel.c3
-rw-r--r--src/kernel/tasks.c76
-rw-r--r--src/kernel/tasks.h64
5 files changed, 149 insertions, 2 deletions
diff --git a/src/Makefile b/src/Makefile
index bcb0da7..c256605 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -33,10 +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 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/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 \
hardware/port.o hardware/port_asm.o \
hardware/interrupts.o hardware/interrupts_asm.o \
hardware/pci.o \
@@ -71,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/tasks.o: kernel/tasks.c kernel/tasks.h
+ $(CC) $(CFLAGS) -c -o kernel/tasks.o kernel/tasks.c
+
hardware/interrupts.o: hardware/interrupts.c hardware/interrupts.h
$(CC) $(CFLAGS) -c -o hardware/interrupts.o hardware/interrupts.c
diff --git a/src/drivers/driver.c b/src/drivers/driver.c
index d0a2f5d..8c20676 100644
--- a/src/drivers/driver.c
+++ b/src/drivers/driver.c
@@ -13,7 +13,7 @@ void driver_manager_init( driver_manager_t *manager )
void driver_manager_add_driver( driver_manager_t *manager, driver_t *driver )
{
if( manager->nof_drivers >= MAX_NOF_DRIVERS - 1 ) {
- kernel_panic( "Allocating more than %d drivers.. increase kernel constant", MAX_NOF_DRIVERS );
+ kernel_panic( "Allocating more than %d drivers.. increase kernel constant MAX_NOF_DRIVERS", MAX_NOF_DRIVERS );
}
manager->driver[manager->nof_drivers] = driver;
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 55dd6f9..9a9f32e 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -128,6 +128,9 @@ void kernel_main( void )
// graphical one..
puts( "Enabling interrupt handing now.." );
+
+ // TODO: if enabling tasks, this could be our really last execution
+ // in the main kernel thread
interrupts_enable( );
puts( "Running.." );
diff --git a/src/kernel/tasks.c b/src/kernel/tasks.c
new file mode 100644
index 0000000..164409a
--- /dev/null
+++ b/src/kernel/tasks.c
@@ -0,0 +1,76 @@
+#include "tasks.h"
+
+#include "kernel.h"
+#include "string.h"
+
+void task_init( task_t *task, uint16_t gdt_code_segment_selector, task_func_t *entrypoint )
+{
+ memset( task, 0, sizeof( task_t ) );
+
+ task->cpu_state = (cpu_state_t *)( task->stack + TASK_STACK_SIZE - sizeof( cpu_state_t ) );
+
+ task->cpu_state->eax = 0;
+ task->cpu_state->ebx = 0;
+ task->cpu_state->ecx = 0;
+ task->cpu_state->edx = 0;
+ task->cpu_state->esi = 0;
+ task->cpu_state->edi = 0;
+ task->cpu_state->ebp = 0;
+
+ // neded for security spaces and users
+ //~ task->cpu_state->esp = 0;
+ //~ task->cpu_state->ss = 0;
+
+ task->cpu_state->eip = (uint32_t)entrypoint;
+ task->cpu_state->cs = gdt_code_segment_selector;
+
+ // TODO: why?
+ task->cpu_state->eflags = 0x202;
+
+ //~ task->cpu_state->error = 0;
+
+ //~ task->cpu_state->gs = 0;
+ //~ task->cpu_state->fs = 0;
+ //~ task->cpu_state->es = 0;
+ //~ task->cpu_state->ds = 0;
+}
+
+void task_manager_init( task_manager_t *manager )
+{
+ memset( manager, 0, sizeof( task_manager_t ) );
+
+ manager->nof_tasks = 0;
+ manager->current_task = -1;
+ memset( manager->task, 0, MAX_NOF_TASKS * sizeof( task_t * ) );
+}
+
+void task_manager_add_task( task_manager_t *manager, task_t *task )
+{
+ if( manager->nof_tasks >= MAX_NOF_TASKS - 1 ) {
+ kernel_panic( "Allocating more than %d tasks.. increase kernel constant MAX_NOF_TASKS", MAX_NOF_TASKS );
+ }
+
+ manager->task[manager->nof_tasks] = task;
+ manager->nof_tasks++;
+}
+
+cpu_state_t *task_manager_schedule_task( task_manager_t *manager, cpu_state_t *cpu_state )
+{
+ // no tasks, no task switch
+ if( manager->nof_tasks == 0 ) {
+ return cpu_state;
+ }
+
+ // store state of the current task
+ if( manager->current_task >= 0 ) {
+ manager->task[manager->current_task]->cpu_state = cpu_state;
+ }
+
+ // pick next task (simple round robin)
+ manager->current_task++;
+ if( manager->current_task >= manager->nof_tasks ) {
+ manager->current_task = 0;
+ }
+
+ return manager->task[manager->current_task]->cpu_state;
+}
diff --git a/src/kernel/tasks.h b/src/kernel/tasks.h
new file mode 100644
index 0000000..604c463
--- /dev/null
+++ b/src/kernel/tasks.h
@@ -0,0 +1,64 @@
+#ifndef TASKS_H
+#define TASKS_H
+
+#include <stdint.h>
+
+#define TASK_STACK_SIZE 4096
+
+#if defined( __TINYC__ )
+#pragma pack(1)
+#endif
+
+typedef struct {
+ // pushed by us
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+
+ // really needed?
+ //~ uint32_t gs;
+ //~ uint32_t fs;
+ //~ uint32_t es;
+ //~ uint32_t ds;
+
+ // ?
+ uint32_t error;
+
+ // pushed by the CPU
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
+} __attribute__( ( packed ) ) cpu_state_t;
+
+#if defined( __TINYC__ )
+#pragma pack()
+#endif
+
+typedef struct {
+ uint8_t stack[TASK_STACK_SIZE];
+ cpu_state_t *cpu_state;
+} task_t;
+
+typedef void (*task_func_t)( void );
+
+void task_init( task_t *task, uint16_t gdt_code_segment_selector, task_func_t *entrypoint );
+
+#define MAX_NOF_TASKS 256
+
+typedef struct {
+ int nof_tasks;
+ int current_task;
+ task_t *task[MAX_NOF_TASKS];
+} task_manager_t;
+
+void task_manager_init( task_manager_t *manager );
+void task_manager_add_task( task_manager_t *manager, task_t *task );
+cpu_state_t *task_manager_schedule_task( task_manager_t *manager, cpu_state_t *cpu_state );
+
+#endif // TASKS_H