Start large change of tasking system
This commit is contained in:
parent
7f79f1367e
commit
613f77f949
@ -15,7 +15,7 @@ isr_common_stub:
|
||||
mov gs, ax
|
||||
|
||||
; 2. Call C handler
|
||||
call isr_handler
|
||||
call isr_handler
|
||||
; 3. Restore state
|
||||
pop eax
|
||||
mov ds, ax
|
||||
|
@ -171,7 +171,10 @@ void isr_handler(registers_t r) {
|
||||
case 80:
|
||||
if (r.eax==1) {
|
||||
tss_stack_reset();
|
||||
tasking_yield();
|
||||
tasking_yield(r);
|
||||
r.ds=0x23;
|
||||
r.ss=0x23;
|
||||
r.cs=0x1B;
|
||||
} else if (r.eax==2) {
|
||||
tasking_createTask((void*)r.ebx);
|
||||
} else if (r.eax==3) {
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "../tasking.h"
|
||||
#include "isr.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "kmalloc.h"
|
||||
#include "memory.h"
|
||||
#include "gdt.h"
|
||||
@ -26,24 +27,34 @@ void tasking_init() {
|
||||
|
||||
Task* tasking_createTaskCr3(void* eip,void* cr3) {
|
||||
Task* task=kmalloc(sizeof(Task));
|
||||
task->regs.eax=0;
|
||||
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;
|
||||
task->regs.cr3=(uint32_t)cr3;
|
||||
task->cr3=(uint32_t)cr3;
|
||||
uint32_t old_cr3;
|
||||
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(old_cr3)::"%eax");
|
||||
load_address_space(task->regs.cr3);
|
||||
task->regs.esp=((uint32_t)alloc_pages(1))+0xfff;
|
||||
load_address_space(task->cr3);
|
||||
task->esp=((uint32_t)alloc_pages(1))+0xfff;
|
||||
registers_t registers;
|
||||
registers.ds=0x23;
|
||||
registers.eip=(uint32_t)eip;
|
||||
registers.cs=0x1B;
|
||||
uint32_t eflags;
|
||||
asm volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(eflags)::"%eax");
|
||||
registers.eflags=eflags|0x200;
|
||||
registers.useresp=task->esp;
|
||||
registers.ss=0x23;
|
||||
char* interrupt_data_char=(char*)task->esp;
|
||||
char* registers_char=(char*)®isters;
|
||||
for (int i=0;i<sizeof(registers_t);i++) {
|
||||
interrupt_data_char[sizeof(registers_t)-i]=registers_char[i];
|
||||
}
|
||||
registers_t* interrupt_data=(registers_t*)task->esp;
|
||||
interrupt_data->ds=0x23;
|
||||
interrupt_data->eip=(uint32_t)eip;
|
||||
interrupt_data->cs=0x1B;
|
||||
asm volatile("pushfl; movl (%%esp), %%eax; movl %%eax, %0; popfl;":"=m"(eflags)::"%eax");
|
||||
interrupt_data->eflags=eflags|0x200;
|
||||
interrupt_data->useresp=task->esp;
|
||||
interrupt_data->ss=0x23;
|
||||
load_address_space(old_cr3);
|
||||
task->regs.ebp=0;
|
||||
task->msg_store=NULL;
|
||||
task->rd=0;
|
||||
task->wr=0;
|
||||
task->next=NULL;
|
||||
task->pid=next_pid;
|
||||
task->priv=0;
|
||||
@ -83,7 +94,7 @@ void tasking_send_msg(uint32_t pid,void* msg,uint32_t size) {
|
||||
uint32_t cr3;
|
||||
asm volatile("movl %%cr3, %%eax; movl %%eax, %0;":"=m"(cr3)::"%eax");
|
||||
void* phys_addr=virt_to_phys(msg);
|
||||
load_address_space(task->regs.cr3);
|
||||
load_address_space(task->cr3);
|
||||
uint32_t page=find_free_pages((size/4096)+1);
|
||||
map_pages((void*)(page<<12),phys_addr,(size/4096)+1,1,0);
|
||||
if (task->msg_store==NULL) {
|
||||
@ -124,14 +135,22 @@ void* tasking_get_msg(uint32_t* sender) {
|
||||
return data;
|
||||
}
|
||||
|
||||
void tasking_yield() {
|
||||
void tasking_yield(registers_t registers) {
|
||||
Task* task=currentTask->next;
|
||||
if (!task) {
|
||||
task=headTask;
|
||||
}
|
||||
Task* oldCurr=currentTask;
|
||||
currentTask=task;
|
||||
load_address_space(task->regs.cr3);
|
||||
oldCurr->esp=registers.useresp;
|
||||
registers_t* interrupt_data=(registers_t*)registers.useresp;
|
||||
load_address_space(task->cr3);
|
||||
char* interrupt_data_char=(char*)interrupt_data;
|
||||
char* registers_char=(char*)®isters;
|
||||
for (int i=0;i<sizeof(registers_t);i++) {
|
||||
interrupt_data_char[sizeof(registers_t)-i]=registers_char[i];
|
||||
}
|
||||
// memcpy(interrupt_data,®isters,sizeof(registers_t));
|
||||
if (task->priv) {
|
||||
allow_all_ports();
|
||||
} else {
|
||||
@ -157,5 +176,5 @@ void tasking_yield() {
|
||||
iret; \
|
||||
1: \
|
||||
");
|
||||
switchTask(&oldCurr->regs, ¤tTask->regs);
|
||||
switchTask(task->esp);
|
||||
}
|
||||
|
@ -3,22 +3,19 @@
|
||||
|
||||
#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 kmode;
|
||||
char** msg_store;
|
||||
uint32_t* sender_store;
|
||||
uint32_t msg_indx;
|
||||
uint8_t rd;
|
||||
uint8_t wr;
|
||||
uint32_t pid;
|
||||
char priv;
|
||||
int errno;
|
||||
uint32_t esp;
|
||||
uint32_t cr3;
|
||||
char priv;
|
||||
int errno;
|
||||
uint32_t pid;
|
||||
char** msg_store;
|
||||
uint32_t* sender_store;
|
||||
uint32_t msg_indx;
|
||||
uint8_t rd;
|
||||
uint8_t wr;
|
||||
struct Task* next;
|
||||
} Task;
|
||||
|
||||
int* tasking_get_errno_address();
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "tasking.h"
|
||||
|
||||
void switchTask(Registers *from, Registers *to);
|
||||
void switchTask(uint32_t stack);
|
||||
uint32_t readEip();
|
||||
|
||||
#endif
|
||||
|
@ -1,49 +1,14 @@
|
||||
.section .text
|
||||
.global switchTask
|
||||
switchTask:
|
||||
pusha
|
||||
pushf
|
||||
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
|
||||
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
|
||||
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
|
||||
pop %eax
|
||||
mov %eax,%esp
|
||||
pop %eax
|
||||
mov %ax,%ds
|
||||
mov %ax,%es
|
||||
mov %ax,%fs
|
||||
mov %ax,%gs
|
||||
popa
|
||||
add $8,%esp # Cleans up the pushed error code and pushed ISR number
|
||||
iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
|
||||
|
@ -2,9 +2,10 @@
|
||||
#define CPU_TASKING_H
|
||||
|
||||
#include "i386/tasking.h"
|
||||
#include "i386/isr.h"
|
||||
|
||||
void tasking_init();
|
||||
void tasking_yield();
|
||||
void tasking_yield(registers_t registers);
|
||||
Task* tasking_createTask(void* eip);
|
||||
Task* tasking_createTaskCr3(void* eip,void* cr3);
|
||||
char isPrivleged(uint32_t pid);
|
||||
|
@ -105,6 +105,26 @@ void kmain(struct multiboot_boot_header_tag* hdr) {
|
||||
copy_data(cr3,ptr,pheader.memsz,(void*)pheader.vaddr);
|
||||
}
|
||||
createTaskCr3((void*)header.entry,cr3);
|
||||
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: \
|
||||
");
|
||||
for(;;) {
|
||||
yield();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user