diff --git a/src/bringelle.c b/src/bringelle.c index 38c066e..167e6d5 100644 --- a/src/bringelle.c +++ b/src/bringelle.c @@ -49,10 +49,10 @@ void bringelle(){ print("Launch user tasks \n"); int* page_dir=paging_allocate(2); - task_create(page_dir, utask,100); + task_create(page_dir, utask,100, 0xFF); int* page_dir2=paging_allocate(2); - task_create(page_dir2, utask2,100); + task_create(page_dir2, utask2,100,0xFF); scheduler_start(); diff --git a/src/core/scheduler.c b/src/core/scheduler.c index fffeaf2..d046298 100644 --- a/src/core/scheduler.c +++ b/src/core/scheduler.c @@ -10,45 +10,44 @@ u16 current_id; u16 nproc; void schedule(u32 *stack){ - // Note that this function is called by clock - // clock is called by INT_CLOCK (core/int.S) - // which store all the process information on - // the stack. Thus, knowing the C calling conventions - // and that schedule() is call by two functions with no parameters, - // the first process register can be accessed by ebp+2 + // Note that this function is called by clock() + // and clock() is called by INT_CLOCK (cf core/int.S) + // which stores all the processes registers on + // the stack. - // No proc to schedule + // No proc to schedule, just skip this function if(nproc<2) return; PROC *p=&procs[current_id]; - p->regs.gs=stack[2]; // ebp+2=gs cf note above - p->regs.fs=stack[3]; - p->regs.es=stack[4]; - p->regs.ds=stack[5]; - p->regs.edi=stack[6]; - p->regs.esi=stack[7]; - p->regs.ebp=stack[8]; - // We do not take p->regs.esp=stack[9] + p->regs.gs=stack[0]; // cf function specification in scheduler.h + p->regs.fs=stack[1]; + p->regs.es=stack[2]; + p->regs.ds=stack[3]; + p->regs.edi=stack[4]; + p->regs.esi=stack[5]; + p->regs.ebp=stack[6]; + // We do not take p->regs.esp=stack[7] // since it corresponds to the kernel stack // (it was push during the interruption) - p->regs.edx=stack[10]; - p->regs.ecx=stack[11]; - p->regs.ebx=stack[12]; - p->regs.eax=stack[13]; - p->regs.eip=stack[14]; - p->regs.cs=stack[15]; - p->regs.eflags=stack[16]; - p->regs.esp=stack[17]; - p->regs.ss=stack[18]; + p->regs.edx=stack[8]; + p->regs.ecx=stack[9]; + p->regs.ebx=stack[10]; + p->regs.eax=stack[11]; + p->regs.eip=stack[12]; + p->regs.cs=stack[13]; + p->regs.eflags=stack[14]; + p->regs.esp=stack[15]; + p->regs.ss=stack[16]; + // Get the next task to run current_id++; if(current_id>=nproc) current_id=0; p=&procs[current_id]; // Have a clean stack on next interrupt - TSS.esp0=(u32)stack+19; + TSS.esp0=(u32)stack+17; asm("mov %%ss, %0": "=m" (TSS.ss0)); // Ensure interrupts are activated and NT flag is clear @@ -66,6 +65,7 @@ void schedule(u32 *stack){ void clock(){ u32* stack; asm("mov %%ebp, %0":"=r" (stack)); + stack=&stack[2]; // Make stack pointing to gs static int tic=0; static int sec=0; @@ -80,11 +80,11 @@ void clock(){ schedule(stack); } -void task_create(int *page_dir, void *task, int task_size){ +void task_create(int *page_dir, void *task, int task_size, int stack_offset){ if(nproc<=MAX_PROC){ // Compute various addresses void *entry_point=PAGING_ENTRY_POINT_VIRT; - void *ustack=(void*)(PAGING_ENTRY_POINT_VIRT+0xFF); + void *ustack=(void*)(PAGING_ENTRY_POINT_VIRT+stack_offset); // Load the task into memory memcpy(task,PAGING_ENTRY_POINT_PHY(page_dir), task_size); diff --git a/src/core/scheduler.h b/src/core/scheduler.h index fbcf6bd..ecb9428 100644 --- a/src/core/scheduler.h +++ b/src/core/scheduler.h @@ -3,7 +3,6 @@ #include "mem.h" - #define MAX_PROC 10 // If you change the following struct @@ -29,11 +28,27 @@ typedef struct PROC { extern char show_tics; extern char scheduler_on; extern PROC procs[MAX_PROC]; -extern u16 current_id; -extern u16 nproc; +extern u16 current_id; // Current running task PID/id +extern u16 nproc; // Number of active tasks +/** + * Must be called at each clock interrupt + */ void clock(); -void schedule(); -void task_create(int *page_dir, void *task, int task_size); +/** + * Called by clock() and schedule the next task + * Stack is a pointer pointing to the gs register on the stack. + * The stack must contains the interrupted process registers in the following + * order: gs,fs,es,ds,edi,esi,ebp,UNUSED,edx,ecx,ebx,eax,eip,cs,eflags,esp,ss + */ +void schedule(u32 *stack); +/** + * Create a new task to be schedule + */ +void task_create(int *page_dir, void *task, int task_size, int stack_offset); +/** + * Stack the scheduler starting by task with PID 0 + */ void scheduler_start(); + #endif \ No newline at end of file