Exceptions crash the system
Exceptions crash the system
Hi.
I decided to rewrite the core code that works with GDT and IDT.
Now when I try to generate an exception using int my system crashes.
In the kmain() function, I configure GDT and IDT using the init_descriptor_tables()
The init_gdt() and init_idt() functions are used to configure GDT and IDT.
This file describes the functions that update GDT and LDT.
In the interrupt.S file macros describe handlers for the first 32 interrupts(except reserved ones)
All of them should call isr_common_stub() which calls isr_handler(), as a result I expect the handler to print the interrupt number in serial. log, but during the interrupt the system crashes(qemu restarts the kernel).
What might be the problem? GDT and IDT are configured correctly, but the isr_common_stub handler is not called.
I decided to rewrite the core code that works with GDT and IDT.
Now when I try to generate an exception using int my system crashes.
In the kmain() function, I configure GDT and IDT using the init_descriptor_tables()
The init_gdt() and init_idt() functions are used to configure GDT and IDT.
This file describes the functions that update GDT and LDT.
In the interrupt.S file macros describe handlers for the first 32 interrupts(except reserved ones)
All of them should call isr_common_stub() which calls isr_handler(), as a result I expect the handler to print the interrupt number in serial. log, but during the interrupt the system crashes(qemu restarts the kernel).
What might be the problem? GDT and IDT are configured correctly, but the isr_common_stub handler is not called.
-
- Member
- Posts: 5878
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Exceptions crash the system
Try logging the fault with "-d cpu_reset" or "-d int". This will tell you where and why it's crashing, which should help you figure out where to look.mrjbom wrote:but during the interrupt the system crashes(qemu restarts the kernel).
Re: Exceptions crash the system
I used "-d int -d cpu_reset" at startup and here's what QEMU Monitor showed.Octocontrabass wrote:Try logging the fault with "-d cpu_reset" or "-d int". This will tell you where and why it's crashing, which should help you figure out where to look.mrjbom wrote:but during the interrupt the system crashes(qemu restarts the kernel).
QEMU reports triple fault, I don't know exactly what can cause it, the handlers should work correctly, I couldn't find errors in GDT and LDT.
logs:
Code: Select all
//after __asm__ volatile ("int $0x00");
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000663
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 ffff0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
//before __asm__ volatile ("int $0x00");
Triple fault
CPU Reset (CPU 0)
EAX=00000258 EBX=00010000 ECX=00074fe0 EDX=fd1d4bfc
ESI=00000000 EDI=00000000 EBP=0114a908 ESP=0114a900
EIP=00100178 EFL=00200006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 7f600000 00000027
IDT= 00147fa0 000007ff
CR0=80000011 CR2=00000000 CR3=0114b000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=0114a900 CCO=EFLAGS
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
-
- Member
- Posts: 5878
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Exceptions crash the system
I don't see anything obviously wrong there. Where are the "-d int" logs? The two or three exceptions right before the triple fault are what you need to look at.
Re: Exceptions crash the system
Later I will try to get more information about logs.Octocontrabass wrote:I don't see anything obviously wrong there. Where are the "-d int" logs? The two or three exceptions right before the triple fault are what you need to look at.
I'll let you know if I find out anything.
Apparently, I have problems with handlers, the ones that are isr(number of int) in the interrupt.S file.
I decompiled interrS.o and found this code in the handlers:

This is clearly not what should be there. So it turns out that my headers are damaged.
For example, interrgdtS.o(gdt.S) looks normal.

I think that macros are to blame, for some reason they worked incorrectly and the code became incorrect.
In addition, I can't find the isr_common_stub() function code, it was also generated incorrectly for some reason.

For some reason, the code associated with interrupt handling was not compiled properly.
-
- Member
- Posts: 5878
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Exceptions crash the system
No, it is correct. Your decompiler is not smart enough to automatically recognize that it's code that needs to be disassembled.mrjbom wrote:This is clearly not what should be there.
Re: Exceptions crash the system
What if you configure your IDT as something like this (as I did in my OS):mrjbom wrote:The init_gdt() and init_idt() functions are used to configure GDT and IDT.
Code: Select all
UINT_32 status = 0, i;
for(i=255;i>0;i--)
{
SetIDTEntry(i, (UINT_32)(void*)ISR_DEFAULT, 0x08, 0x8E);
__irq_routines[i] = 0;
}
SetIDTEntry(0, (UINT_32)(void*)ISR_DEFAULT, 0x08, 0x8E);
__irq_routines[0] = 0;
SetIDTEntry(0, (UINT_32)(void*)ISR0, 0x08, 0x8E);
SetIDTEntry(1, (UINT_32)(void*)ISR1, 0x08, 0x8E);
SetIDTEntry(2, (UINT_32)(void*)ISR2, 0x08, 0x8E);
SetIDTEntry(3, (UINT_32)(void*)ISR3, 0x08, 0x8E);
SetIDTEntry(4, (UINT_32)(void*)ISR4, 0x08, 0x8E);
SetIDTEntry(5, (UINT_32)(void*)ISR5, 0x08, 0x8E);
SetIDTEntry(6, (UINT_32)(void*)ISR6, 0x08, 0x8E);
SetIDTEntry(7, (UINT_32)(void*)ISR7, 0x08, 0x8E);
SetIDTEntry(8, (UINT_32)(void*)ISR8, 0x08, 0x8E);
SetIDTEntry(9, (UINT_32)(void*)ISR9, 0x08, 0x8E);
SetIDTEntry(10, (UINT_32)(void*)ISR10, 0x08, 0x8E);
SetIDTEntry(11, (UINT_32)(void*)ISR11, 0x08, 0x8E);
SetIDTEntry(12, (UINT_32)(void*)ISR12, 0x08, 0x8E);
SetIDTEntry(13, (UINT_32)(void*)ISR13, 0x08, 0x8E);
SetIDTEntry(14, (UINT_32)(void*)ISR14, 0x08, 0x8E);
SetIDTEntry(15, (UINT_32)(void*)ISR15, 0x08, 0x8E);
SetIDTEntry(16, (UINT_32)(void*)ISR16, 0x08, 0x8E);
SetIDTEntry(17, (UINT_32)(void*)ISR17, 0x08, 0x8E);
SetIDTEntry(18, (UINT_32)(void*)ISR18, 0x08, 0x8E);
SetIDTEntry(19, (UINT_32)(void*)ISR19, 0x08, 0x8E);
SetIDTEntry(20, (UINT_32)(void*)ISR20, 0x08, 0x8E);
SetIDTEntry(21, (UINT_32)(void*)ISR21, 0x08, 0x8E);
SetIDTEntry(22, (UINT_32)(void*)ISR22, 0x08, 0x8E);
SetIDTEntry(23, (UINT_32)(void*)ISR23, 0x08, 0x8E);
SetIDTEntry(24, (UINT_32)(void*)ISR24, 0x08, 0x8E);
SetIDTEntry(25, (UINT_32)(void*)ISR25, 0x08, 0x8E);
SetIDTEntry(26, (UINT_32)(void*)ISR26, 0x08, 0x8E);
SetIDTEntry(27, (UINT_32)(void*)ISR27, 0x08, 0x8E);
SetIDTEntry(28, (UINT_32)(void*)ISR28, 0x08, 0x8E);
SetIDTEntry(29, (UINT_32)(void*)ISR29, 0x08, 0x8E);
SetIDTEntry(30, (UINT_32)(void*)ISR30, 0x08, 0x8E);
SetIDTEntry(31, (UINT_32)(void*)ISR31, 0x08, 0x8E);
/* important */
__irq_remap();
SetIDTEntry(32, (UINT_32)(void*)IRQ0, 0x08, 0x8E);
SetIDTEntry(33, (UINT_32)(void*)IRQ1, 0x08, 0x8E);
SetIDTEntry(34, (UINT_32)(void*)IRQ2, 0x08, 0x8E);
SetIDTEntry(35, (UINT_32)(void*)IRQ3, 0x08, 0x8E);
SetIDTEntry(36, (UINT_32)(void*)IRQ4, 0x08, 0x8E);
SetIDTEntry(37, (UINT_32)(void*)IRQ5, 0x08, 0x8E);
SetIDTEntry(38, (UINT_32)(void*)IRQ6, 0x08, 0x8E);
SetIDTEntry(39, (UINT_32)(void*)IRQ7, 0x08, 0x8E);
SetIDTEntry(40, (UINT_32)(void*)IRQ8, 0x08, 0x8E);
SetIDTEntry(41, (UINT_32)(void*)IRQ9, 0x08, 0x8E);
SetIDTEntry(42, (UINT_32)(void*)IRQ10, 0x08, 0x8E);
SetIDTEntry(43, (UINT_32)(void*)IRQ11, 0x08, 0x8E);
SetIDTEntry(44, (UINT_32)(void*)IRQ12, 0x08, 0x8E);
SetIDTEntry(45, (UINT_32)(void*)IRQ13, 0x08, 0x8E);
SetIDTEntry(46, (UINT_32)(void*)IRQ14, 0x08, 0x8E);
SetIDTEntry(47, (UINT_32)(void*)IRQ15, 0x08, 0x8E);
idt_pointer.size = (sizeof(GATEDESCRIPTOR) * 256) - 1;
idt_pointer.base = (UINT_32)((void*)(&idt[0]));
status = IDTLoad();
if (!status)
{
panic("IDT pointer loading Failed\n");
return 0;
}
Re: Exceptions crash the system
You are right, macros are really not to blame.Octocontrabass wrote:No, it is correct. Your decompiler is not smart enough to automatically recognize that it's code that needs to be disassembled.mrjbom wrote:This is clearly not what should be there.
I tried calling isr0 manually and found that the problem occurs when trying to write data to the DS register.
In this line.
Re: Exceptions crash the system
Apparently I'm setting handlers correctly in the descriptor table.iman wrote:What if you configure your IDT as something like this (as I did in my OS):mrjbom wrote:The init_gdt() and init_idt() functions are used to configure GDT and IDT.Code: Select all
UINT_32 status = 0, i; for(i=255;i>0;i--) { SetIDTEntry(i, (UINT_32)(void*)ISR_DEFAULT, 0x08, 0x8E); __irq_routines[i] = 0; } SetIDTEntry(0, (UINT_32)(void*)ISR_DEFAULT, 0x08, 0x8E); __irq_routines[0] = 0; SetIDTEntry(0, (UINT_32)(void*)ISR0, 0x08, 0x8E); SetIDTEntry(1, (UINT_32)(void*)ISR1, 0x08, 0x8E); . . . SetIDTEntry(30, (UINT_32)(void*)ISR30, 0x08, 0x8E); SetIDTEntry(31, (UINT_32)(void*)ISR31, 0x08, 0x8E); /* important */ __irq_remap(); SetIDTEntry(32, (UINT_32)(void*)IRQ0, 0x08, 0x8E); . . . SetIDTEntry(47, (UINT_32)(void*)IRQ15, 0x08, 0x8E); idt_pointer.size = (sizeof(GATEDESCRIPTOR) * 256) - 1; idt_pointer.base = (UINT_32)((void*)(&idt[0])); status = IDTLoad(); if (!status) { panic("IDT pointer loading Failed\n"); return 0; }
Is it worth registering handlers for reserved handlers?
Re: Exceptions crash the system
At least in my case, it did not hurt anything. I am not sure what would happen if you don't assign a handler to them.mrjbom wrote:Is it worth registering handlers for reserved handlers?
Re: Exceptions crash the system
Well, I won't assign them, I don't need them anyway.iman wrote:At least in my case, it did not hurt anything. I am not sure what would happen if you don't assign a handler to them.mrjbom wrote:Is it worth registering handlers for reserved handlers?
Re: Exceptions crash the system
"Reserved" only means "I don't know what this is". There is a (small) possibility that future CPUs could implement these exceptions. If you have no handler registered and an exception were to fire in those slots, this would be promoted to a double fault. However, since the only handling you can really do in those exceptions is to panic because of unknown exception, it really doesn't matter whether you panic there or in the double fault handler.mrjbom wrote:Is it worth registering handlers for reserved handlers?
Carpe diem!
Re: Exceptions crash the system
I understand that.nullplan wrote:"Reserved" only means "I don't know what this is". There is a (small) possibility that future CPUs could implement these exceptions. If you have no handler registered and an exception were to fire in those slots, this would be promoted to a double fault. However, since the only handling you can really do in those exceptions is to panic because of unknown exception, it really doesn't matter whether you panic there or in the double fault handler.mrjbom wrote:Is it worth registering handlers for reserved handlers?
In any case, this does not apply to my problem now, because if I remove __asm__ volatile ("int $0x0") from my code, the error does not occur and everything works correctly.
In this case, the problem is caused by an attempt to load the AX value in DS.
I have no idea why it doesn't allow loading DS.
Re: Exceptions crash the system
Well, go about this rationally. What could it be? Is the AX value reasonable? What about the GDT base address? In the register dumps up top, you had a very weird GDT base address.mrjbom wrote:In this case, the problem is caused by an attempt to load the AX value in DS.
I have no idea why it doesn't allow loading DS.
Trying to load a non-present segment, or a segment beyond the end of the GDT will fail. If the GDTR is also misconfigured, a reasonable access to the GDT will cause a page fault, or possibly a double fault.
Carpe diem!
Re: Exceptions crash the system
I noticed that lgdt (%eax) does not load the correct structure address into gdt.nullplan wrote:Well, go about this rationally. What could it be? Is the AX value reasonable? What about the GDT base address? In the register dumps up top, you had a very weird GDT base address.mrjbom wrote:In this case, the problem is caused by an attempt to load the AX value in DS.
I have no idea why it doesn't allow loading DS.
Here's what qemu shows right after lgdt (%eax).
The eax value contains the correct address, but gdt contains a different value.
Registers immediately after executing this line.
Code: Select all
EAX=001487a0 EBX=00010000 ECX=00074fe0 EDX=000000f2
ESI=00000000 EDI=00000000 EBP=0114a8e8 ESP=0114a8cc
EIP=00108ab5 EFL=00200016 [----AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0018 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 7f600000 00000027
IDT= 00000000 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Last edited by mrjbom on Mon Aug 17, 2020 10:59 am, edited 2 times in total.