feat: wrapper pour interruptions et pour l'IRQ0 (Scheduler+Timer) et début d'implémentation du scheduling
This commit is contained in:
parent
dd3e40d53e
commit
11428c2415
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -14,10 +14,66 @@
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
|
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");
|
print("Appel d'une interruption\r\n");
|
||||||
}
|
}
|
||||||
|
if (dump->cs==SEL_KERNEL_CODE)
|
||||||
|
{
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_kernel();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setESP(dump);
|
||||||
|
restcpu_user();
|
||||||
|
iret();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Les expections */
|
/* Les expections */
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 $^
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
55
lib/timer.c
55
lib/timer.c
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************/
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue