Interrupt handler looses state

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
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Interrupt handler looses state

Post by Qeroq »

Hello,
I'm writing a kernel almost completely in C++ and for interrupt handling I defined the following classes:
Oxygen::Kernel::Processor::InterruptAdvisor (abstract) registering the IDT and holding an array of interrupt handlers
Oxygen::Kernel::Processor::InterruptHandler (abstract) can be registered to an interrupt advisor for one or more interrupt numbers
Oxygen::Kernel::Processor::X86::X86InterruptAdvisor: Implementation of InterruptAdvisor

The last one, X86InterruptAdvisor acts as a singleton. Handlers can be attached at anytime, as they are not directly written in the IDT, instead some proxy methods receive the original interrupt. Handlers are attached to an array InterruptHandler *handlers[256].

When my class is receiving an interrupt the instance of the X86InterruptAdvisor is fetched which will look whether there is a handler registered for the number of the fired interrupt. But the array is completely empty then, although it was filled before. Also a test property "int hello" which I set from zero to one before the interrupt fires is reset to zero.

A snippet of my code I use for interrupt handling, jumped to by _int_callNUMBER:

Code: Select all

; Common interrupt handler
_int_call_common:
    pusha                   ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax

    mov ax, ds              ; Lower 16-bits of eax = ds.
    push eax                ; save the data segment descriptor

    mov ax, 0x10            ; load the kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call _int_handler

    pop ebx                 ; Reload the original data segment descriptor
    mov ds, bx
    mov es, bx
    mov fs, bx
    mov gs, bx

    popa                    ; Pops edi,esi,ebp...
    add esp, 8              ; Cleans up the pushed error code and pushed ISR number
    iretd                   ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Interrupt handler looses state

Post by Gigasoft »

I wonder why every interrupt handler that ends up in a forum post here looks the same or nearly the same, despite being posted by different people? All of them set DS, ES, FS and GS to the same value when returning. Why everyone would want to restore FS and GS to the old value of DS is beyond me.
User avatar
Creature
Member
Member
Posts: 548
Joined: Sat Dec 27, 2008 2:34 pm
Location: Belgium

Re: Interrupt handler looses state

Post by Creature »

Gigasoft wrote:I wonder why every interrupt handler that ends up in a forum post here looks the same or nearly the same, despite being posted by different people? All of them set DS, ES, FS and GS to the same value when returning. Why everyone would want to restore FS and GS to the old value of DS is beyond me.
Most likely because JamesM does it that way and it's (AFAIK) still a prominent learning source.
When the chance of succeeding is 99%, there is still a 50% chance of that success happening.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Interrupt handler looses state

Post by Candy »

berkus wrote:
Gigasoft wrote:I wonder why every interrupt handler that ends up in a forum post here looks the same or nearly the same, despite being posted by different people? All of them set DS, ES, FS and GS to the same value when returning. Why everyone would want to restore FS and GS to the old value of DS is beyond me.
Because unless you use FS and GS for some OS-specific needs, they are usual data access segments and have the same values as DS and ES.
Then there's the longmode OSes for which all those segments don't matter, just the DPL. FS and GS come from FSBASE and GSBASE so even if you do use them they're still the same selector.
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Re: Interrupt handler looses state

Post by Qeroq »

Yeah, it's true, I set FS and GS, because JamesM did this. And as I'm not really sophisticated with OS dev and asm, I believed him that it made some sense.

Apparently my interrupt handling code is quite similar to the one used in Metta, I attached some code I use for interrupt handling.
Attachments
X86InterruptAdvisor.h
Oxygen::Kernel::Processor::X86::X86InterruptAdvisor header
(3.15 KiB) Downloaded 24 times

[The extension s has been deactivated and can no longer be displayed.]

X86InterruptAdvisor.cpp
Oxygen::Kernel::Processor::X86::X86InterruptAdvisor
(2.65 KiB) Downloaded 36 times
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
Qeroq
Member
Member
Posts: 52
Joined: Wed Aug 25, 2010 6:35 am
Location: Bonn, Germany

Re: Interrupt handler looses state

Post by Qeroq »

You're right, I don't need the global, but it's really not the problem. The thing is, that may interrupt handler (handle(InterruptState) gets called, setUp() is always called before interrupts are thrown. I'm just trying to avoid real work in the constructor, but I might move it to the constructor later on. The worst thing is, that the array containing the list of interrupt handlers is completely empty (Yes, I filled it before the first interrupt).

I was planning to do some cleanup when I get it working, this was rather a quick and dirty approach. And, as I'm from the Java world, I'm really used to use massively nested namespaces and I really like it this way as it makes sense to me.
https://github.com/qero/Hydrogen (Loader for AMD64 kernels running on top of GRUB2)
Post Reply