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