From 3c3f0bb88e76c151160543846a8abfa083d7cf3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Sat, 15 Dec 2018 19:13:26 +0100 Subject: [PATCH] feat: suppression de NASM en tant qu'assembleur et utilisateur de GAS, bascule des handlers sur un nouveau fichier et modification progressive des interruptions/exceptions --- README.md | 3 +- include/cpu.h | 1 + include/handlers.h | 41 ++++ include/interrupts.h | 2 +- include/keyboard.h | 5 +- include/mouse.h | 5 +- include/multiboot.h | 13 + include/multiboot2.h | 11 +- include/syscall.h | 2 +- lib/cpu.c | 19 ++ lib/handlers.c | 376 +++++++++++++++++++++++++++++ lib/interrupts.c | 514 +--------------------------------------- lib/keyboard.c | 10 +- lib/makefile | 13 +- lib/mouse.c | 10 +- lib/syscall.c | 33 ++- makefile | 2 +- makesyscall.py | 6 +- programs/lib/libsys.c | 7 +- programs/lib/libvideo.c | 2 +- system/makefile | 4 +- system/multiboot.S | 88 +++++++ system/multiboot.asm | 58 ----- system/system.c | 4 +- templates/syscall.c | 32 +-- 25 files changed, 612 insertions(+), 649 deletions(-) create mode 100644 include/handlers.h create mode 100644 include/multiboot.h create mode 100644 lib/handlers.c create mode 100644 system/multiboot.S delete mode 100644 system/multiboot.asm diff --git a/README.md b/README.md index 9d5e80d..a912802 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,6 @@ Compilation: Nom | Paquet | Version --- | --- | --- -NASM | nasm | 2.11.08 gcc | gcc | 5.4.0 20160609 GNU Make | make | 4.1 Outils divers | binutils | 2.26-8 @@ -106,7 +105,7 @@ Puis cloner le source chez vous avec la commande : Sous linux - Debian & Ubuntu like -`sudo apt-get install nasm gcc qemu fusefat fuseext2 cgdb ovmf bsdmainutils tar bsdmainutils indent binutils` +`sudo apt-get install gcc qemu fusefat fuseext2 cgdb ovmf bsdmainutils tar bsdmainutils indent binutils` ou sinon, depuis un terminal disposé sur le répertoire cos2000 diff --git a/include/cpu.h b/include/cpu.h index 6db616e..0b2c3c5 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -43,3 +43,4 @@ bool cansetflag(u32 flag); void cpuid(u32 op, u32 * eax, u32 * ebx, u32 * ecx, u32 * edx); u8 getcpuinfos(cpuinfo * inf); void show_cpu(regs * stack); +void cpuerror(const u8 * src, const regs * stack, bool returnto); diff --git a/include/handlers.h b/include/handlers.h new file mode 100644 index 0000000..d7b4a18 --- /dev/null +++ b/include/handlers.h @@ -0,0 +1,41 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ +#include "types.h" + +__attribute__((interrupt)) void interruption(exception_stack_noerror *caller); +void exception0(); +void exception1(); +void exception2(); +void exception3(); +void exception4(); +void exception5(); +void exception6(); +void exception7(); +void exception8(); +void exception9(); +void exception10(); +void exception11(); +void exception12(); +void exception13(); +void exception14(); +void exception15(); +void exception16(); +void exception17(); +void exception18(); +__attribute__((interrupt)) void irq0(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq1(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq2(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq3(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq4(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq5(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq6(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq7(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq8(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq9(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq10(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq11(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq12(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq13(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq14(exception_stack_noerror *caller); +__attribute__((interrupt)) void irq15(exception_stack_noerror *caller); diff --git a/include/interrupts.h b/include/interrupts.h index 1ca0f01..e3d85ff 100644 --- a/include/interrupts.h +++ b/include/interrupts.h @@ -339,5 +339,5 @@ void makeidtdes(u32 offset, u16 select, u16 type, idtdes * desc); void initpic(void); void enableirq(u8 irq); void disableirq(u8 irq); -void cpuerror(const u8 * src, const regs * stack); +void cpuerror(const u8 * src, const regs * stack, bool returnto); #endif diff --git a/include/keyboard.h b/include/keyboard.h index 5d9c57f..b0ba376 100644 --- a/include/keyboard.h +++ b/include/keyboard.h @@ -1,6 +1,9 @@ /*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ + +#include "interrupts.h" + #define SCAN_CTRL 0x1D #define SCAN_LEFTSHIFT 0x2A #define SCAN_RIGHTSHIFT 0x36 @@ -31,7 +34,7 @@ #define STATUS_NUM 0x2000 #define STATUS_SCRL 0x4000 -void keyboard(void); +__attribute__((interrupt)) void keyboard_handler(exception_stack_noerror *caller); void reboot(void); void outkbd(u8 port, u8 data); u8 waitascii(void); diff --git a/include/mouse.h b/include/mouse.h index 194d85d..118576e 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -1,7 +1,10 @@ /*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ + +#include "interrupts.h" + bool initmouse(void); -void mouse(void); +__attribute__((interrupt)) void mouse_handler(exception_stack_noerror *caller); void outmseack(u8 value); void outmsecmd(u8 command); diff --git a/include/multiboot.h b/include/multiboot.h new file mode 100644 index 0000000..959c631 --- /dev/null +++ b/include/multiboot.h @@ -0,0 +1,13 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ +#include "types.h" +#include "multiboot2.h" + +u32 getgrubinfo(u8 type); +u8 *getgrubinfo_cmdline(void); +u32 getgrubinfo_ram(void); +struct multiboot_tag_mmap *getgrubinfo_mem(void); +struct multiboot_tag_framebuffer *getgrubinfo_fb(void); +void getgrubinfo_all(void); +void initmultiboot(const u32 addr); diff --git a/include/multiboot2.h b/include/multiboot2.h index e7d91fb..c81f77a 100644 --- a/include/multiboot2.h +++ b/include/multiboot2.h @@ -1,8 +1,6 @@ /*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ -#include "types.h" - #ifndef MULTIBOOT # define MULTIBOOT @@ -71,6 +69,7 @@ # define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 # define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 +#include "types.h" struct multiboot_header { /* Must be MULTIBOOT_MAGIC - see above. */ @@ -389,12 +388,4 @@ struct multiboot_tag_load_base_addr u32 load_base_addr; }; -u32 getgrubinfo(u8 type); -u8 *getgrubinfo_cmdline(void); -u32 getgrubinfo_ram(void); -struct multiboot_tag_mmap *getgrubinfo_mem(void); -struct multiboot_tag_framebuffer *getgrubinfo_fb(void); -void getgrubinfo_all(void); -void initmultiboot(const u32 addr); - #endif diff --git a/include/syscall.h b/include/syscall.h index 1d8cf85..858d139 100644 --- a/include/syscall.h +++ b/include/syscall.h @@ -47,4 +47,4 @@ /* Vers 6 arguments maximum */ void initsyscall(void); -void sysenter_handler(void); +__attribute__ ((noreturn)) void sysenter_handler(void); diff --git a/lib/cpu.c b/lib/cpu.c index 7e3b423..09f13f6 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -33,6 +33,25 @@ static u8 *msg[] = { static u8 space[] = " "; +/******************************************************************************/ +/* Affiche une erreur CPU et fige l'ordinateur */ + +void cpuerror(const u8 * src, const regs * stack, bool returnto) +{ + printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); + if (stack != NULL) + show_cpu(stack); + print("\033[0m\r\n"); + sti(); + waitascii(); + if (!returnto) + { + print("Retour en force au SHELL\r\n"); + initselectors(getinitretry()); + + } +} + /******************************************************************************/ /* Annule les FLAGs CPU */ diff --git a/lib/handlers.c b/lib/handlers.c new file mode 100644 index 0000000..6692e1e --- /dev/null +++ b/lib/handlers.c @@ -0,0 +1,376 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ +#include "interrupts.h" +#include "types.h" +#include "asm.h" +#include "memory.h" +#include "video.h" +#include "gdt.h" +#include "system.h" +#include "debug.h" +#include "process.h" + +/******************************************************************************/ +/* Déclenché lors de l'appel d'une interruption */ + +__attribute__((interrupt)) void interruption(exception_stack_noerror *caller) +{ + print("Appel d'une interruption\r\n"); +} + +/******************************************************************************/ +/* Les expections */ + +void exception0() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#DE Divide error", dump, false); +} + +void exception1() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + changevc(6); + clearscreen(); + show_lightcpu(dump); + printf("\r\n\033[7m[P]\033[0m PAS A PAS \033[7m D \033[0m PAS A PAS DETAILLE \033[7m C \033[0m CONTINUER \033[7m S \033[0m STOPPER \033[7m V \033[0m VOIR \033[7m S \033[0m SCINDER"); + sti(); + u8 ascii = waitascii(); + cli(); + if (ascii == 'P' || ascii == 'p') + setdebugreg(0, + caller->eip + disasm(caller->eip, NULL, false), + DBG_EXEC); + else if (ascii == 'D' || ascii == 'd') + setdebugreg(0, 0, DBG_CLEAR); + else if (ascii == 'C' || ascii == 'c') + setdebugreg(0, 0, DBG_CLEAR); + else if (ascii == 'S' || ascii == 's') + { + changevc(0); + sti(); + initselectors(getinitretry()); + } + changevc(0); + restdebugcpu(); + iret(); +} + +void exception2() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("NMI Non-maskable hardware interrupt", dump, false); +} + +void exception3() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#BP INT3 instruction", dump, true); + iret(); +} + +void exception4() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#OF INTO instruction detected overflow", dump, false); +} + +void exception5() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#BR BOUND instruction detected overrange", dump, false); +} + +void exception6() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#UD Invalid instruction opcode", dump, false); +} + +void exception7() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#NM No coprocessor", dump, false); +} + +void exception8() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#DF Double fault", dump, false); +} + +void exception9() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("Coprocessor segment overrun", dump, false); +} + +void exception10() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#TS Invalid task state segment (TSS)", dump, false); +} + +void exception11() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#NP Segment not present", dump, false); +} + +void exception12() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#SS Stack fault", dump, false); +} + +void exception13() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu(dump, caller, oldesp); + cpuerror("#GP General protection fault (GPF)", dump, false); +} + +static u8 ex14_errors1[] = + "Supervisory process tried to read a non-present page entry"; +static u8 ex14_errors2[] = + "Supervisory process tried to read a page and caused a protection fault"; +static u8 ex14_errors3[] = + "Supervisory process tried to write to a non-present page entry"; +static u8 ex14_errors4[] = + "Supervisory process tried to write a page and caused a protection fault"; +static u8 ex14_errors5[] = + "User process tried to read a non-present page entry"; +static u8 ex14_errors6[] = + "User process tried to read a page and caused a protection fault"; +static u8 ex14_errors7[] = + "User process tried to write to a non-present page entry"; +static u8 ex14_errors8[] = + "User process tried to write a page and caused a protection fault"; +static u8 *ex14_errors[] = + { &ex14_errors1, &ex14_errors2, &ex14_errors3, &ex14_errors4, + &ex14_errors5, &ex14_errors6, &ex14_errors7, &ex14_errors8 +}; + +void exception14() +{ + regs *dump; + exception_stack *caller; + u32 *oldesp; + getEBP(oldesp); + dumpcpu(); + getESP(dump); + dump->ebp = *oldesp; + dump->eip = caller->eip; + dump->cs = caller->cs; + if (caller->cs == SEL_KERNEL_CODE) + dump->esp = (u32) oldesp + sizeof(exception_stack); + else + { + dump->esp = (u32) ((exception_stack_user *) caller)->esp; + dump->ss = (u32) ((exception_stack_user *) caller)->ss; + } + if (dump->cr2 >= USER_CODE && dump->cr2 < USER_STACK) + { + virtual_range_new(getcurrentprocess()->pdd, + (u8 *) (dump->cr2 & 0xFFFFF000), + PAGESIZE, PAGE_ALL); + } + else + { + printf("Page fault - %s at adress %Y cs:eip - %Y:%Y\r\n", + ex14_errors[caller->error_code & 0xF], dump->cr2, + dump->cs, dump->eip); + cpuerror("#PGF Page fault", dump, false); + } + restdebugcpu(); + iret(); +} + +void exception15() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("(reserved)", dump, false); +} + +void exception16() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#MF Coprocessor error", dump, false); +} + +void exception17() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#AC Alignment check", dump, false); +} + +void exception18() +{ + regs *dump; + exception_stack_noerror *caller; + u32 *oldesp; + savecpu_noerror(dump, caller, oldesp); + cpuerror("#MC Machine check", dump, false); +} + +/******************************************************************************/ +/* Les IRQ par défaut */ + +__attribute__((interrupt)) void irq0(exception_stack_noerror *caller) +{ print("irq 0"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq1(exception_stack_noerror *caller) +{ + print("irq 1"); + while ((inb(0x64) & 1) == 0); + inb(0x60); + irqendmaster(); +} + +__attribute__((interrupt)) void irq2(exception_stack_noerror *caller) +{ print("irq 2"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq3(exception_stack_noerror *caller) +{ + print("irq 3"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq4(exception_stack_noerror *caller) +{ + print("irq 4"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq5(exception_stack_noerror *caller) +{ + print("irq 5"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq6(exception_stack_noerror *caller) +{ + print("irq 6"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq7(exception_stack_noerror *caller) +{ + print("irq 7"); + irqendmaster(); +} + +__attribute__((interrupt)) void irq8(exception_stack_noerror *caller) +{ + print("irq 8"); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq9(exception_stack_noerror *caller) +{ + print("irq 9"); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq10(exception_stack_noerror *caller) +{ + print("irq 10"); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq11(exception_stack_noerror *caller) +{ + print("irq 11"); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq12(exception_stack_noerror *caller) +{ + print("irq 12"); + while ((inb(0x64) & 1) == 0); + inb(0x60); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq13(exception_stack_noerror *caller) +{ + print("irq 13"); + irqendslave(); + irqendmaster(); + popad(); + popf(); +} + +__attribute__((interrupt)) void irq14(exception_stack_noerror *caller) +{ + print("irq 14"); + irqendslave(); + irqendmaster(); +} + +__attribute__((interrupt)) void irq15(exception_stack_noerror *caller) +{ + print("irq 15"); + irqendslave(); + irqendmaster(); +} diff --git a/lib/interrupts.c b/lib/interrupts.c index 08c4259..a308567 100644 --- a/lib/interrupts.c +++ b/lib/interrupts.c @@ -10,6 +10,7 @@ #include "system.h" #include "debug.h" #include "process.h" +#include "handlers.h" #define IDT_SIZE 256 /* nombre de descripteurs */ @@ -142,519 +143,6 @@ void putidt(u32 offset, u16 select, u16 type, u16 index) idt[index] = temp; } -/******************************************************************************/ -/* Affiche une erreur CPU et fige l'ordinateur */ - -void cpuerror(const u8 * src, const regs * stack) -{ - printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); - if (stack != NULL) - show_cpu(stack); - print("\033[0m\r\n"); - sti(); - waitascii(); - initselectors(retry_address); - /*while (true) { - nop(); - } */ -} - -/******************************************************************************/ -/* Déclenché lors de l'appel d'une interruption */ - -void interruption() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - print("Appel d'une interruption\r\n"); - restdebugcpu(); - iret(); -} - -/******************************************************************************/ -/* Les expections */ - -void exception0() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#DE Divide error", dump); -} - -void exception1() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - changevc(6); - clearscreen(); - show_lightcpu(dump); - printf("\r\n\033[7m[P]\033[0m PAS A PAS \033[7m D \033[0m PAS A PAS DETAILLE \033[7m C \033[0m CONTINUER \033[7m S \033[0m STOPPER \033[7m V \033[0m VOIR \033[7m S \033[0m SCINDER"); - sti(); - u8 ascii = waitascii(); - cli(); - if (ascii == 'P' || ascii == 'p') - setdebugreg(0, - caller->eip + disasm(caller->eip, NULL, false), - DBG_EXEC); - else if (ascii == 'D' || ascii == 'd') - setdebugreg(0, 0, DBG_CLEAR); - else if (ascii == 'C' || ascii == 'c') - setdebugreg(0, 0, DBG_CLEAR); - else if (ascii == 'S' || ascii == 's') - { - changevc(0); - sti(); - initselectors(retry_address); - } - changevc(0); - restdebugcpu(); - iret(); -} - -void exception2() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("NMI Non-maskable hardware interrupt", dump); -} - -void exception3() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#BP INT3 instruction", dump); -} - -void exception4() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#OF INTO instruction detected overflow", dump); -} - -void exception5() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#BR BOUND instruction detected overrange", dump); -} - -void exception6() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#UD Invalid instruction opcode", dump); -} - -void exception7() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#NM No coprocessor", dump); -} - -void exception8() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#DF Double fault", dump); -} - -void exception9() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("Coprocessor segment overrun", dump); -} - -void exception10() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#TS Invalid task state segment (TSS)", dump); -} - -void exception11() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#NP Segment not present", dump); -} - -void exception12() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#SS Stack fault", dump); -} - -void exception13() -{ - regs *dump; - exception_stack *caller; - u32 *oldesp; - savecpu(dump, caller, oldesp); - cpuerror("#GP General protection fault (GPF)", dump); -} - -static u8 ex14_errors1[] = - "Supervisory process tried to read a non-present page entry"; -static u8 ex14_errors2[] = - "Supervisory process tried to read a page and caused a protection fault"; -static u8 ex14_errors3[] = - "Supervisory process tried to write to a non-present page entry"; -static u8 ex14_errors4[] = - "Supervisory process tried to write a page and caused a protection fault"; -static u8 ex14_errors5[] = - "User process tried to read a non-present page entry"; -static u8 ex14_errors6[] = - "User process tried to read a page and caused a protection fault"; -static u8 ex14_errors7[] = - "User process tried to write to a non-present page entry"; -static u8 ex14_errors8[] = - "User process tried to write a page and caused a protection fault"; -static u8 *ex14_errors[] = - { &ex14_errors1, &ex14_errors2, &ex14_errors3, &ex14_errors4, - &ex14_errors5, &ex14_errors6, &ex14_errors7, &ex14_errors8 -}; - -void exception14() -{ - regs *dump; - exception_stack *caller; - u32 *oldesp; - getEBP(oldesp); - dumpcpu(); - getESP(dump); - caller = (exception_stack *) (oldesp + 1); - dump->ebp = *oldesp; - dump->eip = caller->eip; - dump->cs = caller->cs; - if (caller->cs == SEL_KERNEL_CODE) - dump->esp = (u32) oldesp + sizeof(exception_stack); - else - { - dump->esp = (u32) ((exception_stack_user *) caller)->esp; - dump->ss = (u32) ((exception_stack_user *) caller)->ss; - } - if (dump->cr2 >= USER_CODE && dump->cr2 < USER_STACK) - { - virtual_range_new(getcurrentprocess()->pdd, - (u8 *) (dump->cr2 & 0xFFFFF000), - PAGESIZE, PAGE_ALL); - } - else - { - printf("Page fault - %s at adress %Y cs:eip - %Y:%Y\r\n", - ex14_errors[caller->error_code & 0xF], dump->cr2, - dump->cs, dump->eip); - cpuerror("#PGF Page fault", dump); - } - restdebugcpu(); - iret(); -} - -void exception15() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("(reserved)", dump); -} - -void exception16() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#MF Coprocessor error", dump); -} - -void exception17() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#AC Alignment check", dump); -} - -void exception18() -{ - regs *dump; - exception_stack_noerror *caller; - u32 *oldesp; - savecpu_noerror(dump, caller, oldesp); - cpuerror("#MC Machine check", dump); -} - -/******************************************************************************/ -/* Les IRQ par défaut */ - -void irq0() -{ - cli(); - pushf(); - pushad(); - print("irq 0"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq1() -{ - cli(); - pushf(); - pushad(); - print("irq 1"); - while ((inb(0x64) & 1) == 0); - inb(0x60); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq2() -{ - cli(); - pushf(); - pushad(); - print("irq 2"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq3() -{ - cli(); - pushf(); - pushad(); - print("irq 3"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq4() -{ - cli(); - pushf(); - pushad(); - print("irq 4"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq5() -{ - cli(); - pushf(); - pushad(); - print("irq 5"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq6() -{ - cli(); - pushf(); - pushad(); - print("irq 6"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq7() -{ - cli(); - pushf(); - pushad(); - print("irq 7"); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq8() -{ - cli(); - pushf(); - pushad(); - print("irq 8"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq9() -{ - cli(); - pushf(); - pushad(); - print("irq 9"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq10() -{ - cli(); - pushf(); - pushad(); - print("irq 10"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq11() -{ - cli(); - pushf(); - pushad(); - print("irq 11"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq12() -{ - cli(); - pushf(); - pushad(); - print("irq 12"); - while ((inb(0x64) & 1) == 0); - inb(0x60); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq13() -{ - cli(); - pushf(); - pushad(); - print("irq 13"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq14() -{ - cli(); - pushf(); - pushad(); - print("irq 14"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - -void irq15() -{ - cli(); - print("irq 15"); - irqendslave(); - irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); -} - /******************************************************************************/ /* Initialise une IDT */ diff --git a/lib/keyboard.c b/lib/keyboard.c index 53cd8bc..a8ee520 100644 --- a/lib/keyboard.c +++ b/lib/keyboard.c @@ -361,11 +361,8 @@ unsigned convert(u32 keypressed) /******************************************************************************/ /* Handler d'interruption IRQ 1 pour le clavier */ -void keyboard(void) +__attribute__((interrupt)) void keyboard_handler(exception_stack_noerror *caller) { - cli(); - pushf(); - pushad(); u8 scancode, ascii; cli(); while ((inb(0x64) & 1) == 0); @@ -379,11 +376,6 @@ void keyboard(void) bufferascii[ptrascii] = ascii; } irqendmaster(); - popad(); - popf(); - sti(); - leave(); - iret(); } /******************************************************************************/ diff --git a/lib/makefile b/lib/makefile index 8f37f25..00f5cdb 100755 --- a/lib/makefile +++ b/lib/makefile @@ -1,4 +1,4 @@ -CC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -m32 -F elf_i386 -fno-pie -no-pie -I ../include +CC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -m32 -F elf_i386 -fno-pie -no-pie -I ../include -c LINK=ld -m elf_i386 -r -o SRCS= $(wildcard *.c) OBJS= $(SRCS:.c=.o) @@ -15,6 +15,17 @@ togit: clean indent libs.o:$(OBJS) $(LINK) libs.o $(OBJS) +handlers.o:handlers.c + $(CC) -mgeneral-regs-only $^ + +keyboard.o:keyboard.c + $(CC) -mgeneral-regs-only $^ + +mouse.o:mouse.c + $(CC) -mgeneral-regs-only $^ + +syscall.o:syscall.c + $(CC) -fomit-frame-pointer $^ .o: .c $(CC) $^ diff --git a/lib/mouse.c b/lib/mouse.c index ab48d16..fac73ca 100644 --- a/lib/mouse.c +++ b/lib/mouse.c @@ -64,11 +64,8 @@ void outmsecmd(u8 command) /******************************************************************************/ /* Handler d'interruption de la souris IRQ 12 */ -void mouse(void) +__attribute__((interrupt)) void mouse_handler(exception_stack_noerror *caller) { - cli(); - pushf(); - pushad(); u8 mbyte = inb(0x60); s8 changex, changey; @@ -145,11 +142,6 @@ void mouse(void) endofint: irqendmaster(); irqendslave(); - popad(); - popf(); - sti(); - leave(); - iret(); } /*******************************************************************************/ diff --git a/lib/syscall.c b/lib/syscall.c index f869a02..a808a2e 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -15,9 +15,19 @@ * %eax System call number. * %ebx Arg1 * %esi Arg2 - * %edi Arg3 -/*******************************************************************************/ + * %edi Arg3*/ +/*******************************************************************************/ +/* Initialise les appels système par SYSENTER/SYSEXIT */ + +void initsyscall(void) +{ + wrmsr(0x174, SEL_KERNEL_CODE, 0x0); + wrmsr(0x175, 0x60000, 0x0); + wrmsr(0x176, &sysenter_handler, 0x0); +} + +/*******************************************************************************/ /* Fonction permettant de tester le fonctionnement de SYSENTER */ /* SYSCALL { @@ -43,26 +53,16 @@ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump) } /*******************************************************************************/ - -/* Initialise les appels système par SYSENTER/SYSEXIT */ - -void initsyscall(void) -{ - wrmsr(0x174, SEL_KERNEL_CODE, 0x0); - wrmsr(0x175, 0x60000, 0x0); - wrmsr(0x176, &sysenter_handler + 6, 0x0); -} - -/*******************************************************************************/ - /* Entrée pour les appels système SYSENTER */ -void sysenter_handler(void) +__attribute__ ((noreturn)) void sysenter_handler(void) { cli(); regs *dump; dumpcpu(); getESP(dump); + dump->cs=SEL_USER_CODE; + dump->eip=dump->edx; sti(); switch (dump->eax) { @@ -83,7 +83,7 @@ void sysenter_handler(void) break; default: - printf("Appel syscall vers fonction inexistante en %Y:%Y\r\n", dump->cs, dump->eip); + printf("Appel syscall vers fonction inexistante en %Y:%Y", dump->cs, dump->eip); break; } restdebugcpu(); @@ -92,4 +92,3 @@ void sysenter_handler(void) /*******************************************************************************/ - diff --git a/makefile b/makefile index 110ee55..f68fd87 100755 --- a/makefile +++ b/makefile @@ -22,7 +22,7 @@ harddisk: final/harddisk.img.final uefi: final/harddiskuefi.img.final install: - (sudo apt-get install nasm gcc qemu fusefat fuseext2 cgdb ovmf bsdmainutils tar bsdmainutils indent binutils bochs bochs-x bochsbios dos2unix) + (sudo apt-get install gcc qemu fusefat fuseext2 cgdb ovmf bsdmainutils tar bsdmainutils indent binutils bochs bochs-x bochsbios dos2unix) togit: make -C system togit diff --git a/makesyscall.py b/makesyscall.py index d00762c..3c07502 100644 --- a/makesyscall.py +++ b/makesyscall.py @@ -146,9 +146,13 @@ for lib in alllibs: if numargs>0: textargs=textargs+"," textargs=textargs+"(u32) "+syscall['ARGS'][i]['NAME'] + if syscall['RETURN']!='void': + textargs="return "+textargs+");" + else: + textargs=textargs+");\n return;" text=text+getfunction(syscall)+""" { - """+textargs+"""); + """+textargs+""" } """ diff --git a/programs/lib/libsys.c b/programs/lib/libsys.c index 887f434..362745c 100644 --- a/programs/lib/libsys.c +++ b/programs/lib/libsys.c @@ -8,22 +8,23 @@ u32 getticks(void) { - syscall0(4); + return syscall0(4); } void exit(u32 resultcode) { syscall1(5,(u32) resultcode); + return; } u8 waitkey(void) { - syscall0(1); + return syscall0(1); } u32 testapi(u32 arg1, u32 arg2, u32 arg3) { - syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); + return syscall3(0,(u32) arg1,(u32) arg2,(u32) arg3); } diff --git a/programs/lib/libvideo.c b/programs/lib/libvideo.c index 62cf7df..ce19fb7 100644 --- a/programs/lib/libvideo.c +++ b/programs/lib/libvideo.c @@ -8,7 +8,7 @@ u32 print(u8* string) { - syscall1(2,(u32) string); + return syscall1(2,(u32) string); } diff --git a/system/makefile b/system/makefile index 471387a..7ac37e4 100755 --- a/system/makefile +++ b/system/makefile @@ -1,5 +1,5 @@ GCC=gcc -O0 -g -nostdinc -ffreestanding -fno-builtin -Wall -w -I ../include -m32 -fno-pie -no-pie -c -o -ASM=nasm -f elf -o +ASM=gcc -nostdinc -ffreestanding -fno-builtin -m32 -c -fno-pie -no-pie LINK=ld -m elf_i386 -T linker.lds -n -o CONVERT=dos2unix INDENT=indent -nhnl -l75 -ppi3 -ts8 -bls -nbc -di8 -nbad -nbap -nsob -i8 -bl -bli0 -ncdw -nce -cli8 -cbi0 -npcs -cs -saf -sai -saw -nprs -lp -npsl @@ -18,7 +18,7 @@ system.o: $(GCC) system.o system.c multiboot.o: - $(ASM) multiboot.o multiboot.asm -dVESA=$(VESA) + $(ASM) multiboot.S -DVESA=$(VESA) clean: $(REMOVE) *.o diff --git a/system/multiboot.S b/system/multiboot.S new file mode 100644 index 0000000..0e85e65 --- /dev/null +++ b/system/multiboot.S @@ -0,0 +1,88 @@ +/*******************************************************************************/ +/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ +/* */ + +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 +#define MULTIBOOT_MOD_ALIGN 0x00001000 +#define MULTIBOOT_INFO_ALIGN 0x00000008 +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +.section .multiboot, "a" +.align MULTIBOOT_HEADER_ALIGN +multiboot_header: +.long MULTIBOOT2_HEADER_MAGIC +.long MULTIBOOT_ARCHITECTURE_I386 +.long multiboot_header_end - multiboot_header +.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) +#ifdef VESA +#warning VESA active +framebuffer_tag_start: +.align MULTIBOOT_HEADER_ALIGN +.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER +.short MULTIBOOT_HEADER_TAG_OPTIONAL +.long framebuffer_tag_end - framebuffer_tag_start +.long 1024 +.long 768 +.long 32 +framebuffer_tag_end: +#endif +.align MULTIBOOT_HEADER_ALIGN +.short MULTIBOOT_HEADER_TAG_END +.short 0 +.long 8 +multiboot_header_end: +.section .text +.globl start +start: +pushl %ebx +pushl %eax +call main +hlt diff --git a/system/multiboot.asm b/system/multiboot.asm deleted file mode 100644 index 49e2ee6..0000000 --- a/system/multiboot.asm +++ /dev/null @@ -1,58 +0,0 @@ -;/*******************************************************************************/ -;/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -;/* */ -[BITS 32] - -SECTION .multiboot - -%define MULTIBOOT_TAG_ALIGN 8 -%define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 -%define MULTIBOOT_ARCHITECTURE_I386 0 - -%define MULTIBOOT_HEADER_TAG_OPTIONAL 1 - -%define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 - -%define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 - -%define MULTIBOOT_HEADER_TAG_END 0 - -%define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 - -%defstr vesa VESA - -multiboot_header: -align MULTIBOOT_TAG_ALIGN - dd MULTIBOOT2_HEADER_MAGIC ; magic - dd MULTIBOOT_ARCHITECTURE_I386 ; architecture - dd multiboot_header_end - multiboot_header - dd -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header)) -align MULTIBOOT_TAG_ALIGN -%if vesa = "no" -%warning "Avec la console VGA/EGA." -%else -framebuffer_tag_start: -%warning "Avec le FRAMEBUFFER VESA." - dw MULTIBOOT_HEADER_TAG_FRAMEBUFFER ; type - dw MULTIBOOT_HEADER_TAG_OPTIONAL ; flags - dd framebuffer_tag_end - framebuffer_tag_start - dd 1024 ; width - dd 768 ; height - dd 32 ; depth -align MULTIBOOT_TAG_ALIGN -framebuffer_tag_end: -%endif - dw MULTIBOOT_HEADER_TAG_END - dw 0 - dd 8 -multiboot_header_end: -SECTION .text - -global start -extern main - -start: - push ebx - push eax - call main - hlt diff --git a/system/system.c b/system/system.c index e49f2c2..768bf8b 100644 --- a/system/system.c +++ b/system/system.c @@ -85,13 +85,13 @@ int main(u32 magic, u32 addr) ok(); print(" -Installation du pilote clavier (IRQ 1)"); - setidt((u32) keyboard, 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, SEL_KERNEL_CODE, + setidt((u32) mouse_handler, SEL_KERNEL_CODE, ENTRY_PRESENT | ENTRY_RING0 | INTGATE, 100); enableirq(2); enableirq(12); diff --git a/templates/syscall.c b/templates/syscall.c index 73d20f9..7ef09a1 100644 --- a/templates/syscall.c +++ b/templates/syscall.c @@ -15,9 +15,20 @@ * %eax System call number. * %ebx Arg1 * %esi Arg2 - * %edi Arg3 -/*******************************************************************************/ + * %edi Arg3*/ +/*******************************************************************************/ +/* Initialise les appels système par SYSENTER/SYSEXIT */ + +void initsyscall(void) +{ + wrmsr(0x174, SEL_KERNEL_CODE, 0x0); + wrmsr(0x175, 0x60000, 0x0); + wrmsr(0x176, &sysenter_handler, 0x0); + return; +} + +/*******************************************************************************/ /* Fonction permettant de tester le fonctionnement de SYSENTER */ /* SYSCALL { @@ -43,26 +54,16 @@ u32 testapi(u32 arg1, u32 arg2, u32 arg3, regs* dump) } /*******************************************************************************/ - -/* Initialise les appels système par SYSENTER/SYSEXIT */ - -void initsyscall(void) -{ - wrmsr(0x174, SEL_KERNEL_CODE, 0x0); - wrmsr(0x175, 0x60000, 0x0); - wrmsr(0x176, &sysenter_handler + 6, 0x0); -} - -/*******************************************************************************/ - /* Entrée pour les appels système SYSENTER */ -void sysenter_handler(void) +__attribute__ ((noreturn)) void sysenter_handler(void) { cli(); regs *dump; dumpcpu(); getESP(dump); + dump->cs=SEL_USER_CODE; + dump->eip=dump->edx; sti(); switch (dump->eax) { @@ -77,4 +78,3 @@ void sysenter_handler(void) /*******************************************************************************/ -