Page 1 of 2
IRET: what's the problem
Posted: Thu May 01, 2008 7:34 am
by AlfaOmega08
Two days ago, I've unfortunately lost all my sources
So... I'm rewriting another time my kernel.
A bug I've never seen is destroying my neurons:
The kernel uses a JM similar method to handle interrupt. An NOERRORCODE and an ERRORCODE macros that defines all the interrupts and pushes the int number and a false error code in case there isn't one. Then a jump to a common routine. When the handler gives the IRET, bochs signals a not valid code segment. And a GPF fires. Then the GPF handle gives the IRET and another GPF fires. That's wanderful...
Hacking the bochs source, it now show wich segment is it trying to use. It's trying to use segment 0x202.
It's very strange. Also because 0x202 is the eflags mask!!!
I've also checked the ESP value immediately after the int and before the iret. The two values are equal.
What's the problem?
Thanks.
Posted: Thu May 01, 2008 7:38 am
by JamesM
Hi,
Posting your interrupt handler code will help a lot. I think possibly you're forgetting to pop the error code and interrupt number from your stack after your interrupt handler is called.
Secondly, go to
http://www.googlecode.com for a free Subversion repository, so you can NEVER lose your code!
Cheers,
James
Posted: Thu May 01, 2008 7:43 am
by AlfaOmega08
This is the handler code:
Code: Select all
%macro ISR_NOERRCODE 1
[GLOBAL isr%1]
isr%1:
CLI
PUSH BYTE 0
PUSH BYTE %1
JMP ISRCommonStub
%endmacro
%macro ISR_ERRCODE 1
[GLOBAL isr%1]
isr%1:
CLI
PUSH BYTE %1
JMP ISRCommonStub
%endmacro
[EXTERN isrHandler]
ISRCommonStub:
PUSH DS
PUSH ES
PUSH EAX
PUSH ECX
PUSH EDX
PUSH EBX
PUSH EBP
PUSH ESI
PUSH EDI
MOV BX, 0x10
MOV DS, BX
MOV ES, BX
PUSH ESP
CALL isrHandler
POP ESP
POP EDI
POP ESI
POP EBP
POP EBX
POP EDX
POP ECX
POP EAX
POP ES
POP DS
ADD ESP, 8
IRET
After there are 252 ISR_NOERRCODE from 0 to 255 excluding 8 and 10-14 ints and ISR_ERRCODE for 8 and 10-14 ints
Posted: Thu May 01, 2008 7:53 am
by JamesM
Hi,
I'm not convinced by your pushing and popping of DS and ES.
I don't know (or can't remember) what happens if you try and push/pop a 16-bit register in 32-bit protected mode but it could be what is messing you up.
My code (I've just looked) does this:
Code: Select all
mov ax, ds
push eax
...
pop eax
mov ds, eax
...
You see it pushes a 32-bit value onto the stack and pops a 32-bit value off the stack - I'm pretty sure I wrote it that way for a very specific reason but I can't for the life of me remember why now!
Try it that way and see if it solves your problem.
Cheers,
James
Posted: Thu May 01, 2008 8:47 am
by AlfaOmega08
No. It doesn't work...
Because of my code is now equal to yours, maybe the problem is in other parts of the kernel?
Posted: Thu May 01, 2008 8:50 am
by JamesM
OK, now try removing the call to isrHandler.
remove this line (temporarily):
Then, you should know if the problem lies in the asm or the C code.
Posted: Thu May 01, 2008 9:27 am
by AlfaOmega08
It doesn't work anytime
I've try also this:
Code: Select all
%macro ISR_NOERRCODE 1
[GLOBAL isr%1]
isr%1:
IRET
CLI
PUSH BYTE 0
PUSH BYTE %1
JMP ISRCommonStub
%endmacro
%macro ISR_ERRCODE 1
[GLOBAL isr%1]
isr%1:
ADD ESP, 4
IRET
CLI
PUSH BYTE %1
JMP ISRCommonStub
%endmacro
Nothing...
Posted: Thu May 01, 2008 10:08 am
by Dex
Posted: Thu May 01, 2008 2:22 pm
by Hangin10
JamesM wrote:I don't know (or can't remember) what happens if you try and push/pop a 16-bit register in 32-bit protected mode but it could be what is messing you up.
This confused me recently as well. Section 6.2.2 "Stack Alignment" of Vol. 1 states "Pushing a 16-bit value onto a 32-bit wide stack can result in stack misaligned (that is, the stack pointer is not aligned on a doubleword boundary). One exception to this rule is when the contents of a segment register (a 16-bit segment selector) are pushed onto a 32-bit wide stack. Here, the processor automatically aligns the stack pointer to the next 32-bit boundary." But in the psuedocode in the instruction set reference, it looks like it only works for FS and GS.
Posted: Thu May 01, 2008 2:43 pm
by JamesM
How are you testing your interrupts? are you manually doing a software interrupt? If so, what interrupt number are you triggering? Make sure it's one that doesn't need an error code pushed, because software interrupts don't do that!
Posted: Thu May 01, 2008 5:27 pm
by edfed
Posted: Thu May 01, 2008 8:08 pm
by pcmattman
edfed wrote:
what does it mean?
Are you serious!?
Posted: Thu May 01, 2008 8:26 pm
by bewing
Well, the code
is a little more confusing now that he's stuffing in debugging IRETs here and there.
Posted: Thu May 01, 2008 8:30 pm
by pcmattman
Whoops! I thought he was genuinely asking what those lines meant
.
It really should be:
Code: Select all
CLI
ADD ESP, 4 # are you sure you need this?
PUSH BYTE %1
JMP ISRCommonStub
STI
IRET
Although IMO you shuold write ISRCommonStub to handle the STI/IRET for you
Posted: Fri May 02, 2008 4:22 am
by jal
JamesM wrote:I don't know (or can't remember) what happens if you try and push/pop a 16-bit register in 32-bit protected mode but it could be what is messing you up.
James, no! You just fell a few meters on my admiration scale :)))
JAL