Open maximilien-noal opened 1 year ago
Here is the plan for this issue:
"How about I go and extend our INT 33 handler with the missing functionality, while using the gui as source for mouse data. And you work on getting the I/O 0x60 & 0x64, irq12, INT 74 and INT 15 to work? Tackle the task from both ends., and at a certain point connect the 2 together?"
This is related to Krondor.
A high level overview of the mouse/bios/mouse driver/keyboard/io handler interactions on real hardware:
On real hardware the mouse triggers the PS/2 chip to raise an irq 12 and put data on ports 0x60 and 0x64.
This triggers an INT 74. This is caught by BIOS.
BIOS checks internally if something has registered itself there by using INT 15.
Then it calls that.
That piece of software then reads the data from the I/O ports and decodes the mouse protocol.
Then it creates an "event" from it if it determines that something has happened. It then calculates the current mouse position and updates it internal data
If another piece of software has used INT 33 to register a callback for certain events, it checks if this event matches that mask.
In that case it will store the registers and then send some of it's own state to that callback.
When that returns it restores the registers and returns the call to BIOS
INT 74 is handled by BIOS.
Other programs can tell BIOS by using INT 15 that they can handle certain hardware events.
BIOS keeps track of those and calls the appropriate code when the intterupt occurs
Perhaps look into BIOSes too, such as: https://github.com/640-KB/GLaBIOS
https://alex.dzyoba.com/blog/os-interrupts/
Setup interrupts: Create IDT table Set IDT entry #9 2 with interrupt gate pointing to keyboard ISR Load IDT address with lidt Send interrupt mask 0xfd (11111101) to PIC1 to unmask (enable) IRQ1 Enable interrupts with sti Human hits keyboard button Keyboard controller raises interrupt line IRQ1 in PIC1 PIC checks if this line is not masked (it’s not) and send interrupt number 9 to CPU CPU checks if interrupts disabled by checking IF in EFLAGS (it’s not) (Assume that currently we’re executing in kernel mode) Push EFLAGS, CS, and EIP on the stack Push an error code from PIC (if appropriate) on the stack Look into IDT pointed by idtr and fetch segment selector from IDT descriptor 9. Check privilege levels and load segment selector and ISR address into the CS:EIP Clear IF flag because IDT entries are interrupt gates Pass control to ISR Receive interrupt in ISR: Disable interrupt with cli (just in case) Save interrupted procedure state with pusha Push current DS value on the stack Reload DS, ES, FS, GS from kernel data segment Acknowledge interrupt by sending EOI (0x20) to master PIC (I/O port 0x20) Read keyboard status from keyboard controller (I/O port 0x64) If status is 1 then read keycode from keyboard controller (I/O port 0x60) Finally, print char via VGA buffer or send it to TTY Return from interrupt: Pop from stack and restore DS Restore interrupted procedure state with popa Enable interrupts with sti iret
Note, that this happens every time you hit the keyboard key. And don’t forget that there are few dozens of other interrupts like clocks, network packets and such that is handled seamlessly without you even noticing that. Can you imagine how fast is your hardware? Can you imagine how well written your operating system is? Now think about it and give OS writers and hardware designers a good praise.
Description of protocol between mouse and I/O ports 0x60 and 0x64: https://wiki.osdev.org/Mouse_Input
Assembly source code of ctmouse driver, including some very informative txt files: https://github.com/FDOS/mouse
Tell BIOS which routine to call when handling irq12 / INT 74 INT 15 C2 07: https://mirror.cs.msu.ru/oldlinux.org/Linux.old/docs/interrupts/int-html/rb-1603.htm
IBM doc on keyboard/mouse controller: http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
INT 15 handling BIOS code:
https://github.com/coreboot/seabios/blob/master/src/mouse.c