Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!husc6!bloom-beacon!dyer From: dyer@athena.mit.edu (Steve Dyer) Newsgroups: comp.unix.xenix,comp.unix.questions,comp.sys.ibm.pc Subject: Re: How do I access the ports? Message-ID: <1235@bloom-beacon.MIT.EDU> Date: Tue, 4-Aug-87 19:25:53 EDT Article-I.D.: bloom-be.1235 Posted: Tue Aug 4 19:25:53 1987 Date-Received: Thu, 6-Aug-87 06:39:18 EDT References: <302@uvicctr.UUCP> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: dyer@spdcc.COM (Steve Dyer) Distribution: world Organization: Massachusetts Institute of Technology Lines: 54 Keywords: xenix, port Xref: mnetor comp.unix.xenix:556 comp.unix.questions:3467 comp.sys.ibm.pc:6352 The I/O instructions can only be run by the XENIX kernel when you're running on a machine with protected mode. IN, INB, OUT, OUTB all give a protection violation when executed by a user-mode process. Welcome to the world of mini-computer style protection. A UNIX device driver (part of the kernel) usually performs all IO instructions and handles device interrupts, presenting a controlled interface to a user process. Now, having said that, there is an undocumented set of character special files which present a process with the IO space, in the same way that /dev/mem and /dev/kmem present a process with access to physical and kernel virtual memory, respectively. I was just about to write this myself when I discovered a set of routines uploaded to the CIS Microsoft XENIX SIG which point out their existence and presented sample implementations of inb and outb. First, you have to make the special device. mknod /dev/port c 4 3 A read from /dev/port performs an INB on the port represented by the file offset, and a write performs an OUTB in the same way. I have been told unofficially that minor 4 does IN/OUT 16-bit operations, and minor 5 does 32-bit IO operations under XENIX 386. I have never tested these two variants, although minor 3 works under XENIX 386. Thus, the scheme is roughly: char c; fh = open("/dev/port", mode); /* set mode appropriately */ lseek(fh, (long) ioaddress, 0); /* you might test the return val */ read_or_write(fh, &c, 1); /* you might test the return val */ Several hopefully obvious caveats: first, because these devices are undocumented, there's no guarantee that they will remain in future releases of XENIX. I wouldn't build any production software assuming that major 4 minor whatever will behave in this fashion. Second, you should be aware that poking at IO port locations in user mode can be a recipe for disaster, since you have the potential to be changing the state of the machine out from underneath the kernel, which believes that it is in full control of the machine. I have limited my "poking" around to fiddling IO registers of devices which don't do any IO of their own; and would not produce any unwanted interrupts as a result of such operations (I'm playing with an unsupported video card). If you started a DMA operation or an operation which would cause an interrupt which wasn't expected, then there's no reason to assume the machine would not crash and burn. Basically, these devices are useful for controlled experimentation, or to "unwedge" a stuck device (I used to do this all the time with "db" to /dev/kmem on the PDP-11/70 to wake up a magtape--its IO regs are memory mapped.) However, if you have any regular, useful work to perform, you really should write a UNIX device driver. Steve Dyer dyer@harvard.HARVARD.EDU dyer@spdcc.COM aka {harvard,wanginst,ima,ihnp4,bbn,m2c}!spdcc!dyer