NEVILLE%umass-cs.csnet@csnet-relay.arpa (03/30/86)
We have just added an 8 meg. board to our Micro-Vax II running Ultrix 1.1 and since we are a small group (usually only a dozen user processes) we find that we are running with about 25% memory usage. Our job mix lends itself well to speed increase from RAM 'disk' emulation, in particular we would like to put /tmp there or better yet make a /ramtmp that could be tried before the real /tmp. i would also like to put some images like emacs, cc, ccom, more, etc. there. Has anyone done a driver for a RAM 'disk' device? i will be happy to summarize responses to the list. -neville Internet: neville@umass.csnet
meier@srcsip.UUCP (Christopher Meier) (04/08/86)
In article <2213@brl-smoke.ARPA> NEVILLE%umass-cs.csnet@csnet-relay.arpa writes: > >Has anyone done a driver for a RAM 'disk' device? > >i will be happy to summarize responses to the list. > > Internet: neville@umass.csnet I would be interested in seeing the summary. Christopher Meier Honeywell S&RC/SIP/AIT {philabs,ihnp4!mmm}!srcsip!meier -- Christopher Meier Honeywell S&RC/SIP/AIT {philabs,ihnp4!mmm}!srcsip!meier
toma@fluke.UUCP (Tom Anderson) (04/17/86)
> > We have just added an 8 meg. board to our Micro-Vax II running Ultrix 1.1 > and since we are a small group (usually only a dozen user processes) we > find that we are running with about 25% memory usage. Our job mix lends > itself well to speed increase from RAM 'disk' emulation, in particular > we would like to put /tmp there or better yet make a /ramtmp that could > be tried before the real /tmp. i would also like to put some images > like emacs, cc, ccom, more, etc. there. > > Has anyone done a driver for a RAM 'disk' device? > > i will be happy to summarize responses to the list. > > -neville > > Internet: neville@umass.csnet A few months ago, I put together a primitive ram disk driver for my Sun-2/120 (I don't recall which version of Sun Unix I was running at the time) to see if I could speed up button menu response by putting menu files there (it didn't; evidently the slow response was principally due to swapping in various pieces of the suntools chameleon). It's rather small, but I've included two sizes so it should be obvious how to scale it to any size you want. It is primitive in that it does not understand anything about special block numbers, so that it can't "fake" the i-list, etc. and thus achieve better "disk" storage efficiency (it is pretty absymal for small sizes). I did this so that it would be impervious to file sys. changes by Sun. You'll definitely want to experiment a bit with the file system parameters. (1) To install the driver, add the following lines to /sys/conf/files.sun (or whatever file your machine uses): ramdisk/rd64.c optional rdsmall ramdisk/rd512.c optional rdlarge Note: files.sun is in alphabetic order. I have no idea if this is necessary, having noticed it at the outset and never having tried to violate it. (2) Next, your machine should have /sys/machine symbolically linked to /sun or whatever. Modify /sys/{sun,whatever}/conf.c according to the following: (2a) At the appropriate point above the declaration for bdevsw[], add: #include "rdsmall.h" #include "rdlarge.h" #if NRDSMALL > 0 | NRDLARGE > 0 int rdstrategy(), rdread(), rdwrite(); #define rdopen nulldev #define rdclose nulldev #else #define rdstrategy nodev #define rdopen nodev #define rdclose nodev #define rdread nodev #define rdwrite nodev #endif (2b) In bdevsw[], add a line for the block device, using whatever major device number (call it BDN) you think is safe: struct bdevsw bdevsw[] = { . . . { rdopen, rdclose, rdstrategy, nodev, /*9*/ 0, 0 }, }; (2c) In cdevsw[], add a line for the character device (call it CDN): struct cdevsw cdevsw[] = { . . . { rdopen, rdclose, rdread, rdwrite, /*36*/ nodev, nodev, nulldev, 0, nodev, 0, }, }; (3) Add a line to your configuration description file in /sys/conf: pseudo-device rdlarge1 OR pseudo-device rdsmall1 where you can only have one size or the other, not both (I found it convenient to set it up this way - you may prefer to only have one driver and re-define the size). Also, if want more than one ram disk partition, change the trailing digit. (4) Add entries in /dev for the ram disk: /etc/mknod rd0 b BDN 0 ; chmod 600 rd0 /etc/mknod rrd0 c CDN 0 ; chmod 600 rrd0 (6) Append the following lines to /etc/rc.local, modifying the mount point, adding appropriate lines if you have more than one partition you wish to use as a file system, and modifying the file sys. parameters appropriately: (for the 64K ram disk): /etc/mkfs /dev/rrd0 128 128 1 4096 512 1 10 60 1024 /etc/mount /dev/rd0 /ram0 /bin/rm /ram0/lost+found (for the 512K ram disk): /etc/mkfs /dev/rrd0 1024 128 1 4096 512 1 10 60 1024 /etc/mount /dev/rd0 /ram0 /bin/rm /ram0/lost+found (7) Finally, create the directory /sys/ramdisk, extract the following shell archive there, and build your new kernel. Naturally, neither I nor John Fluke Mfg. Co. can assume any responsibility for damage, mutations, premature balding, etc. caused by using this driver. However, this is taken directly from the /sys arena on my machine, where it does work. If you have any problems, bugs, excess money, lucrative job offers, etc., feel free to drop a line. Tom Anderson John Fluke Mfg. Co., Inc. PO Box C9090, MS 245F Everett, Wa. 98206 (206) 356-5895 # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by toma on Wed Apr 16 16:18:50 PST 1986 # Contents: rd512.c rd64.c echo x - rd512.c sed 's/^@//' > "rd512.c" <<'@//E*O*F rd512.c//' /* * rd512.c - 512k ram disk driver for 4.2bsd Unix * * 1/25/86 - toma - creation date */ /* #define RDDEBUG */ #include "rdlarge.h" #include "../h/param.h" #include "../h/buf.h" #include "../h/user.h" #include "../h/uio.h" #define RDNUMBLKS 1024 /* block count of each "ram disk" */ char rdarray[NRDLARGE][RDNUMBLKS][DEV_BSIZE] ; /* the "ram disk" */ struct buf rrdbuf [NRDLARGE] ; /* buffers for raw i/o */ /* * strategy routine for block dev. i/f (no open, close necessary) */ rdstrategy (bp) register struct buf * bp; { int unit; register long count; register char * cp, * rdp ; unit = minor(bp->b_dev); /* check for illegal minor dev. num. */ if (unit >= NRDLARGE) { bp->b_flags |= B_ERROR ; /* check for reads or writes past the end of rdarray for that unit */ } else if ( &rdarray[unit][bp->b_blkno][bp->b_bcount-1] - &rdarray[unit][0][0] >= RDNUMBLKS * DEV_BSIZE ){ bp->b_flags |= B_ERROR ; printf("rd: read/write past end of device attempted\n"); } else { #ifdef RDDEBUG printf("rdarray size: %d\n", sizeof(rdarray)); printf("rd: bcount: %d, blkno: %d\n", bp->b_bcount, bp->b_blkno); bp->b_resid = 0L ; iodone(bp); return; #endif rdp = rdarray[unit][bp->b_blkno]; cp = bp->b_un.b_addr; count = bp->b_bcount; if ((bp->b_flags & (B_READ|B_WRITE)) == B_READ) { while (count--) *cp++ = *rdp++; } else { while (count--) *rdp++ = *cp++; } bp->b_resid = 0L ; } iodone(bp); } /* * Raw I/O I/F routines: read, write (nulldev for open, close * in conf.c) */ rdread (dev, uio) dev_t dev; struct uio * uio; { int unit = minor(dev); if (unit >= NRDLARGE) return (ENXIO); return (physio(rdstrategy, &rrdbuf[unit], dev, B_READ, minphys, uio)); } rdwrite (dev, uio) dev_t dev; struct uio * uio; { int unit = minor(dev); if (unit >= NRDLARGE) return (ENXIO); return (physio(rdstrategy, &rrdbuf[unit], dev, B_WRITE, minphys, uio)); } @//E*O*F rd512.c// chmod u=rw,g=r,o=r rd512.c echo x - rd64.c sed 's/^@//' > "rd64.c" <<'@//E*O*F rd64.c//' /* * rd64.c - 64k ram disk driver for 4.2bsd Unix * * 1/25/86 - toma - creation date */ /* #define RDDEBUG */ #include "rdsmall.h" #include "../h/param.h" #include "../h/buf.h" #include "../h/user.h" #include "../h/uio.h" #define RDNUMBLKS 128 /* block count of each "ram disk" */ char rdarray[NRDSMALL][RDNUMBLKS][DEV_BSIZE] ; /* the "ram disk" */ struct buf rrdbuf [NRDSMALL] ; /* buffers for raw i/o */ /* * strategy routine for block dev. i/f (no open, close necessary) */ rdstrategy (bp) register struct buf * bp; { int unit; register long count; register char * cp, * rdp ; unit = minor(bp->b_dev); /* check for illegal minor dev. num. */ if (unit >= NRDSMALL) { bp->b_flags |= B_ERROR ; /* check for reads or writes past the end of rdarray for that unit */ } else if ( &rdarray[unit][bp->b_blkno][bp->b_bcount-1] - &rdarray[unit][0][0] >= RDNUMBLKS * DEV_BSIZE ){ bp->b_flags |= B_ERROR ; printf("rd: read/write past end of device attempted\n"); } else { #ifdef RDDEBUG printf("rdarray size: %d\n", sizeof(rdarray)); printf("rd: bcount: %d, blkno: %d\n", bp->b_bcount, bp->b_blkno); bp->b_resid = 0L ; iodone(bp); return; #endif rdp = rdarray[unit][bp->b_blkno]; cp = bp->b_un.b_addr; count = bp->b_bcount; if ((bp->b_flags & (B_READ|B_WRITE)) == B_READ) { while (count--) *cp++ = *rdp++; } else { while (count--) *rdp++ = *cp++; } bp->b_resid = 0L ; } iodone(bp); } /* * Raw I/O I/F routines: read, write (nulldev for open, close * in conf.c) */ rdread (dev, uio) dev_t dev; struct uio * uio; { int unit = minor(dev); if (unit >= NRDSMALL) return (ENXIO); return (physio(rdstrategy, &rrdbuf[unit], dev, B_READ, minphys, uio)); } rdwrite (dev, uio) dev_t dev; struct uio * uio; { int unit = minor(dev); if (unit >= NRDSMALL) return (ENXIO); return (physio(rdstrategy, &rrdbuf[unit], dev, B_WRITE, minphys, uio)); } @//E*O*F rd64.c// chmod u=rw,g=r,o=r rd64.c exit 0