💾 Archived View for spam.works › mirrors › textfiles › computers › reagen.asc captured on 2023-12-28 at 17:21:07.
View Raw
More Information
⬅️ Previous capture (2023-06-14)
-=-=-=-=-=-=-
_RAM DISK DRIVER FOR UNIX_
by Jeff Reagen
[LISTING ONE]
/* The following is a RAM disk driver developed for Unix Sys V/386
* release 3.2. -- Author: Jeff Reagen 05-02-90.
#include "sys/types.h"
#include "sys/param.h"
#include "sys/immu.h"
#include "sys/fs/s5dir.h"
#include "sys/signal.h"
#include "sys/user.h"
#include "sys/errno.h"
#include "sys/cmn_err.h"
#include "sys/buf.h"
#define RD_SIZE_IN_PAGES 0x100L /* 256 4K pages => 1 MB */
#define RD_MAX 1 /* Max RAM Disks */
#define RAMDISK(x) (int)(x&0x0F) /* Ram disk number from dev */
#define DONT_SLEEP 1 /* sptalloc parameter */
/* For ioctl routines.
#define RD_GETSIZE 1 /* return size of RAM disk */
struct rd_getsize { /* Structure passed to rdioctl */
daddr_t sectors;
long in_bytes;
};
/* Valid states for the RAM disk driver.
#define RD_UNDEFINED 0x0000 /* Disk has not been setup */
#define RD_CONFIGURED 0x0001 /* Configured disk */
#define RD_OPEN 0x0002 /* Indicates disk has been opened */
/* The RAM disk is created iff the size field has been defined. Since
* sptalloc only allocates pages, make sure the size is
* some multiple of page size (4096).
struct ram_config {
int state; /* current state */
caddr_t virt; /* virtual address of RAM disk */
long size; /* RAM disk size in units of 4K */
};
struct ram_config rd_cfg = {RD_UNDEFINED, (caddr_t)0, RD_SIZE_IN_PAGES};
extern caddr_t sptalloc();
/* rdinit - initialize the RAM disk.
*/
rdinit (dev)
dev_t dev;
{
/* Has a RAM disk been defined? */
if (rd_cfg.size == 0)
{
/* Just return silently - ram disk is not configured. */
return 0;
}
/* Last parameter 1 in sptalloc calls prevents sleep if no memory. */
if ((rd_cfg.virt = sptalloc (rd_cfg.size, PG_P,0,DONT_SLEEP)) == NULL)
{
cmn_err (CE_WARN,"Could not allocate enough memory for RAM disk.\n");
return 0;
}
rd_cfg.state |= RD_CONFIGURED;
return;
}
/* rdopen
*/
rdopen (dev)
dev_t dev;
{
int rdisk;
rdisk = RAMDISK(dev);
if ( rdisk >= RD_MAX)
{
/* RAM disk specified foes not exist. */
u.u_error = ENODEV;
return;
}
/* Make sure ram disk has been configured. */
if ( (rd_cfg.state & RD_CONFIGURED) != RD_CONFIGURED)
{
/* disk has not been configured! */
u.u_error = ENOMEM;
return;
}
/* RAM disk successfully opened. */
rd_cfg.state |= RD_OPEN;
}
/* rdclose - close the RAM disk.
*/
rdclose (dev)
dev_t dev;
{
rd_cfg.state &= ~RD_OPEN;
return;
}
/* rdstrategy - the entire synchronous transfer operation happens here.
*/
rdstrategy (bp)
register struct buf *bp;
{
register long req_start; /* start of transfer */
register long byte_size; /* Max capacity of RAM disk in bytes. */
int disk; /* RAM disk being requested for service. */
disk = RAMDISK(bp->b_dev);
/* Validate disk number. */
if (disk >= RD_MAX)
{
/* Disk does not exist. */
bp->b_flags |= B_ERROR;
bp->b_error = ENODEV;
iodone(bp);
return;
}
/* Validate request range. Reads can be trimmed back... */
byte_size = rd_cfg.size * NBPP;
req_start = bp->b_blkno * NBPSCTR;
bp->b_resid = 0; /* Number of bytes remaining after transfer */
/* Check for requests exceeding the upper bound of the disk. */
if (req_start + bp->b_bcount > byte_size)
{
if (bp->b_flags & B_READ)
{
/* Read */
/* Adjust residual count. */
bp->b_resid = req_start + bp->b_bcount - byte_size;
bp->b_bcount = byte_size - req_start;
}
else
{
/* Write - always fails */
bp->b_resid = bp->b_bcount;
bp->b_flags |= B_ERROR;
iodone (bp);
return;
}
}
/* Service the request. */
if (bp->b_flags & B_READ)
{
bcopy (rd_cfg.virt + req_start, bp->b_un.b_addr, bp->b_bcount);
}
else
{
bcopy (bp->b_un.b_addr, rd_cfg.virt + req_start, bp->b_bcount);
}
bp->b_flags &= ~B_ERROR; /* Make sure an error is NOT reported. */
iodone(bp);
return;
}
/* rdread - character read interface.
rdread (dev)
dev_t dev;
{
/* Validate request based on number of 512 bytes sectors supported. */
if (physck ((daddr_t)rd_cfg.size << DPPSHFT, B_READ))
{
/* Have physio allocate the buffer header, then call rdstrategy. */
physio (rdstrategy, (struct buf *)NULL, dev, B_READ);
}
}
/* rdwrite - character write interface.
rdwrite (dev)
dev_t dev;
{
/* Validate request based on number of 512 bytes sectors supported. */
if (physck ((daddr_t)rd_cfg.size << DPPSHFT, B_WRITE))
{
/* Have physio allocate the buffer header, then call rdstrategy. */
physio (rdstrategy, (struct buf *)NULL, dev, B_WRITE);
}
}
/* rdioctl - returns size of RAM disk.
*/
rdioctl (dev, command, arg, mode)
dev_t dev;
int command;
int *arg;
int mode;
{
struct rd_getsize sizes;
if ( RAMDISK(dev) > RD_MAX || !(rd_cfg.state&RD_CONFIGURED) )
{
u.u_error = ENODEV;
return;
}
switch (command) {
case RD_GETSIZE:
sizes.sectors = rd_cfg.size << DPPSHFT;
sizes.in_bytes = rd_cfg.size * NBPP;
/* Now transfer the request to user space */
if (copyout (&sizes, arg, sizeof (sizes)) )
{
u.u_error = EFAULT;
}
break;
default:
/* Error - do not recognize command submitted. */
u.u_error = EINVAL;
return;
}
}
/* rdintr - the RAM disk does not generate hardware interrupts,
* so this routine simply prints a warning message and returns.
*/
rdintr ()
{
cmn_err (CE_WARN, "RAM disk took a spurious hardware interrupt.\n");
}
/* rdprint - send messages concerning the RAM disk to the console.
*/
rdprint (dev, str)
dev_t dev;
char *str;
{
cmn_err (CE_NOTE, "%s on Ram Disk %d.\n", str, RAMDISK (dev));
}
[Example 1: How an application queries the RAM disk's size]
#include "sys/types.h"
main ()
{
int fd;
struct rd_size {
daddr_t sector_count;
long b_count;
} ram_disk_size;
if ( (fd = open ("/dev/rdsk/rd0", O_RDONLY)) < 0)
{
printf ("Could not open RAM disk to do ioctl.\n");
exit (1);
}
if ( ioctl (fd, RD_GETSIZE, &ram_disk_size) < 0)
{
printf ("Could not determine size of RAM disk.\n");
exit (2);
}
printf ("The RAM disk consists of %d sectors occupying %d bytes.\n",
ram_disk_size.sector_count, ram_disk_size.b_count);
}
[Exampl? 2(a)? Entr? fo? th? drive? i? th? /etc/conf/sdevice.? ?
file.]
rd Y 1 0 0 0 0 0 0 0
[Example 2(b): Entry in the master device file.]
rd ocrwiI icbo rd 0 0 1 2 -1
[Example 2(c): The idinstall command.]
/etc/conf/bin/idinstall -a -m -k rd
[Exampl? 2(d)? Th? tw? nodes? fo? characte? an? bloc? device? ?
respectively.]
rd rdsk/rd0 c 0
rd dsk/rd0 b 0
[Exampl? 2(e)? Th? modifie? S01MOUNTFSY? file.]
cd /
# Make a filesystem on the RAM disk.
/etc/mkfs /dev/dsk/rd0 2048:150
/etc/mountall /etc/fstab