Keyboard Controller
From OSDev Wiki
The Keyboard Controller (KBC) is located on the mainboard. The name is misleading because the Controller does more then controlling the communication with the hardware on the keyboard.
In the early days the controller was a single chip (8042). As of today it is part of the Advanced Integrated Peripheral.
Contents |
Functions of the KBC
- Controlling one or two PS/2 connectors OR one 5pin DIN connector
- CPU Reset
- Enable/Disable the A20-Gate
- Controlling the PC Speaker together with the Programmable Interval Timer.
KBC Types
There are two kinds of KBCs that somewhat differ from each other. The first KBC is the AT-KBC introduced with the AT-System. The second one is the PS/2-KBC introduced with the PS/2-System.
The ancestor of the AT-System the XT-System used the Programmable Peripheral Interface (PPI) for comparable tasks.
USB Legacy Support
By modern standards you will find many PCs bundled with USB input devices. Some PCs may not even have PS/2 connectors at all. To remain compatible with old software, the mainboard emulates USB Keyboards and Mouses as PS/2 devices. This is called USB Legacy Support.
Because the implementation differ by manufacturer and mainboard there are flaws and sometimes even bugs:
- Some emulation layers also handle the communication with the real PS/2 connectors regardless of any connected USB device. So maybe not all capabilities of the PS/2 connectors and devices can be used.
For example extended mouse modes needed to use the scroll wheel won't work or the keyboard only works on the first PS/2 connector and the mouse only on the second connector.
- The SMM BIOS that's providing the PS/2 USB Legacy Support may not support extended memory techniques or the Long mode and therefore cause system crashes.
The follow part needs to to be confirmed!
This emulation layer is disabled as soon as the USB Chipset gets initiated by software. (The mainboard knows the OS has USB drivers and therefore can communicate with the devices directly)
Examples
Simple keyboard handler for real mode
This is an example how to use the keyboard in real mode. The Scancode for pressed and released keys is displayed on the screen.
The source works with NASM and FASM. You can copy the output file to the boot sector of a floppy or use it with an Emulator.
use16 org 0x7C00 ;Disable interrupts cli ;set DS to 0 xor ax, ax push ax pop ds ;The IRQ1 (keyboard) is mapped on interrupt 9 by default ;Now we write the address of the handler in the Interrupt descriptor table (IDT) mov word[ds:(9*4) ], keyboard_handler ;Offset mov word[ds:(9*4)+2], 0 ;Segment ;Enable interrupts sti jmp $ ;This handler gets called each time a IRQ1 is triggered by the keyboard keyboard_handler: pusha ;read scancode in al, 0x60 ;Here you can do with the scancode whatever you like. ;For example converting it to another keyboard layout or test for special keys and trigger a reboot call write_byte_as_hex mov al, '|' call bios.write_char ;Now we tell the first PIC that the IRQ is handled mov al, 0x20 out 0x20, al popa iret ;Input: al = char bios.write_char: pusha mov ah, 0x0E int 0x10 popa ret hex_chars: db '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ;This is a small function to write a value on the screen ;Input: al = byte write_byte_as_hex: pusha and ax, 0xFF push ax mov bx, ax shr bx, 4 mov al, [hex_chars+bx] call bios.write_char pop bx and bx, 0xF mov al, [hex_chars+bx] call bios.write_char popa ret times 510-($-$$) db 0 dw 0xAA55
CPU Reset
To trigger a CPU Reset (No matter what state the CPU currently has) you have to write the value 0xFE to the Outputport.
;Wait for a empty Input Buffer wait1: in al, x064 test al, 00000010b jne wait1 ;Send 0xD1 to the KBC. This is the command to write the Outputport. mov al, 0xD1 out 0x64, al ;Wait for a empty Input Buffer wait2: in al, x064 test al, 00000010b jne wait2 ;Now we can write the new value (0xFE) for the Outputport to port 0x60 mov al, 0xFE out 0x60, al


