Ram disk on 4.x (or Ultrix)
Tom Anderson
toma at fluke.UUCP
Thu Apr 17 10:25:28 AEST 1986
>
> 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 at 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
More information about the Comp.unix.wizards
mailing list