views:

1172

answers:

2

So I'm working on keyboard input for a very bare bones kernel that I'm throwing together, and I'm completely stuck. I can't seem to find any information online that can tell me the information I need to know.

My kernel is running in protected mode right now, so I can't use the "normal" real mode keyboard routines without jumping into real mode and back, which I'm trying to avoid. So basically, I want 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, not something that comes up very often as usually asm tutorials assume you're running an OS underneath...

I'm very new to x86 assembly, so really I'm just looking for some good resources for working with the standard hardware from protected mode. I think I'll be good if I can get that going.

Oh, if you're going to post code examples, I'm compiling the assembly bits with NASM, and linking it to C bits compiled with DJGPP if it matters.

Thanks

+5  A: 

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.

Adam Rosenfield
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!
Nicholas Flynt
+3  A: 

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).

CesarB
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?
Nicholas Flynt
It's ports 0x60 _to_ 0x6f (look at /proc/ioports at any x86 Linux machine). Of these, 0x60 and 0x64 are actually used.
CesarB