Linux asm - int 16h analogue to read raw keyboard scancodes

665 views Asked by At

For my studies I need to write a program on asm, which will wait until the keyboard key is pressed, and then print it's scan-code and ASCII code of the key's character.

I know that BIOS's int 16h can do the job, but I am using Linux right now and can't find an appropriate analogue syscall for it.

What should I use for this task? I am currently using Debian Stretch and NASM for my assembly code.

1

There are 1 answers

1
Peter Cordes On BEST ANSWER

Normally the kernel translates keyboard scancodes into ASCII characters that you can read on a tty. But there are ways to get raw scancodes, e.g. look at how showkey(1) does it (http://kbd-project.org/) on a text console. https://wiki.archlinux.org/index.php/Keyboard_input

https://github.com/legionus/kbd/blob/2.0.4/src/showkey.c shows that you can use an ioctl(2) on a file descriptor for the console terminal to set the KBD translation mode to RAW (scancodes) or MEDIUMRAW (keycodes). Then you can make normal read system calls.

ioctl(fd, KDSKBMODE, show_keycodes ? K_MEDIUMRAW : K_RAW)

Obviously you can make these system calls from hand-written asm using syscall on x86-64 or int 0x80 on 32-bit x86, looking up the syscall numbers in asm/unistd_64.h, and the values of other constants in their respective headers.


showkey takes care to set up a watchdog timer to exit cleanly, and catch signals, because doing this intercepts keys before the kernel processes control-C or ctrl+alt+f2 sequences. So without a timeout, there'd be no way to exit the program. And if you exited without restoring normal mode, there'd be no way to type on the console to run a command to restore normal keyboard mode.