feat: scheduling opérationnel mais subsiste des bogues inconnus

This commit is contained in:
Nicolas Hordé 2018-12-20 16:29:04 +01:00
parent 74b0b4e2e9
commit eff52c8853
15 changed files with 155 additions and 68 deletions

26
API.md
View File

@ -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);` `u32 testapi(u32 arg1, u32 arg2, u32 arg3);`
*Description:Simple function to test if SYSCALL API is correctly running* *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);` `u8 waitkey(void);`
*Description:Wait for user to press a key and return the ascii code pressed* *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* *Description:End a task for user or kernel domain*
* syscall id : **5** * syscall id : **5**
* arguments : **1** * arguments : **1**
* * argument 1 : **u32 resultcode** *Code result of the execution* * * argument 1 : **u32 resultcode** *Code result of the execution*
* results : **void** * results : **u32**
* dump of register cpu: **no** * dump of register cpu: **no**

View File

@ -224,11 +224,12 @@ Pour l'instant quelques commandes seulement sont disponibles:
* gestion avancée de la mémoire (vmalloc). * gestion avancée de la mémoire (vmalloc).
* chargeur ELF32, * chargeur ELF32,
* espace utilisateur et appels systèmes, * espace utilisateur et appels systèmes,
* liste d'API automatiquement mise à jour, * ordonnanceur de tâche (par TSS),
#### En cours #### 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 #### A faire

View File

@ -139,6 +139,7 @@ typedef struct task
{ {
tid_t tid; tid_t tid;
stack kernel_stack; stack kernel_stack;
stack syscall_stack;
u32 status; u32 status;
regs dump; regs dump;
TAILQ_ENTRY(task) tailq; TAILQ_ENTRY(task) tailq;
@ -195,8 +196,8 @@ pid_t clone(void);
pid_t exec(u8* entry, u8* args, bool kerneltask); pid_t exec(u8* entry, u8* args, bool kerneltask);
void switchtask(tid_t tid); void switchtask(tid_t tid);
tid_t getnexttask(void); process* getnextprocess(pid_t pid);
task* getnexttask(void);
task* findtask(tid_t tid); task* findtask(tid_t tid);
task* findcurrenttask(void); task* findcurrenttask(void);
process* findprocess(pid_t pid); process* findprocess(pid_t pid);

View File

@ -40,6 +40,7 @@ clean:
$(REMOVE) *.c~ $(REMOVE) *.c~
$(REMOVE) */*.c~ $(REMOVE) */*.c~
$(REMOVE) ../include/*.h~ $(REMOVE) ../include/*.h~
$(REMOVE) ./TEST/*.c
sync sync
indent: indent:

View File

@ -70,7 +70,7 @@ u32 iself(u8 * src)
"ARGS": [ "ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} {"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
], ],
"RETURN":"void" "RETURN":"u32"
} }
END */ END */
@ -158,10 +158,12 @@ void initprocesses(void)
if (aprocess==NULL) return NULL; if (aprocess==NULL) return NULL;
aprocess->pid = pid; aprocess->pid = pid;
aprocess->result = 0; aprocess->result = 0;
aprocess->status = PROCESS_STATUS_READY; aprocess->status = PROCESS_STATUS_RUN;
aprocess->iskernel = true; aprocess->iskernel = true;
TAILQ_INIT(&aprocess->task_head); TAILQ_INIT(&aprocess->task_head);
current=createtask(pid,getinitretry(),true); 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) pid_t getfreepid(void)
{ {
if (lastpid==0 || lastpid>MAXNUMPROCESS)
lastpid==1;
u32 i = lastpid; u32 i = lastpid;
u32 parsed = 0; u32 parsed = 0;
while (processes[i++].status != PROCESS_STATUS_FREE while (processes[i++].status != PROCESS_STATUS_FREE
@ -260,9 +264,15 @@ void switchtask(tid_t tid)
if (aprocess==NULL) return; if (aprocess==NULL) return;
current = tid; current = tid;
if (!aprocess->iskernel) if (!aprocess->iskernel)
{
setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0); setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0);
wrmsr(0x175, atask->syscall_stack.esp0, 0x0);
}
else else
{
setTSS(0x0, 0x0); setTSS(0x0, 0x0);
wrmsr(0x175, 0x0, 0x0);
}
atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF; atask->dump.eflags = (atask->dump.eflags | 0x200) & 0xFFFFBFFF;
createdump(atask->dump); createdump(atask->dump);
if (atask->dump.cs==SEL_KERNEL_CODE) if (atask->dump.cs==SEL_KERNEL_CODE)
@ -272,6 +282,42 @@ void switchtask(tid_t tid)
iret(); 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 */ /* Cherche l'adresse d'une tâche */
@ -285,6 +331,7 @@ task* findtask(tid_t tid)
return next; return next;
} }
/*******************************************************************************/ /*******************************************************************************/
/* Cherche l'adresse de la tâche courante */ /* 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); if (aprocess==NULL) return maketid(0,0);
task *new = (task *) vmalloc(sizeof(task)); task *new = (task *) vmalloc(sizeof(task));
TAILQ_INSERT_TAIL(&aprocess->task_head, new, tailq); TAILQ_INSERT_TAIL(&aprocess->task_head, new, tailq);
page *astack = virtual_page_getfree(); page *apage = virtual_page_getfree();
if (kerneltask) if (kerneltask)
{ {
new->dump.ss = SEL_KERNEL_STACK; new->dump.ss = SEL_KERNEL_STACK;
if (pid!=1)
new->dump.esp = new->dump.esp =
(u32) astack->vaddr + PAGESIZE - 16; (u32) apage->vaddr + PAGESIZE - 16;
new->dump.esp = KERNEL_STACK_ADDR;
new->dump.eflags = 0x0; new->dump.eflags = 0x0;
new->dump.cs = SEL_KERNEL_CODE; new->dump.cs = SEL_KERNEL_CODE;
new->dump.ds = SEL_KERNEL_DATA; 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.ss0 = SEL_KERNEL_STACK;
new->kernel_stack.esp0 = 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.ss = SEL_USER_STACK | RPL_RING3;
new->dump.esp = USER_STACK - 16; new->dump.esp = USER_STACK - 16;
new->dump.eflags = 0x0; 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->dump.cr3 = aprocess->pdd->addr->paddr;
} }
new->tid=getfreeptid(pid); new->tid=getfreeptid(pid);
if (entry==NULL)
new->dump.eip = aprocess->entry; new->dump.eip = aprocess->entry;
else
new->dump.eip = entry;
new->dump.eax = 0; new->dump.eax = 0;
new->dump.ecx = 0; new->dump.ecx = 0;
new->dump.edx = 0; new->dump.edx = 0;

View File

@ -8,6 +8,7 @@
#include "timer.h" #include "timer.h"
#include "vga.h" #include "vga.h"
#include "gdt.h" #include "gdt.h"
#include "process.h"
static u8 curs[4] = { "-\\|/" }; static u8 curs[4] = { "-\\|/" };
@ -39,7 +40,6 @@ u32 gettimer(void)
__attribute__ ((noreturn)) void timer_handler(regs *dump) __attribute__ ((noreturn)) void timer_handler(regs *dump)
{ {
u32 interruption=dump->eip;
exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1); exception_stack_noerror *caller = (exception_stack_noerror*) ((u32*)dump->esp+1);
bool noerror,user; bool noerror,user;
if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE) if (caller->cs==SEL_KERNEL_CODE || caller->cs==SEL_USER_CODE)
@ -77,10 +77,17 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump)
user=true; user=true;
} }
} }
irqendmaster();
showchar(0, 0, curs[curspos], 7); showchar(0, 0, curs[curspos], 7);
curspos = (curspos + 1) & 0x3; curspos = (curspos + 1) & 0x3;
time++; 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) if (dump->cs==SEL_KERNEL_CODE)
{ {
setESP(dump); setESP(dump);

View File

@ -92,11 +92,14 @@ int test(void)
/* Test l'usage de création de tâche */ /* Test l'usage de création de tâche */
#include "TEST/test.c" #include "TEST/test.c"
#include "TEST/test2.c"
int testtask() int testtask()
{ {
print("*** Creation d'une tache\r\n"); 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); runprocess(pid);
} }

View File

@ -25,7 +25,7 @@ extern wrapper_sysenter;
void initsyscall(void) void initsyscall(void)
{ {
wrmsr(0x174, SEL_KERNEL_CODE, 0x0); wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
wrmsr(0x175, 0x60000, 0x0); wrmsr(0x175, NULL, 0x0);
wrmsr(0x176, &wrapper_sysenter, 0x0); wrmsr(0x176, &wrapper_sysenter, 0x0);
return; return;
} }
@ -62,20 +62,20 @@ __attribute__ ((noreturn)) void sysenter_handler(regs *dump)
sti(); sti();
switch (dump->eax) switch (dump->eax)
{ {
case 4:
dump->eax=(u32) gettimer();
break;
case 2: case 2:
dump->eax=(u32) print(dump->ebx); dump->eax=(u32) print(dump->ebx);
break; break;
case 0: case 0:
dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump); dump->eax=(u32) testapi(dump->ebx, dump->esi, dump->edi, dump);
break; break;
case 4:
dump->eax=(u32) gettimer();
break;
case 1: case 1:
dump->eax=(u32) waitascii(); dump->eax=(u32) waitascii();
break; break;
case 5: case 5:
processexit(dump->ebx); dump->eax=(u32) processexit(dump->ebx);
break; break;
default: default:

View File

@ -14,11 +14,14 @@ syscall: clean remakeapi all
remakeapi: remakeapi:
python makesyscall.py 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: lib/TEST/test.c:
xxd -i programs/test 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: programs/test:
make -C programs make -C programs

View File

@ -4,8 +4,8 @@
#include "types.h"; #include "types.h";
u32 testapi(u32 arg1, u32 arg2, u32 arg3);
u32 getticks(void); u32 getticks(void);
u32 testapi(u32 arg1, u32 arg2, u32 arg3);
u8 waitkey(void); u8 waitkey(void);
void exit(u32 resultcode); u32 exit(u32 resultcode);

View File

@ -6,25 +6,24 @@
#include "syscall.h"; #include "syscall.h";
#include "types.h"; #include "types.h";
u32 testapi(u32 arg1, u32 arg2, u32 arg3)
{
return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3);
}
u32 getticks(void) u32 getticks(void)
{ {
return syscall0(4); return syscall0(4);
} }
u32 testapi(u32 arg1, u32 arg2, u32 arg3)
{
return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3);
}
u8 waitkey(void) u8 waitkey(void)
{ {
return syscall0(1); return syscall0(1);
} }
void exit(u32 resultcode) u32 exit(u32 resultcode)
{ {
syscall1(5,(u32) resultcode); return syscall1(5,(u32) resultcode);
return;
} }

View File

@ -24,7 +24,6 @@ lib/libs.a:
clean: clean:
make -C lib clean make -C lib clean
$(REMOVE) ../lib/TEST/test.c
$(REMOVE) *.o $(REMOVE) *.o
$(REMOVE) *.c~ $(REMOVE) *.c~
find . -type f ! -perm /u=x -maxdepth 1 -regex '.+/\.?[^\.]+' -exec $(REMOVE) {} \; find . -type f ! -perm /u=x -maxdepth 1 -regex '.+/\.?[^\.]+' -exec $(REMOVE) {} \;

17
programs/test2.c Normal file
View File

@ -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);
}

View File

@ -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, "ID":2,
"LIBRARY":"libvideo", "LIBRARY":"libvideo",
"NAME":"print", "NAME":"print",
@ -27,17 +38,6 @@
"DUMP":"yes" "DUMP":"yes"
} }
,
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
"INTERNALNAME":"gettimer",
"DESCRIPTION":"Return the internal value of the timer",
"ARGS": [],
"RETURN":"u32"
}
, ,
{ {
"ID":1, "ID":1,
@ -59,7 +59,7 @@
"ARGS": [ "ARGS": [
{"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"} {"TYPE":"u32","NAME":"resultcode","DESCRIPTION":"Code result of the execution"}
], ],
"RETURN":"void" "RETURN":"u32"
} }
] ]

View File

@ -25,7 +25,7 @@ extern wrapper_sysenter;
void initsyscall(void) void initsyscall(void)
{ {
wrmsr(0x174, SEL_KERNEL_CODE, 0x0); wrmsr(0x174, SEL_KERNEL_CODE, 0x0);
wrmsr(0x175, 0x60000, 0x0); wrmsr(0x175, NULL, 0x0);
wrmsr(0x176, &wrapper_sysenter, 0x0); wrmsr(0x176, &wrapper_sysenter, 0x0);
return; return;
} }