Linux asm - int 16h analogue to read raw keyboard scancodes
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.
linux assembly keyboard nasm scancodes
add a comment |
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.
linux assembly keyboard nasm scancodes
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just usesint 16h(and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.
– Dave M.
Nov 23 '18 at 20:33
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32
add a comment |
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.
linux assembly keyboard nasm scancodes
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.
linux assembly keyboard nasm scancodes
linux assembly keyboard nasm scancodes
edited Nov 24 '18 at 10:26
Verloren
asked Nov 23 '18 at 20:20
VerlorenVerloren
508
508
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just usesint 16h(and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.
– Dave M.
Nov 23 '18 at 20:33
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32
add a comment |
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just usesint 16h(and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.
– Dave M.
Nov 23 '18 at 20:33
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just uses
int 16h (and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.– Dave M.
Nov 23 '18 at 20:33
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just uses
int 16h (and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.– Dave M.
Nov 23 '18 at 20:33
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32
add a comment |
1 Answer
1
active
oldest
votes
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.
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452539%2flinux-asm-int-16h-analogue-to-read-raw-keyboard-scancodes%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
add a comment |
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.
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
add a comment |
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.
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.
answered Nov 23 '18 at 20:35
Peter CordesPeter Cordes
127k18190326
127k18190326
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
add a comment |
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
Note that this only works in the virtual console, not inside a terminal emulator.
– fuz
Nov 23 '18 at 20:39
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53452539%2flinux-asm-int-16h-analogue-to-read-raw-keyboard-scancodes%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly.
– fuz
Nov 23 '18 at 20:32
Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just uses
int 16h(and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary.– Dave M.
Nov 23 '18 at 20:33
You might be able to use the "input" subsystem for this. See man input-events.
– Jester
Nov 23 '18 at 22:32