From eff52c8853b7a7ede81c424b87137108b0a2cb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Thu, 20 Dec 2018 16:29:04 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20scheduling=20op=C3=A9rationnel=20mais?= =?UTF-8?q?=20subsiste=20des=20bogues=20inconnus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API.md | 26 +++++++-------- README.md | 5 +-- include/process.h | 5 +-- lib/makefile | 1 + lib/process.c | 70 +++++++++++++++++++++++++++++++++++---- lib/scheduler.c | 31 ++++++++++------- lib/shell.c | 7 ++-- lib/syscall.c | 10 +++--- makefile | 5 ++- programs/include/libsys.h | 4 +-- programs/lib/libsys.c | 15 ++++----- programs/makefile | 1 - programs/test2.c | 17 ++++++++++ syscalls.txt | 24 +++++++------- templates/syscall.c | 2 +- 15 files changed, 155 insertions(+), 68 deletions(-) create mode 100644 programs/test2.c diff --git a/API.md b/API.md index 0cf463b..2dc4230 100644 --- a/API.md +++ b/API.md @@ -9,6 +9,17 @@ All fonctions in the "libsys" library. ------ +`u32 getticks(void);` + +*Description:Return the internal value of the timer* + +* syscall id : **4** +* arguments : **0** +* results : **u32** +* dump of register cpu: **no** + +------ + `u32 testapi(u32 arg1, u32 arg2, u32 arg3);` *Description:Simple function to test if SYSCALL API is correctly running* @@ -23,17 +34,6 @@ All fonctions in the "libsys" library. ------ -`u32 getticks(void);` - -*Description:Return the internal value of the timer* - -* syscall id : **4** -* arguments : **0** -* results : **u32** -* dump of register cpu: **no** - ------- - `u8 waitkey(void);` *Description:Wait for user to press a key and return the ascii code pressed* @@ -45,14 +45,14 @@ All fonctions in the "libsys" library. ------ -`void exit(u32 resultcode);` +`u32 exit(u32 resultcode);` *Description:End a task for user or kernel domain* * syscall id : **5** * arguments : **1** * * argument 1 : **u32 resultcode** *Code result of the execution* -* results : **void** +* results : **u32** * dump of register cpu: **no** diff --git a/README.md b/README.md index c16cad4..7e30652 100644 --- a/README.md +++ b/README.md @@ -224,11 +224,12 @@ Pour l'instant quelques commandes seulement sont disponibles: * gestion avancée de la mémoire (vmalloc). * chargeur ELF32, * espace utilisateur et appels systèmes, -* liste d'API automatiquement mise à jour, +* ordonnanceur de tâche (par TSS), #### En cours -* ordonnanceur de tâche (par TSS), +* correction de bogues - stabilisation du projet +* liste d'API automatiquement mise à jour avec intégration de librairies & header, #### A faire diff --git a/include/process.h b/include/process.h index 600da91..e0d478d 100644 --- a/include/process.h +++ b/include/process.h @@ -139,6 +139,7 @@ typedef struct task { tid_t tid; stack kernel_stack; + stack syscall_stack; u32 status; regs dump; TAILQ_ENTRY(task) tailq; @@ -195,8 +196,8 @@ pid_t clone(void); pid_t exec(u8* entry, u8* args, bool kerneltask); void switchtask(tid_t tid); -tid_t getnexttask(void); - +process* getnextprocess(pid_t pid); +task* getnexttask(void); task* findtask(tid_t tid); task* findcurrenttask(void); process* findprocess(pid_t pid); diff --git a/lib/makefile b/lib/makefile index 68e0cd6..11671c1 100755 --- a/lib/makefile +++ b/lib/makefile @@ -40,6 +40,7 @@ clean: $(REMOVE) *.c~ $(REMOVE) */*.c~ $(REMOVE) ../include/*.h~ + $(REMOVE) ./TEST/*.c sync indent: diff --git a/lib/process.c b/lib/process.c index 5272762..8c4a324 100644 --- a/lib/process.c +++ b/lib/process.c @@ -70,7 +70,7 @@ u32 iself(u8 * src) "ARGS": [ {"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} ], -"RETURN":"void" +"RETURN":"u32" } END */ @@ -158,10 +158,12 @@ void initprocesses(void) if (aprocess==NULL) return NULL; aprocess->pid = pid; aprocess->result = 0; - aprocess->status = PROCESS_STATUS_READY; + aprocess->status = PROCESS_STATUS_RUN; aprocess->iskernel = true; TAILQ_INIT(&aprocess->task_head); current=createtask(pid,getinitretry(),true); + task *atask = findtask(current); + atask->status = TASK_STATUS_RUN; } /*******************************************************************************/ @@ -169,6 +171,8 @@ void initprocesses(void) pid_t getfreepid(void) { + if (lastpid==0 || lastpid>MAXNUMPROCESS) + lastpid==1; u32 i = lastpid; u32 parsed = 0; while (processes[i++].status != PROCESS_STATUS_FREE @@ -260,9 +264,15 @@ void switchtask(tid_t tid) if (aprocess==NULL) return; current = tid; if (!aprocess->iskernel) + { setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0); + wrmsr(0x175, atask->syscall_stack.esp0, 0x0); + } else + { setTSS(0x0, 0x0); + wrmsr(0x175, 0x0, 0x0); + } atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF; createdump(atask->dump); if (atask->dump.cs==SEL_KERNEL_CODE) @@ -272,6 +282,42 @@ void switchtask(tid_t tid) iret(); } + +/*******************************************************************************/ +/* Cherche le prochain processus */ +process* getnextprocess(pid_t pid) +{ + u32 i = (u32) pid; + while (processes[i++].status != PROCESS_STATUS_RUN) + { + if (i >= MAXNUMPROCESS) + i = 0; + } + return &processes[i-1]; +} + +/*******************************************************************************/ +/* Cherche la prochaine tâche */ +task* getnexttask(void) +{ + process *aprocess=findcurrentprocess(); + u32 flag=0; + task *next; + while(flag<2) { + if (aprocess==NULL) return NULL; + TAILQ_FOREACH(next, &aprocess->task_head, tailq) + { + if (next->status == TASK_STATUS_RUN) + if (current.pid != next->tid.pid || next->tid.number>current.number) + return next; + if (current.pid==next->tid.pid && current.number==next->tid.number) + flag++; + } + aprocess=getnextprocess(aprocess->pid); + } + return NULL; +} + /*******************************************************************************/ /* Cherche l'adresse d'une tâche */ @@ -285,6 +331,7 @@ task* findtask(tid_t tid) return next; } + /*******************************************************************************/ /* Cherche l'adresse de la tâche courante */ @@ -333,12 +380,14 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) if (aprocess==NULL) return maketid(0,0); task *new = (task *) vmalloc(sizeof(task)); TAILQ_INSERT_TAIL(&aprocess->task_head, new, tailq); - page *astack = virtual_page_getfree(); + page *apage = virtual_page_getfree(); if (kerneltask) { new->dump.ss = SEL_KERNEL_STACK; - new->dump.esp = - (u32) astack->vaddr + PAGESIZE - 16; + if (pid!=1) + new->dump.esp = + (u32) apage->vaddr + PAGESIZE - 16; + new->dump.esp = KERNEL_STACK_ADDR; new->dump.eflags = 0x0; new->dump.cs = SEL_KERNEL_CODE; new->dump.ds = SEL_KERNEL_DATA; @@ -351,7 +400,11 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) { new->kernel_stack.ss0 = SEL_KERNEL_STACK; new->kernel_stack.esp0 = - (u32) astack->vaddr + PAGESIZE - 16; + (u32) apage->vaddr + PAGESIZE - 16; + page *apage = virtual_page_getfree(); + new->syscall_stack.ss0 = SEL_KERNEL_STACK; + new->syscall_stack.esp0 = + (u32) apage->vaddr + PAGESIZE - 16; new->dump.ss = SEL_USER_STACK | RPL_RING3; new->dump.esp = USER_STACK - 16; new->dump.eflags = 0x0; @@ -363,7 +416,10 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) new->dump.cr3 = aprocess->pdd->addr->paddr; } new->tid=getfreeptid(pid); - new->dump.eip = aprocess->entry; + if (entry==NULL) + new->dump.eip = aprocess->entry; + else + new->dump.eip = entry; new->dump.eax = 0; new->dump.ecx = 0; new->dump.edx = 0; diff --git a/lib/scheduler.c b/lib/scheduler.c index 459f72b..1dda468 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -8,6 +8,7 @@ #include "timer.h" #include "vga.h" #include "gdt.h" +#include "process.h" static u8 curs[4] = { "-\\|/" }; @@ -39,7 +40,6 @@ u32 gettimer(void) __attribute__ ((noreturn)) void timer_handler(regs *dump) { - u32 interruption=dump->eip; exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1); bool noerror,user; if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE) @@ -77,21 +77,28 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump) user=true; } } + irqendmaster(); showchar(0, 0, curs[curspos], 7); curspos = (curspos + 1) & 0x3; time++; - irqendmaster(); + task *new=getnexttask(); + if (new!=NULL) + { + task *old=findcurrenttask(); + memcpy(&dump, &old->dump, sizeof(dump), 0); + switchtask(new->tid); + } if (dump->cs==SEL_KERNEL_CODE) - { - setESP(dump); - restcpu_kernel(); - } - else - { - setESP(dump); - restcpu_user(); - iret(); - } + { + setESP(dump); + restcpu_kernel(); + } + else + { + setESP(dump); + restcpu_user(); + iret(); + } } diff --git a/lib/shell.c b/lib/shell.c index b3674e7..9e234a4 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -92,11 +92,14 @@ int test(void) /* Test l'usage de création de tâche */ #include "TEST/test.c" - +#include "TEST/test2.c" int testtask() { print("*** Creation d'une tache\r\n"); - pid_t pid = createprocess(&programs_test, false); + pid_t pid; + pid = createprocess(&programs_test2, false); + runprocess(pid); + pid = createprocess(&programs_test, false); runprocess(pid); } diff --git a/lib/syscall.c b/lib/syscall.c index fbc96e3..b8406c3 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -25,7 +25,7 @@ extern wrapper_sysenter; void initsyscall(void) { wrmsr(0x174, SEL_KERNEL_CODE, 0x0); - wrmsr(0x175, 0x60000, 0x0); + wrmsr(0x175, NULL, 0x0); wrmsr(0x176, &wrapper_sysenter, 0x0); return; } @@ -62,20 +62,20 @@ __attribute__ ((noreturn)) void sysenter_handler(regs *dump) sti(); switch (dump->eax) { + case 4: + dump->eax=(u32) gettimer(); + break; case 2: dump->eax=(u32) print(dump->ebx); break; case 0: dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump); break; - case 4: - dump->eax=(u32) gettimer(); - break; case 1: dump->eax=(u32) waitascii(); break; case 5: - processexit(dump->ebx); + dump->eax=(u32) processexit(dump->ebx); break; default: diff --git a/makefile b/makefile index 1273163..c816519 100755 --- a/makefile +++ b/makefile @@ -14,11 +14,14 @@ syscall: clean remakeapi all remakeapi: python makesyscall.py -programs: programs/test lib/TEST/test.c +programs: programs/test lib/TEST/test.c lib/TEST/test2.c lib/TEST/test.c: xxd -i programs/test lib/TEST/test.c +lib/TEST/test2.c: + xxd -i programs/test2 lib/TEST/test2.c + programs/test: make -C programs diff --git a/programs/include/libsys.h b/programs/include/libsys.h index 9f68378..fb8f40e 100644 --- a/programs/include/libsys.h +++ b/programs/include/libsys.h @@ -4,8 +4,8 @@ #include "types.h"; -u32 testapi(u32 arg1, u32 arg2, u32 arg3); u32 getticks(void); +u32 testapi(u32 arg1, u32 arg2, u32 arg3); u8 waitkey(void); -void exit(u32 resultcode); +u32 exit(u32 resultcode); diff --git a/programs/lib/libsys.c b/programs/lib/libsys.c index 6ba6c83..086681b 100644 --- a/programs/lib/libsys.c +++ b/programs/lib/libsys.c @@ -6,25 +6,24 @@ #include "syscall.h"; #include "types.h"; -u32 testapi(u32 arg1, u32 arg2, u32 arg3) -{ - return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); -} - u32 getticks(void) { return syscall0(4); } +u32 testapi(u32 arg1, u32 arg2, u32 arg3) +{ + return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); +} + u8 waitkey(void) { return syscall0(1); } -void exit(u32 resultcode) +u32 exit(u32 resultcode) { - syscall1(5,(u32) resultcode); - return; + return syscall1(5,(u32) resultcode); } diff --git a/programs/makefile b/programs/makefile index 01a4c45..a17bb24 100755 --- a/programs/makefile +++ b/programs/makefile @@ -24,7 +24,6 @@ lib/libs.a: clean: make -C lib clean - $(REMOVE) ../lib/TEST/test.c $(REMOVE) *.o $(REMOVE) *.c~ find . -type f ! -perm /u=x -maxdepth 1 -regex '.+/\.?[^\.]+' -exec $(REMOVE) {} \; diff --git a/programs/test2.c b/programs/test2.c new file mode 100644 index 0000000..84b085e --- /dev/null +++ b/programs/test2.c @@ -0,0 +1,17 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ + +#include "libsys.h"; +#include "libvideo.h"; +#include "types.h"; + +void main(void) +{ + while (true) + { + if (getticks()%10==0) + print("[TEST]\r\n"); + } + exit(1); +} diff --git a/syscalls.txt b/syscalls.txt index fdf2395..ff30c0c 100644 --- a/syscalls.txt +++ b/syscalls.txt @@ -1,5 +1,16 @@ [ { +"ID":4, +"NAME":"getticks", +"LIBRARY":"libsys", +"INTERNALNAME":"gettimer", +"DESCRIPTION":"Return the internal value of the timer", +"ARGS": [], +"RETURN":"u32" +} + +, +{ "ID":2, "LIBRARY":"libvideo", "NAME":"print", @@ -27,17 +38,6 @@ "DUMP":"yes" } -, -{ -"ID":4, -"NAME":"getticks", -"LIBRARY":"libsys", -"INTERNALNAME":"gettimer", -"DESCRIPTION":"Return the internal value of the timer", -"ARGS": [], -"RETURN":"u32" -} - , { "ID":1, @@ -59,7 +59,7 @@ "ARGS": [ {"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} ], -"RETURN":"void" +"RETURN":"u32" } ] \ No newline at end of file diff --git a/templates/syscall.c b/templates/syscall.c index f29441e..6d2158f 100644 --- a/templates/syscall.c +++ b/templates/syscall.c @@ -25,7 +25,7 @@ extern wrapper_sysenter; void initsyscall(void) { wrmsr(0x174, SEL_KERNEL_CODE, 0x0); - wrmsr(0x175, 0x60000, 0x0); + wrmsr(0x175, NULL, 0x0); wrmsr(0x176, &wrapper_sysenter, 0x0); return; }