IDT & Optimization
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
IDT & Optimization
When I compile my kernel using -O2 GCC flag, everything is fine: no crashes, everything runs as it should.
However, if I change this -O3 or -Ofast, it no longer works as it should. The GDT is loaded (no crash),
but when I load the IDT.....system reset.
The GDT and IDT structs both use attribute packed, so does the -O3 (as well as -Ofast), mess with it and disregard it...If so, wouldn't it crash at GDT installation?
I'm curious why this happens. Note: I tested this using qemu-system-i386
However, if I change this -O3 or -Ofast, it no longer works as it should. The GDT is loaded (no crash),
but when I load the IDT.....system reset.
The GDT and IDT structs both use attribute packed, so does the -O3 (as well as -Ofast), mess with it and disregard it...If so, wouldn't it crash at GDT installation?
I'm curious why this happens. Note: I tested this using qemu-system-i386
Re: IDT & Optimization
Quick and usual answer: use Bochs or QEmu built-in debugger to see what is happening.
One should look at the dissassembly near 'lgdt' instruction, examine what is loaded into segment registers and what is the exact instruction that causes triple-fault.
One should look at the dissassembly near 'lgdt' instruction, examine what is loaded into segment registers and what is the exact instruction that causes triple-fault.
Re: IDT & Optimization
You may be interested in these wiki articles:
http://wiki.osdev.org/IDT_problems
http://wiki.osdev.org/James_Molloy's_Known_Bugs
http://wiki.osdev.org/System_V_ABI
My magic crystal ball tells me what your assembly is not following the ABI of your target platform or somehow writing code that the compiler is allowed to optimize because you wrote it poorly. Please share your IDT setting code and other relevant bits, so we can get an idea of what is going on. Usually when the kernel breaks when optimization levels are changed, it means that you are writing poor code and generally abuse the language and compiler, rather than working together with the compiler in a robust way.
http://wiki.osdev.org/IDT_problems
http://wiki.osdev.org/James_Molloy's_Known_Bugs
http://wiki.osdev.org/System_V_ABI
My magic crystal ball tells me what your assembly is not following the ABI of your target platform or somehow writing code that the compiler is allowed to optimize because you wrote it poorly. Please share your IDT setting code and other relevant bits, so we can get an idea of what is going on. Usually when the kernel breaks when optimization levels are changed, it means that you are writing poor code and generally abuse the language and compiler, rather than working together with the compiler in a robust way.
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
Re: IDT & Optimization
My IDT struct code is:
Is there something wrong with this that is causing this to not work with -O3?
Code: Select all
struct idt_entry
{
unsigned short base_lo;
unsigned short sel;
unsigned char always0;
unsigned char flags;
unsigned short base_hi;
} __attribute__((packed));
struct idt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct idt_entry idt[256];
struct idt_ptr idtp;
void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags)
{
idt[num].base_lo = (base & 0xFFFF);
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt[num].sel = sel;
idt[num].always0 = 0;
idt[num].flags = flags;
}
/* Installs the IDT */
void idt_install()
{
idtp.limit = (sizeof (struct idt_entry) * 256) - 1;
idtp.base = (unsigned int)&idt;
/* Clear out the entire IDT, initializing it to zeros */
memset(&idt, 0, sizeof(struct idt_entry) * 256);
idt_load();
}
/* Assembly function idt_load() in NASM */
global idt_load
extern idtp
idt_load:
lidt [idtp]
ret
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: IDT & Optimization
Please bother to show us the assembler output.
EDIT: For both -O2 and -O3
EDIT: For both -O2 and -O3
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
Re: IDT & Optimization
What do you mean by assembler output?
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: IDT & Optimization
Show us what you get from GCC after the initial compilation. Hint: '-S' or if you prefer disassemble the kernel.
And show only the relevant parts.
And show only the relevant parts.
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
Re: IDT & Optimization
OK. Well, for -O2 I get this:
and for -O3:
They are both exactly the same... This makes me even more confused why one works and the other doesn't...
Code: Select all
.file "idt.c"
.text
.align 16
.globl idt_set_gate
.type idt_set_gate, @function
idt_set_gate:
.LFB0:
.cfi_startproc
movzbl 4(%esp), %eax
movl 8(%esp), %edx
movb $0, idt+4(,%eax,8)
movw %dx, idt(,%eax,8)
shrl $16, %edx
movw %dx, idt+6(,%eax,8)
movl 12(%esp), %edx
movw %dx, idt+2(,%eax,8)
movl 16(%esp), %edx
movb %dl, idt+5(,%eax,8)
ret
.cfi_endproc
.LFE0:
.size idt_set_gate, .-idt_set_gate
.align 16
.globl idt_install
.type idt_install, @function
idt_install:
.LFB1:
.cfi_startproc
subl $28, %esp
.cfi_def_cfa_offset 32
movl $2047, %eax
movl $2048, 8(%esp)
movl $0, 4(%esp)
movl $idt, (%esp)
movw %ax, idtp
movl $idt, idtp+2
call memset
addl $28, %esp
.cfi_def_cfa_offset 4
jmp idt_load
.cfi_endproc
.LFE1:
.size idt_install, .-idt_install
.comm idtp,6,1
.comm idt,2048,32
.ident "GCC: (GNU) 4.8.2"
Code: Select all
.file "idt.c"
.text
.align 16
.globl idt_set_gate
.type idt_set_gate, @function
idt_set_gate:
.LFB0:
.cfi_startproc
movzbl 4(%esp), %eax
movl 8(%esp), %edx
movb $0, idt+4(,%eax,8)
movw %dx, idt(,%eax,8)
shrl $16, %edx
movw %dx, idt+6(,%eax,8)
movl 12(%esp), %edx
movw %dx, idt+2(,%eax,8)
movl 16(%esp), %edx
movb %dl, idt+5(,%eax,8)
ret
.cfi_endproc
.LFE0:
.size idt_set_gate, .-idt_set_gate
.align 16
.globl idt_install
.type idt_install, @function
idt_install:
.LFB1:
.cfi_startproc
subl $28, %esp
.cfi_def_cfa_offset 32
movl $2047, %eax
movl $2048, 8(%esp)
movl $0, 4(%esp)
movl $idt, (%esp)
movw %ax, idtp
movl $idt, idtp+2
call memset
addl $28, %esp
.cfi_def_cfa_offset 4
jmp idt_load
.cfi_endproc
.LFE1:
.size idt_install, .-idt_install
.comm idtp,6,1
.comm idt,2048,32
.ident "GCC: (GNU) 4.8.2"
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: IDT & Optimization
Which gives me an impression that the problem is somewhere else, or worse there may be a bug in your code itself. As previously said, use Bochs and look at it's output, I bet you'll get what you want.They are both exactly the same... This makes me even more confused why one works and the other doesn't...
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
Re: IDT & Optimization
Maybe you can use breakpoints to tell exactly which line will it reset.. (afterall Bochs is just really powerful, you can do so much with it)
CookieOS. Want a cookie? Its only black and white for now though, probably as bad as my baking skills.
Re: IDT & Optimization
Hi,
Mostly, you're going to need to find out more about the symptoms. Does it do the same on different computers/emulators? Does it lock up, or cause an exception? Which exception? What is the return CS:EIP for the exception? Does the memory at that address contain the instruction/s you expect (and what are they)? What is the exception's error code?
Cheers,
Brendan
That suggests the problem is somewhere else. Possibilities include a timing dependent problem (e.g. maybe an IRQ occurs after X ms, and changing the speed of any previous code causes the IRQ to interrupt in different places), a "random" memory corruption in any previous code (e.g. writing to an uninitialised pointer, memory management bugs, etc; where minor differences in memory layout or stack layout results in something different getting trashed), a boot loader problem (e.g. only loading 4 sectors, where "-O3" makes the kernel slightly larger than 4 sectors), etc.inixsoftware wrote:They are both exactly the same... This makes me even more confused why one works and the other doesn't...
Mostly, you're going to need to find out more about the symptoms. Does it do the same on different computers/emulators? Does it lock up, or cause an exception? Which exception? What is the return CS:EIP for the exception? Does the memory at that address contain the instruction/s you expect (and what are they)? What is the exception's error code?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
Re: IDT & Optimization
OK. So now from the Bochs console, when I use my kernel compiled with -O3 I get:
00128266044e[CPU0 ] interrupt(): gate.type(9) != {5,6,7,14,15}
00128266044e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
0d)
00128266044e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
08)
00128266044i[CPU0 ] CPU is in protected mode (active)
00128266044i[CPU0 ] CS.mode = 32 bit
00128266044i[CPU0 ] SS.mode = 32 bit
00128266044i[CPU0 ] EFER = 0x00000000
00128266044i[CPU0 ] | EAX=00000800 EBX=00108060 ECX=00000026 EDX=00000000
00128266044i[CPU0 ] | ESP=00100128 EBP=0007feac ESI=00118dc8 EDI=00118dc8
00128266044i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt OF df if tf SF zf af pf cf
00128266044i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00128266044i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | EIP=00100135 (00100135)
00128266044i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00128266044i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[128266044] [0x000000100135] 0008:0000000000100135 (unk. ctxt): (invalid)
; ffff
00128266044e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
status is 00h, resetting
00128266044i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00128266044i[CPU0 ] cpu hardware reset
while with -O2 I get no issue. Is the -O3 causing gate problems which cause the reset?
00128266044e[CPU0 ] interrupt(): gate.type(9) != {5,6,7,14,15}
00128266044e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
0d)
00128266044e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x
08)
00128266044i[CPU0 ] CPU is in protected mode (active)
00128266044i[CPU0 ] CS.mode = 32 bit
00128266044i[CPU0 ] SS.mode = 32 bit
00128266044i[CPU0 ] EFER = 0x00000000
00128266044i[CPU0 ] | EAX=00000800 EBX=00108060 ECX=00000026 EDX=00000000
00128266044i[CPU0 ] | ESP=00100128 EBP=0007feac ESI=00118dc8 EDI=00118dc8
00128266044i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt OF df if tf SF zf af pf cf
00128266044i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00128266044i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00128266044i[CPU0 ] | EIP=00100135 (00100135)
00128266044i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00128266044i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[128266044] [0x000000100135] 0008:0000000000100135 (unk. ctxt): (invalid)
; ffff
00128266044e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
status is 00h, resetting
00128266044i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00128266044i[CPU0 ] cpu hardware reset
while with -O2 I get no issue. Is the -O3 causing gate problems which cause the reset?
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: IDT & Optimization
You know what's wrong, do you?00128266044e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
status is 00h, resetting
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)
-
- Member
- Posts: 32
- Joined: Fri Jan 31, 2014 8:21 am
Re: IDT & Optimization
So my IDT must be invalid causing a double fault (and since there were no double fault handlers) which caused a triple fault, system reset. Is that right?
- Bender
- Member
- Posts: 449
- Joined: Wed Aug 21, 2013 3:53 am
- Libera.chat IRC: bender|
- Location: Asia, Singapore
Re: IDT & Optimization
Exception 13........ Does that sound familiar? Hmm....inixsoftware wrote:So my IDT must be invalid causing a double fault (and since there were no double fault handlers) which caused a triple fault, system reset. Is that right?
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
(R3X Runtime VM)(CHIP8 Interpreter OS)