I need help with the Interrupt Service Routines

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
robin1201
Posts: 17
Joined: Sun Aug 22, 2021 3:11 pm
Location: Germany

I need help with the Interrupt Service Routines

Post by robin1201 »

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.
Attachments
ISR-IDT.zip
Sourcecode
(2.76 KiB) Downloaded 33 times
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: I need help with the Interrupt Service Routines

Post by bzt »

robin1201 wrote:As soon as I want to execute the assembler code sti with C the operating system stops and restarts.
This is a typical symptom of a triple-fault.

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
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: I need help with the Interrupt Service Routines

Post by nullplan »

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!
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: I need help with the Interrupt Service Routines

Post by bzt »

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.
Thanks, that's what I wanted to say by "do not try IRQs", but your description is much better and more helpful.

Cheers,
bzt
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I need help with the Interrupt Service Routines

Post by nexos »

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...
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: I need help with the Interrupt Service Routines

Post by MichaelPetch »

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:

Code: Select all

 __asm__ volatile("lidt (%0)" : : "r" (&mainIdtReg));
Would be better written as:

Code: Select all

__asm__ volatile("lidt %0" : : "m" (mainIdtReg));
. 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:

Code: Select all

add rsp, 8
at the end should be

Code: Select all

add rsp, 16
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.
robin1201
Posts: 17
Joined: Sun Aug 22, 2021 3:11 pm
Location: Germany

Re: I need help with the Interrupt Service Routines

Post by robin1201 »

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.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I need help with the Interrupt Service Routines

Post by nexos »

but they mean that grub is the problem
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.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: I need help with the Interrupt Service Routines

Post by MichaelPetch »

I guess one obvious question is - did you put the processor in long mode (64-bit) before executing 64-bit code?
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: I need help with the Interrupt Service Routines

Post by MichaelPetch »

nexos wrote:
but they mean that grub is the problem
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.
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
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: I need help with the Interrupt Service Routines

Post by nexos »

MichaelPetch wrote:When the interrupts change CS for the first time in some environments it can lead to faults.
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.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Post Reply