feat: wrapper pour interruptions et pour l'IRQ0 (Scheduler+Timer) et début d'implémentation du scheduling

This commit is contained in:
Nicolas Hordé 2018-12-19 16:13:47 +01:00
parent dd3e40d53e
commit 11428c2415
13 changed files with 299 additions and 191 deletions

View File

@ -63,7 +63,7 @@ Compilation:
Nom | Paquet | Version Nom | Paquet | Version
--- | --- | --- --- | --- | ---
gcc | gcc | 5.4.0 20160609 gcc | gcc | *>7.0*
GNU Make | make | 4.1 GNU Make | make | 4.1
Outils divers | binutils | 2.26-8 Outils divers | binutils | 2.26-8
@ -222,16 +222,16 @@ Pour l'instant quelques commandes seulement sont disponibles:
* affichage de chaîne de caractères (prinfs,sprintf,vsprintf) avec type (bin,hexa,octal,float,double,string,char), * affichage de chaîne de caractères (prinfs,sprintf,vsprintf) avec type (bin,hexa,octal,float,double,string,char),
* mode protégé limité à 4Go de mémoire vive (32 bits), * mode protégé limité à 4Go de mémoire vive (32 bits),
* gestion avancée de la mémoire (vmalloc). * gestion avancée de la mémoire (vmalloc).
* chargeur ELF32,
* espace utilisateur et appels systèmes,
* liste d'API automatiquement mise à jour,
#### En cours #### En cours
* espace utilisateur et appels systèmes,
* ordonnanceur de tâche (par TSS), * ordonnanceur de tâche (par TSS),
* liste d'API automatiquement mise à jour,
#### A faire #### A faire
* chargeur ELF32,
* pilote IDE/ATA (PIO mode), * pilote IDE/ATA (PIO mode),
* fonctions affichage image PNG, * fonctions affichage image PNG,
* double buffering, * double buffering,

View File

@ -185,7 +185,6 @@ typedef struct process
pid_t getcurrentpid(void); pid_t getcurrentpid(void);
pid_t getparentpid(void); pid_t getparentpid(void);
pid_t getfreepid(void); pid_t getfreepid(void);
void usepid(pid_t pid);
tid_t getcurrenttid(void); tid_t getcurrenttid(void);
tid_t maketid(pid_t pid, u32 number); tid_t maketid(pid_t pid, u32 number);

View File

@ -1,4 +1,7 @@
/*******************************************************************************/ /*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */ /* */
void timer(void);
#include "interrupts.h"
__attribute__ ((noreturn)) void timer_handler(regs *dump);

View File

@ -30,7 +30,7 @@ void initgdt(u32 offset)
tss0.trapflag = 0x00; tss0.trapflag = 0x00;
tss0.iomap = 0x00; tss0.iomap = 0x00;
tss0.esp0 = 0x00; tss0.esp0 = 0x6000;
tss0.ss0 = SEL_TSS; tss0.ss0 = SEL_TSS;
makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED, 0x00, &gdt[7]); /* descripteur de tss */ makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED, 0x00, &gdt[7]); /* descripteur de tss */

View File

@ -14,9 +14,65 @@
/******************************************************************************/ /******************************************************************************/
/* Déclenché lors de l'appel d'une interruption */ /* Déclenché lors de l'appel d'une interruption */
__attribute__((interrupt)) void interruption(exception_stack_noerror *caller) __attribute__ ((noreturn)) void interruption_handler(regs *dump)
{ {
print("Appel d'une interruption\r\n"); 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)
{
noerror=true;
dump->eip = caller->eip;
dump->cs = caller->cs;
dump->eflags = caller->eflags;
if (dump->cs==SEL_KERNEL_CODE)
{
dump->esp = (u32) caller + sizeof(exception_stack_noerror);
user=false;
}
else
{
dump->esp = (u32) ((exception_stack_noerror_user*) caller)->esp;
dump->ss = (u32) ((exception_stack_noerror_user*) caller)->ss;
user=true;
}
}
else
{
noerror=false;
dump->eip = ((exception_stack*)caller)->eip;
dump->cs = ((exception_stack*)caller)->cs;
if (dump->cs==SEL_KERNEL_CODE)
{
dump->esp = (u32) caller + sizeof(exception_stack);
user=false;
}
else
{
dump->esp = (u32) ((exception_stack_user*) caller)->esp;
dump->ss = (u32) ((exception_stack_user*) caller)->ss;
user=true;
}
}
switch (interruption)
{
case 20:
show_lightcpu(dump);
break;
default:
print("Appel d'une interruption\r\n");
}
if (dump->cs==SEL_KERNEL_CODE)
{
setESP(dump);
restcpu_kernel();
}
else
{
setESP(dump);
restcpu_user();
iret();
}
} }
/******************************************************************************/ /******************************************************************************/
@ -178,7 +234,8 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump)
/* Les IRQ par défaut */ /* Les IRQ par défaut */
__attribute__((interrupt)) void irq0(exception_stack_noerror *caller) __attribute__((interrupt)) void irq0(exception_stack_noerror *caller)
{ print("irq 0"); {
print("irq 0");
irqendmaster(); irqendmaster();
} }
@ -267,8 +324,6 @@ __attribute__((interrupt)) void irq13(exception_stack_noerror *caller)
print("irq 13"); print("irq 13");
irqendslave(); irqendslave();
irqendmaster(); irqendmaster();
popad();
popf();
} }
__attribute__((interrupt)) void irq14(exception_stack_noerror *caller) __attribute__((interrupt)) void irq14(exception_stack_noerror *caller)

View File

@ -12,7 +12,46 @@ pushl %esp
pushf pushf
pushl %cs pushl %cs
pushl $\num pushl $\num
jmp dumpcpu jmp exception_suite
.endm
.macro semidumpcpu
pushl %ds
pushl %es
pushl %fs
pushl %gs
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
mov %cr0, %eax
pushl %eax
mov %cr2, %eax
pushl %eax
mov %cr3, %eax
pushl %eax
mov %cr4, %eax
pushl %eax
mov %dr0, %eax
pushl %eax
mov %dr1, %eax
pushl %eax
mov %dr2, %eax
pushl %eax
mov %dr3, %eax
pushl %eax
mov %dr6, %eax
pushl %eax
mov %dr7, %eax
pushl %eax
mov $0xC0000080, %ecx
rdmsr
pushl %edx
pushl %eax
pushl %esp
.endm .endm
exception 0 exception 0
@ -35,6 +74,10 @@ exception 16
exception 17 exception 17
exception 18 exception 18
exception_suite:
semidumpcpu
call exception_handler
.global wrapper_sysenter .global wrapper_sysenter
wrapper_sysenter: wrapper_sysenter:
pushl %ss pushl %ss
@ -42,79 +85,25 @@ pushl %esp
pushf pushf
pushl %cs pushl %cs
pushl $0x00 pushl $0x00
pushl %ds semidumpcpu
pushl %es
pushl %fs
pushl %gs
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
mov %cr0, %eax
pushl %eax
mov %cr2, %eax
pushl %eax
mov %cr3, %eax
pushl %eax
mov %cr4, %eax
pushl %eax
mov %dr0, %eax
pushl %eax
mov %dr1, %eax
pushl %eax
mov %dr2, %eax
pushl %eax
mov %dr3, %eax
pushl %eax
mov %dr6, %eax
pushl %eax
mov %dr7, %eax
pushl %eax
mov $0xC0000080, %ecx
rdmsr
pushl %edx
pushl %eax
pushl %esp
call sysenter_handler call sysenter_handler
dumpcpu: .global wrapper_interruption
pushl %ds wrapper_interruption:
pushl %es pushl %ss
pushl %fs
pushl %gs
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
mov %cr0, %eax
pushl %eax
mov %cr2, %eax
pushl %eax
mov %cr3, %eax
pushl %eax
mov %cr4, %eax
pushl %eax
mov %dr0, %eax
pushl %eax
mov %dr1, %eax
pushl %eax
mov %dr2, %eax
pushl %eax
mov %dr3, %eax
pushl %eax
mov %dr6, %eax
pushl %eax
mov %dr7, %eax
pushl %eax
mov $0xC0000080, %ecx
rdmsr
pushl %edx
pushl %eax
pushl %esp pushl %esp
call exception_handler pushf
pushl %cs
pushl $0x00
semidumpcpu
call interruption_handler
.global wrapper_timer
wrapper_timer:
pushl %ss
pushl %esp
pushf
pushl %cs
pushl $0x00
semidumpcpu
call timer_handler

View File

@ -41,6 +41,7 @@ extern wrapper_exception15;
extern wrapper_exception16; extern wrapper_exception16;
extern wrapper_exception17; extern wrapper_exception17;
extern wrapper_exception18; extern wrapper_exception18;
extern wrapper_interruption;
/******************************************************************************/ /******************************************************************************/
/* Initialise la reprise après erreur */ /* Initialise la reprise après erreur */
@ -208,7 +209,7 @@ void initidt(void)
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18);
for (i = 19; i < 32; i++) for (i = 19; i < 32; i++)
{ {
putidt((u32) interruption, SEL_KERNEL_CODE, putidt((u32) &wrapper_interruption, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i); ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
} }
putidt((u32) irq0, SEL_KERNEL_CODE, putidt((u32) irq0, SEL_KERNEL_CODE,
@ -229,7 +230,7 @@ void initidt(void)
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 39); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 39);
for (i = 40; i < 96; i++) for (i = 40; i < 96; i++)
{ {
putidt((u32) interruption, SEL_KERNEL_CODE, putidt((u32) &wrapper_interruption, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i); ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
} }
putidt((u32) irq8, SEL_KERNEL_CODE, putidt((u32) irq8, SEL_KERNEL_CODE,
@ -250,7 +251,7 @@ void initidt(void)
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 103); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 103);
for (i = 104; i < IDT_SIZE; i++) for (i = 104; i < IDT_SIZE; i++)
{ {
putidt((u32) interruption, SEL_KERNEL_CODE, putidt((u32) &wrapper_interruption, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | TRAPGATE, i); ENTRY_PRESENT | ENTRY_RING0 | TRAPGATE, i);
} }
/* initialise le registre idt */ /* initialise le registre idt */

View File

@ -364,7 +364,6 @@ unsigned convert(u32 keypressed)
__attribute__((interrupt)) void keyboard_handler(exception_stack_noerror *caller) __attribute__((interrupt)) void keyboard_handler(exception_stack_noerror *caller)
{ {
u8 scancode, ascii; u8 scancode, ascii;
cli();
while ((inb(0x64) & 1) == 0); while ((inb(0x64) & 1) == 0);
scancode = inb(0x60); scancode = inb(0x60);
ascii = convert(scancode); ascii = convert(scancode);

View File

@ -22,13 +22,13 @@ libs.o:$(OBJS) $(OBJASM)
$(ASM) $^ $(ASM) $^
handlers.o:handlers.c handlers.o:handlers.c
$(CC) -mno-sse $^ $(CC) -mgeneral-regs-only $^
keyboard.o:keyboard.c keyboard.o:keyboard.c
$(CC) -mno-sse $^ $(CC) -mgeneral-regs-only $^
mouse.o:mouse.c mouse.o:mouse.c
$(CC) -mno-sse $^ $(CC) -mgeneral-regs-only $^
syscall.o:syscall.c syscall.o:syscall.c
$(CC) -fomit-frame-pointer $^ $(CC) -fomit-frame-pointer $^

View File

@ -95,6 +95,8 @@ u32 loadelf(u8 * src, pid_t pid)
header = (elf32 *) src; header = (elf32 *) src;
program = (elf32p *) (src + header->e_phoff); program = (elf32p *) (src + header->e_phoff);
code = iself(src); code = iself(src);
process *aprocess=findprocess(pid);
if (aprocess==NULL) return NULL;
if (code != 0) if (code != 0)
{ {
printf("Erreur de chargement ELF, %s !\r\n", printf("Erreur de chargement ELF, %s !\r\n",
@ -119,13 +121,13 @@ u32 loadelf(u8 * src, pid_t pid)
} }
if (program->p_flags == PF_X + PF_R) if (program->p_flags == PF_X + PF_R)
{ {
processes[(u32)pid].exec_low = (u8 *) v_begin; aprocess->exec_low = (u8 *) v_begin;
processes[(u32)pid].exec_high = (u8 *) v_end; aprocess->exec_high = (u8 *) v_end;
} }
if (program->p_flags == PF_W + PF_R) if (program->p_flags == PF_W + PF_R)
{ {
processes[(u32)pid].bss_low = (u8 *) v_begin; aprocess->bss_low = (u8 *) v_begin;
processes[(u32)pid].bss_high = (u8 *) v_end; aprocess->bss_high = (u8 *) v_end;
} }
memcpy((u8 *) (src + program->p_offset), memcpy((u8 *) (src + program->p_offset),
(u8 *) v_begin, program->p_filesz, 0); (u8 *) v_begin, program->p_filesz, 0);
@ -144,19 +146,21 @@ u32 loadelf(u8 * src, pid_t pid)
void initprocesses(void) void initprocesses(void)
{ {
u32 i = 1; u32 i = 0;
processes = (process *) vmalloc(sizeof(process) * MAXNUMPROCESS); processes = (process *) vmalloc(sizeof(process) * MAXNUMPROCESS);
while (i < MAXNUMPROCESS) while (i < MAXNUMPROCESS)
{ {
processes[i].pid = NULL; processes[i].pid = NULL;
processes[i++].status = PROCESS_STATUS_FREE; processes[i++].status = PROCESS_STATUS_FREE;
} }
createtask(0,getinitretry(),true); pid_t pid=getfreepid();
processes[0].result = 0; process *aprocess=findprocess(pid);
processes[0].status = PROCESS_STATUS_READY; if (aprocess==NULL) return NULL;
processes[0].iskernel = true; aprocess->pid = pid;
current = maketid(0,0); aprocess->result = 0;
lastpid = NULL; aprocess->status = PROCESS_STATUS_READY;
aprocess->iskernel = true;
current=createtask(pid,getinitretry(),true);
} }
/*******************************************************************************/ /*******************************************************************************/
@ -166,8 +170,8 @@ pid_t getfreepid(void)
{ {
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
&& ++parsed < MAXNUMPROCESS) && parsed++ < MAXNUMPROCESS)
{ {
if (i >= MAXNUMPROCESS) if (i >= MAXNUMPROCESS)
i = 0; i = 0;
@ -177,6 +181,7 @@ pid_t getfreepid(void)
printf("PANIC: plus d'emplacement disponible pour un novueau processus\n"); printf("PANIC: plus d'emplacement disponible pour un novueau processus\n");
return NULL; return NULL;
} }
lastpid=i;
return (pid_t)i; return (pid_t)i;
} }
@ -185,15 +190,15 @@ pid_t getfreepid(void)
tid_t getfreeptid(pid_t pid) tid_t getfreeptid(pid_t pid)
{ {
tid_t new; process *aprocess=findprocess(pid);
new.pid=pid; if (aprocess==NULL) return maketid(0,0);
task_t *task_head= &processes[(u32)pid].task_head; u32 number=0;
task *next; task *next;
TAILQ_FOREACH(next, task_head, tailq) TAILQ_FOREACH(next, &aprocess->task_head, tailq)
if (next->tid.number>new.number) if (next->tid.number>number)
new.number=next->tid.number; number=next->tid.number;
next->tid.number++; number++;
return new; return maketid(pid,number);
} }
/*******************************************************************************/ /*******************************************************************************/
@ -228,7 +233,10 @@ tid_t maketid(pid_t pid, u32 number)
process* findprocess(pid_t pid) process* findprocess(pid_t pid)
{ {
return &processes[(u32)pid]; if ((u32)pid>0)
return &processes[(u32)pid-1];
else
return NULL;
} }
/*******************************************************************************/ /*******************************************************************************/
@ -236,15 +244,7 @@ process* findprocess(pid_t pid)
process* findcurrentprocess(void) process* findcurrentprocess(void)
{ {
return &processes[(u32)getcurrentpid()]; return &processes[(u32)getcurrentpid()-1];
}
/*******************************************************************************/
/* Determine le dernier PID occupé */
void usepid(pid_t pid)
{
lastpid = pid;
} }
/*******************************************************************************/ /*******************************************************************************/
@ -254,7 +254,9 @@ void switchtask(tid_t tid)
{ {
tid_t previous = current; tid_t previous = current;
task *atask = findtask(tid); task *atask = findtask(tid);
if (atask==NULL) return;
process *aprocess=findprocess(tid.pid); process *aprocess=findprocess(tid.pid);
if (aprocess==NULL) return;
if (!aprocess->iskernel) if (!aprocess->iskernel)
setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0); setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0);
else else
@ -273,9 +275,10 @@ void switchtask(tid_t tid)
task* findtask(tid_t tid) task* findtask(tid_t tid)
{ {
task_t *task_head= &processes[(u32)tid.pid].task_head; process *aprocess=findprocess(tid.pid);
if (aprocess==NULL) return NULL;
task *next; task *next;
TAILQ_FOREACH(next, task_head, tailq) TAILQ_FOREACH(next, &aprocess->task_head, tailq)
if (next->tid.number==tid.number) if (next->tid.number==tid.number)
return next; return next;
} }
@ -296,7 +299,9 @@ void deletetask(tid_t tid)
{ {
stoptask(tid); stoptask(tid);
process* aprocess=findprocess(tid.pid); process* aprocess=findprocess(tid.pid);
if (aprocess==NULL) return;
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return;
TAILQ_REMOVE(&aprocess->task_head, atask, tailq); TAILQ_REMOVE(&aprocess->task_head, atask, tailq);
vfree(atask); vfree(atask);
} }
@ -307,6 +312,7 @@ void deletetask(tid_t tid)
void runtask(tid_t tid) void runtask(tid_t tid)
{ {
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return;
if (atask->status == TASK_STATUS_READY) if (atask->status == TASK_STATUS_READY)
{ {
atask->status = TASK_STATUS_RUN; atask->status = TASK_STATUS_RUN;
@ -322,6 +328,7 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
tid_t tid; tid_t tid;
tid.pid=pid; tid.pid=pid;
process* aprocess=findprocess(pid); process* aprocess=findprocess(pid);
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 *astack = virtual_page_getfree();
@ -355,7 +362,6 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
} }
new->tid=getfreeptid(pid); new->tid=getfreeptid(pid);
new->dump.eip = aprocess->entry; new->dump.eip = aprocess->entry;
new->status=TASK_STATUS_READY;
new->dump.eax = 0; new->dump.eax = 0;
new->dump.ecx = 0; new->dump.ecx = 0;
new->dump.edx = 0; new->dump.edx = 0;
@ -372,8 +378,9 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
void stoptask(tid_t tid) void stoptask(tid_t tid)
{ {
task *current=findtask(tid); task *atask=findtask(tid);
current->status=TASK_STATUS_STOP; if (atask==NULL) return;
atask->status=TASK_STATUS_STOP;
} }
/*******************************************************************************/ /*******************************************************************************/
@ -384,18 +391,24 @@ pid_t createprocess(u8 *src, bool kerneltask)
tid_t previous = current; tid_t previous = current;
current.pid = getfreepid(); current.pid = getfreepid();
current.number = 0; current.number = 0;
usepid(current.pid);
process* new=findcurrentprocess(); process* new=findcurrentprocess();
if (new==NULL) return NULL;
new->pid = current.pid; new->pid = current.pid;
new->pdd = virtual_pd_create(); new->pdd = virtual_pd_create();
TAILQ_INIT(&new->page_head); TAILQ_INIT(&new->page_head);
TAILQ_INIT(&new->task_head);
new->iskernel=kerneltask; new->iskernel=kerneltask;
setCR3(new->pdd->addr->paddr); setCR3(new->pdd->addr->paddr);
new->entry = loadelf(src, new->pid); new->entry = loadelf(src, new->pid);
createtask(new->pid,new->entry, new->iskernel); createtask(new->pid,new->entry, new->iskernel);
current = previous; current = previous;
process* old=findcurrentprocess(); process* old=findcurrentprocess();
setCR3(old->pdd->addr->paddr); if (old==NULL) return NULL;
u32 cr3=KERNEL_PD_ADDR;
if (old->pdd!=NULL)
cr3=old->pdd->addr->paddr;
setCR3(cr3);
new->status=PROCESS_STATUS_READY;
return new->pid; return new->pid;
} }
@ -406,6 +419,7 @@ void deleteprocess(pid_t pid)
{ {
stopprocess(pid); stopprocess(pid);
process* aprocess=findprocess(pid); process* aprocess=findprocess(pid);
if (aprocess==NULL) return;
task *next; task *next;
TAILQ_FOREACH(next, &aprocess->task_head, tailq) TAILQ_FOREACH(next, &aprocess->task_head, tailq)
deletetask(next->tid); deletetask(next->tid);
@ -419,11 +433,13 @@ void deleteprocess(pid_t pid)
void runprocess(pid_t pid) void runprocess(pid_t pid)
{ {
process* aprocess=findprocess(pid); process* aprocess=findprocess(pid);
if (aprocess==NULL) return;
if (aprocess->status == PROCESS_STATUS_READY) if (aprocess->status == PROCESS_STATUS_READY)
{ {
aprocess->status = PROCESS_STATUS_RUN; aprocess->status = PROCESS_STATUS_RUN;
tid_t tid=maketid(pid,0); tid_t tid=maketid(pid,1);
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return;
atask->status=TASK_STATUS_RUN; atask->status=TASK_STATUS_RUN;
switchtask(tid); switchtask(tid);
} }
@ -435,6 +451,7 @@ void runprocess(pid_t pid)
void stopprocess(pid_t pid) void stopprocess(pid_t pid)
{ {
process* aprocess=findprocess(pid); process* aprocess=findprocess(pid);
if (aprocess==NULL) return;
if (aprocess->status == PROCESS_STATUS_RUN) if (aprocess->status == PROCESS_STATUS_RUN)
{ {
aprocess->status = PROCESS_STATUS_READY; aprocess->status = PROCESS_STATUS_READY;

98
lib/scheduler.c Normal file
View File

@ -0,0 +1,98 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "interrupts.h"
#include "types.h"
#include "asm.h"
#include "memory.h"
#include "timer.h"
#include "vga.h"
#include "gdt.h"
static u8 curs[4] = { "-\\|/" };
static u8 curspos = 0;
static u32 time = 0;
/******************************************************************************/
/* Récupère la valeur du timer */
/* SYSCALL
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
"INTERNALNAME":"gettimer",
"DESCRIPTION":"Return the internal value of the timer",
"ARGS": [],
"RETURN":"u32"
}
END */
u32 gettimer(void)
{
return time;
}
/******************************************************************************/
/* Handler d'interruption du timer IRQ 0 */
__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)
{
noerror=true;
dump->eip = caller->eip;
dump->cs = caller->cs;
dump->eflags = caller->eflags;
if (dump->cs==SEL_KERNEL_CODE)
{
dump->esp = (u32) caller + sizeof(exception_stack_noerror);
user=false;
}
else
{
dump->esp = (u32) ((exception_stack_noerror_user*) caller)->esp;
dump->ss = (u32) ((exception_stack_noerror_user*) caller)->ss;
user=true;
}
}
else
{
noerror=false;
dump->eip = ((exception_stack*)caller)->eip;
dump->cs = ((exception_stack*)caller)->cs;
if (dump->cs==SEL_KERNEL_CODE)
{
dump->esp = (u32) caller + sizeof(exception_stack);
user=false;
}
else
{
dump->esp = (u32) ((exception_stack_user*) caller)->esp;
dump->ss = (u32) ((exception_stack_user*) caller)->ss;
user=true;
}
}
showchar(0, 0, curs[curspos], 7);
curspos = (curspos + 1) & 0x3;
time++;
irqendmaster();
if (dump->cs==SEL_KERNEL_CODE)
{
setESP(dump);
restcpu_kernel();
}
else
{
setESP(dump);
restcpu_user();
iret();
}
}
/*******************************************************************************/

View File

@ -1,55 +0,0 @@
/*******************************************************************************/
/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */
/* */
#include "interrupts.h"
#include "types.h"
#include "asm.h"
#include "memory.h"
#include "timer.h"
#include "vga.h"
static u8 curs[4] = { "-\\|/" };
static u8 curspos = 0;
static u32 time = 0;
/******************************************************************************/
/* Récupère la valeur du timer */
/* SYSCALL
{
"ID":4,
"NAME":"getticks",
"LIBRARY":"libsys",
"INTERNALNAME":"gettimer",
"DESCRIPTION":"Return the internal value of the timer",
"ARGS": [],
"RETURN":"u32"
}
END */
u32 gettimer(void)
{
return time;
}
/******************************************************************************/
/* Handler d'interruption de la souris IRQ 0 */
void timer(void)
{
cli();
pushf();
pushad();
showchar(0, 0, curs[curspos], 7);
curspos = (curspos + 1) & 0x3;
time++;
irqendmaster();
popad();
popf();
sti();
leave();
iret();
}
/*******************************************************************************/

View File

@ -25,6 +25,8 @@ static u8 errormsg[] =
"\033[150C\033[8D\033[37m\033[1m[\033[31mERREUR\033[37m]\033[0m"; "\033[150C\033[8D\033[37m\033[1m[\033[31mERREUR\033[37m]\033[0m";
static u8 key = 0; static u8 key = 0;
extern wrapper_timer;
void ok() void ok()
{ {
print(okmsg); print(okmsg);
@ -78,20 +80,20 @@ int main(u32 magic, u32 addr)
sti(); sti();
ok(); ok();
print(" -Installation de l'horloge systeme (IRQ 0)"); print(" -Installation de l'ordonnanceur et horloge systeme (IRQ 0)");
setidt((u32) timer, SEL_KERNEL_CODE, setidt((u32) &wrapper_timer, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32);
enableirq(0); enableirq(0);
ok(); ok();
print(" -Installation du pilote clavier (IRQ 1)"); print(" -Installation du pilote clavier (IRQ 1)");
setidt((u32) keyboard_handler, SEL_KERNEL_CODE, setidt((u32) &keyboard_handler, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 33); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 33);
enableirq(1); enableirq(1);
ok(); ok();
print(" -Installation du pilote souris (IRQ12+IRQ2)"); print(" -Installation du pilote souris (IRQ12+IRQ2)");
setidt((u32) mouse_handler, SEL_KERNEL_CODE, setidt((u32) &mouse_handler, SEL_KERNEL_CODE,
ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100); ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100);
enableirq(2); enableirq(2);
enableirq(12); enableirq(12);