fix: correction du scheduling

This commit is contained in:
Nicolas Hordé 2018-12-26 00:54:19 +01:00
parent 75a8602c5b
commit e3d708850d
8 changed files with 94 additions and 61 deletions

View File

@ -43,4 +43,4 @@ bool cansetflag(u32 flag);
void cpuid(u32 op, u32 * eax, u32 * ebx, u32 * ecx, u32 * edx); void cpuid(u32 op, u32 * eax, u32 * ebx, u32 * ecx, u32 * edx);
u8 getcpuinfos(cpuinfo * inf); u8 getcpuinfos(cpuinfo * inf);
void show_cpu(regs * stack); void show_cpu(regs * stack);
void cpuerror(const u8 * src, const regs * stack, bool returnto); void cpuerror(const u8 * src, const regs * dump, bool returnto);

View File

@ -249,33 +249,62 @@ lors d'un iret en mode kernel:
/* save pile */ /* save pile */
typedef struct regs typedef struct regs
{ {
u64 efer; union {
u32 dr7; struct {
u32 dr6; u64 efer;
u32 dr3; u32 dr7;
u32 dr2; u32 dr6;
u32 dr1; u32 dr3;
u32 dr0; u32 dr2;
u32 cr4; u32 dr1;
u32 cr3; u32 dr0;
u32 cr2; u32 cr4;
u32 cr0; u32 cr3;
u32 ebp; u32 cr2;
u32 edi; u32 cr0;
u32 esi; u32 ebp;
u32 edx; u32 edi;
u32 ecx; u32 esi;
u32 ebx; u32 edx;
u32 eax; u32 ecx;
u32 gs; u32 ebx;
u32 fs; u32 eax;
u32 es; u32 gs;
u32 ds; u32 fs;
u32 eip; u32 es;
u32 cs; u32 ds;
u32 eflags; u32 eip;
u32 esp; u32 cs;
u32 ss; u32 eflags;
u32 esp;
u32 ss;
};
struct {
u32 efer_low, efer_high;
u32 dummy[13*sizeof(u32)];
u16 dx,hdx;
u16 cx,hcx;
u16 bx,hbx;
u16 ax,hax;
u16 gsl,dummy_gs;
u16 fsl,dummy_fs;
u16 esl,dummy_es;
u16 dsl,dummy_ds;
u16 ip,hip;
u16 csl,dummy_cs;
u16 flags,hflags;
u16 sp,hsp;
u16 ssl,dummy_ss;
};
struct {
u64 dummy2;
u32 dummy3[13*sizeof(u32)];
u8 dl,dh,dx2,hdx2;
u8 cl,ch,cx2,hcx2;
u8 bl,bh,bx2,hbx2;
u8 al,ah,ax2,hax2;
};
}
} regs __attribute__ ((packed)); } regs __attribute__ ((packed));
/* exception pile depuis code kernel*/ /* exception pile depuis code kernel*/

View File

@ -7,6 +7,7 @@
#include "string.h" #include "string.h"
#include "asm.h" #include "asm.h"
#include "gdt.h" #include "gdt.h"
#include "process.h"
/* Technologies supportées */ /* Technologies supportées */
@ -36,11 +37,18 @@ static u8 space[] = " ";
/******************************************************************************/ /******************************************************************************/
/* Affiche une erreur CPU et fige l'ordinateur */ /* Affiche une erreur CPU et fige l'ordinateur */
void cpuerror(const u8 * src, const regs * stack, bool returnto) void cpuerror(const u8 * src, const regs * dump, bool returnto)
{ {
printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); process *aprocess=findcurrentprocess();
if (stack != NULL) if (!aprocess->iskernel && !returnto)
show_cpu(stack); {
printf("\033[31m*** ERREUR CPU, KILLING PROCESS %u : %s *** \r\n", aprocess->pid, src);
deleteprocess(aprocess->pid);
}
else
printf("\033[31m*** ERREUR CPU : %s *** \r\n", src);
if (dump != NULL)
show_cpu(dump);
print("<Appuyer une touche pour continuer>\033[0m\r\n"); print("<Appuyer une touche pour continuer>\033[0m\r\n");
sti(); sti();
waitascii(); waitascii();

View File

@ -19,13 +19,13 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump)
u32 interruption=dump->eip; 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 & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE)
{ {
noerror=true; noerror=true;
dump->eip = caller->eip; dump->eip = caller->eip;
dump->cs = caller->cs; dump->cs = caller->cs;
dump->eflags = caller->eflags; dump->eflags = caller->eflags;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack_noerror); dump->esp = (u32) caller + sizeof(exception_stack_noerror);
user=false; user=false;
@ -42,7 +42,7 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump)
noerror=false; noerror=false;
dump->eip = ((exception_stack*)caller)->eip; dump->eip = ((exception_stack*)caller)->eip;
dump->cs = ((exception_stack*)caller)->cs; dump->cs = ((exception_stack*)caller)->cs;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack); dump->esp = (u32) caller + sizeof(exception_stack);
user=false; user=false;
@ -62,7 +62,7 @@ __attribute__ ((noreturn)) void interruption_handler(regs *dump)
default: default:
print("Appel d'une interruption\r\n"); print("Appel d'une interruption\r\n");
} }
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
setESP(dump); setESP(dump);
restcpu_kernel(); restcpu_kernel();
@ -104,13 +104,13 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump)
u32 exception=dump->eip; u32 exception=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 & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE)
{ {
noerror=true; noerror=true;
dump->eip = caller->eip; dump->eip = caller->eip;
dump->cs = caller->cs; dump->cs = caller->cs;
dump->eflags = caller->eflags; dump->eflags = caller->eflags;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack_noerror); dump->esp = (u32) caller + sizeof(exception_stack_noerror);
user=false; user=false;
@ -127,7 +127,7 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump)
noerror=false; noerror=false;
dump->eip = ((exception_stack*)caller)->eip; dump->eip = ((exception_stack*)caller)->eip;
dump->cs = ((exception_stack*)caller)->cs; dump->cs = ((exception_stack*)caller)->cs;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack); dump->esp = (u32) caller + sizeof(exception_stack);
user=false; user=false;
@ -217,7 +217,7 @@ __attribute__ ((noreturn)) void exception_handler(regs *dump)
cpuerror("#MC Machine check", dump, false); cpuerror("#MC Machine check", dump, false);
} }
endofexception: endofexception:
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
setESP(dump); setESP(dump);
restcpu_kernel(); restcpu_kernel();

View File

@ -270,10 +270,12 @@ void switchtask(tid_t tid)
{ {
setTSS(0x0, 0x0); setTSS(0x0, 0x0);
wrmsr(0x175, 0x0, 0x0); wrmsr(0x175, 0x0, 0x0);
} }
if (((atask->dump.cs & 0xFFF8) !=SEL_KERNEL_CODE) && ((atask->dump.cs & 0xFFF8) !=SEL_USER_CODE))
cpuerror("SWITCH ERROR", &atask->dump, false);
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 & 0xFFF8)==SEL_KERNEL_CODE)
restcpu_kernel(); restcpu_kernel();
else else
restcpu_user(); restcpu_user();
@ -382,11 +384,12 @@ void deletetask(tid_t tid)
stoptask(tid); stoptask(tid);
process* aprocess=findprocess(tid.pid); process* aprocess=findprocess(tid.pid);
if (aprocess==NULL) return; if (aprocess==NULL) return;
if (current.pid=tid.pid && current.number==tid.number)
current=maketid(1,1);
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return; if (atask==NULL) return;
TAILQ_REMOVE(&aprocess->task_head, atask, tailq); TAILQ_REMOVE(&aprocess->task_head, atask, tailq);
vfree(atask); vfree(atask);
sti();
} }
/*******************************************************************************/ /*******************************************************************************/
@ -394,15 +397,10 @@ void deletetask(tid_t tid)
void runtask(tid_t tid) void runtask(tid_t tid)
{ {
cli();
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return; 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;
//switchtask(tid);
}
sti();
} }
/*******************************************************************************/ /*******************************************************************************/
@ -466,7 +464,6 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
new->dump.edi = 0; new->dump.edi = 0;
new->status = TASK_STATUS_READY; new->status = TASK_STATUS_READY;
return new->tid; return new->tid;
sti();
} }
/*******************************************************************************/ /*******************************************************************************/
@ -474,11 +471,9 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask)
void stoptask(tid_t tid) void stoptask(tid_t tid)
{ {
cli();
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return; if (atask==NULL) return;
atask->status=TASK_STATUS_STOP; atask->status=TASK_STATUS_STOP;
sti();
} }
/*******************************************************************************/ /*******************************************************************************/
@ -495,9 +490,9 @@ pid_t createprocess(u8 *src, bool kerneltask)
if (new==NULL) return NULL; if (new==NULL) return NULL;
new->parent=oldprocess->pid; new->parent=oldprocess->pid;
new->pdd = virtual_pd_create(); new->pdd = virtual_pd_create();
new->iskernel=kerneltask;
TAILQ_INIT(&new->page_head); TAILQ_INIT(&new->page_head);
TAILQ_INIT(&new->task_head); TAILQ_INIT(&new->task_head);
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);
@ -509,8 +504,8 @@ pid_t createprocess(u8 *src, bool kerneltask)
cr3=old->pdd->addr->paddr; cr3=old->pdd->addr->paddr;
setCR3(cr3); setCR3(cr3);
new->status=PROCESS_STATUS_READY; new->status=PROCESS_STATUS_READY;
sti();
return new->pid; return new->pid;
sti();
} }
/*******************************************************************************/ /*******************************************************************************/
@ -522,6 +517,8 @@ void deleteprocess(pid_t pid)
stopprocess(pid); stopprocess(pid);
process* aprocess=findprocess(pid); process* aprocess=findprocess(pid);
if (aprocess==NULL) return; if (aprocess==NULL) return;
if (current.pid==pid)
current=maketid(1,1);
task *next; task *next;
TAILQ_FOREACH(next, &aprocess->task_head, tailq) TAILQ_FOREACH(next, &aprocess->task_head, tailq)
deletetask(next->tid); deletetask(next->tid);
@ -544,7 +541,6 @@ void runprocess(pid_t pid)
task *atask=findtask(tid); task *atask=findtask(tid);
if (atask==NULL) return; if (atask==NULL) return;
atask->status=TASK_STATUS_RUN; atask->status=TASK_STATUS_RUN;
//switchtask(tid);
} }
sti(); sti();
} }

View File

@ -42,13 +42,13 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump)
{ {
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 & 0xFFF8)==SEL_KERNEL_CODE || (caller->cs & 0xFFF8)==SEL_USER_CODE)
{ {
noerror=true; noerror=true;
dump->eip = caller->eip; dump->eip = caller->eip;
dump->cs = caller->cs; dump->cs = caller->cs;
dump->eflags = caller->eflags; dump->eflags = caller->eflags;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack_noerror); dump->esp = (u32) caller + sizeof(exception_stack_noerror);
user=false; user=false;
@ -65,7 +65,7 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump)
noerror=false; noerror=false;
dump->eip = ((exception_stack*)caller)->eip; dump->eip = ((exception_stack*)caller)->eip;
dump->cs = ((exception_stack*)caller)->cs; dump->cs = ((exception_stack*)caller)->cs;
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
dump->esp = (u32) caller + sizeof(exception_stack); dump->esp = (u32) caller + sizeof(exception_stack);
user=false; user=false;
@ -88,7 +88,7 @@ __attribute__ ((noreturn)) void timer_handler(regs *dump)
memcpy(dump, &old->dump, sizeof(regs), 0); memcpy(dump, &old->dump, sizeof(regs), 0);
switchtask(new->tid); switchtask(new->tid);
} }
if (dump->cs==SEL_KERNEL_CODE) if ((dump->cs & 0xFFF8)==SEL_KERNEL_CODE)
{ {
setESP(dump); setESP(dump);
restcpu_kernel(); restcpu_kernel();

View File

@ -136,8 +136,8 @@ int testtask()
pid_t pid; pid_t pid;
pid = createprocess(&programs_test2, false); pid = createprocess(&programs_test2, false);
runprocess(pid); runprocess(pid);
//pid = createprocess(&programs_test, false); pid = createprocess(&programs_test, false);
//runprocess(pid); runprocess(pid);
} }
/*******************************************************************************/ /*******************************************************************************/

View File

@ -11,7 +11,7 @@ void main(void)
print("demarrage...\r\n"); print("demarrage...\r\n");
while (true) while (true)
{ {
if (getticks()%100000==0) if (getticks()%100==0)
print("[TEST]\r\n"); print("[TEST]\r\n");
} }
exit(1); exit(1);