fix: ajout gestion erreur Pagefault plus fin + mécanisme pile exception

This commit is contained in:
Nicolas Hordé 2018-10-02 17:16:23 +02:00
parent 28c831870e
commit baf52f0594
9 changed files with 108 additions and 56 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -15,6 +15,6 @@ int readgdt();
int detectcpu();
int mode();
int clear();
int dump_regs();
int regs();
int info();
int pagefault();

View File

@ -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();
}
/*******************************************************************************/

View File

@ -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("<Appuyer une touche pour continuer>\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);
}
/******************************************************************************/

View File

@ -18,7 +18,7 @@ static command commands[] = {
{"MODE" , "", &mode},
{"DETECTCPU" , "", &detectcpu},
{"TEST2D" , "", &test2d},
{"REGS" , "", &dump_regs},
{"REGS" , "", &regs},
{"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;
}

View File

@ -57,6 +57,8 @@ view:
debug: debug-system
redebug: littleclean debug-system
debug64: debug-system64
debug-boot: all harddisk qemu-debug