fix: gestion des erreurs améliorée avec dump de tout les registres, interruption remaniées et fonctions GDT et IDT idem

This commit is contained in:
Nicolas Hordé 2018-10-04 14:55:41 +02:00
parent 72abe00043
commit f07f637447
9 changed files with 214 additions and 134 deletions

View File

@ -31,19 +31,22 @@
#define lgdt(gdtr) asm ("lgdtl %0"::"m" (*gdtr))
#define lldt(ldtr) asm ("lldtl %0"::"m" (*ldtr))
#define ltr(tss) asm volatile ("ltr %%ax":: "a" (tss))
#define sidt(idtr) asm ("sidtl %0"::"m" (*idtr))
#define sgdt(gdtr) asm ("sgdtl %0"::"m" (*gdtr))
#define wrmsr(reg,low,high) asm volatile ("wrmsr" :: "c" (reg), "a" (low), "d" (high))
#define rdmsr(reg,low,high) asm volatile ("rdmsr" :: "=a" (low), "=d" (high) : "c" (reg) )
#define ltr(tss) asm volatile ("ltr %%ax":: "a" (tss))
#define sldt(ldtr) asm ("sldtl %0"::"m" (*ldtr))
#define str(tss) asm volatile ("str %%ax;\
mov %%ax,%0":: "m" (tss))
#define wrmsr(reg,low,high) asm volatile ("wrmsr" :: "c" (reg), "a" (low), "d" (high))
#define rdmsr(reg,low,high) asm volatile ("rdmsr" :: "=a" (low), "=d" (high) : "c" (reg) )
/******************************************************************************/

View File

@ -33,9 +33,9 @@
#define SEG_PRESENT 0b10000000 /* Segment défini (obligatoire) */
#define SEG_RING0 0b00000000 /* Segment anneau 0 */
#define SEG_RING1 0b00100000 /* Segment anneau 0 */
#define SEG_RING2 0b01000000 /* Segment anneau 0 */
#define SEG_RING3 0b01100000 /* Segment anneau 0 */
#define SEG_RING1 0b00100000 /* Segment anneau 1 */
#define SEG_RING2 0b01000000 /* Segment anneau 2 */
#define SEG_RING3 0b01100000 /* Segment anneau 3 */
#define SEG_NORMAL 0b00010000 /* Segment normal pile/data/code (0 pour système) */

View File

@ -23,11 +23,20 @@
#define ICW4_BUF_MASTER 0x0C /* mode/master avec tampon*/
#define ICW4_SFNM 0x10 /* Complètement lié ou non */
#define INTGATE 0x8E00 /* utilise pour gerer les interruptions */
#define TRAPGATE 0x8F00 /* utilise pour faire des appels systemes */
#define TASKGATE 0x8500 /* utilise pour commuter des taches */
#define CALLGATE 0x8C00 /* utilise pour appeler du code */
#define LDTDES 0x8200 /* utilise pour pointer une LDT */
#define INTGATE 0x0E00 /* utilise pour gerer les interruptions */
#define TRAPGATE 0x0F00 /* utilise pour faire des appels systemes */
#define TASKGATE 0x0500 /* utilise pour commuter des taches */
#define CALLGATE 0x0C00 /* utilise pour appeler du code */
#define LDTDES 0x0200 /* utilise pour pointer une LDT */
#define ENTRY_PRESENT 0b1000000000000000 /* Segment défini (obligatoire) */
#define ENTRY_STORAGE 0b0001000000000000 /* Segment défini (obligatoire) */
#define ENTRY_RING0 0b0000000000000000 /* Segment anneau 0 */
#define ENTRY_RING1 0b0010000000000000 /* Segment anneau 1 */
#define ENTRY_RING2 0b0100000000000000 /* Segment anneau 2 */
#define ENTRY_RING3 0b0110000000000000 /* Segment anneau 3 */
/* 00-11-010-0 : Compteur 0 - LSB puis MSB - generateur taux - binaire */
#define TIMER0 0x40 /* port E/S pour le timer canal 0 */
@ -39,6 +48,15 @@
/* save pile */
typedef struct save_stack {
u64 efer;
u32 dr7;
u32 dr6;
u32 dr5;
u32 dr4;
u32 dr3;
u32 dr2;
u32 dr1;
u32 dr0;
u32 cr4;
u32 cr3;
u32 cr2;

View File

@ -20,3 +20,7 @@ int info();
int pgfaultr();
int pgfaultw();
int divzerr();
int invalidop();
int segfault();
int int3();
int generalfault();

View File

@ -149,8 +149,9 @@ u32 setESP(u32 stack)
void dump_cpu(save_stack *stack)
{
save_stack new;
asm(" addl $0x50,%%esp \n \
asm(" movl %%eax,%%ebx":::);
asm(" addl %[size],%%esp \n \
addl $0x8,%%esp \n \
pushl %%eax \n \
pushl %%ebx \n \
pushl %%ecx \n \
@ -160,21 +161,45 @@ asm(" addl $0x50,%%esp \n \
pushl %%ebp \n \
pushl %%esp \n \
pushl %%cs \n \
pushl 0x0 \n \
pushl $0x0 \n \
pushl %%ds \n \
pushl %%es \n \
pushl %%fs \n \
pushl %%gs \n \
pushl %%ss \n \
pushf \n \
mov %%cr0, %%ebx \n \
pushl %%ebx\n \
mov %%cr2, %%ebx \n \
pushl %%ebx\n \
mov %%cr3, %%ebx \n \
pushl %%ebx\n \
mov %%cr4, %%ebx \n \
pushl %%ebx":::);
mov %%eax,%%ebx \n \
mov %%cr0, %%eax \n \
pushl %%eax\n \
mov %%cr2, %%eax \n \
pushl %%eax\n \
mov %%cr3, %%eax \n \
pushl %%eax\n \
mov %%cr4, %%eax \n \
pushl %%eax \n \
mov %%dr0, %%eax \n \
pushl %%eax\n \
mov %%dr1, %%eax \n \
pushl %%eax\n \
mov %%dr2, %%eax \n \
pushl %%eax\n \
mov %%dr3, %%eax \n \
pushl %%eax\n \
mov %%dr4, %%eax \n \
pushl %%eax\n \
mov %%dr5, %%eax \n \
pushl %%eax\n \
mov %%dr6, %%eax \n \
pushl %%eax\n \
mov %%dr7, %%eax \n \
pushl %%eax\n \
mov $0xC0000080, %%ecx \n \
rdmsr \n \
pushl %%edx \n \
pushl %%eax \n \
subl $0x8,%%esp \n \
mov %%ebx,%%eax"::[size] "a" (sizeof(save_stack)):);
save_stack new;
memcpy(&new, stack, sizeof(save_stack), 1);
}
@ -210,7 +235,10 @@ void show_cpu(save_stack *stack)
struct idtr idtreg;
sidt(&idtreg);
printf("IDT= %Y %Y\r\n",idtreg.base,idtreg.limite);
printf("CR0=%Y CR2=%Y CR3=%Y CR4=%Y\r\n",stack->cr0,stack->cr2,stack->cr3,stack->cr4);
printf("DR0=%Y DR1=%Y DR2=%Y DR3=%Y\r\n",stack->dr0,stack->dr1,stack->dr2,stack->dr3);
printf("DR4=%Y DR5=%Y DR6=%Y DR7=%Y\r\n",stack->dr4,stack->dr5,stack->dr6,stack->dr7);
printf("EFER=%lY\r\n",stack->efer);
printf("STACK\r\n");
if (abs(KERNEL_STACK_ADDR-stack->esp)>0x10000)
printf("Pile invalide !");

View File

@ -36,7 +36,7 @@ void initgdt(u32 offset)
makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED , 0x00, &gdt[7]); /* descripteur de tss */
/* initialise le registre gdt */
gdtreg.limite = GDT_SIZE * 8;
gdtreg.limite = GDT_SIZE * sizeof(gdtdes);
gdtreg.base = GDT_ADDR;
/* recopie de la GDT a son adresse */
memcpy(&gdt, (u8 *) gdtreg.base, gdtreg.limite, 1);

View File

@ -139,7 +139,7 @@ void putidt(u32 offset, u16 select, u16 type, u16 index)
void cpuerror(const u8 * src, const save_stack *stack)
{
printf("\033[31m*** ERREUR CPU : %s *** \r\n", src);
show_cpu(stack);
if (stack!=NULL) show_cpu(stack);
print("<Appuyer une touche pour continuer>\033[0m\r\n");
sti();
waitascii();
@ -169,8 +169,9 @@ void interruption()
void exception0()
{
cli();
save_stack dump;
exception_stack_noerror *current = getESP()+0x80;
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
@ -190,7 +191,14 @@ void exception2()
void exception3()
{
cpuerror("INT3 instruction",NULL);
cli();
save_stack dump;
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
dump.esp=(current+1);
cpuerror("INT3 instruction",&dump);
}
void exception4()
@ -205,7 +213,14 @@ void exception5()
void exception6()
{
cpuerror("invalid instruction opcode",NULL);
cli();
save_stack dump;
exception_stack_noerror *current = getESP()+0x28+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
dump.esp=(current+1);
cpuerror("Invalid instruction opcode",&dump);
}
void exception7()
@ -230,7 +245,14 @@ void exception10()
void exception11()
{
cpuerror("segment not present",NULL);
cli();
save_stack dump;
exception_stack_noerror *current = getESP()+0x30+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
dump.esp=(current+1);
cpuerror("segment not present",&dump);
}
void exception12()
@ -240,13 +262,21 @@ void exception12()
void exception13()
{
cpuerror("general protection fault (GPF)",NULL);
cli();
save_stack dump;
exception_stack_noerror *current = getESP()+0x30+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
dump.esp=(current+1);
cpuerror("general protection fault (GPF)",&dump);
}
void exception14()
{
cli();
save_stack dump;
exception_stack *current = getESP()+0x80;
exception_stack *current = getESP()+0x28+sizeof(save_stack);
dump_cpu(&dump);
dump.eip=current->eip;
dump.cs=current->cs;
@ -544,52 +574,52 @@ void irq15()
void initidt(void)
{
u16 i;
putidt((u32) exception0, SEL_KERNEL_CODE, INTGATE, 0);
putidt((u32) exception1, SEL_KERNEL_CODE, INTGATE, 1);
putidt((u32) exception2, SEL_KERNEL_CODE, INTGATE, 2);
putidt((u32) exception3, SEL_KERNEL_CODE, INTGATE, 3);
putidt((u32) exception4, SEL_KERNEL_CODE, INTGATE, 4);
putidt((u32) exception5, SEL_KERNEL_CODE, INTGATE, 5);
putidt((u32) exception6, SEL_KERNEL_CODE, INTGATE, 6);
putidt((u32) exception7, SEL_KERNEL_CODE, INTGATE, 7);
putidt((u32) exception8, SEL_KERNEL_CODE, INTGATE, 8);
putidt((u32) exception9, SEL_KERNEL_CODE, INTGATE, 9);
putidt((u32) exception10, SEL_KERNEL_CODE, INTGATE, 10);
putidt((u32) exception11, SEL_KERNEL_CODE, INTGATE, 11);
putidt((u32) exception12, SEL_KERNEL_CODE, INTGATE, 12);
putidt((u32) exception13, SEL_KERNEL_CODE, INTGATE, 13);
putidt((u32) exception14, SEL_KERNEL_CODE, INTGATE, 14);
putidt((u32) exception15, SEL_KERNEL_CODE, INTGATE, 15);
putidt((u32) exception16, SEL_KERNEL_CODE, INTGATE, 16);
putidt((u32) exception17, SEL_KERNEL_CODE, INTGATE, 17);
putidt((u32) exception18, SEL_KERNEL_CODE, INTGATE, 18);
putidt((u32) exception0, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 0);
putidt((u32) exception1, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 1);
putidt((u32) exception2, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 2);
putidt((u32) exception3, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 3);
putidt((u32) exception4, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 4);
putidt((u32) exception5, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 5);
putidt((u32) exception6, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 6);
putidt((u32) exception7, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 7);
putidt((u32) exception8, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 8);
putidt((u32) exception9, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 9);
putidt((u32) exception10, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 10);
putidt((u32) exception11, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 11);
putidt((u32) exception12, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 12);
putidt((u32) exception13, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 13);
putidt((u32) exception14, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 14);
putidt((u32) exception15, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 15);
putidt((u32) exception16, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 16);
putidt((u32) exception17, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 17);
putidt((u32) exception18, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18);
for (i = 19; i < 32; i++) {
putidt((u32) interruption, 0x20, TRAPGATE, i);
putidt((u32) interruption, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
}
putidt((u32) irq0, SEL_KERNEL_CODE, INTGATE, 32);
putidt((u32) irq1, SEL_KERNEL_CODE, INTGATE, 33);
putidt((u32) irq2, SEL_KERNEL_CODE, INTGATE, 34);
putidt((u32) irq3, SEL_KERNEL_CODE, INTGATE, 35);
putidt((u32) irq4, SEL_KERNEL_CODE, INTGATE, 36);
putidt((u32) irq5, SEL_KERNEL_CODE, INTGATE, 37);
putidt((u32) irq6, SEL_KERNEL_CODE, INTGATE, 38);
putidt((u32) irq7, SEL_KERNEL_CODE, INTGATE, 39);
putidt((u32) irq0, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32);
putidt((u32) irq1, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 33);
putidt((u32) irq2, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 34);
putidt((u32) irq3, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 35);
putidt((u32) irq4, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 36);
putidt((u32) irq5, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 37);
putidt((u32) irq6, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 38);
putidt((u32) irq7, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 39);
for (i = 40; i < 96; i++) {
putidt((u32) interruption, 0x20, TRAPGATE, i);
putidt((u32) interruption, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING3 | TRAPGATE, i);
}
putidt((u32) irq8, SEL_KERNEL_CODE, INTGATE, 96);
putidt((u32) irq9, SEL_KERNEL_CODE, INTGATE, 97);
putidt((u32) irq10, SEL_KERNEL_CODE, INTGATE, 98);
putidt((u32) irq11, SEL_KERNEL_CODE, INTGATE, 99);
putidt((u32) irq12, SEL_KERNEL_CODE, INTGATE, 100);
putidt((u32) irq13, SEL_KERNEL_CODE, INTGATE, 101);
putidt((u32) irq14, SEL_KERNEL_CODE, INTGATE, 102);
putidt((u32) irq15, SEL_KERNEL_CODE, INTGATE, 103);
putidt((u32) irq8, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 96);
putidt((u32) irq9, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 97);
putidt((u32) irq10, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 98);
putidt((u32) irq11, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 99);
putidt((u32) irq12, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100);
putidt((u32) irq13, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 101);
putidt((u32) irq14, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 102);
putidt((u32) irq15, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 103);
for (i = 104; i < IDT_SIZE; i++) {
putidt((u32) interruption, 0x20, TRAPGATE, i);
putidt((u32) interruption, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | TRAPGATE, i);
}
/* initialise le registre idt */
idtreg.limite = IDT_SIZE * 8;
idtreg.limite = IDT_SIZE * sizeof(idtdes);
idtreg.base = IDT_ADDR;
/* recopie de la IDT a son adresse */
memcpy(&idt, (u8 *) idtreg.base, idtreg.limite, 1);

View File

@ -24,8 +24,11 @@ static command commands[] = {
{"INFO" , "", &info},
{"PGFAULTW" , "", &pgfaultw},
{"PGFAULTR" , "", &pgfaultr},
{"DIVZERR" , "", &divzerr}
{"DIVZERR" , "", &divzerr},
{"INVALIDOP","", &invalidop},
{"INT3" , "", &int3},
{"GENERALFAULT" , "", &generalfault},
{"SEGFAULT","", &segfault}
};
/*******************************************************************************/
@ -59,6 +62,40 @@ void shell()
}
}
/*******************************************************************************/
/* Génère une interruption 3 */
int int3()
{
print("Creation d'une erreur interruption 3 !\r\n");
asm("int $0x3");
}
/*******************************************************************************/
/* Génère une erreur general fault */
int generalfault()
{
print("Creation d'une erreur general fault !\r\n");
asm("mov $0x666, %ax; ltr %ax");
}
/*******************************************************************************/
/* Génère une erreur double fault */
int segfault()
{
print("Creation d'une erreur double fault !\r\n");
setidt(&segfault, SEL_KERNEL_CODE, INTGATE, 104);
asm("int $0x68");
}
/*******************************************************************************/
/* Génère une erreur d'opcode invalide */
int invalidop()
{
print("Creation d'une erreur d'opcode invalide !\r\n");
asm("mov %cr7, %eax");
}
/*******************************************************************************/
/* Génère une erreur de division par 0 */
int divzerr()
@ -162,16 +199,24 @@ int readidt()
idtdes *desc;
struct idtr idtreg;
sidt(&idtreg);
printf("Information sur l'IDT\r\nAdresse:%X Limite:%hX", idtreg.base,
printf("Information sur l'IDT\r\nAdresse:%X Limite:%hX\r\n", idtreg.base,
(u32) idtreg.limite);
desc = idtreg.base;
for (index = 0; index < idtreg.limite / sizeof(idtdes); index++) {
u32 select = desc[index].select;
u32 offset =
desc[index].offset0_15 + (desc[index].offset16_31 << 16);
u32 type = desc[index].type;
printf("\r\nInterruption % d Selecteur %hX: offset:%X type:",
i++, select, offset, type);
u32 type = desc[index].type & 0x0F00;
u8 *type2;
if (i>=32 & i<=39)
type2="IRQ master";
else if (i>=96 & i<=103)
type2="IRQ slave ";
else if (i<19)
type2="EXCEPTION ";
else
type2="INTERRUPT ";
printf("\r\%s % hu %hY:%Y - ", type2,i++, select, offset, type);
if (type == INTGATE)
print("INTGATE");
else if (type == TRAPGATE)
@ -198,61 +243,13 @@ int readidt()
int readgdt()
{
u32 index;
gdtdes *desc;
struct gdtr gdtreg;
sgdt(&gdtreg);
printf("Information sur la GDT\r\nAdresse:%X Limite:%hX", gdtreg.base,
(u32) gdtreg.limite);
desc = gdtreg.base;
for (index = 0; index < gdtreg.limite / sizeof(gdtdes); index++) {
u32 acces = desc[index].acces;
if (acces >> 7 == 1) {
u32 flags = desc[index].flags;
u32 limit =
desc[index].lim0_15 + (desc[index].lim16_19 << 16);
u32 base =
desc[index].base0_15 +
(desc[index].base16_23 << 16) +
(desc[index].base24_31 << 24);
printf
("\r\nSelecteur %hX: base:%X limit:%X access:%hX flags:%hX\r\n -> ",
index * sizeof(gdtdes), base, limit, acces, flags);
if ((acces >> 4) & 1 == 1)
print("System ");
else {
if (acces & 1 == 1)
print("Access ");
}
if ((acces >> 3) & 1 == 1) {
print("Code.");
if ((acces >> 1) & 1 == 1)
print("Readable ");
if ((acces >> 2) & 1 == 1)
print("Conforming ");
else
print("Normal ");
} else {
print("Data.");
if ((acces >> 2) & 1 == 1)
print("Down ");
else
print("up ");
if ((acces >> 1) & 1 == 1)
print("writeable ");
}
if (flags & 1 == 1)
print("Dispo ");
if ((flags >> 2) & 1 == 1)
print("32bits ");
else
print("16bits ");
if ((flags >> 3) & 1 == 1)
print("4k ");
else
print("1b ");
u8 dpl = (acces >> 5) & 0b11;
printf("DPL:%d", dpl);
}
printf("Information sur la GDT\r\nAdresse:%X Limite:%hX\r\n", gdtreg.base, gdtreg.limite);
for (index = 0; index < gdtreg.limite ; index+=sizeof(gdtdes)) {
if (!isdesvalid(index))
printf("\033[31m");
printf("SEL =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\033[0m\r\n",index,getdesbase(index),getdeslimit(index),getdesdpl(index),getdestype(index),getdessize(index),getdesbit3(index),getdesbit2(index),getdesbit1(index),getdesalign(index));
}
return 0;
}

View File

@ -86,17 +86,17 @@ int main(u32 magic, u32 addr)
ok();
print(" -Installation du handler timer (IRQ 0)");
setidt((u32) timer, SEL_KERNEL_CODE, INTGATE, 32);
setidt((u32) timer, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32);
enableirq(0);
ok();
print(" -Installation du handler clavier (IRQ 1)");
setidt((u32) keyboard, SEL_KERNEL_CODE, INTGATE, 33);
setidt((u32) keyboard, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 33);
enableirq(1);
ok();
print(" -Installation du handler souris (IRQ12+Cascade IRQ2)");
setidt((u32) mouse, SEL_KERNEL_CODE, INTGATE, 100);
setidt((u32) mouse, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100);
enableirq(2);
enableirq(12);
if (initmouse() != 1)