Savepoint, trying to implement tasks but it aint workin
This commit is contained in:
parent
0d81f79a96
commit
bb441eaeb6
2
Makefile
2
Makefile
|
@ -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
0
arch/i686/ata.c
Normal 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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
62
arch/i686/interrupts/irq0.s
Normal file
62
arch/i686/interrupts/irq0.s
Normal 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
|
||||
|
||||
|
|
@ -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
0
include/kernel/io/ata.h
Normal file
38
include/kernel/task.h
Normal file
38
include/kernel/task.h
Normal 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);
|
20
kernel/elf.c
20
kernel/elf.c
|
@ -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
0
kernel/io/fat.c
Normal 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
141
kernel/task.c
Normal 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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue