Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 (Tek) 9/28/84 based on 9/17/84; site motel6.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!vax135!cornell!uw-beaver!tektronix!reed!motel6!keith From: keith@motel6.UUCP (Keith Packard) Newsgroups: net.bugs.2bsd Subject: ramdisk driver for 2.9 Message-ID: <195@motel6.UUCP> Date: Mon, 18-Nov-85 06:28:59 EST Article-I.D.: motel6.195 Posted: Mon Nov 18 06:28:59 1985 Date-Received: Wed, 20-Nov-85 00:16:40 EST Distribution: net Organization: 5440 SE 41st, Portland, OR Lines: 247 I have just completed a driver that makes a segment of memory into a pseudo disk drive. It was rather simple to do but I thought that someone might like to see just how it was done. The device driver itself is very short and straight forward. The remaining modifications were also fairly straight forward if you know where to put the hooks in. The description that follows is about the 2.9 distribution that I received from berkeley about a year or so ago. It can be applied to the bostic 2.9 distribution although I am still working on getting that system running (I'm bringing up the networking code on my 11/73 - more details about that when it works) and don't have that code on-line (I'm hacking on that on another computer). The allocation of the block of memory occurs in the startup code along with the allocation for disk buffers and clists. The constant NRAM specifies how many 512-byte blocks to allocate for the ramdisk and is defined in "ram.h": ********ram.h********* /* * number of blocks for a ram disk */ # define NRAM 512 ********EOF*********** accordingly, include ram.h in machdep.c and add a declaration at the top of startup: ****machdep.c***** /* * Machine dependent startup code */ startup() { register memaddr i, freebase; + #if NRAM > 0 + unsigned ramstart; + #endif extern end; ***** then put in the allocation code: ***** #ifdef UCB_CLIST #define C (nclist * sizeof(struct cblock)) if ((clststrt = malloc(coremap, btoc(C))) == 0) panic("clists"); maxmem -= btoc(C); clstaddr = ((ubadr_t) clststrt) << 6; #undef C #else clstaddr = (ubadr_t) &cfree; #endif UCB_CLIST + #if NRAM > 0 + #define C (NRAM << 3) + if ((ramstart = malloc (coremap, C)) == 0) + panic ("ramdisk"); + maxmem -= C; + raminit (ramstart); + #undef C + #endif NRAM #if defined(PROFILE) && !defined(ENABLE34) maxmem -= msprof(); #endif defined(PROFILE) && !defined(ENABLE34) ****** Then fix c.c to include a ramdisk entry. Your c.c will probably be different as I have also written a driver for my DTC/Xebec winchester controller which precedes the ramdisk entries. ******* c.c ****** + #include "ram.h" + #if NRAM > 0 + int ramstrategy(), ramread(), ramwrite(); + extern struct buf ramtab; + #define ramopen nulldev + #define ramclose nulldev + #define _ramtab &ramtab + #else + #define ramopen nodev + #define ramclose nodev + #define ramstrategy nodev + #define ramread nodev + #define ramwrite nodev + #define _ramtab ((struct buf *) NULL) + #endif NRAM #include "rl.h" #if NRL > 0 int rlstrategy(), rlread(), rlwrite(); extern struct buf rltab; #define rlopen nulldev #define rlclose nulldev #define _rltab &rltab #else #define rlopen nodev #define rlclose nodev #define rlstrategy nodev #define rlread nodev #define rlwrite nodev #define _rltab ((struct buf *) NULL) #endif NRL ********** bdevsw *********** #if NRX > 0 rxopen, rxclose, rxstrategy, nulldev, _rxtab, /* rx = 10 */ #else rx2open, rx2close, rx2strategy, nulldev, _rx2tab, /* rx2 = 10 */ #endif xeopen, xeclose, xestrategy, nulldev, _xetab, /* xe = 11 */ + ramopen, ramclose, ramstrategy, + nulldev, _ramtab, /* ram = 12 */ }; ************ cdevsw ************* #if NRX > 0 rxopen, rxclose, rxread, rxwrite, rxioctl, nulldev, 0, /* rx = 22 */ #else rx2open, rx2close, rx2read, rx2write, rx2ioctl, nulldev, 0, /* rx2 = 22 */ #endif xeopen, xeclose, xeread, xewrite, nodev, nulldev, 0, /* xe = 23 */ + ramopen, ramclose, ramread, ramwrite, + nodev, nulldev, 0, /* ram = 24 */ }; ********************** Now install the driver in ../dev/ram.c: *************** ram.c ************ /* * SCCS id @(#)ram.c 2.1 (motel6) 11/18/85 */ /* * ram disk driver */ #include "ram.h" #if NRAM > 0 #include "param.h" #include #include #include #include #include struct buf rrambuf; struct buf ramtab; /* * starting click of ram buffer */ unsigned ramclick; # define bltocl(b) (((b)<<3) + ramclick) ramattach(addr, unit) char *addr; { return(1); } raminit (base) unsigned base; { ramclick = base; } ramstrategy(bp) register struct buf *bp; { int ramc, bufc, count; if (!ramclick) { goto bad; } if(bp->b_blkno + (bp->b_bcount>>BSHIFT) >= NRAM) { if((bp->b_blkno == NRAM) && (bp->b_flags & B_READ)) bp->b_resid = bp->b_bcount; else { bad: ; bp->b_error = ENXIO; bp->b_flags |= B_ERROR; } iodone(bp); return; } /* * just copy the whole block using * the l.s copy routine, if possible */ if ((bp->b_un.b_addr & 63) || (bp->b_bcount & 63)) { goto bad; } bufc = ((bp->b_un.b_addr >> 6) & 01777); bufc += bp->b_xmem << 10; ramc = bltocl (bp->b_blkno); count = bp->b_bcount >> 6; if (bp->b_flags & B_READ) copy (ramc, bufc, count); else copy (bufc, ramc, count); iodone (bp); } ramread(dev) dev_t dev; { physio(ramstrategy, &rrambuf, dev, B_READ); } ramwrite(dev) dev_t dev; { physio(ramstrategy, &rrambuf, dev, B_WRITE); } #endif NRAM ***************EOF**************** that should be it. make a new kernel, boot it and make the devices in /dev. Note that the raw device does not support completely general I/O - it is very possible to break things doing raw i/o. I suggest never using the raw device. keith packard tektronix!reed!motel6!keith