feat: gestion d'exception avancé avec dump des registres
This commit is contained in:
parent
baf52f0594
commit
72abe00043
|
@ -41,6 +41,10 @@
|
|||
|
||||
#define ltr(tss) asm volatile ("ltr %%ax":: "a" (tss))
|
||||
|
||||
#define str(tss) asm volatile ("str %%ax;\
|
||||
mov %%ax,%0":: "m" (tss))
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define outb(port,value) \
|
||||
|
|
|
@ -43,5 +43,6 @@ 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);
|
||||
|
||||
u32 setESP(u32 stack);
|
||||
void dump_cpu(save_stack *stack);
|
||||
void show_cpu(save_stack *stack);
|
||||
|
|
|
@ -77,3 +77,11 @@ typedef struct tss {
|
|||
void inittr(void);
|
||||
void initgdt(u32 offset);
|
||||
void makegdtdes(u32 base, u32 limite, u8 acces, u8 flags, gdtdes *desc);
|
||||
u32 getdesbase(u16 sel);
|
||||
u8 getdestype(u16 sel);
|
||||
u32 getdessize(u16 sel);
|
||||
u32 getdeslimit(u16 sel);
|
||||
bool isdesvalid(u16 sel);
|
||||
u8 getdesbit3(u16 sel);
|
||||
u32 getdesdpl(u16 sel);
|
||||
u16 getdesalign(u16 sel);
|
||||
|
|
|
@ -37,6 +37,29 @@
|
|||
#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) */
|
||||
|
||||
/* save pile */
|
||||
typedef struct save_stack {
|
||||
u32 cr4;
|
||||
u32 cr3;
|
||||
u32 cr2;
|
||||
u32 cr0;
|
||||
u32 eflags;
|
||||
u32 ss;
|
||||
u32 gs;
|
||||
u32 fs;
|
||||
u32 es;
|
||||
u32 ds;
|
||||
u32 eip;
|
||||
u32 cs;
|
||||
u32 esp;
|
||||
u32 ebp;
|
||||
u32 edi;
|
||||
u32 esi;
|
||||
u32 edx;
|
||||
u32 ecx;
|
||||
u32 ebx;
|
||||
u32 eax;
|
||||
} save_stack __attribute__ ((packed));
|
||||
/* exception pile */
|
||||
typedef struct exception_stack {
|
||||
u32 error_code;
|
||||
|
@ -72,7 +95,7 @@ struct idtr {
|
|||
void initpic(void);
|
||||
void enableirq(u8 irq);
|
||||
void disableirq(u8 irq);
|
||||
void cpuerror(const u8 * src, const exception_stack *stack);
|
||||
void cpuerror(const u8 * src, const save_stack *stack);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,4 +17,6 @@ int mode();
|
|||
int clear();
|
||||
int regs();
|
||||
int info();
|
||||
int pagefault();
|
||||
int pgfaultr();
|
||||
int pgfaultw();
|
||||
int divzerr();
|
||||
|
|
171
lib/cpu.c
171
lib/cpu.c
|
@ -6,6 +6,7 @@
|
|||
#include "memory.h"
|
||||
#include "string.h"
|
||||
#include "asm.h"
|
||||
#include "gdt.h"
|
||||
|
||||
/* Technologies supportées */
|
||||
|
||||
|
@ -135,103 +136,99 @@ u32 getESP(void)
|
|||
return stack;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Fixe la tête de pile */
|
||||
|
||||
u32 setESP(u32 stack)
|
||||
{
|
||||
asm("movl %[param],%%esp;": [param] "=r"(stack));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Sauvegarde les registres CPU */
|
||||
|
||||
void dump_cpu(save_stack *stack)
|
||||
{
|
||||
save_stack new;
|
||||
asm(" addl $0x50,%%esp \n \
|
||||
pushl %%eax \n \
|
||||
pushl %%ebx \n \
|
||||
pushl %%ecx \n \
|
||||
pushl %%edx \n \
|
||||
pushl %%esi \n \
|
||||
pushl %%edi \n \
|
||||
pushl %%ebp \n \
|
||||
pushl %%esp \n \
|
||||
pushl %%cs \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":::);
|
||||
memcpy(&new, stack, sizeof(save_stack), 1);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Affiche les registres CPU */
|
||||
|
||||
void dump_regs(exception_stack *stack)
|
||||
void show_cpu(save_stack *stack)
|
||||
{
|
||||
cli();
|
||||
u32 eax = 0;
|
||||
u32 ebx = 0;
|
||||
u32 ecx = 0;
|
||||
u32 edx = 0;
|
||||
u32 esi = 0;
|
||||
u32 edi = 0;
|
||||
u32 ebp = 0;
|
||||
u32 esp = 0;
|
||||
u32 eip = 0;
|
||||
u16 cs = 0;
|
||||
u16 ds = 0;
|
||||
u16 es = 0;
|
||||
u16 fs = 0;
|
||||
u16 gs = 0;
|
||||
u16 ss = 0;
|
||||
u32 cr0 = 0;
|
||||
u32 cr1 = 0;
|
||||
u32 cr2 = 0;
|
||||
u32 cr3 = 0;
|
||||
u32 cr4 = 0;
|
||||
u32 eflags = 0;
|
||||
asm("movl %%eax, %[a1] ;" "movl %%ebx, %[b1] ;" "movl %%ecx, %[c1] ;" "movl %%edx, %[d1] ;" "movl %%esi, %[e1] ;" "movl %%edi, %[f1] ;" "movl %%esp, %[g1] ;" "movl %%ebp, %[h1] ;" "movw %%cs, %[i1] ;" "movw %%ds, %[j1] ;" "movw %%es, %[k1] ;" "movw %%fs, %[l1] ;" "movw %%gs, %[m1] ;" "movw %%ss, %[n1] ;" "mov %%cr0, %%eax ;" "mov %%eax, %[o1] ;" "mov %%cr2, %%eax ;" "mov %%eax, %[p1] ;" "mov %%cr3, %%eax ;" "mov %%eax, %[q1] ;" "mov %%cr4, %%eax ;" "mov %%eax,%[r1] ;":
|
||||
[a1] "=m"(eax),[b1] "=m"(ebx),[c1] "=m"(ecx),[d1] "=m"(edx),[e1] "=m"(esi),
|
||||
[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
|
||||
("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);
|
||||
|
||||
asm("pushf ;" "pop %[f1] ;":
|
||||
[f1] "=m"(eflags));
|
||||
|
||||
printf("EFLAGS=%X", eflags);
|
||||
|
||||
if (eflags & (1 << 0)) // Carry
|
||||
printf(" (C1");
|
||||
else
|
||||
printf(" (C0");
|
||||
|
||||
if (eflags & (1 << 2)) // Parity
|
||||
printf(" P1");
|
||||
else
|
||||
printf(" P0");
|
||||
|
||||
if (eflags & (1 << 4)) // Adjust
|
||||
printf(" A1");
|
||||
else
|
||||
printf(" A0");
|
||||
|
||||
if (eflags & (1 << 6)) // Zero
|
||||
printf(" Z1");
|
||||
else
|
||||
printf(" Z0");
|
||||
|
||||
if (eflags & (1 << 7)) // Sign
|
||||
printf(" S1");
|
||||
else
|
||||
printf(" S0");
|
||||
|
||||
if (eflags & (1 << 11)) // Overflow
|
||||
printf(" O1)\r\n");
|
||||
else
|
||||
printf(" O0)\r\n");
|
||||
printf("EAX=%Y EBX=%Y ECX=%Y EDX=%Y\r\n", stack->eax, stack->ebx, stack->ecx, stack->edx);
|
||||
printf("ESI=%Y EDI=%Y ESP=%Y EBP=%Y\r\n", stack->esi, stack->edi, stack->esp, stack->ebp);
|
||||
printf("EIP=%Y EFL=%Y [%c%c%c%c%c%c%c%c%c]\r\n", stack->eip, stack->eflags,
|
||||
(stack->eflags & (1 <<11)) ? 'O':'-',
|
||||
(stack->eflags & (1 <<10)) ? 'D':'-',
|
||||
(stack->eflags & (1 << 9)) ? 'I':'-',
|
||||
(stack->eflags & (1 << 8)) ? 'T':'-',
|
||||
(stack->eflags & (1 << 7)) ? 'S':'-',
|
||||
(stack->eflags & (1 << 6)) ? 'Z':'-',
|
||||
(stack->eflags & (1 << 4)) ? 'A':'-',
|
||||
(stack->eflags & (1 << 2)) ? 'P':'-',
|
||||
(stack->eflags & (1 << 0)) ? 'C':'-');
|
||||
printf("CS =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->cs,getdesbase(stack->cs),getdeslimit(stack->cs),getdesdpl(stack->cs),getdestype(stack->cs),getdessize(stack->cs),getdesbit3(stack->cs),getdesbit2(stack->cs),getdesbit1(stack->cs),getdesalign(stack->cs));
|
||||
printf("DS =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->ds,getdesbase(stack->ds),getdeslimit(stack->ds),getdesdpl(stack->ds),getdestype(stack->ds),getdessize(stack->ds),getdesbit3(stack->ds),getdesbit2(stack->ds),getdesbit1(stack->ds),getdesalign(stack->ds));
|
||||
printf("SS =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->ss,getdesbase(stack->ss),getdeslimit(stack->ss),getdesdpl(stack->ss),getdestype(stack->ss),getdessize(stack->ss),getdesbit3(stack->ss),getdesbit2(stack->ss),getdesbit1(stack->ss),getdesalign(stack->ss));
|
||||
printf("ES =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->es,getdesbase(stack->es),getdeslimit(stack->es),getdesdpl(stack->es),getdestype(stack->es),getdessize(stack->es),getdesbit3(stack->es),getdesbit2(stack->es),getdesbit1(stack->es),getdesalign(stack->es));
|
||||
printf("FS =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->fs,getdesbase(stack->fs),getdeslimit(stack->fs),getdesdpl(stack->fs),getdestype(stack->fs),getdessize(stack->fs),getdesbit3(stack->fs),getdesbit2(stack->fs),getdesbit1(stack->fs),getdesalign(stack->fs));
|
||||
printf("GS =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->gs,getdesbase(stack->gs),getdeslimit(stack->gs),getdesdpl(stack->gs),getdestype(stack->gs),getdessize(stack->gs),getdesbit3(stack->gs),getdesbit2(stack->gs),getdesbit1(stack->gs),getdesalign(stack->gs));
|
||||
u32 tss;
|
||||
str(tss);
|
||||
printf("TR =%hY %Y %Y DPL=%d %cS%d [%c%c%c] %h ub\r\n",stack->gs,getdesbase(tss),getdeslimit(tss),getdesdpl(tss),getdestype(tss),getdessize(tss),getdesbit3(tss),getdesbit2(tss),getdesbit1(tss),getdesalign(tss));
|
||||
struct gdtr gdtreg;
|
||||
sgdt(&gdtreg);
|
||||
printf("GDT= %Y %Y\r\n",gdtreg.base,gdtreg.limite);
|
||||
struct idtr idtreg;
|
||||
sidt(&idtreg);
|
||||
printf("IDT= %Y %Y\r\n",idtreg.base,idtreg.limite);
|
||||
|
||||
printf("STACK\r\n");
|
||||
u32 i = 0;
|
||||
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) {
|
||||
if (abs(KERNEL_STACK_ADDR-stack->esp)>0x10000)
|
||||
printf("Pile invalide !");
|
||||
else
|
||||
{
|
||||
u32 i=0;
|
||||
for (u32 *pointer = stack->esp; pointer < KERNEL_STACK_ADDR; pointer ++) {
|
||||
if (i>0 && i % 10 == 0) print("\033[10A");
|
||||
if (i>=10)
|
||||
print("\033[25C");
|
||||
printf("+%d:%Y - %Y\r\n", i++, pointer, (u32)(*pointer));
|
||||
if (i > 20) {
|
||||
print("...\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\033[0m");
|
||||
sti();
|
||||
for(u32 j=0;j<10-(i % 10);j++)
|
||||
print("\033[01B");
|
||||
}
|
||||
}
|
||||
/*******************************************************************************/
|
||||
|
|
116
lib/gdt.c
116
lib/gdt.c
|
@ -74,6 +74,122 @@ void initselectors(u32 executingoffset)
|
|||
ret\n"::[data] "i"(SEL_KERNEL_DATA),[code] "i"(SEL_KERNEL_CODE),[stack] "i"(SEL_KERNEL_STACK),[stackoff] "i"(KERNEL_STACK_ADDR),[offset] "m"(executingoffset));
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère la base d'un descripteur GDT */
|
||||
|
||||
u32 getdesbase(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
return (entry[index].base0_15+(entry[index].base16_23<<16)+(entry[index].base24_31<<24));
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère la limite d'un descripteur GDT */
|
||||
|
||||
u32 getdeslimit(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
return (entry[index].lim0_15+(entry[index].lim16_19<<16));
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère la limite d'un descripteur GDT */
|
||||
|
||||
u32 getdesdpl(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
return (entry[index].acces>>5 & 0b11);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère le type d'un descripteur GDT */
|
||||
|
||||
u8 getdestype(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
if (((entry[index].acces & 0b10100) == 0) && ((entry[index].acces & 0b01000) > 0) && ((entry[index].acces & 0b0001) > 0) && ((entry[index].flags & 0b0110) == 0))
|
||||
return 'T';
|
||||
else
|
||||
return (((entry[index].acces & 0b1000) > 0) ? 'C' : 'D');
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère l'info 1 d'un descripteur GDT */
|
||||
|
||||
u8 getdesbit1(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
if (((entry[index].acces & 0b10100) == 0) && ((entry[index].acces & 0b01000) > 0) && ((entry[index].acces & 0b0001) > 0) && ((entry[index].flags & 0b0110) == 0))
|
||||
return (((entry[index].acces & 0b10) > 0) ? 'B' : '-');
|
||||
else
|
||||
return (((entry[index].acces & 0b1) > 0) ? 'A' : '-');
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère l'info 2 d'un descripteur GDT */
|
||||
|
||||
u8 getdesbit2(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
if (((entry[index].acces & 0b10100) == 0) && ((entry[index].acces & 0b01000) > 0) && ((entry[index].acces & 0b0001) > 0) && ((entry[index].flags & 0b0110) == 0))
|
||||
return (((entry[index].flags & 0b1) > 0) ? 'U' : '-');
|
||||
else if ((entry[index].acces & 0b1000) > 0)
|
||||
return (((entry[index].acces & 0b10) > 0) ? 'R' : '-');
|
||||
else
|
||||
return (((entry[index].acces & 0b10) > 0) ? 'W' : 'R');
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère l'info 3 d'un descripteur GDT */
|
||||
|
||||
u8 getdesbit3(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
if ((entry[index].acces & 0b1000) > 0)
|
||||
return (((entry[index].acces & 0b100) > 0) ? 'C' : '-');
|
||||
else
|
||||
return (((entry[index].acces & 0b100) > 0) ? 'D' : 'U');
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère l'alignement d'un descripteur GDT */
|
||||
|
||||
u16 getdesalign(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
return (((entry[index].flags & 0b1000) > 0) ? 4096: 1);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère si descripteur GDT est valide */
|
||||
|
||||
bool isdesvalid(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
return ((entry[index].acces & 0b10000000) > 0);
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* récupère la dimension d'un descripteur GDT */
|
||||
|
||||
u32 getdessize(u16 sel)
|
||||
{
|
||||
gdtdes *entry=GDT_ADDR;
|
||||
u8 index=sel/sizeof(gdtdes);
|
||||
if (((entry[index].acces & 0b10100) == 0) && ((entry[index].acces & 0b01000) > 0) && ((entry[index].acces & 0b0001) > 0) && ((entry[index].flags & 0b0110) == 0))
|
||||
return 32;
|
||||
else
|
||||
return (((entry[index].flags & 0b1000) > 0) ? 32 : 16);
|
||||
}
|
||||
/*******************************************************************************/
|
||||
/* Créé un descripteur GDT */
|
||||
|
||||
|
|
|
@ -136,11 +136,12 @@ void putidt(u32 offset, u16 select, u16 type, u16 index)
|
|||
/******************************************************************************/
|
||||
/* Affiche une erreur CPU et fige l'ordinateur */
|
||||
|
||||
void cpuerror(const u8 * src, const exception_stack *stack)
|
||||
void cpuerror(const u8 * src, const save_stack *stack)
|
||||
{
|
||||
printf("\033[31m*** ERREUR CPU : %s *** \r\n", src);
|
||||
dump_regs(stack);
|
||||
print("<Appuyer une touche pour continuer>\r\n");
|
||||
show_cpu(stack);
|
||||
print("<Appuyer une touche pour continuer>\033[0m\r\n");
|
||||
sti();
|
||||
waitascii();
|
||||
initselectors(retry_address);
|
||||
/*while (true) {
|
||||
|
@ -168,79 +169,90 @@ void interruption()
|
|||
|
||||
void exception0()
|
||||
{
|
||||
cpuerror("divide error",0x0);
|
||||
save_stack dump;
|
||||
exception_stack_noerror *current = getESP()+0x80;
|
||||
dump_cpu(&dump);
|
||||
dump.eip=current->eip;
|
||||
dump.cs=current->cs;
|
||||
dump.esp=(current+1);
|
||||
cpuerror("divide error",&dump);
|
||||
}
|
||||
|
||||
void exception1()
|
||||
{
|
||||
cpuerror("debug exception",0x0);
|
||||
cpuerror("debug exception",NULL);
|
||||
}
|
||||
|
||||
void exception2()
|
||||
{
|
||||
cpuerror("non-maskable hardware interrupt",0x0);
|
||||
cpuerror("non-maskable hardware interrupt",NULL);
|
||||
}
|
||||
|
||||
void exception3()
|
||||
{
|
||||
cpuerror("INT3 instruction",0x0);
|
||||
cpuerror("INT3 instruction",NULL);
|
||||
}
|
||||
|
||||
void exception4()
|
||||
{
|
||||
cpuerror("INTO instruction detected overflow",0x0);
|
||||
cpuerror("INTO instruction detected overflow",NULL);
|
||||
}
|
||||
|
||||
void exception5()
|
||||
{
|
||||
cpuerror("BOUND instruction detected overrange",0x0);
|
||||
cpuerror("BOUND instruction detected overrange",NULL);
|
||||
}
|
||||
|
||||
void exception6()
|
||||
{
|
||||
cpuerror("invalid instruction opcode",0x0);
|
||||
cpuerror("invalid instruction opcode",NULL);
|
||||
}
|
||||
|
||||
void exception7()
|
||||
{
|
||||
cpuerror("no coprocessor",0x0);
|
||||
cpuerror("no coprocessor",NULL);
|
||||
}
|
||||
|
||||
void exception8()
|
||||
{
|
||||
cpuerror("double fault",0x0);
|
||||
cpuerror("double fault",NULL);
|
||||
}
|
||||
|
||||
void exception9()
|
||||
{
|
||||
cpuerror("coprocessor segment overrun",0x0);
|
||||
cpuerror("coprocessor segment overrun",NULL);
|
||||
}
|
||||
|
||||
void exception10()
|
||||
{
|
||||
cpuerror("invalid task state segment (TSS)",0x0);
|
||||
cpuerror("invalid task state segment (TSS)",NULL);
|
||||
}
|
||||
|
||||
void exception11()
|
||||
{
|
||||
cpuerror("segment not present",0x0);
|
||||
cpuerror("segment not present",NULL);
|
||||
}
|
||||
|
||||
void exception12()
|
||||
{
|
||||
cpuerror("stack fault",0x0);
|
||||
cpuerror("stack fault",NULL);
|
||||
}
|
||||
|
||||
void exception13()
|
||||
{
|
||||
cpuerror("general protection fault (GPF)",0x0);
|
||||
cpuerror("general protection fault (GPF)",NULL);
|
||||
}
|
||||
|
||||
void exception14()
|
||||
{
|
||||
exception_stack *stack = getESP()+0x30;
|
||||
u8 *errorstring;
|
||||
switch (stack->error_code) {
|
||||
save_stack dump;
|
||||
exception_stack *current = getESP()+0x80;
|
||||
dump_cpu(&dump);
|
||||
dump.eip=current->eip;
|
||||
dump.cs=current->cs;
|
||||
dump.esp=(current+1);
|
||||
u8 *errorstring="page fault";
|
||||
switch (current->error_code) {
|
||||
case 0:
|
||||
errorstring="page fault - Supervisory process tried to read a non-present page entry";
|
||||
break;
|
||||
|
@ -266,27 +278,27 @@ void exception14()
|
|||
errorstring="Page fault - User process tried to write a page and caused a protection fault";
|
||||
break;
|
||||
}
|
||||
cpuerror(errorstring,stack);
|
||||
cpuerror(errorstring,&dump);
|
||||
}
|
||||
|
||||
void exception15()
|
||||
{
|
||||
cpuerror("(reserved)",0x0);
|
||||
cpuerror("(reserved)",NULL);
|
||||
}
|
||||
|
||||
void exception16()
|
||||
{
|
||||
cpuerror("coprocessor error",0x0);
|
||||
cpuerror("coprocessor error",NULL);
|
||||
}
|
||||
|
||||
void exception17()
|
||||
{
|
||||
cpuerror("alignment check",0x0);
|
||||
cpuerror("alignment check",NULL);
|
||||
}
|
||||
|
||||
void exception18()
|
||||
{
|
||||
cpuerror("machine check",0x0);
|
||||
cpuerror("machine check",NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -218,7 +218,9 @@ unsigned convert(u32 keypressed)
|
|||
}
|
||||
|
||||
else if (key == SCAN_F9) {
|
||||
dump_regs();
|
||||
save_stack dump;
|
||||
dump_cpu(&dump);
|
||||
show_cpu(&dump);
|
||||
}
|
||||
|
||||
else if (key == SCAN_F10) {
|
||||
|
|
30
lib/shell.c
30
lib/shell.c
|
@ -22,7 +22,10 @@ static command commands[] = {
|
|||
{"GDT" , "", &readgdt},
|
||||
{"IDT" , "", &readidt},
|
||||
{"INFO" , "", &info},
|
||||
{"PAGEFAULT" , "", &pagefault}
|
||||
{"PGFAULTW" , "", &pgfaultw},
|
||||
{"PGFAULTR" , "", &pgfaultr},
|
||||
{"DIVZERR" , "", &divzerr}
|
||||
|
||||
};
|
||||
|
||||
/*******************************************************************************/
|
||||
|
@ -56,13 +59,28 @@ void shell()
|
|||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Génère une erreur de division par 0 */
|
||||
int divzerr()
|
||||
{
|
||||
print("Creation d'une erreur de division par 0 !\r\n");
|
||||
asm("movl $0x0,%ecx; divl %ecx");
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Génère une erreur de page à l'adresse 0xE0000000 */
|
||||
int pagefault()
|
||||
int pgfaultw()
|
||||
{
|
||||
print("Creation d'une erreur de page !\r\n");
|
||||
asm("mov $0x66666666, %eax \n \
|
||||
mov %eax,0xE0000000");
|
||||
asm("movl $0x66666666,(0xE0000000)");
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
/* Génère une erreur de page à l'adresse 0xD0000000 */
|
||||
int pgfaultr()
|
||||
{
|
||||
print("Creation d'une erreur de page !\r\n");
|
||||
asm("movl (0xD0000000),%eax");
|
||||
}
|
||||
|
||||
/*******************************************************************************/
|
||||
|
@ -78,7 +96,9 @@ int info()
|
|||
|
||||
int regs()
|
||||
{
|
||||
dump_regs(0x0);
|
||||
save_stack dump;
|
||||
dump_cpu(&dump);
|
||||
show_cpu(&dump);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -463,6 +463,8 @@ u32 printf(const u8 * string, ...)
|
|||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'y':
|
||||
case 'Y':
|
||||
if (asize==0)
|
||||
num = (u64) va_arg(args, u8);
|
||||
else if (asize==1)
|
||||
|
@ -474,9 +476,9 @@ u32 printf(const u8 * string, ...)
|
|||
if (charadd == 0xFF)
|
||||
charadd = '0';
|
||||
itoa(num, &buffer, 16, sizes[asize], charadd);
|
||||
if (achar == 'X')
|
||||
if (achar == 'X'||achar == 'Y')
|
||||
strtoupper(&buffer);
|
||||
print(&strbase16);
|
||||
if (achar == 'X') print(&strbase16);
|
||||
counter += print(&buffer) + 1;
|
||||
flag = false;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue