I need help with the Interrupt Service Routines
I need help with the Interrupt Service Routines
Hello everyone.
I am working on a 64-Bit Operating System and I am working on the IDT and ISR at the moment but I have a problem. As soon as I want to execute the assembler code sti with C the operating system stops and restarts.
I have already tried everything and can't get any further. I hope you can help me. I have attached the source code of the most necessary files.
I am working on a 64-Bit Operating System and I am working on the IDT and ISR at the moment but I have a problem. As soon as I want to execute the assembler code sti with C the operating system stops and restarts.
I have already tried everything and can't get any further. I hope you can help me. I have attached the source code of the most necessary files.
- Attachments
-
- ISR-IDT.zip
- Sourcecode
- (2.76 KiB) Downloaded 33 times
Re: I need help with the Interrupt Service Routines
This is a typical symptom of a triple-fault.robin1201 wrote:As soon as I want to execute the assembler code sti with C the operating system stops and restarts.
My advice:
1. do not try IRQs, first only set up exceptions. Only go to IRQs when you have mastered exception handling.
2. use bochs. That will drop you at a debugger prompt, and it will print out what exceptions were triggered before the triple-fault.
3. use bochs' debugger to examine your IDT, the function addresses in it; then the stack when an ISR is called.
Cheers,
bzt
Re: I need help with the Interrupt Service Routines
To add to the above: You can only enable interrupts once you have initialized all interrupt controllers and masked out all interrupts you don't know yet. Otherwise you will get interrupts you don't know, and those are simply not helpful to you.
Carpe diem!
Re: I need help with the Interrupt Service Routines
Thanks, that's what I wanted to say by "do not try IRQs", but your description is much better and more helpful.nullplan wrote:To add to the above: You can only enable interrupts once you have initialized all interrupt controllers and masked out all interrupts you don't know yet. Otherwise you will get interrupts you don't know, and those are simply not helpful to you.
Cheers,
bzt
Re: I need help with the Interrupt Service Routines
One thing to remember is that STI only enables hardware interrupts. Those are different then software interrupts. I would recommend first trying out exceptions. Try loading an IDT, then calling a DIV 0. See what happens. From there, debug using Bochs (as it is the most friednly emulator. Also, if you haven't, you really should read the Intel Manual's chapter about the IDT and the sections about the GDT, if you haven't. You need to understand these concepts in order to debug something like the GDT or IDT. Forum members, the wiki, nor OSDev tutorials will provide you with as much clarity as reading the manuals themselves. I learned this the very, very hard way...
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: I need help with the Interrupt Service Routines
I have to agree with nexos that BOCHS might be useful here. It has a command 'info idt' to look at the IDT structure to see if it is correct and many other useful tools. It does a reasonable job at helping find very low level bugs early on in OSDEV. If you are using QEMU then I'd recommend running it with the options '-d int -no-reboot -no-shutdown' . When the first interrupt occurs it is likely faulting and then ends up with a double fault and triple fault. These extra options with QEMU might be able to tell you what caused the original fault, as QEMU will dump the processor state (including most of the registers), error code etc and then stop. It might be helpful to even post that output here in your question. Putting your entire project in Github would also help if you want people to help debug it. The code you show may not even be the source of the issue.
Although your LIDT inline assembly looks correct (and likely works) it has a subtle bug that an optimising compiler could in theory generate unexpected code. This:Would be better written as:. Your version says that the pointer is an input, but not the data that the pointer points to. It is possible (but unlikely in this case) that the compiler would not fill in the mainIdtReg structure before calling this inline assembly if it thinks the inline assembly doesn't use the data at that address. My version ensures that the entire mainIdtReg structure will be realized into memory first. But this is not likely the source of your problems.
Another thing is that x86-64 also has registers R8 to R15 and your push and pop macros aren't using them.
I did notice one big problem in isr_common:at the end should be since the error code and interrupt number are pushed as 2 8 byte values (16 total). It also is not needed to do a CLI to begin and an STI to end an interrupt the way you are doing it. If you create an interrupt gate for the IDT entries the processor will automatically disable external interrupts before the interrupt handler is called and the interrupt state will be restored when the IRETQ is done.
Although your LIDT inline assembly looks correct (and likely works) it has a subtle bug that an optimising compiler could in theory generate unexpected code. This:
Code: Select all
__asm__ volatile("lidt (%0)" : : "r" (&mainIdtReg));
Code: Select all
__asm__ volatile("lidt %0" : : "m" (mainIdtReg));
Another thing is that x86-64 also has registers R8 to R15 and your push and pop macros aren't using them.
I did notice one big problem in isr_common:
Code: Select all
add rsp, 8
Code: Select all
add rsp, 16
Re: I need help with the Interrupt Service Routines
Yesterday I searched a litle Bit on Google in there a Solution or an example but they mean that grub is the problem an i am using GRUB to boot the kernel is it correct what they said or not? I didn‘t worked so much with grub.
Re: I need help with the Interrupt Service Routines
No, GRUB leaves the IDT in an undefined state. If you lead up your own IDT into IDTR, then GRUB has nothing to do with that.but they mean that grub is the problem
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: I need help with the Interrupt Service Routines
I guess one obvious question is - did you put the processor in long mode (64-bit) before executing 64-bit code?
-
- Member
- Posts: 797
- Joined: Fri Aug 26, 2016 1:41 pm
- Libera.chat IRC: mpetch
Re: I need help with the Interrupt Service Routines
I was thinking that possibly the GRUB scenario they might have found was the one where people create a 32-bit OS and use the GDT that GRUB created (which isn't necessarily valid per the specs). When the interrupts change CS for the first time in some environments it can lead to faults.nexos wrote:No, GRUB leaves the IDT in an undefined state. If you lead up your own IDT into IDTR, then GRUB has nothing to do with that.but they mean that grub is the problem
Re: I need help with the Interrupt Service Routines
That could be possible, as even if the GDT is valid, 0x18 is GRUB's 32 bit selector, meaning that as many people default to 0x08, that could cause problems.MichaelPetch wrote:When the interrupts change CS for the first time in some environments it can lead to faults.