Re: Interrupt Handling Issue
Posted: Sat Aug 19, 2023 12:32 pm
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: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 lineran 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: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.
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
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);
Code: Select all
virtual uint32_t HandleInterrupt(uint32_t esp);
Making this fix should allow your keyboard handler to be called properly.