[comp.sys.ibm.pc] How do I access the ports?

dtsai@uvicctr.UUCP (David Tsai) (08/04/87)

Can anyone help me?  I have been trying to write to ports under the XENIX
operating system and have gotten nowhere in the last month.  The routines 
I want to use are:
 
		out( ), outb( ), in(port):word, inb(port):byte,

and are given in the SCO XENIX System V Development System manual, 
'Programmer's Guide II', pp 8-11 of 'Writing Device Drivers'; and in the IBM
XENIX Version 2.00, pp 10-12 and 10-13 of 'Application Development Guide'.
I know I can write to the ports because:

	1.  there is no problem with the hardwares (had them checked),
	2.  both the SCO XENIX System V and IBM XENIX manuals state that 
	    this can be done,
	3.  the sample codes given in the manuals use the routines.

But I always get unresolved external reference error when linking. 
My problems are: 

	1. I am not sure which .h files are needed,
	2. or which .o file(s) (or Libraries) I must link with.


And I have tried getting around using the 'supplied' routines by writing my own
assembler routines, but this method gives me segmentation violation error
everytime the 'out'and 'in' assembler instructions of the 80286 are encountered.
Does this mean that I have to configure the ports that I want to used?
Do I used mknode?  If I configure the ports, then can I use 'open( )' calls 
and access the ports like a file?  
 

I can help but think I am off on some tangent somewhere and any help, hints, 
source codes or whatever to get me back on track will be greatly appreciated.  


Thanks (in advance).

-- 

--
David Tsai
...!{uw-beaver!ssc-vax, ubc-vision}!uvicctr!dtsai
dtsai@uvicctr.nrl-css.arpa
dtsai@uvunix.bitnet
dtsai@uvunix.uvic.cdn

dyer@athena.mit.edu (Steve Dyer) (08/05/87)

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

mikep@ism780c.UUCP (Michael A. Petonic) (08/05/87)

In article <302@uvicctr.UUCP> dtsai@uvicctr.UUCP (David Tsai) writes:
>Can anyone help me?  I have been trying to write to ports under the XENIX
>operating system and have gotten nowhere in the last month.  The routines 
>I want to use are:
> 
>		out( ), outb( ), in(port):word, inb(port):byte,
>
>and are given in the SCO XENIX System V Development System manual, 
>'Programmer's Guide II', pp 8-11 of 'Writing Device Drivers'; and in the IBM
>XENIX Version 2.00, pp 10-12 and 10-13 of 'Application Development Guide'.
> ...

Well, it's been a while since I've looked at the Xenix Device Driver's
Guide, but that code is to be run in Kernel mode and not in 
user mode.  WHat this means is that the code that you write that
accesses ports has got to be run in kernel mode, which means that it
has to be a part of the operating system.

There are two ways to do this:  You can set up your own device driver
for a device to handle in/output to and from ports.  You could call
this /dev/ports or something.  Follow the device driver guide.  You
could then control the ports through specific ioctl()'s to that
device.

OR you could make a new system call that does the input/output from
ports.  This is probably tougher than a device driver and impossible
without the kernel sources.  

Hope this is of help.

{seismo|sdcrdcf}!ism780c!mikep  
MTS, INTERACTIVE Systems Corp.
2401 Colorado Blvd.
Santa Monica, CA. 90404

ray@madnix.UUCP (Ray P. Hill) (08/07/87)

In article <1235@bloom-beacon.MIT.EDU> dyer@spdcc.COM (Steve Dyer) writes:
>Several hopefully obvious caveats: first, because these devices are
>undocumented, there's no guarantee that they will remain in future
>releases of XENIX.
>
>Steve Dyer
>dyer@harvard.HARVARD.EDU
>dyer@spdcc.COM aka {harvard,wanginst,ima,ihnp4,bbn,m2c}!spdcc!dyer

This feature still works great in SCO Xenix 2.2.1 .
Thanks for the "magic".

						Ray Hill
-- 
UUCP: {harvard,seismo,rutgers}!uwvax!nicmad!madnix!ray
            {ihnp4,decvax,terminus}/

lee@minnow.UUCP (08/10/87)

In article <302@uvicctr.UUCP> dtsai@uvicctr.UUCP (David Tsai) writes:
>
>Can anyone help me?  I have been trying to write to ports under the XENIX
>operating system and have gotten nowhere in the last month.  The routines 
>I want to use are:
> 
>		out( ), outb( ), in(port):word, inb(port):byte,
>

   I built my own card for my IT and had the same need as you do, to 
have the in() and out() functions.

  I found that the only way to do this is to write a device driver, which
I did successfuly a few months ago.

 Do you need help in writing the driver or do you need help in gener-
ating a new kernel.  I think I can help with either.  If its any help,
I could gather up all my source code and mail it to you.  Let me know.

   Gene W. Lee
    (612) 635-6334
 
-- 
Gene Lee  UUCP: ...ihnp4!{meccts,dayton,rosevax}!ems!minnow!lee
UNISYS Corporation     ATT:  (612) 635-6334
If not for the courage of the fearless crew, the minnow would be lost.