Protected Mode Keyboard Access on x86 Assembly
Asked Answered
P

3

16

I'm working on keyboard input for a very basic kernel that I'm developing and I'm completely stuck. I can't seem to find any information online that can show me the information I need to know.

My kernel is running in protected mode right now, so I can't use the real mode keyboard routines without jumping into real mode and back, which I'm trying to avoid. I want to be able to access my keyboard from protected mode. Does anyone know how to do this? The only thing I have found so far is that it involves talking to the controller directly using in/out ports, but beyond that I'm stumped. This is, of course, is not something that comes up very often. Normally, Assembly tutorials assume you're running an operating system underneath.

I'm very new to the x86 assembly, so I'm just looking for some good resources for working with the standard hardware from protected mode. I'm compiling the Assembly source code with NASM and linking it to the C source code compiled with DJGPP. Any suggestions?

Psychosurgery answered 20/10, 2008 at 16:48 Comment(2)
Hi, I know this is an old question, but can you edit your question with the solution, or take a look at my question #22745124 ? Thank youNeral
Also related, wiki.osdev.org/PS/2_Keyboard for legacy (often emulated) PC-compatible keyboard controller stuff. The modern way would be a UEFI "application" that starts in 32 or 64-bit mode, and can ask the UEFI environment to do I/O.Durwyn
D
15

The MIT operating systems class has lots of good references. In particular, check out Adam Chapweske's resources on keyboard and mouse programming.

In short, yes, you will be using the raw in/out ports, which requires either running in kernel mode, or having the I/O permission bits (IOPL) set in the EFLAGS register. See this page for more details on I/O permissions.

Dismember answered 20/10, 2008 at 16:59 Comment(2)
Yay!!! I got it to work thanks to those pages. You're amazing, and I would vote you up 10 times if I could. Now I just need to convert the scan codes to ASCII, but that I can probably do, (And besides, having it output the scancodes to the screen looks really neat!) Thanks a bunch!Psychosurgery
MIT link dead, likely updated to: ocw.mit.edu/courses/electrical-engineering-and-computer-science/…Inheritable
P
3

You work with standard legacy hardware the same way on real and protected modes. In this case, you want to talk with the 8042 at I/O ports 0x60 to 0x6f, which in turn will talk to the controller within the keyboard at the other end of the wire.

A quick Google search found me an interesting resource at http://heim.ifi.uio.no/~stanisls/helppc/8042.html (for the 8042) and http://heim.ifi.uio.no/~stanisls/helppc/keyboard_commands.html (for the keyboard).

In case you are not used to it, you talk with components at I/O ports via the IN (read) and OUT (write) opcodes, which receive the I/O port number (a 16-bit value) and the value to be read or written (either 8, 16, or 32 bits). Note that the size read or written is important! Writing 16 bits to something which is expecting 8 bits (or vice versa) is a recipe for disaster. Get used to these opcodes, since you will be using them a lot (it is the only way to talk to some peripherals, including several essential ones; other peripherals use memory-mapped I/O (MMIO) or bus-mastering DMA).

Panache answered 20/10, 2008 at 17:6 Comment(3)
This is good information, however, I found that I needed to talk with ports 0x60 and ox64, not 0x6F. All the documentation seems to point this way as well. Perhaps a typo?Psychosurgery
It's ports 0x60 to 0x6f (look at /proc/ioports at any x86 Linux machine). Of these, 0x60 and 0x64 are actually used.Panache
Links dead, but wayback machine has them: web.archive.org/web/20150503041658/http://heim.ifi.uio.no/…Inheritable
I
1

The 8042 PS/2 Controller looks like the simplest possibility.

The oszur11 OS tutorial contains a working example under https://sourceforge.net/p/oszur11/code/ci/master/tree/Chapter_06_Shell/04_Makepp/arch/i386/arch/devices/i8042.c

Just:

sudo apt-get install build-essential qemu
sudo ln -s /usr/bin/qemu-system-i386 /usr/bin/qemu
git clone git://git.code.sf.net/p/oszur11/code oszur11
cd oszur11/Chapter_06_Shell/04_Makepp
make qemu

Tested on Ubuntu 14.04 AMD64.

My GitHub mirror (upstream inactive): https://github.com/cirosantilli/oszur11-operating-system-examples

Not reproducing it here because the code it too long, will update if I manage to isolate the keyboard part in a minimal example.

Inheritable answered 20/10, 2015 at 11:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.