Add tasking (No usermode support)
This commit is contained in:
parent
f1334567e1
commit
fdd7afa1c8
@ -1,10 +1,12 @@
|
||||
#include "gdt.h"
|
||||
#include "paging.h"
|
||||
#include "isr.h"
|
||||
#include "../tasking.h"
|
||||
|
||||
void cpu_init() {
|
||||
gdt_init();
|
||||
isr_install();
|
||||
asm volatile("sti");
|
||||
paging_init();
|
||||
tasking_init();
|
||||
}
|
||||
|
99
cpu/i386/tasking.c
Normal file
99
cpu/i386/tasking.c
Normal file
@ -0,0 +1,99 @@
|
||||
#include "tasking_helpers.h"
|
||||
#include "tasking.h"
|
||||
#include "../tasking.h"
|
||||
#include "isr.h"
|
||||
#include "../../libc/stdlib.h"
|
||||
#include "../../libc/stdio.h"
|
||||
#include "memory.h"
|
||||
#include <stdint.h>
|
||||
#define STACK_PAGES 2
|
||||
|
||||
uint32_t next_pid;
|
||||
|
||||
static Task* currentTask;
|
||||
static Task* headTask;
|
||||
|
||||
void tasking_init() {
|
||||
currentTask=NULL;
|
||||
next_pid=0;
|
||||
headTask=createTask(NULL);
|
||||
currentTask=headTask;
|
||||
}
|
||||
|
||||
Task* createTaskEax(void* eip,uint32_t eax) {
|
||||
Task* task=malloc(sizeof(Task));
|
||||
task->regs.eax=eax;
|
||||
task->regs.ebx=0;
|
||||
task->regs.ecx=0;
|
||||
task->regs.edx=0;
|
||||
task->regs.esi=0;
|
||||
task->regs.edi=0;
|
||||
asm volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(task->regs.eflags)::"%eax");
|
||||
task->regs.eip=(uint32_t)eip;
|
||||
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(task->regs.cr3)::"%eax");
|
||||
task->regs.esp=(uint32_t)alloc_memory(1);
|
||||
task->regs.ebp=0;
|
||||
task->msg_store=NULL;
|
||||
task->rd=0;
|
||||
task->wr=0;
|
||||
task->next=NULL;
|
||||
task->pid=next_pid;
|
||||
next_pid++;
|
||||
if (currentTask) {
|
||||
currentTask->next=task;
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
Task* createTask(void* eip) {
|
||||
return createTaskEax(eip,0);
|
||||
}
|
||||
|
||||
void send_msg(uint32_t pid,char* msg) {
|
||||
for (Task* task=headTask;task!=NULL;task=task->next) {
|
||||
if (task->pid==pid) {
|
||||
if (task->msg_store==NULL) {
|
||||
task->msg_store=malloc(sizeof(char*)*256);
|
||||
task->sender_store=malloc(sizeof(uint32_t)*256);
|
||||
}
|
||||
task->msg_store[task->wr]=msg;
|
||||
task->sender_store[task->wr]=currentTask->pid;
|
||||
task->wr++;
|
||||
if (task->wr==task->rd) {
|
||||
task->wr--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* get_msg(uint32_t* sender) {
|
||||
if (!currentTask->msg_store) {
|
||||
return NULL;
|
||||
}
|
||||
if (currentTask->msg_store[currentTask->rd]==NULL) {
|
||||
currentTask->rd++;
|
||||
if (currentTask->msg_store[currentTask->rd]==NULL) {
|
||||
currentTask->rd--;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*sender=currentTask->sender_store[currentTask->rd];
|
||||
char* data=currentTask->msg_store[currentTask->rd];
|
||||
currentTask->msg_store[currentTask->rd]=NULL;
|
||||
currentTask->sender_store[currentTask->rd]=0;
|
||||
currentTask->rd++;
|
||||
if (currentTask->rd>currentTask->wr) {
|
||||
currentTask->rd=currentTask->wr-1;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void yield() {
|
||||
Task* task=currentTask->next;
|
||||
if (!task) {
|
||||
task=headTask;
|
||||
}
|
||||
Task* oldCurr=currentTask;
|
||||
currentTask=task;
|
||||
switchTask(&oldCurr->regs, ¤tTask->regs);
|
||||
}
|
22
cpu/i386/tasking.h
Normal file
22
cpu/i386/tasking.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef INT_TASKING_H
|
||||
#define INT_TASKING_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3;
|
||||
} Registers;
|
||||
|
||||
typedef struct Task {
|
||||
Registers regs;
|
||||
struct Task* next;
|
||||
char** msg_store;
|
||||
uint32_t* sender_store;
|
||||
uint32_t msg_indx;
|
||||
uint8_t rd;
|
||||
uint8_t wr;
|
||||
uint32_t pid;
|
||||
} Task;
|
||||
|
||||
|
||||
#endif
|
9
cpu/i386/tasking_helpers.h
Normal file
9
cpu/i386/tasking_helpers.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef TASKING_HELPERS_H
|
||||
#define TASKING_HELPERS_H
|
||||
|
||||
#include "tasking.h"
|
||||
|
||||
void switchTask(Registers *from, Registers *to);
|
||||
uint32_t readEip();
|
||||
|
||||
#endif
|
53
cpu/i386/tasking_helpers.s
Normal file
53
cpu/i386/tasking_helpers.s
Normal file
@ -0,0 +1,53 @@
|
||||
.section .text
|
||||
.global switchTask
|
||||
switchTask:
|
||||
pusha
|
||||
pushf
|
||||
mov %cr3, %eax #Push CR3
|
||||
push %eax
|
||||
mov 44(%esp), %eax #The first argument, where to save
|
||||
mov %ebx, 4(%eax)
|
||||
mov %ecx, 8(%eax)
|
||||
mov %edx, 12(%eax)
|
||||
mov %esi, 16(%eax)
|
||||
mov %edi, 20(%eax)
|
||||
mov 36(%esp), %ebx #EAX
|
||||
mov 40(%esp), %ecx #IP
|
||||
mov 20(%esp), %edx #ESP
|
||||
add $4, %edx #Remove the return value ;)
|
||||
mov 16(%esp), %esi #EBP
|
||||
mov 4(%esp), %edi #EFLAGS
|
||||
mov %ebx, (%eax)
|
||||
mov %edx, 24(%eax)
|
||||
mov %esi, 28(%eax)
|
||||
mov %ecx, 32(%eax)
|
||||
mov %edi, 36(%eax)
|
||||
pop %ebx #CR3
|
||||
mov %ebx, 40(%eax)
|
||||
push %ebx #Goodbye again ;)
|
||||
mov 48(%esp), %eax #Now it is the new object
|
||||
mov 4(%eax), %ebx #EBX
|
||||
mov 8(%eax), %ecx #ECX
|
||||
mov 12(%eax), %edx #EDX
|
||||
mov 16(%eax), %esi #ESI
|
||||
mov 20(%eax), %edi #EDI
|
||||
mov 28(%eax), %ebp #EBP
|
||||
push %eax
|
||||
mov 36(%eax), %eax #EFLAGS
|
||||
push %eax
|
||||
popf
|
||||
pop %eax
|
||||
mov 24(%eax), %esp #ESP
|
||||
push %eax
|
||||
mov 40(%eax), %eax #CR3
|
||||
mov %eax, %cr3
|
||||
pop %eax
|
||||
push %eax
|
||||
mov 32(%eax), %eax #EIP
|
||||
xchg (%esp), %eax #We do not have any more registers to use as tmp storage
|
||||
mov (%eax), %eax #EAX
|
||||
ret #This ends all!
|
||||
.global readEip
|
||||
readEip:
|
||||
pop %eax
|
||||
jmp %eax
|
10
cpu/tasking.h
Normal file
10
cpu/tasking.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef TASKING_H
|
||||
#define TASKING_H
|
||||
#include "i386/tasking.h"
|
||||
|
||||
void tasking_init();
|
||||
void yield();
|
||||
Task* createTask(void* eip);
|
||||
void send_msg(uint32_t pid,char* msg);
|
||||
char* get_msg(uint32_t* sender);
|
||||
#endif
|
@ -1,10 +1,18 @@
|
||||
#include "../cpu/cpu_init.h"
|
||||
#include "../cpu/i386/ports.h"
|
||||
#include "../cpu/i386/tasking.h"
|
||||
#include "../drivers/vga.h"
|
||||
#include <grub/text_fb_info.h>
|
||||
#include <stdlib.h>
|
||||
#include "multiboot.h"
|
||||
|
||||
void task() {
|
||||
vga_write_string("TASK!\n");
|
||||
for (;;) {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
||||
void kmain(multiboot_info_t* header) {
|
||||
cpu_init();
|
||||
text_fb_info info;
|
||||
@ -19,26 +27,26 @@ void kmain(multiboot_info_t* header) {
|
||||
}
|
||||
vga_init(info);
|
||||
vga_write_string("Hello\n");
|
||||
asm volatile(" \
|
||||
cli; \
|
||||
mov $0x23, %ax; \
|
||||
mov %ax, %ds; \
|
||||
mov %ax, %es; \
|
||||
mov %ax, %fs; \
|
||||
mov %ax, %gs; \
|
||||
\
|
||||
mov %esp, %eax; \
|
||||
pushl $0x23; \
|
||||
pushl %eax; \
|
||||
pushf; \
|
||||
pop %eax; \
|
||||
or $0x200,%eax; \
|
||||
push %eax; \
|
||||
pushl $0x1B; \
|
||||
push $1f; \
|
||||
iret; \
|
||||
1: \
|
||||
");
|
||||
// asm volatile(" \
|
||||
// cli; \
|
||||
// mov $0x23, %ax; \
|
||||
// mov %ax, %ds; \
|
||||
// mov %ax, %es; \
|
||||
// mov %ax, %fs; \
|
||||
// mov %ax, %gs; \
|
||||
// \
|
||||
// mov %esp, %eax; \
|
||||
// pushl $0x23; \
|
||||
// pushl %eax; \
|
||||
// pushf; \
|
||||
// pop %eax; \
|
||||
// or $0x200,%eax; \
|
||||
// push %eax; \
|
||||
// pushl $0x1B; \
|
||||
// push $1f; \
|
||||
// iret; \
|
||||
// 1: \
|
||||
// ");
|
||||
vga_write_string("UMODE!\n");
|
||||
port_byte_out(0xe9,'U');
|
||||
port_byte_out(0xe9,'M');
|
||||
@ -47,4 +55,9 @@ void kmain(multiboot_info_t* header) {
|
||||
port_byte_out(0xe9,'E');
|
||||
port_byte_out(0xe9,'!');
|
||||
port_byte_out(0xe9,'\n');
|
||||
vga_write_string("Task create\n");
|
||||
createTask(task);
|
||||
vga_write_string("Task switch\n");
|
||||
yield();
|
||||
vga_write_string("Back in main\n");
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
cpu/i386/interrupt.o
|
||||
cpu/i386/paging_helpers.o
|
||||
cpu/i386/seg_upd.o
|
||||
cpu/i386/tasking_helpers.o
|
||||
kernel/boot.o
|
||||
|
Loading…
Reference in New Issue
Block a user