Master the fundamental concepts of build a mini kernel through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksKeyboards send scancode bytes on IRQ1 from the 8042 controller. Make/break codes map through translation tables to ASCII for simple text mode shells.
Read path:
0x640x60For example, scancode 0x1E press with shift held may yield uppercase A in your lookup table.
The PS/2 scan-code translation you implement here , make codes, break codes, the shift/caps-lock XOR trick , is exactly what every BIOS and early Linux console driver did before USB HID keyboards became standard. Confusing a break code for a make code is a classic bug that makes a kernel think a key is still held down forever after it's released.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will handle IRQ1, maintain modifier state, and push translated characters into a ring buffer. The task asks you to ignore break codes without duplicating key events.
Write the core of a PS/2 keyboard driver. The keyboard sends scan codes (set 1), not characters. A key press sends its make code, and releasing it sends the break code, which is the make code + 0x80. Some keys send a 0xE0 prefix first. The driver tracks modifier state (Shift, Ctrl, Alt, Caps Lock), translates make codes into characters through lookup tables, and stores them in a fixed-size circular buffer that the kernel reads later. If the buffer is full, new keys are dropped.
cLoading…
| Make codes | Keys (unshifted / shifted) |
|---|---|
| 0x01 | Esc |
| 0x02-0x0D | 1 2 3 4 5 6 7 8 9 0 - = / ! @ # $ % ^ & * ( ) _ + |
| 0x0E, 0x0F | Backspace, Tab |
| 0x10-0x1B | q w e r t y u i o p [ ] / Q … P { } |
| 0x1C | Enter |
| 0x1E: 0x29 | a s d f g h j k l ; ' and backtick / A … L : " ~ |
| 0x2B: 0x35 | \\ z x c v b n m , . / / ` |
| 0x39 | Space |
Modifiers: Left Shift 0x2A, Right Shift 0x36, Ctrl 0x1D, Alt 0x38 (held while pressed), and Caps Lock 0x3A (toggles on each press). With 0xE0: 1D right Ctrl, 38 right Alt, 48 <UP>, 50 <DOWN>, 4B <LEFT>, 4D <RIGHT>, 47 <HOME>, 4F <END>, 53 <DEL>.
^X (upper-case letter). Alt prefixes any key with M-.\n, \b, \t and <ESC>.E0 codes) are ignored and counted.cLoading…
read concatenates the stored keys exactly as written above. Nothing is printed for the scan codes themselves.
Input:
cLoading…
Output:
cLoading…
0xE0 prefix across bytes (and across lines).Hidden tests cover Caps Lock with and without Shift, Ctrl and Alt combinations, arrow keys, buffer overflow, symbols on the number row, and unknown scan codes.