summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-08-22 00:52:30 +0200
committerMiguel <m.i@gmx.at>2018-08-22 00:52:30 +0200
commit59038fc67c20a1f04e5d2fd5f9a444e707d1d3ea (patch)
tree1b0161c1b6d5caefe900f419fed31cc7d7ad6017
parent72c6e9763ca61bc9d7de5f7080ee1c8a1c7c1562 (diff)
userspace and kernelspace taskswitching
-rw-r--r--asm/pit.s50
-rw-r--r--asm/task.s37
-rw-r--r--kernel/gdt.c10
-rw-r--r--kernel/kernel.h1
-rw-r--r--kernel/mem.c1
-rw-r--r--kernel/scheduler.c25
-rw-r--r--kernel/usermode.c23
7 files changed, 80 insertions, 67 deletions
diff --git a/asm/pit.s b/asm/pit.s
index ab8dcdb..c25e9a1 100644
--- a/asm/pit.s
+++ b/asm/pit.s
@@ -12,32 +12,38 @@ pit_get_ticks:
pit_interrupt_handler:
- // increase tick counter
- push %eax
- mov $ticks, %eax
- incl (%eax)
- pop %eax
-
- ////
-
- pusha //Push all standard registers
-
- mov %esp, %eax //save current stack pointer (pointing to registers!)
-
- movl $stack_top, %esp //use stack from multiboot.s(16Kb)
+ push %eax // persist
- // call our scheduler passing it the old stack addres (pointing to pushed registers (pusha))
- push %eax
- call task_switch_next
-
- // the scheduler returned the new stack pointer (after taskswitch)
- mov %eax, %esp //Replace the stack with what the C code gave us
+ // INC TICK COUNTER
+ mov $ticks, %eax
+ incl (%eax)
- // acknowlege irq
- mov $0x20,%al
+ // ACK IRQ
+ mov $0x20,%al
out %al,$0x20
+
+ pop %eax // load original
- popa //Put the standard registers back
+ ///////
+
+ pusha //Push all standard registers
+ push %ds //Push data segment
+ push %es //etc...
+ push %fs
+ push %gs
+
+ mov %esp, %eax // remember current %esp
+ movl $stack_top, %esp // switch to our small scheduler stack
+
+ push %eax // set original %esp as param and...
+ call task_switch_next // call scheduler
+ mov %eax, %esp // use %esp we got from scheduler
+
+ pop %gs
+ pop %fs
+ pop %es
+ pop %ds
+ popa
iret
diff --git a/asm/task.s b/asm/task.s
index 7611d4a..c29bdae 100644
--- a/asm/task.s
+++ b/asm/task.s
@@ -2,15 +2,21 @@
task_pusha:
pushf
-
- push $0x8
+ push $0x8 // code segment
push $userfunc
pusha
+
+ push %ds
+ push %es
+ push %fs
+ push %gs
+
/*
+
now stack looks like:
- param // esp+48
+ param // esp+64
returnaddy
eflags
@@ -26,9 +32,14 @@ task_pusha:
esi
edi
+ ds
+ es
+ fs
+ gs
+
*/
- mov 48(%esp),%eax // get address of alternative stack where we want to simulate the pusha
+ mov 64(%esp),%eax // get address of alternative stack where we want to simulate the pusha
mov (%esp),%ecx
mov %ecx,(%eax)
@@ -66,10 +77,24 @@ task_pusha:
mov 44(%esp),%ecx
mov %ecx,44(%eax)
+ mov 48(%esp),%ecx
+ mov %ecx,48(%eax)
+
+ mov 52(%esp),%ecx
+ mov %ecx,52(%eax)
+
+ mov 56(%esp),%ecx
+ mov %ecx,56(%eax)
+
+ pop %gs
+ pop %fs
+ pop %es
+ pop %ds
+
+ popa
+
pop %eax
pop %eax
pop %eax
- popa
-
ret
diff --git a/kernel/gdt.c b/kernel/gdt.c
index 06a0949..88478c7 100644
--- a/kernel/gdt.c
+++ b/kernel/gdt.c
@@ -1,7 +1,6 @@
// http://wiki.osdev.org/GDT_Tutorial
-#include "lib/logger/log.h"
+#define FOOLOS_MODULE_NAME "gdt"
#include "usermode.h"
-#define FOOLOS_MODULE_NAME "GDT"
#include <stdint.h>
#define GDT_SIZE 6
@@ -85,13 +84,10 @@ void encodeGdtEntry(uint8_t *target, GDT source)
6 db 11001111b ;flags & seg.limit
7 db 0x0 ;base
*/
-
-
}
void gdt_init()
{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setting up Global Descriptor Table");
//selector 0x0
myGDT[0].base=0;
myGDT[0].limit=0;
@@ -122,15 +118,11 @@ void gdt_init()
myGDT[5].limit=sizeof(tss_struct); //tss end?
myGDT[5].type=0x89;
-
// transcript to format the processor wants
for(int i=0;i<GDT_SIZE;i++)
encodeGdtEntry(&gdt_struct[8*i],myGDT[i]);
-
// updat
install_tss();
setup_gdt(&gdt_struct[0],8*GDT_SIZE);
-
-
}
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 1880045..5ac10d1 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -11,6 +11,7 @@
#define FIFO_MAX_RINGBUFFERS 20
#define MAX_FIFOS 20
#define MAX_FD 20
+#define MAX_TASKS 255
#define FOOLOS_CONSOLE_AUTOBREAK // add newline automatically at end of line
diff --git a/kernel/mem.c b/kernel/mem.c
index a167d8b..8b90911 100644
--- a/kernel/mem.c
+++ b/kernel/mem.c
@@ -219,7 +219,6 @@ uint32_t mem_init(multiboot_information *info)
// we deinit everything below mem_min_block anyway
pmmngr_deinit_region(0,mem_min_block*PMMNGR_BLOCK_SIZE);
-
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Usable ~%d / %d MB ",mem_free_blocks*4096/1024/1024,total_mem/1024/1024);
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 4823276..d6e2c76 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -13,8 +13,6 @@
#include "fs/fs.h"
#include "fs/ext2.h"
-#define MAX_TASKS 10
-
static volatile int volatile current_task=-1;
static volatile struct task_list_struct
@@ -36,7 +34,6 @@ volatile int add_task(uint32_t esp, uint32_t vmem)
{
if(task_list[i].active!=true)
{
-
task_list[i].parent=current_task;
task_list[i].vmem=vmem;
task_list[i].esp=esp;
@@ -174,30 +171,12 @@ volatile void scheduler_init(pdirectory *dir)
task_list[1].vmem=dir;
task_list[1].esp = kballoc(4); // fresh 16kb stack from here.
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",1,task_list[1].esp);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",0,task_list[0].esp);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",task_list[1].esp+4*4096-1);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"fresh esp on: 0x%08X",task_list[0].esp+4*4096-1);
task_pusha(task_list[1].esp); // pusha but to alternative location
task_pusha(task_list[0].esp); // pusha but to alternative location
- /*
- current_task=0;
- unsigned esp, ebp, eax, ebx, ecx, edx;
-
- asm(
- "movl %%esp, %0;"
- "movl %%ebp, %1;"
- "movl %%eax, %2;"
- "movl %%ebx, %3;"
- "movl %%ecx, %4;"
- "movl %%edx, %5;"
- :"=r"(esp), "=r"(ebp), "=r"(eax), "=r"(ebx), "=r"(ecx), "=r"(edx)
- );
-
- // TODO: prepare stack so popa get's what it wants!
- int i=task_fork(esp);
- */
-
// finally enable interrrupts so the scheduler is called (by timer)
x86_sti();
diff --git a/kernel/usermode.c b/kernel/usermode.c
index 81dc5c1..bb614d0 100644
--- a/kernel/usermode.c
+++ b/kernel/usermode.c
@@ -15,6 +15,9 @@
//https://wiki.osdev.org/Task_State_Segment
tss_struct sys_tss; //Define the TSS as a global structure
+static volatile uint32_t c1;
+static volatile uint32_t c2;
+
void install_tss(int cpu_no){
// now fill each value
@@ -28,20 +31,28 @@ void install_tss(int cpu_no){
void userfunc()
{
+
// we need enable here again (since the pushed eflags have it disabled)!
x86_sti();
// if we are pid 0, replace ourselves with /bin/init TODO: switch to usermode before!
- if(task_get_current_pid()==0)syscall(SYSCALL_EXECVE,BIN_INIT,NULL,NULL);
+ if(task_get_current_pid()==0)
+ {
+ //usermode(&initfunc);
+ while(1)
+ {
+ c2++;
+ }
+ }
- // kernel worker thread
+ // kernel worker thread on pid1
if(task_get_current_pid()==1)
{
+ while(1)
+ {
+ c1++;
+ }
}
}
-void switch_to_user_mode()
-{
- usermode(&userfunc);
-}