From e6efe69c614d7781d18a7189831e8243abf57664 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 2 Jul 2017 21:39:09 +0200 Subject: started to add task scheduling --- src/Makefile | 6 ++++- src/drivers/driver.c | 2 +- src/kernel/kernel.c | 3 +++ src/kernel/tasks.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/kernel/tasks.h | 64 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 src/kernel/tasks.c create mode 100644 src/kernel/tasks.h (limited to 'src') 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 + +#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 -- cgit v1.2.3-54-g00ecf