Accessing I/O Ports, Part 2
Descriptors vs. Direct Access
The technique presented last week for accessing I/O ports is portable
and safe but too slow for certain applications. Instead of using a
descriptor, Linux allows a process to write to an I/O port directly,
thereby avoiding the overhead associated with write() and read().
The outb() Syscall
A process can call the function outb() to write directly to an I/O
port. outb() takes two arguments: the data to be written to the I/O
port and the I/O port number. For example, to write the character 0x01
to our remote control, call outb() as follows:
outb(0x01, 0x378+2); /*turn the lights on*/
The use of symbolic constants can make the code more readable:
const char ON=0x01;
const char OFF=0x00;
const int PORT=0x378+2;
outb(OFF, PORT); /*turn the lights off*/
Obtaining Permissions
This is all well and good; however, by default Linux terminates a
process that attempts to access an I/O port directly (with good
reason!). A process that accesses I/O ports directly must get the
necessary permissions beforehand using one of two methods. The first
(and safer) way is to call ioperm(). ioperm() allows a process with
super-user privileges access to each I/O port in the range 0-0x3ff.
Thus, if you wish to access the ports 0x378, 0x379, and 0x380 (the
ports that access /dev/lp1), call ioperm() as follows:
ioperm(0x378, 3, 1);
The first argument is the first port in the range. The second argument
is the number of ports in the range. The last argument is either 1 or
0. The value 1 allows access to the ports in the range and 0 denies
access to them. ioperm() returns 0 on success and -1 on error.
Alternatively, a process with super-user privileges can enable access
to all the I/O ports at once by calling the iopl() function as follows:
iopl(3);
The above call causes a process to switch to what is known as "I/O
protection level 3", which grants a process full access to the I/O bus.
As a rule, you should use ioperm() to obtain permission to access I/O
ports; use iopl() only if your process needs to access ports higher
than 0x3ff.
A note on last week's tip:
The device names "dev/port" and "dev/lp1" should read "/dev/port"
and "/dev/lp1", respectively.
» posted by ITworld staff
ITworld
Sign up for ITworld's Daily newsletter
Follow ITworld on Twitter @IT_world
jfruh
Apple syncing patent can't come soon enough
pasmith
New Twitter features borrow from 3rd party clients
Esther Schindler
Open Source Changes the Software Acquisition Process
mikelgan
How to set up continuous podcast play on the new iTunes
David Strom
Five important Windows 7 mobility features
sjvn
Guard your Wi-Fi for your own sake
Sandra Henry-Stocker
Grepping on Whole Words
Sidekick: The Good News & the Bad News
Either way you look at it Microsoft Data Center management did not follow standards or best practices in this failure. In which case it makes me wonder more about the outsourcing of corporate data much less personal data.
- mburton325
Join the conversation here
Quick, practical advice for IT pros. Made fresh daily.
Want to cash in on your IT savvy? Send your tip to tips@itworld.com. If we post it, we'll send you a $25 Amazon e-gift card.












