From 613f77f949014edeb308f80d2db6797133048ae0 Mon Sep 17 00:00:00 2001 From: pjht Date: Sat, 11 May 2019 10:11:28 -0500 Subject: [PATCH] Start large change of tasking system --- cpu/i386/interrupt.asm | 2 +- cpu/i386/isr.c | 5 +++- cpu/i386/tasking.c | 57 +++++++++++++++++++++++++------------- cpu/i386/tasking.h | 25 ++++++++--------- cpu/i386/tasking_helpers.h | 2 +- cpu/i386/tasking_helpers.s | 55 +++++++----------------------------- cpu/tasking.h | 3 +- kernel/kernel.c | 20 +++++++++++++ 8 files changed, 87 insertions(+), 82 deletions(-) diff --git a/cpu/i386/interrupt.asm b/cpu/i386/interrupt.asm index 455a5cf..7033262 100644 --- a/cpu/i386/interrupt.asm +++ b/cpu/i386/interrupt.asm @@ -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 diff --git a/cpu/i386/isr.c b/cpu/i386/isr.c index 53eff04..eecff6e 100644 --- a/cpu/i386/isr.c +++ b/cpu/i386/isr.c @@ -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) { diff --git a/cpu/i386/tasking.c b/cpu/i386/tasking.c index e902996..071487d 100644 --- a/cpu/i386/tasking.c +++ b/cpu/i386/tasking.c @@ -3,6 +3,7 @@ #include "../tasking.h" #include "isr.h" #include +#include #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;iesp; + 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;ipriv) { allow_all_ports(); } else { @@ -157,5 +176,5 @@ void tasking_yield() { iret; \ 1: \ "); - switchTask(&oldCurr->regs, ¤tTask->regs); + switchTask(task->esp); } diff --git a/cpu/i386/tasking.h b/cpu/i386/tasking.h index f47d63a..1f42658 100644 --- a/cpu/i386/tasking.h +++ b/cpu/i386/tasking.h @@ -3,22 +3,19 @@ #include -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(); diff --git a/cpu/i386/tasking_helpers.h b/cpu/i386/tasking_helpers.h index 45f8783..c3dc6ad 100644 --- a/cpu/i386/tasking_helpers.h +++ b/cpu/i386/tasking_helpers.h @@ -3,7 +3,7 @@ #include "tasking.h" -void switchTask(Registers *from, Registers *to); +void switchTask(uint32_t stack); uint32_t readEip(); #endif diff --git a/cpu/i386/tasking_helpers.s b/cpu/i386/tasking_helpers.s index 2dac4e3..000c814 100644 --- a/cpu/i386/tasking_helpers.s +++ b/cpu/i386/tasking_helpers.s @@ -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 diff --git a/cpu/tasking.h b/cpu/tasking.h index d917d46..ff7463d 100644 --- a/cpu/tasking.h +++ b/cpu/tasking.h @@ -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); diff --git a/kernel/kernel.c b/kernel/kernel.c index 10d5075..1b4f81b 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -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(); }