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 :cry: :cry: :cry:
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!!! :shock:
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):

Code: Select all

 CALL isrHandler
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 :cry: :cry: :cry:
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

Code: Select all

   IRET 
   CLI
what does it mean?

Posted: Thu May 01, 2008 8:08 pm
by pcmattman
edfed wrote:

Code: Select all

   IRET 
   CLI
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. :wink:

Posted: Thu May 01, 2008 8:30 pm
by pcmattman
Whoops! I thought he was genuinely asking what those lines meant :oops: .

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