usenet@carssdf.UUCP (John Watson) (07/26/90)
Is there any way for a user to do direct (INP/OUTP) io to devices similar to the printer port without writing a device driver? These instructions normally result in a protection violation. John Watson rutgers!carssdf!usenet
glenn@extro.ucc.su.OZ.AU (Glenn Geers) (07/27/90)
From article <251@carssdf.UUCP>, by usenet@carssdf.UUCP (John Watson): > > Is there any way for a user to do direct (INP/OUTP) io to devices > similar to the printer port without writing a device driver? These > instructions normally result in a protection violation. A lot of people would like to know how to do this. It turns out that it can be done on Xenix 2.2.2 and up using an ioctl. Only root can perform the call and so programs which use it must be set uid 0. The primary application is graphics - the ioctl is part of the graphics stuff in Xenix. I don't think it will work under SCO UNIX for general (non-graphics) i/o. Anyway, enough waffle. Here's how to do it: /* ** I don't claim this code does anything useful. ** Do with it what you will ** I disclaim copyright ** G. Geers */ #include <stdio.h> #include <sys/machdep.h> main() { int fd; fd = open("/dev/null", 2); /* open a useful file */ ioctl(fd, IOPRIVL, 1); /* ** Guess what? ** You've just set the i/o privelege level of the current process ** to 3. You can write anywhere in the i/o address space! ** Be *careful*. Make 100% sure you have your i/o addresses correct ** otherwise you might trash your hard disk. */ write_to_port(); ioctl(fd, IOPRIVL, 0); /* reset to normal */ } write_to_port() should be an assembler routine using ins/outs or whatever. I use gcc so I like to embed my assembler inside C code using asm(). That way stack frames and returns can be done easily. Also tests can be done in C and it is possible to assign variables to specific 386 registers. If you are using masm you have to do this stuff yourself. Whenever I write/port graphics applications I produce two (#ifdef'd) versions one which doesn't write to hardware directly and one which does. For some applications (e.g. dvivga) high speed writing of individual pixels is not required but for others (e.g. ghostscript) it is. So I comprimise; security versus speed. DISCLAIMER Please nnote: I have *not* used this for anything except graphics so I don't claim that it will work. And if you trash your hard disk or do anything else nasty I'm not responsible. Enjoy, Glenn p.s. If anyone does have courage enough to try non-graphics applications I'd like to hear of the results glenn@extro.ucc.su.oz.au -- Glenn Geers | "So when it's over, we're back to people. Department of Theoretical Physics | Just to prove that human touch can have The University of Sydney | no equal." Sydney NSW 2006 Australia | - Basia Trzetrzelewska, 'Prime Time TV'
pgd@bbt.se (P.Garbha) (07/27/90)
In article <1990Jul26.232311.21450@metro.ucc.su.OZ.AU> glenn@extro.ucc.su.OZ.AU (Glenn Geers) writes: >From article <251@carssdf.UUCP>, by usenet@carssdf.UUCP (John Watson): >> >> Is there any way for a user to do direct (INP/OUTP) io to devices >> similar to the printer port without writing a device driver? These >> instructions normally result in a protection violation. > >A lot of people would like to know how to do this. >It turns out that it can be done on Xenix 2.2.2 and up using an ioctl. Only I think there exist another possibility. Create a dev file with major number 4 (same as mem), and minor numbers according to the following list: 3 -- for byte in/out to port 4 -- for word in/out to port 5 -- for lword in/out to port These devices will go to i/o device space. So lseek to the address you want to do input/output to, and read/write to one of these ports. Now this is untested, and undocumented (at least I have not found the documentation for it. Maybe it is there, somewhere). If someone (from SCO?) could confirm if it is right, or wrong, it would be nice. If this is not right, can someone tell what minor device number 3,4 & 5 actually are doing on the mem device?
jak@sactoh0.UUCP (Jay A. Konigsberg) (07/29/90)
From article <251@carssdf.UUCP>, by usenet@carssdf.UUCP (John Watson): > > Is there any way for a user to do direct (INP/OUTP) io to devices > similar to the printer port without writing a device driver? These > instructions normally result in a protection violation. A lot of people would like to know how to do this. It turns out that it can be done on Xenix 2.2.2 and up using an ioctl. Only The following code works on Xenix 2.3.2 (386), Unix Sys V (3B2) and several other Unix platforms. ==== The code could use a little cleaning up, but it works as stated. See termio(7) and ioctl(2) for further information. -------------------------------------------------------------------------- #include <termio.h> main() { struct termio ttyset; unsigned short holdvalue; unsigned char holdnext; /* enter raw mode */ ioctl(0, TCGETA, &ttyset); holdvalue=ttyset.c_lflag; holdnext=ttyset.c_cc[4]; ttyset.c_cc[4] = (unsigned char)1; ttyset.c_lflag &= ~ICANON; ioctl(0, TCSETAW, &ttyset); /* reset terminal charastics */ ttyset.c_lflag = holdvalue; ttyset.c_cc[4] = holdnext; ioctl(0, TCSETAW, &ttyset); return(0); } -- ------------------------------------------------------------- Jay @ SAC-UNIX, Sacramento, Ca. UUCP=...pacbell!sactoh0!jak If something is worth doing, its worth doing correctly.
glenn@extro.ucc.su.OZ.AU (Glenn Geers) (07/30/90)
Yes, creating /dev/blah with major number 4 and minor number [3,4,5] works as advertised. You lseek in to the device address and then use write or read as the case may be. However, you still don't get around the system call overhead. This can only be achieved by issuing ioctl(fd, IOPRIVL, 1) (1 system call, finished) and then banging away at i/o ports in assembler. For *fast* graphics the latter technique is IMHO essential since even 1 system call per pixel (you need at *least* 2 an lseek and a write or an ioctl) gives rise to a horrible slow down when writing coloured pixels (not a colour plane, each pixel is a different colour). Glenn -- Glenn Geers | "So when it's over, we're back to people. Department of Theoretical Physics | Just to prove that human touch can have The University of Sydney | no equal." Sydney NSW 2006 Australia | - Basia Trzetrzelewska, 'Prime Time TV'
chapman@sco.COM (Brian Chapman) (08/01/90)
glenn@extro.ucc.su.OZ.AU (Glenn Geers) writes: > <...> However, you still don't get around the system >call overhead. This can only be achieved by issuing ioctl(fd, IOPRIVL, 1) >(1 system call, finished) and then banging away at i/o ports in assembler. For >*fast* graphics <...> Yes, direct use of IN & OUT 386 instructions is possible from user space after giving the [EV]GA_IOPRIVL command. BUT... this is only for use with the video I/O ports. You will find that Xenix lets to access all I/O ports but SCO _Unix_ behaves in the more restrictive manner. -- Chapman -- Brian Chapman uunet!sco!chapman Pay no attention to the man behind the curtain!