Initial kthread implementation
This commit is contained in:
parent
5141044c06
commit
2c0f54926d
2
Makefile
2
Makefile
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
38
core/irq_pit.S
Normal 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 */
|
34
core/klibc.c
34
core/klibc.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
67
core/kthread.c
Normal 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
26
core/kthread.h
Normal 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);
|
19
core/main.c
19
core/main.c
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user