Initial kthread implementation

This commit is contained in:
Mathieu Maret 2020-04-23 00:49:09 +02:00
parent 5141044c06
commit 2c0f54926d
11 changed files with 191 additions and 11 deletions

View File

@ -15,7 +15,7 @@ CPPFLAGS += $(foreach dir, $(SUBDIRS), -I$(dir))
asmsrc=$(wildcard *.asm) asmsrc=$(wildcard *.asm)
asmobj=$(asmsrc:%.asm=%.o) asmobj=$(asmsrc:%.asm=%.o)
csrc=$(shell find $(SUBDIRS) -type f -name "*.c")# $(wildcard *.c) csrc=$(shell find $(SUBDIRS) -type f -name "*.c")# $(wildcard *.c)
cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o core/irq_pit.o
deps = $(csrc:%.c=%.d) deps = $(csrc:%.c=%.d)
kernel:$(asmobj) $(cobj) linker.ld kernel:$(asmobj) $(cobj) linker.ld

View File

@ -12,8 +12,8 @@ cpu_context_switch:
pushf // (eflags) esp+56 pushf // (eflags) esp+56
pushl %cs // (cs) esp+52 pushl %cs // (cs) esp+52
pushl $resume_pc // (ip) esp+48 pushl $resume_pc // (ip) esp+48
pushl $0 // (error code) esp+44 pushl $0 // (error code) esp+12+8x4
pushal // (general reg) esp+12+8*4 pushal // (general reg) esp+12
subl $2, %esp // (alignment) esp+10 subl $2, %esp // (alignment) esp+10
pushw %ss // esp+8 pushw %ss // esp+8
pushw %ds // esp+6 pushw %ds // esp+6

View File

@ -16,6 +16,7 @@ void print_handler(struct interrupt_frame *frame, ulong error_code);
void pagefault_handler(struct interrupt_frame *frame, ulong error_code); void pagefault_handler(struct interrupt_frame *frame, ulong error_code);
// IRQ // IRQ
void pit_handler(struct interrupt_frame *frame);
void keyboard_handler(struct interrupt_frame *frame); void keyboard_handler(struct interrupt_frame *frame);
void timer_handler(struct interrupt_frame *frame); void timer_handler(struct interrupt_frame *frame);
void serial_handler(struct interrupt_frame *frame); void serial_handler(struct interrupt_frame *frame);

38
core/irq_pit.S Normal file
View File

@ -0,0 +1,38 @@
.file "irq_pit.S"
.text
.extern selectNextThread
.globl pit_handler
.type pit_handler, @function
pit_handler: // already got eflags, cs and eip on stack thanks to CPU
pushl $0 // err_code esp+12+8*4=44
pushal // (general reg) esp+12
subl $2, %esp // (alignment) esp+10
pushw %ss // esp+8
pushw %ds // esp+6
pushw %es // esp+4
pushw %fs // esp+2
pushw %gs // esp
/* Send EOI to PIC */
movb $0x20, %al
outb %al, $0x20
pushl %esp
call selectNextThread
movl %eax,%esp
/* Restore the CPU context */
popw %gs
popw %fs
popw %es
popw %ds
popw %ss
addl $2,%esp
popal
addl $4, %esp /* Ignore "error code" */
/* This restores the eflags, the cs and the eip registers */
iret /* equivalent to: popfl ; ret */

View File

@ -80,7 +80,7 @@ void reverse(char s[])
} }
/* K&R */ /* K&R */
int strlen(char s[]) int strlen(const char s[])
{ {
int i = 0; int i = 0;
while (s[i] != '\0') while (s[i] != '\0')
@ -90,7 +90,7 @@ int strlen(char s[])
/* K&R /* K&R
* Returns <0 if s1<s2, 0 if s1==s2, >0 if s1>s2 */ * Returns <0 if s1<s2, 0 if s1==s2, >0 if s1>s2 */
int strcmp(char s1[], char s2[]) int strcmp(const char s1[], const char s2[])
{ {
int i; int i;
for (i = 0; s1[i] == s2[i]; i++) { for (i = 0; s1[i] == s2[i]; i++) {
@ -100,6 +100,33 @@ int strcmp(char s1[], char s2[])
return s1[i] - s2[i]; return s1[i] - s2[i];
} }
unsigned int strnlen(const char *s, size_t count)
{
const char *sc;
for (sc = s; count-- && *sc != '\0'; ++sc)
/* nothing */ continue;
return sc - s;
}
char *strzcpy(register char *dst, register const char *src, register int len)
{
int i;
if (len <= 0)
return dst;
for (i = 0; i < len; i++) {
dst[i] = src[i];
if (src[i] == '\0')
return dst;
}
dst[len - 1] = '\0';
return dst;
}
void printf(const char *format, ...) void printf(const char *format, ...)
{ {
va_list ap; va_list ap;
@ -115,7 +142,8 @@ void puts(const char *str)
} }
} }
void putc(const char str){ void putc(const char str)
{
VGAputc(str); VGAputc(str);
serialPutc(str); serialPutc(str);
} }

View File

@ -14,8 +14,10 @@ void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n); void *memset(void *s, int c, size_t n);
char *itoa(int value, char *str, int base); char *itoa(int value, char *str, int base);
void reverse(char s[]); void reverse(char s[]);
int strlen(char s[]); int strlen(const char s[]);
int strcmp(char s1[], char s2[]); unsigned int strnlen(const char * s, size_t count);
int strcmp(const char s1[], const char s2[]);
char *strzcpy(char *dst, const char *src, int len);
void puts(const char *str); void puts(const char *str);
void putc(const char str); void putc(const char str);
void printInt(int integer); void printInt(int integer);

67
core/kthread.c Normal file
View File

@ -0,0 +1,67 @@
#include "kthread.h"
#include "list.h"
#include "alloc.h"
#include "klibc.h"
static struct kthread *currentThread;
void _kthread_exit(){
//TODO
return;
}
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize){
struct kthread * current = (struct kthread *)malloc(sizeof(struct kthread));
strzcpy(current->name, "[KINIT]", KTHREAD_NAME_MAX_LENGTH);
current->stackAddr = mainStack;
current->stackSize = mainStackSize;
list_singleton(currentThread, current);
return 0;
}
struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func,
void *args)
{
struct kthread *thread = (struct kthread *)malloc(sizeof(struct kthread));
if (!thread)
return NULL;
thread->stackAddr = (vaddr_t) malloc(KTHREAD_DEFAULT_STACK_SIZE);
thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE;
if(!thread->stackAddr)
goto free_mem;
if(name)
strzcpy(thread->name, name, KTHREAD_NAME_MAX_LENGTH);
else
strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH);
if(cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
thread->stackAddr, thread->stackSize,
(cpu_kstate_function_arg1_t *)_kthread_exit, 0))
goto free_mem;
list_add_tail(currentThread, thread);
return thread;
free_mem:
free((void *)thread->stackAddr);
free((void *)thread);
return NULL;
}
void deleteKthread(struct kthread *thread){
list_delete(currentThread, thread);
free((void *)thread->stackAddr);
free((void *)thread);
}
struct cpu_state *selectNextThread(struct cpu_state *prevCpu){
currentThread->cpuState = prevCpu;
struct kthread *nextThread = currentThread->next;
currentThread = nextThread;
return nextThread->cpuState;
}

26
core/kthread.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include "cpu_context.h"
#include "mem.h"
#define KTHREAD_NAME_MAX_LENGTH 32
#define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE
struct kthread {
char name[KTHREAD_NAME_MAX_LENGTH];
struct cpu_state *cpuState;
vaddr_t stackAddr;
size_t stackSize;
struct kthread *next;
struct kthread *prev;
};
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize);
struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func,
void *args);
void deleteKthread(struct kthread *thread);
struct cpu_state *selectNextThread(struct cpu_state *prev_cpu);

View File

@ -6,11 +6,13 @@
#include "io.h" #include "io.h"
#include "irq.h" #include "irq.h"
#include "klibc.h" #include "klibc.h"
#include "kthread.h"
#include "mem.h" #include "mem.h"
#include "multiboot.h" #include "multiboot.h"
#include "paging.h" #include "paging.h"
#include "pit.h" #include "pit.h"
#include "serial.h" #include "serial.h"
#include "stack.h"
#include "stdarg.h" #include "stdarg.h"
#ifdef RUN_TEST #ifdef RUN_TEST
#include "test.h" #include "test.h"
@ -24,6 +26,18 @@ void cpuid(int code, uint32_t *a, uint32_t *d)
asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx"); asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx");
} }
void idleThread(void *arg){
(void)arg;
while(1)
printf(".");
}
void dashThread(void *arg){
(void)arg;
while(1)
printf("-");
}
// Multiboot information available here : // Multiboot information available here :
// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec // https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec
// https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format // https://www.gnu.org/software/grub/manual/multiboot/html_node/Boot-information-format.html#Boot%20information%20format
@ -99,7 +113,6 @@ void kmain(unsigned long magic, unsigned long addr)
printf("Setting up IRQ handlers\n"); printf("Setting up IRQ handlers\n");
irqSetRoutine(IRQ_KEYBOARD, keyboard_handler); irqSetRoutine(IRQ_KEYBOARD, keyboard_handler);
irqSetRoutine(IRQ_TIMER, timer_handler);
printf("Enabling HW interrupts\n"); printf("Enabling HW interrupts\n");
exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, print_handler); exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, print_handler);
@ -110,6 +123,10 @@ void kmain(unsigned long magic, unsigned long addr)
printf("Setting up Serial link (115200)\n"); printf("Setting up Serial link (115200)\n");
serialSetup(115200); serialSetup(115200);
allocInit(); allocInit();
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
createKthread("idle", idleThread, NULL);
createKthread("dash", dashThread, NULL);
irqSetRoutine(IRQ_TIMER, pit_handler);
#ifdef RUN_TEST #ifdef RUN_TEST
run_test(); run_test();
#endif #endif

View File

@ -2,8 +2,6 @@
#include "types.h" #include "types.h"
#include "klibc.h" #include "klibc.h"
extern vaddr_t _stack_bottom;
extern vaddr_t _stack_top;
void printStackTrace(unsigned int maxFrames) void printStackTrace(unsigned int maxFrames)
{ {
#ifdef DEBUG #ifdef DEBUG

View File

@ -1,3 +1,6 @@
#pragma once #pragma once
#include "types.h"
extern vaddr_t _stack_bottom;
extern vaddr_t _stack_top;
void printStackTrace(unsigned int maxFrame); void printStackTrace(unsigned int maxFrame);