I've been working at this bug for an obscenely long amount of time and I'm completely stumped, so I'd like to submit it here just in case there's any dumb mistakes I've made along the way that have been missed in the blindness of looking over code, the bochs debugger, and objdump a thousand times over.
The main symptom of the bug is a triple fault upon `iret` from the PIC IRQ ISR. The only real leads I have are the code selector being invalid (Bochs yells at me about this), and the GDT dump seems to confirm this, although I don't know what is clobbering it.
Immediately upon entering the ISR, it seems like the Data segment gets clobbered by `pusha`, or at least that's what it appears to be.
The code called by the ISR:
Code: Select all
00100c61 <pitHandler>:
100c61: 60 pusha
100c62: fc cld
100c63: e8 98 fb ff ff call 100800 <pit_handler>
100c68: 61 popa
100c69: cf iret
Code: Select all
00100800 <pit_handler>:
100800: 83 ec 18 sub $0x18,%esp
100803: 68 a4 16 10 00 push $0x1016a4
100808: e8 f3 01 00 00 call 100a00 <kprint>
10080d: b8 20 00 00 00 mov $0x20,%eax
100812: e6 20 out %al,$0x20
100814: 83 c4 1c add $0x1c,%esp
100817: c3 ret
100818: 8d b4 26 00 00 00 00 lea 0x0(%esi,%eiz,1),%esi
10081f: 90 nop
GDT at `hlt` instruction waiting for interrupts (in my kernel's main function)
Code: Select all
Global Descriptor Table (base=0x00106fe4, limit=24):
GDT[0x00]=??? descriptor hi=0x00400000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=Data segment, base=0x00410010, limit=0x00001741, Read/Write, Expand-down, Accessed
GDT after entering the ISR - (one instruction in, i.e. resting on the `cld` instruction, which makes me think it's the `pusha` instruction?)
Code: Select all
Global Descriptor Table (base=0x00106fe4, limit=24):
GDT[0x00]=??? descriptor hi=0x00400000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0xffffffff, Execute/Read, Non-Conforming, Accessed, 32-bit
GDT[0x02]=??? descriptor hi=0x00000000, lo=0x00000000
Code: Select all
GDT[0x00]=??? descriptor hi=0x00400000, lo=0x00000000
GDT[0x01]=32-Bit Call Gate target=0x0000:0x0010ffff, DPL=0
GDT[0x02]=??? descriptor hi=0x00000000, lo=0x00000000
What might I be missing offhand?