Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!osuunx.ucc.okstate.edu!moe.ksu.ksu.edu!ux1.cso.uiuc.edu!howland.reston.ans.net!noc.near.net!uunet!pipex!warwick!uknet!mcsun!sun4nl!tuegate.tue.nl!svin09.info.win.tue.nl!wzv.win.tue.nl!gvr.win.tue.nl!guido
From: guido@gvr.win.tue.nl (Guido van Rooij)
Newsgroups: comp.os.386bsd.development
Subject: Re: /dev/mem and /sys/i386/i386/mem.c
Date: 29 May 1993 18:33:02 GMT
Organization: Eindhoven University of Technology, The Netherlands
Lines: 130
Distribution: world
Message-ID: <1u8a8u$o8m@wzv.win.tue.nl>
References: <1993May28.222533.24315@ucsu.Colorado.EDU>
NNTP-Posting-Host: gvr.win.tue.nl
galbrait@rintintin.Colorado.EDU (GALBRAITH JOHN) writes:
>I was wondering if somebody could clarify what happens when
>you read/write to /dev/mem in the locations that are supposed
>to be mapped to the I/O bus. The man page says something
>about I/O being located in /dev/mem between 0x10000 to 0xa0000. When
>I look at /sys/i386/i386/mem.c, I can't see how this is going to
>work. Isn't there normal memory at those locations? mem.c does
>not appear to be written to support writes anyway, just reads.
>
>On a similar note, has anybody patched mem.c to support /dev/ioportb
>and /dev/ioportw? I have hacked a little bit on this without
>success. My test program opens a file on /dev/ioportb, does an
>lseek(), and then a write() (writes one byte only.) The
>file is successfully opened, the lseek() call returns correctly with
>no error message or anything, and then it goes to mem.c. The
>uio structure is not correct at this point. The uio_rw field is
>correct, I believe, as is the direction (sorry, I can't remember the
>name of the field.) However, the uio_offset field is way off as
>is the uio_resid. Shouldn't the lseek() call have set the uio_offset
>field? Also, the call to write specifies one byte only (the third
>parameter is a 1) and should set the uio_resid to 1, right?
>
>It ends up trying to do many writes to some random address, and
>all hell breaks loose. What is wrong with my reasoning?
>
>thanks,
>john galbraith
>galbrait@rintintin.colorado.edu
A lot more work needs to be done then just undefining the code in there.
For example, the correct privs for inb/outb's needs to be recorded on
a per process base. And even then, the way this is done in the notdef'ed
code in mem.c is a bit questionable: in this way, each inb or outb is
done in kernel. With a proper interface for setting the bitmap in the TSS
(i.e. specifying, per process, which ports are allowed to read/write),
you can do the inb/outb's in user mode, and is thus much cheaper.
There is a quick hack that gives a process io permission for *every*
port whenever /dev/mem is opened by that process.
Currently that is, according to me, the best solution.
I am told that in 386bsd 0.2 the io system is improved.
-Guido
Here's the patch: (note that I am not using /dev/mem but another
minor for that purpose, but it's quite easy to change that (just
take another minor number))
*** machdep.c~ Fri Apr 30 19:31:38 1993
--- machdep.c Tue May 4 22:11:11 1993
***************
*** 975,980 ****
--- 975,984 ----
proc0.p_addr->u_pcb.pcb_tss.tss_esp0 = (int) kstack + UPAGES*NBPG;
proc0.p_addr->u_pcb.pcb_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL) ;
_gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
+
+ ((struct i386tss *)gdt_segs[GPROC0_SEL].ssd_base)->tss_ioopt =
+ (sizeof(tss))<<16;
+
ltr(_gsel_tss);
/* make a call gate to reenter kernel with */
*** mem.c~ Tue Dec 24 23:23:37 1991
--- mem.c Wed May 5 20:52:10 1993
***************
*** 50,57 ****
--- 50,59 ----
#include "systm.h"
#include "uio.h"
#include "malloc.h"
+ #include "proc.h"
#include "machine/cpu.h"
+ #include "machine/psl.h"
#include "vm/vm_param.h"
#include "vm/lock.h"
***************
*** 60,65 ****
--- 62,103 ----
#include "vm/vm_prot.h"
extern char *vmmap; /* poor name! */
+ /*ARGSUSED*/
+ mmclose(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+ {
+ struct syscframe *fp;
+
+ switch (minor(dev)) {
+ case 14:
+ fp = (struct syscframe *)curproc->p_regs;
+ fp->sf_eflags &= ~PSL_IOPL;
+ break;
+ default:
+ break;
+ }
+ return(0);
+ }
+ /*ARGSUSED*/
+ mmopen(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+ {
+ struct syscframe *fp;
+
+ switch (minor(dev)) {
+ case 14:
+ fp = (struct syscframe *)curproc->p_regs;
+ fp->sf_eflags |= PSL_IOPL;
+ break;
+ default:
+ break;
+ }
+ return(0);
+ }
/*ARGSUSED*/
mmrw(dev, uio, flags)
dev_t dev;
--
Guido van Rooij | Internet: guido@gvr.win.tue.nl
Bisschopsmolen 16 | Phone: ++31.40.461433
5612 DS Eindhoven | ((12+144+20)+3*sqrt(4))/7
The Netherlands | +(5*11)=9^2+0