Savepoint, trying to implement tasks but it aint workin

This commit is contained in:
vanten-s 2024-08-22 13:41:51 +02:00
parent 0d81f79a96
commit bb441eaeb6
Signed by: vanten-s
GPG key ID: DE3060396884D3F2
13 changed files with 344 additions and 27 deletions

View file

@ -25,6 +25,7 @@ kernel/elf.o \
kernel/syscall.o \
kernel/io/keyboard.o \
kernel/heap.o \
kernel/task.o \
LIB_OBJS=\
$(ARCHDIR)/bootstrap.o \
@ -32,6 +33,7 @@ $(ARCHDIR)/tty.o \
$(ARCHDIR)/strlib.o \
$(ARCHDIR)/interrupts/idt.o \
$(ARCHDIR)/interrupts/interrupt.o \
$(ARCHDIR)/interrupts/irq0.o \
$(ARCHDIR)/interrupts/syscall.o \
$(ARCHDIR)/gdt.o \
$(ARCHDIR)/userland.o \

0
arch/i686/ata.c Normal file
View file

View file

@ -15,6 +15,15 @@
#define IRQ6 (IRQ0 + 6)
#define IRQ7 (IRQ0 + 7)
#define IRQ8 0x28
#define IRQ9 (IRQ8 + 1)
#define IRQ10 (IRQ8 + 2)
#define IRQ11 (IRQ8 + 3)
#define IRQ12 (IRQ8 + 4)
#define IRQ13 (IRQ8 + 5)
#define IRQ14 (IRQ8 + 6)
#define IRQ15 (IRQ8 + 7)
#define NUM_ENTRIES 0x100
struct InterruptDescriptor {
@ -97,21 +106,20 @@ static void load_idt()
idt.base = entries;
asm ( "lidt %0" : : "m"(idt) );
asm ( "sti" );
}
struct InterruptDescriptor generate_entry(bool present, void isr(struct interrupt_frame*), uint8_t gate_type, uint8_t ring, uint8_t selector)
static struct InterruptDescriptor generate_entry(bool present, void isr(struct interrupt_frame*), uint8_t gate_type, uint8_t ring, uint8_t selector)
{
struct InterruptDescriptor entry;
entry.present = present;
entry.offset = (uint32_t)isr;
entry.offset = (size_t)isr;
entry.gate_type = gate_type;
entry.ring = ring;
entry.selector = selector;
return entry;
}
void idt_init()
static void add_exceptions()
{
struct InterruptDescriptor entry;
@ -130,23 +138,47 @@ void idt_init()
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
add_entry(entry, DoubleFault);
entry = generate_entry(true, irq, 0xE, 0, 0x8);
}
static void add_irqs()
{
struct InterruptDescriptor entry;
entry = generate_entry(true, irq_1, 0xE, 0, 0x8);
for (int i = IRQ0; i <= IRQ7; i++)
{
add_entry(entry, i);
}
entry = generate_entry(true, irq_2, 0xE, 0, 0x8);
for (int i = IRQ8; i <= IRQ15; i++)
{
add_entry(entry, i);
}
entry = generate_entry(true, irq0, 0xE, 0, 0x8);
add_entry(entry, IRQ0);
entry = generate_entry(true, keyboard_interrupt, 0xE, 0, 0x8);
add_entry(entry, IRQ1);
}
static void add_syscall()
{
struct InterruptDescriptor syscall_entry;
syscall_entry.present = true;
syscall_entry.offset = (uint32_t)syscall;
syscall_entry.offset = (size_t)syscall;
syscall_entry.gate_type = 0xE;
syscall_entry.ring = 3;
syscall_entry.selector = 0x8;
add_entry(syscall_entry, 0x80);
}
void idt_init()
{
add_exceptions();
add_irqs();
add_syscall();
load_idt();
}

View file

@ -1,15 +1,11 @@
#include <kernel/tty.h>
#include <kernel/task.h>
#include "interrupt.h"
#include <stddef.h>
#include <debugging.h>
#include <kernel/io/keyboard.h>
#include "../io.h"
struct interrupt_frame {
uint32_t eflags;
uint32_t cs;
uint32_t eip;
};
uint8_t test = 'a';
static void stack_trace()
@ -25,40 +21,45 @@ static void stack_trace()
}
}
__attribute__((interrupt)) void divide_by_zero(void*)
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame*)
{
terminal_writestring("Yo dude u cant divide by zero yao\n");
while (1) { }
}
__attribute__((interrupt)) void general_protection_fault(void*)
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*)
{
terminal_writestring("GPF handler called\n");
while (1) { }
}
__attribute__((interrupt)) void double_fault(void*)
__attribute__((interrupt)) void double_fault(struct interrupt_frame*)
{
stack_trace();
terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
while (1) { }
}
__attribute__((interrupt)) void exception(void*)
__attribute__((interrupt)) void exception(struct interrupt_frame*)
{
terminal_writestring("Some weird error code stuff\n");
while (1) { }
}
__attribute__((interrupt)) void keyboard_interrupt(void*)
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*)
{
uint8_t scancode = inb(0x60);
handle_keyboard(scancode);
outb(0x20, 0x20);
}
__attribute__((interrupt)) void irq(void*)
__attribute__((interrupt)) void irq_1(struct interrupt_frame*)
{
outb(0x20, 0x20);
}
__attribute__((interrupt)) void irq_2(struct interrupt_frame*)
{
outb(0xA0, 0x20);
outb(0x20, 0x20);
}

View file

@ -1,4 +1,12 @@
struct interrupt_frame;
#include <stddef.h>
struct interrupt_frame {
size_t eip;
size_t cs;
size_t eflags;
size_t ss;
size_t esp;
};
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame* frame);
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame* frame);
@ -6,7 +14,10 @@ __attribute__((interrupt)) void double_fault(struct interrupt_frame* frame);
__attribute__((interrupt)) void exception(struct interrupt_frame* frame);
__attribute__((interrupt)) void syscall(void*);
__attribute__((interrupt)) void syscall(struct interrupt_frame* frame);
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame);
__attribute__((interrupt)) void irq(struct interrupt_frame* frame);
__attribute__((interrupt)) void irq_1(struct interrupt_frame* frame);
__attribute__((interrupt)) void irq_2(struct interrupt_frame* frame);
__attribute__((interrupt)) void irq0(struct interrupt_frame* frame);

View file

@ -0,0 +1,62 @@
.global irq0
.extern _switch_task
.global jump_kernel
.global jump_user
.extern ss
.extern esp
.extern eflags
.extern cs
.extern eip
irq0:
push %esp
push %ebp
push %edx
push %ecx
push %ebx
push %eax
call _switch_task
iret
jump_kernel:
pop %eax /* pop return instruction */
pop %eax
pop %ebx
pop %ecx
pop %edx
pop %ebp
pop %esp
push (eflags)
push (cs)
push (eip)
iret
jump_user:
pop %eax /* pop return instruction */
pop %eax
pop %ebx
pop %ecx
pop %edx
pop %ebp
push (ss)
push (esp)
push (eflags)
push (cs)
push (eip)
iret

View file

@ -21,17 +21,18 @@
void init_pic() {
uint8_t a1;
uint8_t a2;
a1 = inb(PIC1_DATA); // save masks
inb(PIC2_DATA);
a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset
io_wait();
outb(PIC2_DATA, 0xFF); // ICW2: Slave PIC vector offset
outb(PIC2_DATA, 0x28); // ICW2: Slave PIC vector offset
io_wait();
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
io_wait();
@ -45,5 +46,5 @@ void init_pic() {
outb(PIC1_DATA, a1); // restore saved masks.
// outb(PIC2_DATA, a2);
outb(PIC2_DATA, 0xFF);
outb(PIC2_DATA, a2);
}

0
include/kernel/io/ata.h Normal file
View file

38
include/kernel/task.h Normal file
View file

@ -0,0 +1,38 @@
#include <stdint.h>
#include <stddef.h>
struct CPUState {
size_t eax;
size_t ebx;
size_t ecx;
size_t edx;
size_t eip;
size_t esp;
size_t ebp;
size_t cs;
size_t ds;
size_t eflags;
};
struct Task {
struct CPUState state;
};
void switch_task(
size_t eax,
size_t ebx,
size_t ecx,
size_t edx,
size_t ebp,
size_t esp_real,
size_t eip,
size_t cs,
size_t eflags,
size_t esp_fake,
size_t ds
);
void setup_tasks();
void add_task(struct Task task);

View file

@ -3,6 +3,7 @@
#include <debugging.h>
#include <kernel/tty.h>
#include <kernel/gdt.h>
#include <kernel/task.h>
#include <debugging.h>
static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) {
@ -20,5 +21,22 @@ void run_program(uint8_t* program, size_t length)
uint8_t* userland_code = (uint8_t*) 0x00800000;
memcpy(userland_code, program, length);
jump_to_userspace();
struct CPUState target = {
.eip = (size_t) userland_code,
.esp = 0x00c00100,
.eax = 0,
.ebx = 0,
.ecx = 0,
.edx = 0,
.cs = 0x18 | 0x3,
.ds = 0x20 | 0x3,
.eflags = 0x0200,
.ebp = 0x00c00100,
};
struct Task task = {
.state = target,
};
add_task(task);
}

0
kernel/io/fat.c Normal file
View file

View file

@ -3,6 +3,7 @@
#include <kernel/elf.h>
#include <kernel/pic.h>
#include <kernel/heap.h>
#include <kernel/task.h>
#include <debugging.h>
@ -17,6 +18,7 @@ uint8_t program[] = {
0xcd, 0x80, // int 0x80
0xba, 0x00, 0x00, 0x00, 0x00, // mov 0, %edx
0xcd, 0x80, // int 0x80
0xcd, 0x20, // int 0x20
0xb9, 0x00, 0x00, 0x80, 0x00, // mov $start, %ecx
0xff, 0xe1, // jmp *%ecx
};
@ -26,9 +28,18 @@ void kernel_main(void)
/* Initialize terminal interface */
terminal_initialize();
init_pic();
idt_init();
init_pic();
heap_init();
setup_tasks();
asm("sti");
run_program(program, sizeof(program));
while (true) {
asm("hlt");
}
}

141
kernel/task.c Normal file
View file

@ -0,0 +1,141 @@
#include <kernel/task.h>
#include <kernel/heap.h>
struct Task* tasks;
size_t tasks_capacity;
size_t num_tasks;
size_t current_task = 0;
void setup_tasks()
{
tasks = malloc(sizeof(*tasks));
tasks_capacity = 1;
num_tasks = 1;
}
void add_task(struct Task task)
{
if (num_tasks == tasks_capacity) {
struct Task* temp = malloc(sizeof(*tasks) * tasks_capacity * 2);
for (size_t i = 0; i < num_tasks; i++) {
temp[i] = tasks[i];
}
tasks_capacity *= 2;
free(tasks);
tasks = temp;
}
tasks[num_tasks] = task;
num_tasks++;
}
size_t ss;
size_t esp;
size_t eflags;
size_t cs;
size_t eip;
void jump_kernel(size_t eax, size_t ebx, size_t ecx, size_t edx, size_t ebp, size_t esp);
void jump_user(size_t eax, size_t ebx, size_t ecx, size_t edx, size_t ebp);
static void save_state(
size_t eax,
size_t ebx,
size_t ecx,
size_t edx,
size_t esp,
size_t ebp,
size_t eip,
size_t cs,
size_t ds,
size_t eflags
) {
struct CPUState state = {
.eax = eax,
.ebx = ebx,
.ecx = ecx,
.edx = edx,
.esp = esp,
.ebp = ebp,
.eip = eip,
.cs = cs,
.ds = ds,
.eflags = eflags,
};
tasks[current_task].state = state;
current_task++;
current_task %= num_tasks;
}
void next_task() {
struct CPUState s = tasks[current_task].state;
ss = s.ds;
esp = s.esp;
eflags = s.eflags;
cs = s.cs;
eip = s.eip;
if ((cs & 3) == 0) {
jump_kernel(s.eax, s.ebx, s.ecx, s.edx, s.ebp, s.esp);
} else {
jump_user(s.eax, s.ebx, s.ecx, s.edx, s.ebp);
}
}
void _switch_task(
size_t eax,
size_t ebx,
size_t ecx,
size_t edx,
size_t ebp,
size_t esp_current,
size_t eip_passed,
size_t cs_passed,
size_t eflags_passed,
size_t esp_passed,
size_t ds_passed
)
{
if (num_tasks == 0) {
return;
};
size_t ds;
if ((cs & 3) == 0) {
ds = 0x10;
esp_current = esp_current + sizeof(size_t) * 3;
} else {
ds = ds_passed;
esp_current = esp_passed;
}
ss = ds_passed;
esp = esp_passed;
eflags = eflags_passed;
cs = cs_passed;
eip = eip_passed;
save_state(eax, ebx, ecx, edx, esp, ebp, eip_passed, cs_passed, ds, eflags_passed);
next_task();
}