Return to BSD News archive
Newsgroups: comp.unix.bsd Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!osuunx.ucc.okstate.edu!moe.ksu.ksu.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!cs.utexas.edu!uunet!super!rminnich From: rminnich@super.org (Ronald G Minnich) Subject: Re: How do I set up a 2 Meg sharable area between device driver and user? Message-ID: <1994Jan5.033641.21494@super.org> Sender: news@super.org (USENET News System) Nntp-Posting-Host: descartes Organization: Supercomputing Research Center, Bowie, MD References: <2gc1h1$hns@senator-bedfellow.MIT.EDU> <2gd3ts$fc6@u.cc.utah.edu> Date: Wed, 5 Jan 1994 03:36:41 GMT Lines: 84 In article <2gd3ts$fc6@u.cc.utah.edu>, A Wizard of Earth C <terry@cs.weber.edu> wrote: >In article <2gc1h1$hns@senator-bedfellow.MIT.EDU> Glen Schaff <glens@space.mit.edu> writes: >>I am working on a SUN 4.1.1 architecture, and have been trying to set up >>a 2 meg sharable memory region, that a user program can read, and my >>device driver writes. (finding documentation for this is about as easy as >You will need to pin the pages, then you will need to comunicate their >location to the driver. In all honesty, you are better of allocating >*contiguous* wired memory in the driver itself, and then mapping it wow, it is not this hard, we have been doing this for years. Here is some sample code that is typical of the breed. This is from a pseudo-device driver I wrote that supports the TRACE option in SUNOS 4.x (they never shipped the driver). This may not lint, and I don't care, it was a quick piece of work to test something out. It has worked on sun3, sun3x, sun4, and sun4c machines however. In our driver, the driver allocs trace buffers and the user can map those buffers in. Thus walking trace records is very fast. Here is the kind of code that allocates the trace buffers: (this gets 1 page, the 0 means no sleep, there is manifest constant which i can never remember the name of but is probably KMEM_NOSLEEP) (It gets contiguous pages in kernel virtual memory, they don't need to be physically contiguous, and pinning only really matters if dma is going to happen. Is it in your case? If so, check out pageio_setup and bp_mapin and friends.) userinfo = (struct userinfo *) getpages(1,0); /* get it, no sleep */ if (userinfo == NULL) Here is the mmap function. Note that you can interpret offset ANY WAY YOU WANT. This is useful, as we use off 0 to get the the records describing the trace buffer, and 1 and up to get to the buffer. All you have to do is returning a kpfnum (kernel page frame number) to the function calling you. TRDPRINT is a debug macro, usually off :0) trmmap(dev, off, prot) dev_t dev; off_t off; int prot; { register struct tr_device *trdev; int kpfnum = -1; int unit = TRUNIT(dev); int m = major(dev), mi = minor(dev); extern struct userinfo *userinfo; extern struct trace_rec *tracebuffer; extern int ntbufpages; TRDPRINT("trmmap:dev %d major %d minor %d off %x prot %x = req %d\n", dev, m, mi, off, prot, off >> PAGESHIFT); if (btop(off) == 0) /* first page */ { kpfnum = hat_getkpfnum(userinfo); TRDPRINT("kpfnum for trace stats page is 0x%x\n", kpfnum); } else if (btop(off) <= ntbufpages) /* data pages */ { kpfnum = hat_getkpfnum((caddr_t) tracebuffer + ptob(btop(off)-1)); TRDPRINT("kpfnum for trace data page is 0x%x\n", off); } else printf("off 0x%x is invalid for ntbufpages 0x%x\n", off, ntbufpages); return kpfnum; } If you need sample code to dynamically load stuff, let me know. Now the solaris version, well :-) ron -- rminnich@super.org | IBM wants to run ATM at 25 mbits/sec, or 1/2 of OC-1 (301)-805-7451 or 7312 | This would give them OC/2 for OS/2 on a PS/2