diff --git a/README.md b/README.md index fe72259..c16cad4 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Compilation: Nom | Paquet | Version --- | --- | --- -gcc | gcc | 5.4.0 20160609 +gcc | gcc | *>7.0* GNU Make | make | 4.1 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), * mode protégé limité à 4Go de mémoire vive (32 bits), * gestion avancée de la mémoire (vmalloc). +* chargeur ELF32, +* espace utilisateur et appels systèmes, +* liste d'API automatiquement mise à jour, #### En cours -* espace utilisateur et appels systèmes, * ordonnanceur de tâche (par TSS), -* liste d'API automatiquement mise à jour, #### A faire -* chargeur ELF32, * pilote IDE/ATA (PIO mode), * fonctions affichage image PNG, * double buffering, diff --git a/include/process.h b/include/process.h index 62667b2..600da91 100644 --- a/include/process.h +++ b/include/process.h @@ -185,7 +185,6 @@ typedef struct process pid_t getcurrentpid(void); pid_t getparentpid(void); pid_t getfreepid(void); -void usepid(pid_t pid); tid_t getcurrenttid(void); tid_t maketid(pid_t pid, u32 number); diff --git a/include/timer.h b/include/timer.h index 94b33d4..ba48eae 100644 --- a/include/timer.h +++ b/include/timer.h @@ -1,4 +1,7 @@ /*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ -void timer(void); + +#include "interrupts.h" + +__attribute__ ((noreturn)) void timer_handler(regs *dump); diff --git a/lib/gdt.c b/lib/gdt.c index 08ee743..233e1c4 100644 --- a/lib/gdt.c +++ b/lib/gdt.c @@ -30,7 +30,7 @@ void initgdt(u32 offset) tss0.trapflag = 0x00; tss0.iomap = 0x00; - tss0.esp0 = 0x00; + tss0.esp0 = 0x6000; tss0.ss0 = SEL_TSS; makegdtdes(&tss0, 0x67, SEG_PRESENT | SEG_CODE | SEG_RING3 | SEG_ACCESSED, 0x00, &gdt[7]); /* descripteur de tss */ diff --git a/lib/handlers.c b/lib/handlers.c index f32db15..c866a98 100644 --- a/lib/handlers.c +++ b/lib/handlers.c @@ -14,9 +14,65 @@ /******************************************************************************/ /* 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 */ __attribute__((interrupt)) void irq0(exception_stack_noerror *caller) -{ print("irq 0"); +{ + print("irq 0"); irqendmaster(); } @@ -267,8 +324,6 @@ __attribute__((interrupt)) void irq13(exception_stack_noerror *caller) print("irq 13"); irqendslave(); irqendmaster(); - popad(); - popf(); } __attribute__((interrupt)) void irq14(exception_stack_noerror *caller) diff --git a/lib/handlers_asm.S b/lib/handlers_asm.S index 58efa91..a297e57 100644 --- a/lib/handlers_asm.S +++ b/lib/handlers_asm.S @@ -12,7 +12,46 @@ pushl %esp pushf pushl %cs 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 exception 0 @@ -35,6 +74,10 @@ exception 16 exception 17 exception 18 +exception_suite: +semidumpcpu +call exception_handler + .global wrapper_sysenter wrapper_sysenter: pushl %ss @@ -42,79 +85,25 @@ pushl %esp pushf pushl %cs pushl $0x00 -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 +semidumpcpu call sysenter_handler -dumpcpu: -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 +.global wrapper_interruption +wrapper_interruption: +pushl %ss 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 diff --git a/lib/interrupts.c b/lib/interrupts.c index 0c811a3..7839ade 100644 --- a/lib/interrupts.c +++ b/lib/interrupts.c @@ -41,6 +41,7 @@ extern wrapper_exception15; extern wrapper_exception16; extern wrapper_exception17; extern wrapper_exception18; +extern wrapper_interruption; /******************************************************************************/ /* Initialise la reprise après erreur */ @@ -208,7 +209,7 @@ void initidt(void) ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 18); 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); } putidt((u32) irq0, SEL_KERNEL_CODE, @@ -229,7 +230,7 @@ void initidt(void) ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 39); 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); } putidt((u32) irq8, SEL_KERNEL_CODE, @@ -250,7 +251,7 @@ void initidt(void) ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 103); 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); } /* initialise le registre idt */ diff --git a/lib/keyboard.c b/lib/keyboard.c index a8ee520..19460a0 100644 --- a/lib/keyboard.c +++ b/lib/keyboard.c @@ -364,7 +364,6 @@ unsigned convert(u32 keypressed) __attribute__((interrupt)) void keyboard_handler(exception_stack_noerror *caller) { u8 scancode, ascii; - cli(); while ((inb(0x64) & 1) == 0); scancode = inb(0x60); ascii = convert(scancode); diff --git a/lib/makefile b/lib/makefile index d3fd2b9..68e0cd6 100755 --- a/lib/makefile +++ b/lib/makefile @@ -22,13 +22,13 @@ libs.o:$(OBJS) $(OBJASM) $(ASM) $^ handlers.o:handlers.c - $(CC) -mno-sse $^ + $(CC) -mgeneral-regs-only $^ keyboard.o:keyboard.c - $(CC) -mno-sse $^ + $(CC) -mgeneral-regs-only $^ mouse.o:mouse.c - $(CC) -mno-sse $^ + $(CC) -mgeneral-regs-only $^ syscall.o:syscall.c $(CC) -fomit-frame-pointer $^ diff --git a/lib/process.c b/lib/process.c index 916c4a5..c552d6e 100644 --- a/lib/process.c +++ b/lib/process.c @@ -95,6 +95,8 @@ u32 loadelf(u8 * src, pid_t pid) header = (elf32 *) src; program = (elf32p *) (src + header->e_phoff); code = iself(src); + process *aprocess=findprocess(pid); + if (aprocess==NULL) return NULL; if (code != 0) { 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) { - processes[(u32)pid].exec_low = (u8 *) v_begin; - processes[(u32)pid].exec_high = (u8 *) v_end; + aprocess->exec_low = (u8 *) v_begin; + aprocess->exec_high = (u8 *) v_end; } if (program->p_flags == PF_W + PF_R) { - processes[(u32)pid].bss_low = (u8 *) v_begin; - processes[(u32)pid].bss_high = (u8 *) v_end; + aprocess->bss_low = (u8 *) v_begin; + aprocess->bss_high = (u8 *) v_end; } memcpy((u8 *) (src + program->p_offset), (u8 *) v_begin, program->p_filesz, 0); @@ -144,19 +146,21 @@ u32 loadelf(u8 * src, pid_t pid) void initprocesses(void) { - u32 i = 1; + u32 i = 0; processes = (process *) vmalloc(sizeof(process) * MAXNUMPROCESS); while (i < MAXNUMPROCESS) { processes[i].pid = NULL; processes[i++].status = PROCESS_STATUS_FREE; } - createtask(0,getinitretry(),true); - processes[0].result = 0; - processes[0].status = PROCESS_STATUS_READY; - processes[0].iskernel = true; - current = maketid(0,0); - lastpid = NULL; + pid_t pid=getfreepid(); + process *aprocess=findprocess(pid); + if (aprocess==NULL) return NULL; + aprocess->pid = pid; + aprocess->result = 0; + 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 parsed = 0; - while (processes[++i].status != PROCESS_STATUS_FREE - && ++parsed < MAXNUMPROCESS) + while (processes[i++].status != PROCESS_STATUS_FREE + && parsed++ < MAXNUMPROCESS) { if (i >= MAXNUMPROCESS) i = 0; @@ -177,6 +181,7 @@ pid_t getfreepid(void) printf("PANIC: plus d'emplacement disponible pour un novueau processus\n"); return NULL; } + lastpid=i; return (pid_t)i; } @@ -185,15 +190,15 @@ pid_t getfreepid(void) tid_t getfreeptid(pid_t pid) { - tid_t new; - new.pid=pid; - task_t *task_head= &processes[(u32)pid].task_head; + process *aprocess=findprocess(pid); + if (aprocess==NULL) return maketid(0,0); + u32 number=0; task *next; - TAILQ_FOREACH(next, task_head, tailq) - if (next->tid.number>new.number) - new.number=next->tid.number; - next->tid.number++; - return new; + TAILQ_FOREACH(next, &aprocess->task_head, tailq) + if (next->tid.number>number) + number=next->tid.number; + number++; + return maketid(pid,number); } /*******************************************************************************/ @@ -228,7 +233,10 @@ tid_t maketid(pid_t pid, u32 number) 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) { - return &processes[(u32)getcurrentpid()]; -} - -/*******************************************************************************/ -/* Determine le dernier PID occupé */ - -void usepid(pid_t pid) -{ - lastpid = pid; + return &processes[(u32)getcurrentpid()-1]; } /*******************************************************************************/ @@ -254,7 +254,9 @@ void switchtask(tid_t tid) { tid_t previous = current; task *atask = findtask(tid); + if (atask==NULL) return; process *aprocess=findprocess(tid.pid); + if (aprocess==NULL) return; if (!aprocess->iskernel) setTSS(atask->kernel_stack.ss0, atask->kernel_stack.esp0); else @@ -273,9 +275,10 @@ void switchtask(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; - TAILQ_FOREACH(next, task_head, tailq) + TAILQ_FOREACH(next, &aprocess->task_head, tailq) if (next->tid.number==tid.number) return next; } @@ -296,7 +299,9 @@ void deletetask(tid_t tid) { stoptask(tid); process* aprocess=findprocess(tid.pid); + if (aprocess==NULL) return; task *atask=findtask(tid); + if (atask==NULL) return; TAILQ_REMOVE(&aprocess->task_head, atask, tailq); vfree(atask); } @@ -307,6 +312,7 @@ void deletetask(tid_t tid) void runtask(tid_t tid) { task *atask=findtask(tid); + if (atask==NULL) return; if (atask->status == TASK_STATUS_READY) { atask->status = TASK_STATUS_RUN; @@ -322,6 +328,7 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) tid_t tid; tid.pid=pid; process* aprocess=findprocess(pid); + if (aprocess==NULL) return maketid(0,0); task *new = (task *) vmalloc(sizeof(task)); TAILQ_INSERT_TAIL(&aprocess->task_head, new, tailq); page *astack = virtual_page_getfree(); @@ -355,7 +362,6 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) } new->tid=getfreeptid(pid); new->dump.eip = aprocess->entry; - new->status=TASK_STATUS_READY; new->dump.eax = 0; new->dump.ecx = 0; new->dump.edx = 0; @@ -372,8 +378,9 @@ tid_t createtask(pid_t pid,u8 *entry, bool kerneltask) void stoptask(tid_t tid) { - task *current=findtask(tid); - current->status=TASK_STATUS_STOP; + task *atask=findtask(tid); + if (atask==NULL) return; + atask->status=TASK_STATUS_STOP; } /*******************************************************************************/ @@ -384,18 +391,24 @@ pid_t createprocess(u8 *src, bool kerneltask) tid_t previous = current; current.pid = getfreepid(); current.number = 0; - usepid(current.pid); process* new=findcurrentprocess(); + if (new==NULL) return NULL; new->pid = current.pid; new->pdd = virtual_pd_create(); TAILQ_INIT(&new->page_head); + TAILQ_INIT(&new->task_head); new->iskernel=kerneltask; setCR3(new->pdd->addr->paddr); new->entry = loadelf(src, new->pid); createtask(new->pid,new->entry, new->iskernel); current = previous; 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; } @@ -406,6 +419,7 @@ void deleteprocess(pid_t pid) { stopprocess(pid); process* aprocess=findprocess(pid); + if (aprocess==NULL) return; task *next; TAILQ_FOREACH(next, &aprocess->task_head, tailq) deletetask(next->tid); @@ -419,11 +433,13 @@ void deleteprocess(pid_t pid) void runprocess(pid_t pid) { process* aprocess=findprocess(pid); + if (aprocess==NULL) return; if (aprocess->status == PROCESS_STATUS_READY) { aprocess->status = PROCESS_STATUS_RUN; - tid_t tid=maketid(pid,0); + tid_t tid=maketid(pid,1); task *atask=findtask(tid); + if (atask==NULL) return; atask->status=TASK_STATUS_RUN; switchtask(tid); } @@ -435,6 +451,7 @@ void runprocess(pid_t pid) void stopprocess(pid_t pid) { process* aprocess=findprocess(pid); + if (aprocess==NULL) return; if (aprocess->status == PROCESS_STATUS_RUN) { aprocess->status = PROCESS_STATUS_READY; diff --git a/lib/scheduler.c b/lib/scheduler.c new file mode 100644 index 0000000..459f72b --- /dev/null +++ b/lib/scheduler.c @@ -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(); + } +} + + +/*******************************************************************************/ diff --git a/lib/timer.c b/lib/timer.c deleted file mode 100644 index c594e52..0000000 --- a/lib/timer.c +++ /dev/null @@ -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(); -} - -/*******************************************************************************/ diff --git a/system/system.c b/system/system.c index dab3c5e..060f23c 100644 --- a/system/system.c +++ b/system/system.c @@ -25,6 +25,8 @@ static u8 errormsg[] = "\033[150C\033[8D\033[37m\033[1m[\033[31mERREUR\033[37m]\033[0m"; static u8 key = 0; +extern wrapper_timer; + void ok() { print(okmsg); @@ -78,20 +80,20 @@ int main(u32 magic, u32 addr) sti(); ok(); - print(" -Installation de l'horloge systeme (IRQ 0)"); - setidt((u32) timer, SEL_KERNEL_CODE, + print(" -Installation de l'ordonnanceur et horloge systeme (IRQ 0)"); + setidt((u32) &wrapper_timer, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 32); enableirq(0); ok(); 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); enableirq(1); ok(); 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); enableirq(2); enableirq(12);