From: Donald J. Becker (becker@super.org)
Date: 11/20/92


From: becker@super.org (Donald J. Becker)
Subject: Re: How to use sys_iopl (to change I/O privilege) ?    
Date: Sat, 21 Nov 1992 04:40:57 GMT

I assume what you want to do is access I/O ports from a user-level program.

There are two ways to do this. The first requires that you are root
or suid root. (I use this code to test out device drivers without
making a kernel every few minutes.) Do the following:

#include <unistd.h>
...
    /* For devices between 0x000 and 0x3ff use: */
#define PERM_OFF 0
#define PERM_ON 1
    if (ioperm(PORT_BASE, PORT_LENGTH, PERM_ON)) {
        perror("io-perm");
        return 1;
    }
    /* For devices higher than 0x3ff you must enable the whole I/O
        space. */
    if (iopl(3)) {
        perror("io-perm2");
        return 1;
    }

This method has several problems for general use: you must be root or
suid root, there is no enforcement of exclusive or semi-shared access
to a device, and there is no way to get interrupts.

The second way is use my not-yet-released generalized device driver.
I originally developed as alternate soundcard driver, but later
extended it.
Its features are:
        o Every I/O port range of interest is assigned a device.
        o A fixed device list is usually compiled-in.
        o The device list is extensible at runtime by 'root'
        o Each device can be set for exclusive, counted, or shared access.
        o Device names are arbitrary, and are made as usual by 'mknod'
        o Access permission is handled by the normal Unix user/group/all
          permission bits
        o Opening the device allows access to that I/O port range.
        o Once open, an ioctl() returns the port base, range and in-use count.
Still to be implemented is:
        o Translating interrupts to signals

-- 
Donald Becker                                  becker@super.org
Supercomputing Research Center
17100 Science Drive, Bowie MD 21114                301-805-7482