Problem with exceptions/interrupts

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
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Problem with exceptions/interrupts

Post by Midas »

Um, I typed a message and it said it was too long so... :P

www.angusenterprises.co.uk/message.txt

Any ideas? (I'm not just being lazy - I'm still working at it! Just curious if you can point me in the right direction)

Thanks. :)
Regards,
Angus [Óengus] 'Midas' Lepper
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with exceptions/interrupts

Post by Pype.Clicker »

Okay, next time, make sure your message proper is on the board. You can attach your sources (.c, .asm, .pas) if they're too long to be pasted in the message proper or you can provide an external link.

Try to put only the relevant parts of your code on the board.
Okay, I'm having problems with my ISRs for the exceptions...

I've set up my IDT, and have written a few (exceptionally basic, for now, I'll actually turn them into proper ISRs later, they're just checking the concept for this build) ISRs to cover interrupts 0-31 in the IDT.

I then do a divide by zero in the main in order to trigger isr0. This should just cancel interrupts, call the C handler, and print a message before going into an infinite loop.

Here's a few pieces of relevant code (I've left out tonnes to keep the readability except where I feel it might be helpful):
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with exceptions/interrupts

Post by Pype.Clicker »

btw, any reason why you cast all your strings to (unsigned char*) ??

Code: Select all

puts((unsigned char*) "[Masking IRQs...", strlen((unsigned char*) "[Masking IRQs..."));
just suggests to me that your 'puts' function needs to be redefined. Plus, the standard definition of puts is

Code: Select all

  int puts(const char *s);
You shouldn't reuse the standard functions unless they're intended to implement the standard, or everyone will just get confused.
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

Apologies re:messages, I'll sort that out for next time. :-[ Was just a little pushed for time, I guess, and a little impatient. Sorry!

Yeah, the casting to unsigned char is an ugly hack because I've used that for puts... Not really sure why, think I just got used to writing that I suppose. So that's indefensible. As regards the standards thing: I know, this code needs tidied up before being put anywhere really, it's because puts(); is only just past being an ugly hack to check where a piece of code was faulty, I'll change it to the standard just now. (Plus, that's a really ugly and unnecessary way of doing strlen()... Was trying to save time - it shows, doesn't it? ;D)

So sorry, guess I made a bit of a mess of this. :-[ Can I ask - is there a way to attach those sources directly to the message (I can't see it, nor does a simply find-on-page seem to either) or is linking the sources themselves adequate/suitable/permissable?
Regards,
Angus [Óengus] 'Midas' Lepper
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with exceptions/interrupts

Post by Pype.Clicker »

you may need to register to be allowed to attach the stuff. Pointing to an externally-stored source is okay as long as you provide enough information in your post so that readers know without following the link what's your problem about, and what you want them to look at in your sources...

That's not a strict rule, merely a hint to get answers...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with exceptions/interrupts

Post by Pype.Clicker »

btw, some of your handlers are lacking code to remove exception number from the stack before resuming (i guess those have for(;;), but still ...)

Code: Select all

isr14:               ; Page fault exception
   cli            ; Cancel interrupts
   call   CISR14         ; Call our C handler
   iret            ; Return from interrupt

just a question, what's your problem exactly ? not seeing the message ? seeing too much of them ? ...

maybe you should do the test _before_ you EnableInterrupts() too ... you don't need PIC remapped nor IF flag set to handle exceptions: only a correct entry in the IDT.
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

Thanks for the info.

I assumed you didn't need to enable interrupts to handle exceptions (it would seem very, very, very odd to not be able to notify yourself of exception details without having got as far as enabling interrupts), but that was just the way I had been going (next thing was to deal with the keyboard, in theory).

And yes, these interrupt 'handlers' basic aren't. They're just to test that I had the IDT set up correctly and that the 'handlers' were being called - I know I need to deal with popping error codes, giving the handlers the stack frame etc.

Here's what happens: whenever that ISR is called (with or without interrupts enabled), the machine resets. I haven't actually tried any of the other exception handlers, although I very strongly suspect they'll do the same (as it's essentially the same code, just a different message). The machine doesn't reset if the ISR doesn't get called, regardless of whether interrupts are enabled, so I'm certain that the bug is either in my code setting up the IDT or the handler itself.

I can't tell if the message gets printed or not, I'll see if I can find how to 'slow down' the bochs emulation (I know I can set break points but bochs seems to just ignore them - I've tried pbreak 0x100000 which should work, in theory, but it just runs straight on) in order to check.
Regards,
Angus [Óengus] 'Midas' Lepper
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

Thanks to I/O debugging ports in Bochs:

Code: Select all

<bochs:41> s
Next at t=76248443
(0) [0x00100358] 0008:0x00100358 (unk. ctxt): idiv eax, ecx             ; f7f9
<bochs:42> s
CPU_LOOP 1
Error: (0) print_guard_results: guard_found ? (stop reason 0)
Next at t=76248443
(0) [0x00100358] 0008:100358 (unk. ctxt): idiv eax, ecx             ; f7f9
So it reaches the idiv instruction, but doesn't actually go to the interrupt handler. I don't actually understand that error, but I'll go and Google it...
Regards,
Angus [Óengus] 'Midas' Lepper
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

Okay, so stepping up to the instruction right before the idiv in Bochs, I then did dump_cpu. I get the idtr pointer and check the memory there. This points to the first descriptor being:

LowBase = 0x3D00
Segment = 0x0800
Zero = 0x00
Flags = 0xFF
HighBase = 0x1000

So I think it can be safely said that the bug is in the code I'm using to setup the IDT.

I think I'll just try rewriting the IDT code in ASM and see how that goes...
Regards,
Angus [Óengus] 'Midas' Lepper
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with exceptions/interrupts

Post by Pype.Clicker »

yep, machine reset upon exception is usually the sign of a triple fault. You can check wether the handler is okay or not by setting a breakpoint on the first instruction of the exception handler. If you can get there, it means your IDT is okay. If the bochs resets before the breakpoint is met, then you have something terribly wrong with your IDT...

just a thought: have you paging enabled already ? if yes, did you use "x ..." or "xp ..." to check your IDT ?

The reason i ask is that it's fairly common to forget that the CPU will use the base address of IDT regardless of any data segment (e.g. if your data segment has base!=0, make sure you've added data segment base to the offset before you load idtr.base) and that it will have to access the IDT through the paging MMU (that is, if the virtual address of your IDT isn't mapped, you're doomed).

good luck ... don't hesitate to hack your bochs to make it more informative (e.g. make it print the interrupt vector before it tries to use it, etc.)
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

Pype.Clicker wrote: yep, machine reset upon exception is usually the sign of a triple fault.
Yeah, I realised that.
You can check wether the handler is okay or not by setting a breakpoint on the first instruction of the exception handler. If you can get there, it means your IDT is okay. If the bochs resets before the breakpoint is met, then you have something terribly wrong with your IDT...
I tried that, and it very definitely isn't reaching the ISR.
just a thought: have you paging enabled already ? if yes, did you use "x ..." or "xp ..." to check your IDT ?
Paging isn't enabled yet, and I used xp (to read a physical address, yes?): xp /8b[t] 0x102020 to be precise.
The reason i ask is that it's fairly common to forget that the CPU will use the base address of IDT regardless of any data segment (e.g. if your data segment has base!=0, make sure you've added data segment base to the offset before you load idtr.base) and that it will have to access the IDT through the paging MMU (that is, if the virtual address of your IDT isn't mapped, you're doomed).
I hadn't thought of that, thanks for the information. At the moment however I've just got a flat setup with a null descriptor, and a code (0x08) and data (0x10) segment for ring 0, with base = 0 and limit = 4GB.
good luck ... don't hesitate to hack your bochs to make it more informative (e.g. make it print the interrupt vector before it tries to use it, etc.)
Thanks for the wishes, and having edited bochs I can see that it is indeed triple faulting:

'Vector: 0 (Divide by zero)'
'Vector: 8 (Double fault)'
'CPU_LOOP 1'

The IDT doesn't even remotely resemble what it should... So I shall be taking a look at that.

Thanks for your help!

EDIT: Actually, having looked again (remembering low-endianness this time), I can see what the problem is. The IDT entries are fine - except that the 'flags' byte for each of them is set to 0xFF - so I need to fix that, because I have no idea what kind of descriptor that will be... On the upside, that's easy to fix.

EDIT2: Works now. 8) Thanks Pype.Clicker!
Regards,
Angus [Óengus] 'Midas' Lepper
paulbarker

Re:Problem with exceptions/interrupts

Post by paulbarker »

Looks like you've solved half the problem. "CPU_LOOP 1" is a bochs configuration problem, and I've explained it here and elsewhere. Short answer, expect it to come back next time you see a bug, and remember that it hides some pretty useful information (get rid of the message and bochs should print out register values when it dies).

Oh, and whenever that message is around it worries me. On my comp it was associated with segfaults (of bochs, not of the virtualised system) and good old fashioned lockups (bochs refusing to exit).

If you're lazy and just want the fix without the explaination, add the following to your bochsrc:

Code: Select all

debug:         action=ignore
panic:         action=fatal
error:         action=ask
info:          action=report
Midas
Member
Member
Posts: 140
Joined: Sat Jun 24, 2006 4:40 pm
Location: Falkirk, Scotland
Contact:

Re:Problem with exceptions/interrupts

Post by Midas »

paulbarker wrote: Looks like you've solved half the problem. "CPU_LOOP 1" is a bochs configuration problem, and I've explained it here and elsewhere. Short answer, expect it to come back next time you see a bug, and remember that it hides some pretty useful information (get rid of the message and bochs should print out register values when it dies).

Oh, and whenever that message is around it worries me. On my comp it was associated with segfaults (of bochs, not of the virtualised system) and good old fashioned lockups (bochs refusing to exit).

If you're lazy and just want the fix without the explaination, add the following to your bochsrc:

Code: Select all

debug:         action=ignore
panic:         action=fatal
error:         action=ask
info:          action=report
I'm not too lazy, but I'll heed your advice and add them to my bochsrc. :-) I didn't realise that could be changed - not very used to bochs yet and haven't read the docs (other than the developer's ones, such as they are) yet. Thanks!

But yep, I got that sorted now have handlers for the various exceptions in various stages of completion and IRQ0, 1 and 7 with (at least) some sort of handler.
Regards,
Angus [Óengus] 'Midas' Lepper
Post Reply