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/syscall.o \
|
||||||
kernel/io/keyboard.o \
|
kernel/io/keyboard.o \
|
||||||
kernel/heap.o \
|
kernel/heap.o \
|
||||||
|
kernel/task.o \
|
||||||
|
|
||||||
LIB_OBJS=\
|
LIB_OBJS=\
|
||||||
$(ARCHDIR)/bootstrap.o \
|
$(ARCHDIR)/bootstrap.o \
|
||||||
|
@ -32,6 +33,7 @@ $(ARCHDIR)/tty.o \
|
||||||
$(ARCHDIR)/strlib.o \
|
$(ARCHDIR)/strlib.o \
|
||||||
$(ARCHDIR)/interrupts/idt.o \
|
$(ARCHDIR)/interrupts/idt.o \
|
||||||
$(ARCHDIR)/interrupts/interrupt.o \
|
$(ARCHDIR)/interrupts/interrupt.o \
|
||||||
|
$(ARCHDIR)/interrupts/irq0.o \
|
||||||
$(ARCHDIR)/interrupts/syscall.o \
|
$(ARCHDIR)/interrupts/syscall.o \
|
||||||
$(ARCHDIR)/gdt.o \
|
$(ARCHDIR)/gdt.o \
|
||||||
$(ARCHDIR)/userland.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 IRQ6 (IRQ0 + 6)
|
||||||
#define IRQ7 (IRQ0 + 7)
|
#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
|
#define NUM_ENTRIES 0x100
|
||||||
|
|
||||||
struct InterruptDescriptor {
|
struct InterruptDescriptor {
|
||||||
|
@ -97,21 +106,20 @@ static void load_idt()
|
||||||
idt.base = entries;
|
idt.base = entries;
|
||||||
|
|
||||||
asm ( "lidt %0" : : "m"(idt) );
|
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;
|
struct InterruptDescriptor entry;
|
||||||
entry.present = present;
|
entry.present = present;
|
||||||
entry.offset = (uint32_t)isr;
|
entry.offset = (size_t)isr;
|
||||||
entry.gate_type = gate_type;
|
entry.gate_type = gate_type;
|
||||||
entry.ring = ring;
|
entry.ring = ring;
|
||||||
entry.selector = selector;
|
entry.selector = selector;
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void idt_init()
|
static void add_exceptions()
|
||||||
{
|
{
|
||||||
struct InterruptDescriptor entry;
|
struct InterruptDescriptor entry;
|
||||||
|
|
||||||
|
@ -130,23 +138,47 @@ void idt_init()
|
||||||
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
|
entry = generate_entry(true, double_fault, 0xF, 0, 0x8);
|
||||||
add_entry(entry, DoubleFault);
|
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++)
|
for (int i = IRQ0; i <= IRQ7; i++)
|
||||||
{
|
{
|
||||||
add_entry(entry, 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);
|
entry = generate_entry(true, keyboard_interrupt, 0xE, 0, 0x8);
|
||||||
add_entry(entry, IRQ1);
|
add_entry(entry, IRQ1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_syscall()
|
||||||
|
{
|
||||||
struct InterruptDescriptor syscall_entry;
|
struct InterruptDescriptor syscall_entry;
|
||||||
syscall_entry.present = true;
|
syscall_entry.present = true;
|
||||||
syscall_entry.offset = (uint32_t)syscall;
|
syscall_entry.offset = (size_t)syscall;
|
||||||
syscall_entry.gate_type = 0xE;
|
syscall_entry.gate_type = 0xE;
|
||||||
syscall_entry.ring = 3;
|
syscall_entry.ring = 3;
|
||||||
syscall_entry.selector = 0x8;
|
syscall_entry.selector = 0x8;
|
||||||
|
|
||||||
add_entry(syscall_entry, 0x80);
|
add_entry(syscall_entry, 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_init()
|
||||||
|
{
|
||||||
|
add_exceptions();
|
||||||
|
add_irqs();
|
||||||
|
add_syscall();
|
||||||
|
|
||||||
load_idt();
|
load_idt();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
|
#include <kernel/task.h>
|
||||||
|
#include "interrupt.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
#include <kernel/io/keyboard.h>
|
#include <kernel/io/keyboard.h>
|
||||||
#include "../io.h"
|
#include "../io.h"
|
||||||
|
|
||||||
struct interrupt_frame {
|
|
||||||
uint32_t eflags;
|
|
||||||
uint32_t cs;
|
|
||||||
uint32_t eip;
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t test = 'a';
|
uint8_t test = 'a';
|
||||||
|
|
||||||
static void stack_trace()
|
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");
|
terminal_writestring("Yo dude u cant divide by zero yao\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void general_protection_fault(void*)
|
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
terminal_writestring("GPF handler called\n");
|
terminal_writestring("GPF handler called\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void double_fault(void*)
|
__attribute__((interrupt)) void double_fault(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
stack_trace();
|
stack_trace();
|
||||||
terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
|
terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void exception(void*)
|
__attribute__((interrupt)) void exception(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
terminal_writestring("Some weird error code stuff\n");
|
terminal_writestring("Some weird error code stuff\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void keyboard_interrupt(void*)
|
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
uint8_t scancode = inb(0x60);
|
uint8_t scancode = inb(0x60);
|
||||||
handle_keyboard(scancode);
|
handle_keyboard(scancode);
|
||||||
outb(0x20, 0x20);
|
outb(0x20, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void irq(void*)
|
__attribute__((interrupt)) void irq_1(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
outb(0x20, 0x20);
|
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 divide_by_zero(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void general_protection_fault(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 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 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,9 +21,10 @@
|
||||||
|
|
||||||
void init_pic() {
|
void init_pic() {
|
||||||
uint8_t a1;
|
uint8_t a1;
|
||||||
|
uint8_t a2;
|
||||||
|
|
||||||
a1 = inb(PIC1_DATA); // save masks
|
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)
|
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode)
|
||||||
io_wait();
|
io_wait();
|
||||||
|
@ -31,7 +32,7 @@ void init_pic() {
|
||||||
io_wait();
|
io_wait();
|
||||||
outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset
|
outb(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset
|
||||||
io_wait();
|
io_wait();
|
||||||
outb(PIC2_DATA, 0xFF); // ICW2: Slave PIC vector offset
|
outb(PIC2_DATA, 0x28); // ICW2: Slave PIC vector offset
|
||||||
io_wait();
|
io_wait();
|
||||||
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
|
||||||
io_wait();
|
io_wait();
|
||||||
|
@ -45,5 +46,5 @@ void init_pic() {
|
||||||
|
|
||||||
outb(PIC1_DATA, a1); // restore saved masks.
|
outb(PIC1_DATA, a1); // restore saved masks.
|
||||||
// outb(PIC2_DATA, a2);
|
// 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 <debugging.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/gdt.h>
|
#include <kernel/gdt.h>
|
||||||
|
#include <kernel/task.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
|
||||||
static void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) {
|
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;
|
uint8_t* userland_code = (uint8_t*) 0x00800000;
|
||||||
memcpy(userland_code, program, length);
|
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/elf.h>
|
||||||
#include <kernel/pic.h>
|
#include <kernel/pic.h>
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
|
#include <kernel/task.h>
|
||||||
|
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ uint8_t program[] = {
|
||||||
0xcd, 0x80, // int 0x80
|
0xcd, 0x80, // int 0x80
|
||||||
0xba, 0x00, 0x00, 0x00, 0x00, // mov 0, %edx
|
0xba, 0x00, 0x00, 0x00, 0x00, // mov 0, %edx
|
||||||
0xcd, 0x80, // int 0x80
|
0xcd, 0x80, // int 0x80
|
||||||
|
0xcd, 0x20, // int 0x20
|
||||||
0xb9, 0x00, 0x00, 0x80, 0x00, // mov $start, %ecx
|
0xb9, 0x00, 0x00, 0x80, 0x00, // mov $start, %ecx
|
||||||
0xff, 0xe1, // jmp *%ecx
|
0xff, 0xe1, // jmp *%ecx
|
||||||
};
|
};
|
||||||
|
@ -26,9 +28,18 @@ void kernel_main(void)
|
||||||
/* Initialize terminal interface */
|
/* Initialize terminal interface */
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
|
|
||||||
init_pic();
|
|
||||||
idt_init();
|
idt_init();
|
||||||
|
init_pic();
|
||||||
heap_init();
|
heap_init();
|
||||||
|
|
||||||
|
setup_tasks();
|
||||||
|
|
||||||
|
asm("sti");
|
||||||
|
|
||||||
run_program(program, sizeof(program));
|
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