troubleing ISR behaviour

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
libber

troubleing ISR behaviour

Post by libber »

hi i am having a lot of problems with my ISR. i have my idt loaded correctly and i do a divby0 which then calls the appropriate handler, good so far. so if this handler is just nops or something then everything is merry, but if this isr has a call to another function in it, everything messes up i have very little idea why, my goal is to call my print function from within the ISR, i can do this right?

so anyway i made a little function called die() which is just some nops and i call it from within the ISR, it calls just fine and return just fine but when i get to the iret, it dies saying something about an LDT (not really logical here...) so i have examened the stack and intel book 3 and have come to the understanding that before an interrupt as part of the interrupts "call" (if you could call it that) that EIP, CS and eflags are pushed onto the stack along with an error code. i see all this (except what i think is eflags looks sortof abnormal) and have the notes to myself here

Code: Select all

 right before iret!!!!
esp : 0x00103820
esp + 4:  0x00000001
esp + 8:  0x00000005
esp + 12: 0x001007eb (return address, pushed EIP)
esp + 16: 0x00000008 (CS)
esp + 20: 0x00010006 (eflags *guess but complies with intel manual)
esp + 24: 0x00000042
esp + 28: 0x00000028
esp + 32: 0xc0000000
esp + 36: 0x00000007
esp + 42 00000000000
so that is my stack in my ISR after we have called and then retted from the function die() within my ISR and we are about to iret.


i have found out that if i have 3 pops (just to get rid of the junk on the stack (the junk being 0x001007d6 (what looks to be a valid return address for something, not the ISR or function though), 0x00000001 (no idea what this is but 0x1 is the second arg to die() although i see it push the args for die() up earlier and then clean up after itself), and 0x5 and i have no clue what this would be) then if i have these 3 pops then the address at which the interrupt was called (the address of the divby0) goes into eip and cs is correctly popped from the stack and eflags is popped back (although it is not the same as it was before hmmmmm). the thing about this is that since eip is now the instruction that called the interrupt we go into an endless loop of calling the interrupt.

on to the code...

the ISR that is called and the function that it then calls

Code: Select all

void die(char *message, byte halt)   //byte can be a bool, or just a bit
{
   //clear_screen();
   //k_print(message);
//   k_print("cought an exception", 2);
//   k_print("cought an exception", 3);
//   k_print("cought an exception", 7);

   asm("nop");
   asm("nop");
   asm("nop");
   //k_print("a fatal\n", 3);
//   ints_off();
//   asm("hlt");
//   outb(MASTER, EOI);   //not sure why we have to do this, find out
   asm("nop");
}


inline void int00()
{
//   asm("pusha");
//   asm("push %ds");
//   asm("movw $0x10, %ax");   //0x10 (16)is the data segment we setup in the GDT
//   asm("movw %ds, %ax");
   asm("nop");
   asm("nop");
   

   die("aaaa", true);
   asm("nop");
   asm("nop");
   asm("nop");
//   asm("pop %ds");
//   asm("popa");
   asm("nop");
   asm("nop");

   // there are 2 random things on the stack i have no idea what they are, a reasonable address, then 0x1, then 0x05
   //under that is the usuial eip, cs and eflags
   //nasty nasty nasty!
   asm("popl %eax");
   asm("nop");
   asm("nop");
   asm("popl %eax");
   asm("nop");
   asm("nop");
   asm("popl %eax");
   asm("nop");
   asm("nop");
   asm("nop");

   
   asm("iret");

}
in my kernel i seup the pic and of course setup the IDT into a working state

i am compiling with

Code: Select all

gcc -fno-builtins -fomit-frame-pointer -c *.c
i read in intel book 2 that irets behaviour can change based on the NT (nested task) and VM flags, i am worried that the NT flag might be messing me up but i don't know, any thoughts?

also in intel book3 it says that an interrupt sets up the stack like

esp: error code (what would this be, just 00 for divby0 exception?)
esp + 4: EIP
esp + 8: CS
esp + 12: EFLAGS

anyhow i have tried everything i can think of and googled my heart out, hopefully someone can help.

Thanks for your Time,
Libber
User avatar
Candy
Member
Member
Posts: 3883
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:troubleing ISR behaviour

Post by Candy »

http://www.mega-tokyo.com/forum/index.p ... 21;start=0

Reply #2

That is why your iret cannot work (again).
libber

Re:troubleing ISR behaviour

Post by libber »

hrm yes, i read that. i thought that omit frame pointer would get rid of that mov ebp, esp stuff. i dont see those in my code. also the cs register is just fine it pops 0x8 just as it should.
Tim

Re:troubleing ISR behaviour

Post by Tim »

Look, you're wasting your time writing your interrupt handlers in C. Put all the PUSH, POP and IRET code in a separate .asm file and insert a CALL to a C function in the middle. It will prevent all these problems you're having. I don't know of anyone who's successfully written an interrupt handler entirely in C, because of the amount of stuff the compiler puts before and after your inline asm which you can't turn off.
libber

Re:troubleing ISR behaviour

Post by libber »

good plan i have now done this but it isn't quite working. i have stuff in my external asm file and all works well it gets called as it should and everything looks ok but the one thing is that when the ISR returns it returns to the place where the interrupt was called, assuming the divby0 error from my first post is at 0x100123 then once the ISR is done it would go back and execute the code at 0x100123 and thus the ISR would be called agian. am i missing something big here? hehe it is kindof neat that when i hacked around all the junk earlier with my pops and such i got this same result... i am proud of that at least j/k :)

anyhow if you need to see my code for this iteration of my interrupt-related-stuff i can show you but it is really just a simple regurgitation of my xsims IDTkernel

thanks for your time
Libber
User avatar
Candy
Member
Member
Posts: 3883
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:troubleing ISR behaviour

Post by Candy »

A week before your thread this thread was last answered:

http://www.mega-tokyo.com/forum/index.p ... eadid=5008

It's about a divide-by-zero and why you cannot return.
libber

Re:troubleing ISR behaviour

Post by libber »

aaaah well i have proven myself a newbie, i searched the forum with the search tool but i did not find this thread. (might be my fault) either way good to know this answers my question exactly. i guess there is really no reason to return from an interrupt but it is funny because before i posted here at all i had really solved my own problem, if you pop and discard the first 3 dwords on the stack when you make your ISR in c you will get the same behaviour as you do if you do this the right way, i had also made code that just incriments eip inplace on the stack and would then return to the next instruction (i would always have to make it a nop because i would only incriment by 1 or one byte and thus if the next instruction was not a one byte instruction eip would point to the middle of an instruction) but this is very hacked-up and i didn't like it. but i didn't stop to think why i was returning from an exception handler in the first place :)

BUT with the page fault ISR if you want to do paging at the last second (cycle?) then you still have to return right? how is this handeled?

thanks for your time,
Libber

ok thought about this more, so when the page fault exception goes it will correctly go back to the instruction that tried to use the memory and redo the instruction, this time the memory will be there, DUH i did not think throught his
User avatar
Candy
Member
Member
Posts: 3883
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:troubleing ISR behaviour

Post by Candy »

There are three kinds of exceptions, as you know. Traps, faults and aborts.

From a trap you can just return (with some thinking, don't know the full details myself). From a fault you can return if you fixed the problem in your exception handler, otherwise, don't return (because you'll end up in an infinite loop). From an abort you cannot return.
Post Reply