Interrupt Handling Issue

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.
MichaelPetch
Member
Member
Posts: 712
Joined: Fri Aug 26, 2016 1:41 pm
Freenode IRC: mpetch

Re: Interrupt Handling Issue

Post by MichaelPetch »

The problem is a typo in your C++ header and cpp files for the interrupts. Before I tell you what the problem is I'd like to point out that at this point when you are able to start running your code without exceptions being thrown for low level problems and you need to debug the kernel, I recommend using QEMU for debugging. With QEMU you can set breakpoints, step into a function, go to the next statement etc and use symbolic debugging.

To properly debug - generate debug info that QEMU can use. In your Makefile add the -g to GPPPARAMS and ASPARAMS. The debug info is going to be placed in the ELF executable called mykernel.bin. You can launch QEMU with remote debugging and then launch GDB to connect to that using the information in mykernel.bin like this:

Code: Select all

qemu-system-i386 -cdrom mykernel.iso -no-shutdown -no-reboot -S -s &
QEMU_PID=$!

gdb mykernel.bin \
        -ex 'target remote localhost:1234' \
        -ex 'layout src' \
        -ex 'layout regs' \
        -ex 'break *kernelMain' \
        -ex 'continue'

if ps -p $QEMU_PID >/dev/null
then
    kill -9 $QEMU_PID >/dev/null
fi
stty sane
You can of course add a new rule to your Makefile with those commands or put it in a separate debug script. That's up to you, but I prefer the Makefile solution.

I used this to hunt down your problem. When QEMU first hit the kernelMain breakpoint it stopped. I set a another breakpoint at the Keyboard Interrupt entry point with b InterruptManager::handleInterruptRequest0x01 . I then used the continue command c to continue until the next breakpoint is hit. When a keyboard interrupt occurred I used the step command s to step through the assembly code one instruction at a time observing that things looked okay. I continued using step through the CPP code and then noticed that in InterruptManager::DoHandleInterrupt this line

Code: Select all

esp = handlers[interruptNum]->handleInterrupt(esp);
ran the default InterruptHandler::handleInterrupt function rather than what I'd expect KeyboardDriver::handleInterrupt. This is a virtual function so the Keyboard handler should have been called. When I looked at keyboard.h I saw this:

Code: Select all

virtual uint32_t HandleInterrupt(uint32_t esp);
If you look carefully you have HandleInterrupt with a capital 'H' rather than a lowercase 'h'. You need to make this virtual uint32_t handleInterrupt(uint32_t esp); and then make the similar fix in keyboard.cpp.

Making this fix should allow your keyboard handler to be called properly.
Post Reply