From baf52f0594c9df651f7491d52de42f117a6e5455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Tue, 2 Oct 2018 17:16:23 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20ajout=20gestion=20erreur=20Pagefault=20p?= =?UTF-8?q?lus=20fin=20+=20m=C3=A9canisme=20pile=20exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +++-- include/cpu.h | 9 ++++-- include/cpuid.h | 8 ----- include/interrupts.h | 22 +++++++++++-- include/shell.h | 2 +- lib/cpu.c | 35 +++++++++++++-------- lib/interrupts.c | 73 ++++++++++++++++++++++++++++++-------------- lib/shell.c | 6 ++-- makefile | 2 ++ 9 files changed, 108 insertions(+), 56 deletions(-) delete mode 100755 include/cpuid.h diff --git a/README.md b/README.md index 065bb37..a8fe14e 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Sans système d'exploitation votre ordinateur est inopérant: c'est une boite vi COS2000 n'a pas pour but d'être utilisé en exploitation, c'est un système en cours de développement. Vous pouvez néanmoins l'utiliser sur un ordinateur physique ou une machine virtuelle -afin de voir le fonctionnement d'un système rudimentatire. Voir compilation de COS2000... +afin de voir le fonctionnement d'un système d'exploitation rudimentatire. Voir compilation de COS2000... #### Sur quel ordinateur fonctionne t'il ? @@ -119,9 +119,9 @@ Pour tester l'OS en émulation taper donc la commande ```make test``` qui compil Il faut d'abord copier l'image sur une clé (Attention l'opération effacera le contenu de la clé) : -```dd if=./final/harddisk.img.final of=/dev/sdx bs=1M``` (ou sdx est votre périphérique) +```sudo dd if=./final/harddisk.img.final of=/dev/sdx bs=1M``` (ou sdx est votre périphérique) -Bootez sur votre clé en mode bios (legacy). Il est possible que des dysfonctionnement apparaissent sur des machine x86_64 (en cours de résolution). +Bootez sur votre clé en mode bios (legacy). ##### Usage de COS2000 @@ -136,6 +136,7 @@ Pour l'instant quelques commandes seulement sont disponibles: * GDT affiche la table des descripteurs, * IDT affiche la table des interruptions, * INFO affiche des informations issues de GRUB. +* PAGEFAULT génère une erreur de pagination. ![COS2000 le 28-09-2018](https://github.com/dahut87/cos2000v2/raw/develop/Graphisme/screenshots/28-09-2018.png) diff --git a/include/cpu.h b/include/cpu.h index fb75fc3..1cf59f8 100755 --- a/include/cpu.h +++ b/include/cpu.h @@ -1,6 +1,8 @@ /*******************************************************************************/ /* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ /* */ +#include "interrupts.h" + typedef struct cpuinfo { u8 vendor[13]; @@ -37,6 +39,9 @@ bool sse42; bool apic2; } cpuinfo __attribute__ ((packed)); - -u8 getcpuinfos(cpuinfo *inf); +bool cansetflag (u32 flag); +void cpuid(u32 op, u32 *eax, u32 *ebx,u32 *ecx, u32 *edx); +u8 getcpuinfos(cpuinfo *inf); +u32 getESP(void); +void dump_regs(exception_stack *stack); diff --git a/include/cpuid.h b/include/cpuid.h deleted file mode 100755 index 8d0fdf9..0000000 --- a/include/cpuid.h +++ /dev/null @@ -1,8 +0,0 @@ -/*******************************************************************************/ -/* COS2000 - Compatible Operating System - LGPL v3 - Hordé Nicolas */ -/* */ -bool cansetflag (u32 flag); - -void cpuid(u32 op, u32 *eax, u32 *ebx,u32 *ecx, u32 *edx); - -void dump_regs(void); diff --git a/include/interrupts.h b/include/interrupts.h index d0aee52..63277ff 100755 --- a/include/interrupts.h +++ b/include/interrupts.h @@ -3,6 +3,9 @@ /* */ #include "types.h" +#ifndef _INTERRUPTS +#define _INTERRUPTS + #define PIC1_CMD 0x20 /*PIC 8259A Commandes n°1 */ #define PIC1_DATA 0x21 /*PIC 8259A Données n°1 */ #define PIC2_CMD 0xa0 /*PIC 8259A Commandes n°2 */ @@ -34,6 +37,20 @@ #define TIMER_FREQ 1193180 /* fréquence pour timer dans un PC ou AT */ #define HZ 100 /* Fréquence d'horloge (ajutste logiciellement sur IBM-PC) */ +/* exception pile */ +typedef struct exception_stack { + u32 error_code; + u32 eip; + u32 cs; + u32 eflags; +} exception_stack __attribute__ ((packed)); +/* sans code erreur */ +typedef struct exception_stack_noerror { + u32 eip; + u32 cs; + u32 eflags; +} exception_stack_noerror __attribute__ ((packed)); + /* descripteur de segment */ typedef struct idtdes { @@ -55,8 +72,7 @@ struct idtr { void initpic(void); void enableirq(u8 irq); void disableirq(u8 irq); - void cpuerror(const u8 *src); - + void cpuerror(const u8 * src, const exception_stack *stack); - +#endif diff --git a/include/shell.h b/include/shell.h index 009ebff..3b5fee8 100644 --- a/include/shell.h +++ b/include/shell.h @@ -15,6 +15,6 @@ int readgdt(); int detectcpu(); int mode(); int clear(); -int dump_regs(); +int regs(); int info(); int pagefault(); diff --git a/lib/cpu.c b/lib/cpu.c index 79f4377..9349540 100755 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -3,7 +3,6 @@ /* */ #include "types.h" #include "cpu.h" -#include "cpuid.h" #include "memory.h" #include "string.h" #include "asm.h" @@ -127,19 +126,20 @@ u8 getcpuinfos(cpuinfo * proc) } /******************************************************************************/ -/* Retourne un élément de la pile */ +/* Retourne la tête de pile */ -u32 viewstack(u32 pointer) +u32 getESP(void) { u32 stack = 0; - asm("movl %[a1],%%ebp;" "movl (%%ebp), %[a1] ;": [result] "=r"(stack): [a1] "r"(pointer):"%ebp"); + asm("movl %%esp,%[result];": [result] "=r"(stack)); return stack; } + /******************************************************************************/ /* Affiche les registres CPU */ -void dump_regs(void) +void dump_regs(exception_stack *stack) { cli(); u32 eax = 0; @@ -150,6 +150,7 @@ void dump_regs(void) u32 edi = 0; u32 ebp = 0; u32 esp = 0; + u32 eip = 0; u16 cs = 0; u16 ds = 0; u16 es = 0; @@ -167,11 +168,20 @@ void dump_regs(void) [f1] "=m"(edi),[g1] "=m"(esp),[h1] "=m"(ebp),[i1] "=m"(cs),[j1] "=m"(ds), [k1] "=m"(es),[l1] "=m"(fs),[m1] "=m"(gs),[n1] "=m"(ss),[o1] "=m"(cr0), [p1] "=m"(cr2),[q1] "=m"(cr3),[r1] "=m"(cr4)); - + if (stack!=0) { + eip=stack->eip; + eflags=stack->eflags; + cs=stack->cs; + esp=stack; + printf("\033[0m"); + } + else + printf("\033[1mATTENTION PAS DE PILE ! REGISTRES INCERTAINS\r\n"); printf("EAX=%X EBX=%X ECX=%X EDX=%X\r\n", eax, ebx, ecx, edx); printf("ESI=%X EDI=%X ESP=%X EBP=%X\r\n", esi, edi, esp, ebp); + printf("EIP=%X\r\n", eip); printf - ("\033[1m CS=%hX DS=%hX ES=%hX FS=%hX GS=%hX SS=%hX\033[0m\r\n", + ("CS=%hX DS=%hX ES=%hX FS=%hX GS=%hX SS=%hX\r\n", (u32) cs, (u32) ds, (u32) es, (u32) fs, (u32) gs, (u32) ss); printf("CR0=%X CR1=N/A CR2=%X CR3=%X CR4=%X\r\n", cr0, cr2, cr3, cr4); @@ -213,16 +223,15 @@ void dump_regs(void) printf("STACK\r\n"); u32 i = 0; - for (u32 pointer = esp; pointer < 0x400000; pointer += 4) { - if (pointer == ebp) - print("\033[1m\033[31m"); - printf("+%d:%X\t\t%X\033[0m\033[37m\r\n", i++, pointer, - viewstack(pointer)); - if (i > 25) { + for (u32 *pointer = esp; pointer < KERNEL_STACK_ADDR; pointer += 4) { + printf("+%d:%X\t\t%X\r\n", i++, pointer, + (u32)(*pointer)); + if (i > 5) { print("...\r\n"); break; } } + printf("\033[0m"); sti(); } /*******************************************************************************/ diff --git a/lib/interrupts.c b/lib/interrupts.c index e1f9938..d94e8db 100755 --- a/lib/interrupts.c +++ b/lib/interrupts.c @@ -136,11 +136,10 @@ void putidt(u32 offset, u16 select, u16 type, u16 index) /******************************************************************************/ /* Affiche une erreur CPU et fige l'ordinateur */ -void cpuerror(const u8 * src) +void cpuerror(const u8 * src, const exception_stack *stack) { - print("\033[31m***** ERREUR CPU ****\r\n -"); - print(src); - dump_regs(); + printf("\033[31m*** ERREUR CPU : %s *** \r\n", src); + dump_regs(stack); print("\r\n"); waitascii(); initselectors(retry_address); @@ -169,97 +168,125 @@ void interruption() void exception0() { - print("divide error\r\n"); + cpuerror("divide error",0x0); } void exception1() { - cpuerror("debug exception\r\n"); + cpuerror("debug exception",0x0); } void exception2() { - cpuerror("non-maskable hardware interrupt\r\n"); + cpuerror("non-maskable hardware interrupt",0x0); } void exception3() { - cpuerror("INT3 instruction\r\n"); + cpuerror("INT3 instruction",0x0); } void exception4() { - cpuerror("INTO instruction detected overflow\r\n"); + cpuerror("INTO instruction detected overflow",0x0); } void exception5() { - print("BOUND instruction detected overrange\r\n"); + cpuerror("BOUND instruction detected overrange",0x0); } void exception6() { - cpuerror("invalid instruction opcode\r\n"); + cpuerror("invalid instruction opcode",0x0); } void exception7() { - cpuerror("no coprocessor\r\n"); + cpuerror("no coprocessor",0x0); } void exception8() { - cpuerror("double fault\r\n"); + cpuerror("double fault",0x0); } void exception9() { - cpuerror("coprocessor segment overrun\r\n"); + cpuerror("coprocessor segment overrun",0x0); } void exception10() { - cpuerror("invalid task state segment (TSS)\r\n"); + cpuerror("invalid task state segment (TSS)",0x0); } void exception11() { - cpuerror("segment not present\r\n"); + cpuerror("segment not present",0x0); } void exception12() { - cpuerror("stack fault"); + cpuerror("stack fault",0x0); } void exception13() { - cpuerror("general protection fault (GPF)\r\n"); + cpuerror("general protection fault (GPF)",0x0); } void exception14() { - cpuerror("page fault\r\n"); + exception_stack *stack = getESP()+0x30; + u8 *errorstring; + switch (stack->error_code) { + case 0: + errorstring="page fault - Supervisory process tried to read a non-present page entry"; + break; + case 1: + errorstring="Page fault - Supervisory process tried to read a page and caused a protection fault"; + break; + case 2: + errorstring="Page fault - Supervisory process tried to write to a non-present page entry"; + break; + case 3: + errorstring="Page fault - Supervisory process tried to write a page and caused a protection fault"; + break; + case 4: + errorstring="Page fault - User process tried to read a non-present page entry"; + break; + case 5: + errorstring="Page fault - User process tried to read a page and caused a protection fault"; + break; + case 6: + errorstring="Page fault - User process tried to write to a non-present page entry"; + break; + case 7: + errorstring="Page fault - User process tried to write a page and caused a protection fault"; + break; + } + cpuerror(errorstring,stack); } void exception15() { - cpuerror("(reserved)\r\n"); + cpuerror("(reserved)",0x0); } void exception16() { - cpuerror("coprocessor error\r\n"); + cpuerror("coprocessor error",0x0); } void exception17() { - cpuerror("alignment check\r\n"); + cpuerror("alignment check",0x0); } void exception18() { - cpuerror("machine check"); + cpuerror("machine check",0x0); } /******************************************************************************/ diff --git a/lib/shell.c b/lib/shell.c index e13cf35..6cb8f62 100644 --- a/lib/shell.c +++ b/lib/shell.c @@ -18,7 +18,7 @@ static command commands[] = { {"MODE" , "", &mode}, {"DETECTCPU" , "", &detectcpu}, {"TEST2D" , "", &test2d}, - {"REGS" , "", &dump_regs}, + {"REGS" , "", ®s}, {"GDT" , "", &readgdt}, {"IDT" , "", &readidt}, {"INFO" , "", &info}, @@ -60,7 +60,7 @@ void shell() /* Génère une erreur de page à l'adresse 0xE0000000 */ int pagefault() { - print("*** Creation d'une erreur de page ***\r\n"); + print("Creation d'une erreur de page !\r\n"); asm("mov $0x66666666, %eax \n \ mov %eax,0xE0000000"); } @@ -78,7 +78,7 @@ int info() int regs() { - dump_regs(); + dump_regs(0x0); return 0; } diff --git a/makefile b/makefile index 0389950..818fddb 100755 --- a/makefile +++ b/makefile @@ -57,6 +57,8 @@ view: debug: debug-system +redebug: littleclean debug-system + debug64: debug-system64 debug-boot: all harddisk qemu-debug