I register an interrupt handler for my keyboard via a kernel module, the code works well on my virtualbox Linux guest Light Ubuntu 20.04 5.13.0-51-generic
, the interrupt handler work as intended. However, when the same code is being run on my host operating system, Ubuntu 20.04 5.13.0-51-generic
, the init
function ends successfully but the interrupt handler is never called when an interrupt occurs.
request_irq(IRQ_NUMBER, keyb_handler, IRQF_SHARED, "irq_keyboard",
(void *)keyb_handler);
Light Ubuntu (VM) /proc/interrupts (Entry 1)
// When the module isn't loaded, it's like that
1: 56 0 IO-APIC 1-edge i8042
// When the module is load, it's like that
1: 272 0 IO-APIC 1-edge i8042, irq_keyboard
Ubuntu (Host) /proc/interrupts (Entry 1)
// Nothing is shown unless the module is loaded. if the module is loaded, then it's
1: .. 0 .. IO-APIC 1-edge irq_keyboard
What can be the problem? I debugged the code many times on both operating system, and I know for a fact that the code is fine, hence it must be a portability issue. If any additional information is needed, lmk.
CodePudding user response:
Note the "PC" is the original IBM PC from 1987, and its successors. Copies of the original PC copied the hardware, of course, so that the software would still work. And later editions also had to copy the hardware, so that the software would still work.
In these computers, the keyboard port was connected to an Intel 8042 computer chip which was then connected to the CPU. The 8042 chip was in charge of converting between the signals from the keyboard, and the signals to the CPU. So for example it sent an interrupt when it noticed a key was pressed. The interrupt was hard-wired to a certain pin of the interrupt controller.
Modern computers are more flexible. Everything is connected through a bus like PCIe or USB. If it was hard-wired to a keyboard controller chip to a certain interrupt pin, you could only have one keyboard, and what would be the fun in that? USB lets me plug in as many keyboards as I want.
Do you have a USB keyboard? Then your keyboard connection is most likely going through a USB bus to a USB controller chip connected to a PCIe bus connected to the processor. There is no 8042 chip involved. There might not even be an interrupt pin - the controller could use Message-Signaled Interrupts instead.
Your BIOS may have a setting for "PS/2 emulation". If this is turned on, when the operating system tries to talk to that ancient 8042 chip, the BIOS intercepts it and simulates what the 8042 would have done. Probably this is turned off, because you are using an OS newer than 20 years, which knows how to access a USB port, and doesn't need the emulation.
Meanwhile your VM simulates the 8042 chip because it's convenient, more compatible with older operating systems, etc. It might depend on how the VM is set up - there might be an option to choose between an 8042 (PS/2) or USB keyboard. Notice that Linux is using the "i8042" (intel 8042) driver.