ramd1of1 Version 3.1 - Ram disk driver
Berny Goodheart
berny at tndsyd.oz.au
Mon May 20 22:10:42 AEST 1991
This posting consists of a new version of the RAM disk driver
posted earlier this year. The main changes are for the support
of System V.4.0 ESIX (thanks to Ron Bolin) and also better
installation facilities. There are also some bug fixes.
This is a ram disk for UNIX System V.2, V.3 and System V.4 systems
It has been specifically written for the 286/386 PC versions of UNIX
in particular it has been tested on the following versions (mainly
because I can't get to other versions):
Microport: System V/AT 286 All Versions
System V/386 All Versions
Bell Technology: UNIX System V Release 3.0
Interactive Systems: 386/ix 3.2
SCO: System V.3
ESIX SYSTEMS: UNIX System V Release 4.0 Rev A
However, the driver is pretty generic and should not take much
modification to work on other TRUE AT&T type UNIXes.
It has been used extensively by a number of users since 1987 with
few if any problems, but I will keep watch in comp.sources.bugs
for any feedback.
If anyone changes or modifies this code please send me the details so
that I can pass it on to everyone else. Also I should like to here
about other systems it has been ported to other than those mentioned above.
If you mail your email address I will endevour to keep you informed
of any updates from time to time. (See the file called REGISTER)
Berny Goodheart (berny at tndsyd.oz@munnari.oz.au)
-------------------- CUT HERE -----------------------------------------
# This is a shell archive. Remove anything before this line
# then unpack it by saving it in a file and typing "sh file"
# (Files unpacked will be owned by you and have default permissions).
# This archive contains the following files:
# ./contrib/pflopp
# ./contrib/upflopp
# ./contrib/upflopp.1m
# ./INFO.V2
# ./INFO.V3
# ./INFO.V4
# ./MANIFEST
# ./Makefile.V2
# ./Makefile.V3
# ./Makefile.V4
# ./README
# ./REGISTER
# ./S06TMPRAMD
# ./install.V2
# ./magic.V2
# ./ramd.7
# ./ramd.c
# ./ramd.h
# ./ramd_dfile
# ./ramd_master
# ./ramd_mdev
# ./ramd_node
# ./ramd_sdev
# ./raminit
# ./raminit.1m
# ./ramrc.d
# ./ramstat.1m
# ./ramstat.c
# ./ramtab
#
if `test ! -d ./contrib`
then
mkdir ./contrib
echo "mkdir ./contrib"
fi
if `test ! -s ./contrib/pflopp`
then
echo "writing ./contrib/pflopp"
cat > ./contrib/pflopp << '\gux-shar\'
#!/bin/sh
# Use the Ram-disk as a pseudo-floppy
# Check if the file is compressed
ic=0
if [ -f ${1}.Z ]
then
ic=1
fi
# Get the size of the file
chars=`wc -c $1 | cut -f1 -d" "`
blocks=`expr ${chars} / 4096`
# Find a free floppy-device
ramnr=`ramstat | egrep closed | awk 'NR == 1 { print $1 }'`
if [ -z "$ramnr" ]
then
echo "No free RAM-devices"
exit 1
fi
CRAM=/dev/rdsk/ram${ramnr}
BRAM=/dev/dsk/ram${ramnr}
MP=/floppy${ramnr}
# Create the RAM-area
ramstat -i ${blocks} $CRAM
# Copy the image of the floppy to the RAM-disk
if [ $ic -eq 1 ]
then
uncompress < $1 | dd of=$CRAM bs=4k
else
dd if=$1 of=$CRAM bs=4k
fi
# Check that the mountpoint exists
if [ ! -d $MP ]
then
mkdir $MP
fi
# Mount the pseudo-floppy
mount $BRAM $MP
echo $MP
\gux-shar\
else
echo "will not over write ./contrib/pflopp"
fi
if `test ! -s ./contrib/upflopp`
then
echo "writing ./contrib/upflopp"
cat > ./contrib/upflopp << '\gux-shar\'
#!/bin/sh
# upflopp
# - Umount pseudo-floppy and store image in file.
# upflopp ramnr file
ramnr=$1
umount /floppy${ramnr}
dd if=/dev/rdsk/ram${ramnr} of=$2 bs=4k
ramstat -r /dev/dsk/ram${ramnr} /dev/rdsk/ram${ramnr}
\gux-shar\
else
echo "will not over write ./contrib/upflopp"
fi
if `test ! -s ./contrib/upflopp.1m`
then
echo "writing ./contrib/upflopp.1m"
cat > ./contrib/upflopp.1m << '\gux-shar\'
.TH PFLOPP 1M
.SH NAME
.B pflopp,upflopp
\- Mount/unmount pseudo floppy from disk-image.
.SH SYNOPSIS
.B pflopp file
.br
.B upflopp number file
.SH DESCRIPTION
.B Pflopp
is a shell-script that uses the ram-disk as a pseudo floppy. It is used when
an image of a floppy has been created with dd and it is necessary to make
changes to the file-system without copying it to the real floppy.
.B Pflopp
takes one argument, which is the file that contains the image of
the floppy. It automagically searches for a free ram-disk device and
echos the mount-point to standard output.
.B Upflopp
is a shell-script that unmounts a pseudo-floppy. It takes two arguments:
the first argumtent corresponds to the minor-number of the ram-disk
device. The second number is the file that the new image should be stored
in.
.SH FILES
/dev/rdsk/ram?
.br
/dev/dsk/ram?
.br
/floppy?
.SH SEE ALSO
dd(1),ramstat(1M)
.SH AUTHOR
Jan Akalla
\gux-shar\
else
echo "will not over write ./contrib/upflopp.1m"
fi
if `test ! -s ./INFO.V2`
then
echo "writing ./INFO.V2"
cat > ./INFO.V2 << '\gux-shar\'
@(#)INFO.V2 1.1 Copyright (C) B.M.Goodheart 1987, 1988, 1989, 1990
Installation instructions for Microport System V/AT.
The following instructions will help you install the Ram
disk device driver onto your system. You will need the
Microport System V/AT Development Package and the Link
Kit package installed on your system.
The process of adding the driver to your system
is a fairly straight forward process, providing
you take care and read these instructions carefully
before you proceed.
INSTRUCTIONS
============
1. You will need to be Logged in as 'root'
2. Make a backup of your current kernel.
Enter the following command:
cp /system5 /system5.orig
3. Edit the file "Makefile.V2" and change the variable
LINKDIR (default is /etc/linkkit) which specifies the
full path name of your link kit directory.
4. The file 'ramtab' may need to be changed
to reflect your ramdisk initialization requirements.
Edit this file to suite your requirements, the default
configuration is.
1 ramdisk only mounted on '/tmp'
labeled 'tmp'
containing '500' blocks
including '150' inodes
5. Edit the file "ramd_master" file. This file contains
a single record with fields 6 & 7 set to their
default Major numbers of 13 and 14. You will probably
need to modify these to suite your installation.
Field 6 is the BLOCK device Major number for block
special files /dev/dsk/ram?, Field 7 is the CHARACTER
device Major number for the character special files
/dev/ctrlram and /dev/rdsk/ram?
You must also edit the file "install.V2" and modify
the variables BLOCKNO and CHARNO. These variables should
be set to the same values as specified in "ramd_master".
6. Run the makefile by typing:
make -f Makefile.V2 install
7. Change directory into your linkkit/cf directory and
enter the following command:
make wini
8. When the kernel make has finished the new kernel
will be in the linkkit directory. You can now copy
the new kernel into the root directory as follows:
cp ../system5 /system5
sync;sync
9. The Ram disk has now been installed.
Now reboot the system by pressing Ctrl-Alt-Del.
\gux-shar\
else
echo "will not over write ./INFO.V2"
fi
if `test ! -s ./INFO.V3`
then
echo "writing ./INFO.V3"
cat > ./INFO.V3 << '\gux-shar\'
@(#)INFO.V3 1.1 Copyright (C) B.M.Goodheart 1987, 1988, 1989, 1991
Installation instructions for V.3 versions
The following instructions will help you install the Ram
disk device driver onto your V.3 UNIX system. You will need the
Development Package and the Kernel Build Kit installed on your system.
The process of adding this driver to your system
is a fairly straight forward process, providing
you take care and read these instructions carefully
before you proceed.
INSTRUCTIONS
============
1. You need to be logged in as 'root'
2. Edit the file "ramd_mdev" file. This file contains
a single record with fields 5 & 6 set to their
default Major numbers of 2 and 26. You will probably
need to modify these to suite your installation.
Field 5 is the BLOCK device Major number for block
special files /dev/dsk/ram?, Field 6 is the CHARACTER
device Major number for the character special files
/dev/ctrlram and /dev/rdsk/ram?
3. The file 'ramtab' may need to be changed
to reflect your ramdisk initialization requirements.
Edit this file to suite your requirements, the default
configuration is.
1 ramdisk only mounted on '/tmp'
labeled 'tmp'
containing '500' 4k blocks (2 Meg ram disk)
with '150' inodes
4. If you currently use the standard supplied RAM Disk
Driver you should keep a copy of the /etc/rc2.d/S06TMPRAMD
file. This file is overwritten by the Makefile.
5. Make sure you copy your old kernel:
cp /unix /unix.orig
6. You are now ready to make the driver and install it.
type:
make -f Makefile.V3 install
7. You will then have to rebuild the kernel and reboot.
\gux-shar\
else
echo "will not over write ./INFO.V3"
fi
if `test ! -s ./INFO.V4`
then
echo "writing ./INFO.V4"
cat > ./INFO.V4 << '\gux-shar\'
@(#)INFO.V4 1.1 Copyright (C) B.M.Goodheart 1987, 1988, 1989, 1991
Installation instructions for V.4 versions
The following instructions will help you install the Ram
disk device driver onto your V.4 UNIX system. You will need the
Development Package and the Kernel Build Kit installed on your system.
The process of adding this driver to your system
is a fairly straight forward process, providing
you take care and read these instructions carefully
before you proceed.
INSTRUCTIONS
============
1. You need to be logged in as 'root'
2. Edit the file "ramd_mdev" file. This file contains
a single record with fields 5 & 6 set to their
default Major numbers of 2 and 26. You will probably
need to modify these to suite your installation.
Field 5 is the BLOCK device Major number for block
special files /dev/dsk/ram?, Field 6 is the CHARACTER
device Major number for the character special files
/dev/ctrlram and /dev/rdsk/ram?
3. The file 'ramtab' may need to be changed
to reflect your ramdisk initialization requirements.
Edit this file to suite your requirements, the default
configuration is.
1 ramdisk only mounted on '/tmp'
labeled 'tmp'
containing '500' 4k blocks (2 Meg ram disk)
with '150' inodes
4. If you currently use the standard supplied RAM Disk
Driver you should keep a copy of the /etc/rc2.d/S06TMPRAMD
file. This file is overwritten by the Makefile.
5. Make sure you copy your old kernel:
cp /unix /unix.orig
6. You are now ready to make the driver and install it.
type:
make -f Makefile.V4 install
7. You will then have to rebuild the kernel and reboot.
\gux-shar\
else
echo "will not over write ./INFO.V4"
fi
if `test ! -s ./MANIFEST`
then
echo "writing ./MANIFEST"
cat > ./MANIFEST << '\gux-shar\'
INFO.V2 - Installation information for Microport System V/AT
INFO.V3 - Installation information for V.3 versions
INFO.V4 - Installation information for V.4 versions
MANIFEST - This file
Makefile.V2 - SV2 Makefile (For Microport System V/AT only)
Makefile.V3 - SV3 Makefile
Makefile.V4 - SV4 Makefile
README - Release information for all versions
S06TMPRAMD - startup /etc/rc2.d ramdisk allocator
contrib - Directory containing contributed utilities.
install.V2 - Microport specific script for the Makefile
magic.V2 - Microport specific script for the Makefile
ramd.7 - man page
ramd.c - driver source
ramd.h - driver /usr/include/sys header file
ramd_dfile - Microport specific file for dfile.wini
ramd_master - Microport specific file for master
ramd_mdev - configuration master file entry
ramd_node - configuration node entry
ramd_sdev - configuration sdevices entry
raminit - /bin/sh interface for processing RAMDisks
raminit.1m - man page
ramrc.d - Microport specific start up script for the rc2.d directory
ramstat.1m - man page
ramstat.c - user interface to driver
ramtab - RAMDisk setup parameter file
\gux-shar\
else
echo "will not over write ./MANIFEST"
fi
if `test ! -s ./Makefile.V2`
then
echo "writing ./Makefile.V2"
cat > ./Makefile.V2 << '\gux-shar\'
# @(#)Makefile.V2 1.1
# Makefile for Microport System V/AT
DEFS=
CFLAGS = -Ml -c $(DEFS)
LINKDIR = /usr/usr/linkkit
LDFLAGS =
CC=cc
MAN1DIR = /usr/catman/l_man/man1
MAN7DIR = /usr/catman/l_man/man7
all: ramd xramstat
ramd: ramd.c ramd.h
cp ramd.h /usr/include/sys
chown bin /usr/include/sys/ramd.h
chgrp bin /usr/include/sys/ramd.h
chmod 444 /usr/include/sys/ramd.h
$(CC) $(CFLAGS) ramd.c
conf:
ar rv $(LINKDIR)/lib2 ramd.o
iramtab:
@if [ ! -f /etc/ramtab ]; then \
cp ramtab /etc/ramtab ; \
chmod 644 /etc/ramtab ; \
fi
rammdev:
cp $(LINKDIR)/cf/master $(LINKDIR)/cf/master.old
grep -v "^ramd" $(LINKDIR)/cf/master > /tmp/m$$
chmod +x magic.V2
./magic.V2 /tmp/m$$ > $(LINKDIR)/cf/master
rm -f /tmp/m$$
ramnode:
./install.V2
ramsdev:
grep -v "^ramd" $(LINKDIR)/cf/dfile.wini > /tmp/m$$
cat ramd_dfile >> /tmp/m$$
mv /tmp/m$$ $(LINKDIR)/cf/dfile.wini
chmod 444 $(LINKDIR)/cf/dfile.wini
xramstat: ramstat.c ramd.h
$(CC) $(DEFS) -O -s ramstat.c -o ramstat
iramstat: ramstat
cp ramstat /bin/ramstat
chmod 555 /bin/ramstat
chmod u+s /bin/ramstat
raminit:
cp raminit /etc/raminit
chmod 555 /etc/raminit
man: raminit.1m ramstat.1m ramd.7
nroff -man raminit.1m | compress -c > $(MAN1DIR)/raminit.1m.Z
nroff -man ramstat.1m | compress -c > $(MAN1DIR)/ramstat.1m.Z
nroff -man ramd.7 | compress -c > $(MAN7DIR)/ramd.7.Z
rc:
cp ramrc.d /etc/rc2.d
chmod 555 /etc/rc2.d/ramrc.d
install: all conf iramtab ramnode rammdev ramsdev iramstat raminit man rc
clean:
rm -f ramd.o ramstat
cpio:
find . -print | cpio -ocv | compress -c > ramd.cpio.Z
tar:
tar cvf ramd.tar .
shar:
shar -f ramd .
\gux-shar\
else
echo "will not over write ./Makefile.V2"
fi
if `test ! -s ./Makefile.V3`
then
echo "writing ./Makefile.V3"
cat > ./Makefile.V3 << '\gux-shar\'
# @(#)Makefile.V3 1.1
# Makefile for SV3 and SV4.0 - PROTOTYPED ON ESIX SV4.0 5-10-91 - Ron Bolin
# NOTE: setup for SV3
DEFS= -DSV3 -Di386 # -DSV4
CFLAGS = -c $(DEFS)
LDFLAGS =
CC=cc
#MAN1DIR = /usr/share/man/cat1
MAN1DIR = /usr/catman/l_man/man1
#MAN7DIR = /usr/share/man/cat7
MAN7DIR = /usr/catman/l_man/man7
all: ramd xramstat
ramd: ramd.c ramd.h
cp ramd.h /usr/include/sys
chown bin /usr/include/sys/ramd.h
chgrp bin /usr/include/sys/ramd.h
chmod 444 /usr/include/sys/ramd.h
$(CC) $(CFLAGS) ramd.c
conf:
@if [ ! -d /etc/conf/pack.d/ramd ]; then \
mkdir /etc/conf/pack.d/ramd; \
chmod 555 /etc/conf/pack.d/ramd; \
fi ; \
cp ramd.o /etc/conf/pack.d/ramd/Driver.o
iramtab:
@if [ ! -f /etc/ramtab ]; then \
cp ramtab /etc/ramtab ; \
chmod 644 /etc/ramtab ; \
fi
ramnode:
cp ramd_node /etc/conf/node.d/ramd
chmod 444 /etc/conf/node.d/ramd
rammdev:
grep -v "^ramd" /etc/conf/cf.d/mdevice > /tmp/m$$
cat ramd_mdev >> /tmp/m$$
mv /tmp/m$$ /etc/conf/cf.d/mdevice
ramsdev:
@if [ ! -f /etc/conf/sdevice.d/ramd ]; then \
cp ramd_sdev /etc/conf/sdevice.d/ramd; \
fi
xramstat: ramstat.c ramd.h
$(CC) $(DEFS) -O -s ramstat.c -o ramstat
iramstat: ramstat
cp ramstat /bin/ramstat
chmod 555 /bin/ramstat
chmod u+s /bin/ramstat
raminit:
cp raminit /etc/raminit
chmod 555 /etc/raminit
man: raminit.1m ramstat.1m ramd.7
nroff -man raminit.1m | compress -c > $(MAN1DIR)/raminit.1m.Z
nroff -man ramstat.1m | compress -c > $(MAN1DIR)/ramstat.1m.Z
nroff -man ramd.7 | compress -c > $(MAN7DIR)/ramd.7.Z
rc:
cp S06TMPRAMD /etc/rc2.d
chmod 555 /etc/rc2.d/S06TMPRAMD
install: all conf iramtab ramnode rammdev ramsdev iramstat raminit man rc
clean:
rm -f ramd.o ramstat
cpio:
find . -print | cpio -ocv | compress -c > ramd.cpio.Z
tar:
tar cvf ramd.tar .
shar:
shar -f ramd .
\gux-shar\
else
echo "will not over write ./Makefile.V3"
fi
if `test ! -s ./Makefile.V4`
then
echo "writing ./Makefile.V4"
cat > ./Makefile.V4 << '\gux-shar\'
# @(#)Makefile.V4 1.1
# Makefile for SV3 and SV4.0 - PROTOTYPED ON ESIX SV4.0 5-10-91 - Ron Bolin
# NOTE: setup for SV4
DEFS= -DSV4 -Di386 # -DSV3
CFLAGS = -c $(DEFS)
LDFLAGS =
CC=cc
MAN1DIR = /usr/share/man/cat1
#MAN1DIR = /usr/catman/l_man/man1
MAN7DIR = /usr/share/man/cat7
#MAN7DIR = /usr/catman/l_man/man7
all: ramd xramstat
ramd: ramd.c ramd.h
cp ramd.h /usr/include/sys
chown bin /usr/include/sys/ramd.h
chgrp bin /usr/include/sys/ramd.h
chmod 444 /usr/include/sys/ramd.h
$(CC) $(CFLAGS) ramd.c
conf:
@if [ ! -d /etc/conf/pack.d/ramd ]; then \
mkdir /etc/conf/pack.d/ramd; \
chmod 555 /etc/conf/pack.d/ramd; \
fi ; \
cp ramd.o /etc/conf/pack.d/ramd/Driver.o
iramtab:
@if [ ! -f /etc/ramtab ]; then \
cp ramtab /etc/ramtab ; \
chmod 644 /etc/ramtab ; \
fi
ramnode:
cp ramd_node /etc/conf/node.d/ramd
chmod 444 /etc/conf/node.d/ramd
rammdev:
grep -v "^ramd" /etc/conf/cf.d/mdevice > /tmp/m$$
cat ramd_mdev >> /tmp/m$$
mv /tmp/m$$ /etc/conf/cf.d/mdevice
ramsdev:
@if [ ! -f /etc/conf/sdevice.d/ramd ]; then \
cp ramd_sdev /etc/conf/sdevice.d/ramd; \
fi
xramstat: ramstat.c ramd.h
$(CC) $(DEFS) -O -s ramstat.c -o ramstat
iramstat: ramstat
cp ramstat /bin/ramstat
chmod 555 /bin/ramstat
chmod u+s /bin/ramstat
raminit:
cp raminit /etc/raminit
chmod 555 /etc/raminit
man: raminit.1m ramstat.1m ramd.7
nroff -man raminit.1m | compress -c > $(MAN1DIR)/raminit.1m.Z
nroff -man ramstat.1m | compress -c > $(MAN1DIR)/ramstat.1m.Z
nroff -man ramd.7 | compress -c > $(MAN7DIR)/ramd.7.Z
rc:
cp S06TMPRAMD /etc/rc2.d
chmod 555 /etc/rc2.d/S06TMPRAMD
install: all conf iramtab ramnode rammdev ramsdev iramstat raminit man rc
clean:
rm -f ramd.o ramstat
cpio:
find . -print | cpio -ocv | compress -c > ramd.cpio.Z
tar:
tar cvf ramd.tar .
shar:
shar -f ramd .
\gux-shar\
else
echo "will not over write ./Makefile.V4"
fi
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\gux-shar\'
This is a ram disk for UNIX System V.2, V.3 and System V.4 systems
It has been specifically written for the 286/386 PC versions of UNIX
in particular it has been tested on the following versions (mainly
because I can't get to other versions):
Microport: System V/AT 286 All Versions
System V/386 All Versions
Bell Technology: UNIX System V Release 3.0
Interactive Systems: 386/ix 3.2
SCO: System V.3
ESIX SYSTEMS: UNIX System V Release 4.0 Rev A
However, the driver is pretty generic and should not take much
modification to work on other TRUE AT&T type UNIXes.
It has been used extensively by a number of users since 1987 with
few if any problems, but I will keep watch in comp.sources.bugs
for any feedback.
If anyone changes or modifies this code please send me the details so
that I can pass it on to everyone else. Also I should like to here
about other systems it has been ported to other than those mentioned above.
If you mail your email address I will endevour to keep you informed
of any updates from time to time. (See the file called REGISTER)
INSTALLING:
Well I have to say that since there are so many 286/386/486
versions of UNIX/XENIX etc on the market I cannot give
installation details for each. So it's RTFM I am afraid. Read
the section in your documentation on how to install device drivers.
However, Makefiles and installation information is provided
for the above named systems. Before you start read the INFO.V?
file for your version of the OS.
MOD INSTALLING 5-10-91 SV4 PORT BY R L BOLIN
For SV4.0 see Makefile - You may need to edit
/etc/conf/cf.d/mdevice for major number devices for the
RAMDisk (ramd) as default majors are 2 & 26. Makefile
will also work for SV3.2 ISC, ESIX if defined SV3 & i386.
NOTE: SV4.0 ramd driver - the raminit file is configured for a file
system of type s5, if you select someother file system you will
need to adjust the block calculation routine for mkfs.
BUG: ramstat -m, does not report maxmem correctly - gives 0. This
seems to be a BUG in SV4.0 (sysinfo.h).
INFORMATION:
The ram disk uses a portion of the available user
memory and configures it as a disk. To the user
this is totally transparent. The user may read or
write to the ram disk in the normal way, indeed
all standard programs like 'fsck' and 'fsdb' see
the ram disk file system just as if it where a file
system on the hard disk.
Obviously you will need enough memory to configure the
ram disk, the more memory you have the bigger the ram
disk can be. The ram disk has been designed to allow
up to 4 virtual disks to reside in memory at any one time.
The ram disk has undergone some exstensive tests giving
some amazing results, here is an example:
The following criteria was used for the test:
A 968K Byte C Program in 14 Files, 4 directories, 5 Makefiles
A PC-AT clone running System V/AT 80286 Running at 12Mhz
4Mbtye memory fitted
40 Mbyte Hard disk Average Access 65ms
Ram disk mounted as /tmp
RAMDISK SIZE (Blks) COMPILE TIME (Min:sec) EFFICENCY RATE
0 15:09 00%
500 13:27 12%
1000 11:36 25%
1200 09:56 37%
1500 09:07 40%
1800 10:17 33%
2000 11:50 24%
2200 14:03 07%
2500 15:37 -2%
Conclusion
Because the ram disk resides in memory and not
on some physical media such as a hard disk,
the CPU has direct access to the data without
suffering any latency time. Using a ram disk in
this way can be upto 40% more efficient especialy
during developement, However, as the results above
show, if too much memory is devoted to the ram
disk, the efficiency level starts to drop to
almost the same level as having no ram disk installed.
This is because there is a trade off between the
operating system needing more memory to work with,
and the ram disk which assignes portions
of the memory pool to the user, is hogging it all up.
(If you take too much memory up in the ram disk, you will
cause the operating system to use the swap device.)
It can be seen from these results that the ideal
size of the ram disk for the V.2 installation
is 1500 physical blocks assuming 4 Mbyte of memory
is fitted.
*************************************************************************
*************************************************************************
*************************************************************************
It is VERY IMPORTANT to remember that the ram disk
resides in memory, this means if the system should
crash or you should shut the system down without first
saving the contents of the ram disk, ALL the contents
of the ram disk WILL have been lost.
*************************************************************************
*************************************************************************
*************************************************************************
\gux-shar\
else
echo "will not over write ./README"
fi
if `test ! -s ./REGISTER`
then
echo "writing ./REGISTER"
cat > ./REGISTER << '\gux-shar\'
If you like this software and would like me to send you updates
from time to time as they become available please fill out this
registration form and email it to:
UUCP: uunet!munnari.oz!tndsyd.oz.au!berny
INTERNET: berny at tndsyd.oz@munnari.oz.au
DOMAIN: goodheart_berny at tandem.com
ACSnet: berny at tndsyd.oz
Send with mail header "Ramdisk register"
----------------------------------------------------------------
NOTE: This is free software but please read the Copyright note and
disclaimer in the source files.
----------------------------------------------------------------
Email address:
Version of Ramdisk installed:
Number of Systems installed:
OS Vendor:
OS Version:
CPU:
Installed Memory:
Comments:
\gux-shar\
else
echo "will not over write ./REGISTER"
fi
if `test ! -s ./S06TMPRAMD`
then
echo "writing ./S06TMPRAMD"
cat > ./S06TMPRAMD << '\gux-shar\'
# Copyright (c) B.M.Goodheart 1989
# All Rights Reserved
#
# This script makes a filesystem on the RAMdisk and mounts it as /tmp if
# that hasn't already been done.
#ident "@(#)S06TMPRAMD 1.1"
state=$1
case $state in
'start')
/etc/raminit -i -v
;;
'stop')
/etc/raminit -r
;;
esac
\gux-shar\
else
echo "will not over write ./S06TMPRAMD"
fi
if `test ! -s ./install.V2`
then
echo "writing ./install.V2"
cat > ./install.V2 << '\gux-shar\'
# installation script for the ramdisk for Microport System V/AT
#
# @(#)install.V2 1.1
#
# Make the nodes foe special files
RAW=/dev/rdsk
BLOCK=/dev/dsk
BLOCKNO=13
CHARNO=14
for x in 0 1 2 3
do
mknod $BLOCK/ram${x} b $BLOCKNO $x
mknod $RAW/ram${x} c $CHARNO $x
chmod 644 $BLOCK/ram${x} $RAW/ram${x}
done
mknod /dev/ctrlram c $CHARNO 0
chmod 622 /dev/ctrlram
\gux-shar\
else
echo "will not over write ./install.V2"
fi
if `test ! -s ./magic.V2`
then
echo "writing ./magic.V2"
cat > ./magic.V2 << '\gux-shar\'
# little magic to update the master file on Microport System V/AT
(l="`sed -e \"/wini/q\" $1 | wc -l`" ; \
n="`echo $l | sed -e \"s/ //g\"`" ; \
sed -e "/wini/q" $1; \
cat ramd_master; \
sed "1,${n}d" $1)
\gux-shar\
else
echo "will not over write ./magic.V2"
fi
if `test ! -s ./ramd.7`
then
echo "writing ./ramd.7"
cat > ./ramd.7 << '\gux-shar\'
.TH RAM 7
.SH NAME
.B ramd
\- memory resident disk interface
.SH DESCRIPTION
The memory resident disk (ram disk) uses a portion of the available
user memory as a pseudo device configured as far as the user is
concerned, the same as a normal file system. Files are accessed via
the system's normal buffering mechanism and may be read and written
to in the normal way. A raw interface is also provided for direct
serial transmission between the ram disk and the users buffer.
.PP
.PP
.SH RAW INTERFACE
Special filename semantics.
.br
/dev/ctrlram control interface
.br
/dev/rdsk/ram0 ram disk 0
.br
/dev/rdsk/ram1 ram disk 1
.br
/dev/rdsk/ram2 ram disk 2
.br
/dev/rdsk/ram3 ram disk 3
.br
.SH BLOCK INTERFACE
/dev/dsk/ram0 ram disk 0
.br
/dev/dsk/ram1 ram disk 1
.br
/dev/dsk/ram2 ram disk 2
.br
/dev/dsk/ram3 ram disk 3
.br
.PP
.SH AUTHOR
B.M.Goodheart
\gux-shar\
else
echo "will not over write ./ramd.7"
fi
if `test ! -s ./ramd.c`
then
echo "writing ./ramd.c"
cat > ./ramd.c << '\gux-shar\'
/*
*
* @(#)ramd.c 3.1 Copyright (C) B.M.Goodheart 1987, 1888, 1989, 1991
*
*
*
* DISCLAIMER OF WARRANTY.
* This software is distributed "as is" and without warranties as to
* performance of merchantability or any other warranties whether expressed
* or implied. In no event shall the author (the copyright holder) be held
* liable for any loss of profit or any other commercial damage resulting
* from the use or misuse of this software, including but not limited to
* special, incidental, consequential or other damages. THE USER MUST
* ASSUME THE ENTIRE RISK OF USING THIS SOFTWARE.
*
*
* LISCENSE AGREEMENT
* This software is placed into the public domain and
* may be copied or distributed freely provided no profit or
* gain is made and is used for personal use only and the code
* as distributed retains all copyright notices in the code.
* This includes any copyright statements in the target
* binary and executable code produced from the distributed source.
*
*
* DISTRIBUTION NOTE
* This file contains the code for a RAM disk driver for UNIX System 5.2
* and System V.3. It has been designed specifically for Microport's
* System V/AT iAPX286 and Interactive Systems V/386 i386 systems
* but should work with other PC based System V.? ports with only
* minor modifications, specifically the BUFSEL selector on the 80286.
* This driver should work on any V.3 implementation on a PC.
* Thanks to Ron Bolin (gatech!sbmsg1!bsts00!rlb), this driver has
* now been ported and tested on ESIX System V.4.0.
*
*
* IMPORTANT NOTE !!!
* Any files or data stored within the ram disks will be
* LOST FOR EVER if the system is brought down for ANY reason.
*
* There are also two other programs distributed associated
* with the driver, they are ramstat(1M) and raminit(1M).
* These are used to control the ram disk driver in user mode
* See also ram(7). There are also some contibuted support
* programs in the contrib directory.
*
* Berny Goodheart (berny at tndsyd.oz@munnari.oz.au)
*
* Modifications:
* 20-10-87 (001) The ramsize array would still hold the ram
* size even if could not get memory. This has
* now been fixed, variable is now zerod.
*
* 23-10-88 (002) Reduced ambiguouse code, now drops through
* to the same statements. (reduces object size)
*
* 23-10-88 (003) malloc() returns 0 not NULL (who cares)
*
* 12-11-88 (004) fixed a really big bug, god knows how it
* worked in the first place. basically, almost
* all the routines that made reference to
* 'dev' as passed to the sysentry call
* where using the raw data, now uses minor(dev)
* to extraxt the device index proper.
*
* 19-06-89 (005) this mod is huge, basically I have added
* a switch to the compiler "i386" which will
* create the driver for System V.3. The difference
* to V.2 is quite large in that the two systems
* have different memory managment, V.3 uses Page Tables
* to map physical memory to kernel virtual memory.
*
* 20-06-89 (006) fixed the character read overrun which used to
* to panic the system.
*
* 07-07-89 (007) fixed the block count overrun check algorithm in
* the strategy routine.
*
* 09-08-89 (008) Added a few macros so that the code is
* easier to read.
*
* 30-11-89 (009) forgot to add the strategy print routine
* Now the system tells you when you run out of
* space in a ram disk.
*
* 15-04-91 (010) Jan Akalla reported this one. Trying to write to
* the last block in a Ram disk gave out-of-space error.
*
* 10-05-91 (011) Ported to SVR4 by Ron Bolin (gatech!sbmsg1!bsts00!rlb)
* Atlanta, GA.
* Also changed function base names from "ram" to
* "ramd". Assume this conflicted with other routines
* on System VR4 (B.M.G)
*
*
*/
static char *bmgid =
#ifdef TEST
"RAM disk Test Version Copyright (C) Berny Goodheart \n";
#elif SV4
"RAM disk 3.1-(SV4-%s) Copyright (C) Berny Goodheart 5/20/91\n\n";
#else
"RAM disk 3.1-(%s) Copyright (C) Berny Goodheart 5/20/91\n\n";
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/file.h>
#include <sys/sysmacros.h>
#include <sys/map.h>
#include <sys/buf.h>
#include <sys/ramd.h> /* header file for this driver */
#ifdef SV4
#include <sys/uio.h>
#include <sys/kmem.h>
#define cotb potb
#define iodone biodone
struct uio *uio_p;
#endif
#define DSK_PHYS_BLOCK 512 /* bytes in a physical disk block */
#define devnum(bp) minor((bp)->b_dev) /* gets the minor device number */
#define blknum(bp) ((bp)->b_blkno) /* block offset for I/O */
#define RADDR(d) (ramadd[minor(d)])
#define ROPEN(d) (ram_opened[minor(d)])
#define RSTAT(d) (ram_state[minor(d)])
#define RSIZE(d) (ramsize[minor(d)])
#ifndef i386 /* (008) */
#include <sys/mmu.h> /* for BUFSEL selector */
caddr_t mapin();
#define raddr_t paddr_t
#define diskblk(x) (ctob(x))
#define blktophys(bp) (ctob(ramadd[devnum(bp)]) + diskblk(blknum(bp)));
static char *machtype = "iAPX286";
#else
#include <sys/immu.h>
#include <sys/cmn_err.h>
#define mapin(a,b) (a) /* emulate V.2 MMU stuff */
#define raddr_t caddr_t
#define diskblk(x) (x * DSK_PHYS_BLOCK)
#define blktophys(bp) (ramadd[devnum(bp)] + diskblk(blknum(bp)));
static char *machtype = "iAPX386";
#endif
#ifdef SV4
#include <sys/ddi.h> /* last include rule for DDK */
#endif
static raddr_t ramadd[NRDEVS]; /* base address of ram disk */
static int ram_opened[NRDEVS]; /* number of processes sleeping */
static int ram_state[NRDEVS]; /* current ram state */
static int ramDebug = 0; /* debug static flag, 0 = off */
static char busywait = 0; /* sleeping processes */
/*
* ramsize[n] = holds the size of ram disk in physical memory blocks
*
* NOTE on i386 machines
* a physical block must be on a 4k boundry i.e 1 block = 4096 bytes
* on iAPX286 machines a physical block is 512 bytes
*
*/
static int ramsize[NRDEVS];
/*
* This routine is called whenever a process calls the system
* call 'open' on this device
*
*/
ramdopen(dev)
{
busywait++;
(ROPEN(dev))++;
if(ramDebug)
(void)printf("Ram-[%d] opened by uid-[%d]\n"
,minor(dev)
,u.u_ruid);
/*
*
* Mask out any other opens while we are busy.
* The kernel does not experience any further CPU
* work while this happens, the process is simply
* put to sleep and added to the process que until
* awoken later..
*
*/
while(busywait != 1) /* mask out ram_opened opens */
(void)sleep((caddr_t)&busywait, PRIBIO + 1);
/*
*
* Is it a valid device
*
*/
if(minor(dev) < 0 || minor(dev) > (NRDEVS - 1))
u.u_error = ENODEV; /* (002) */
/*
* wakeup any pending I/O
*
*/
busywait--;
(void)wakeup((caddr_t)&busywait);
}
ramdclose(dev)
{
ROPEN(dev) = 0; /* only called on last close */
}
/*
* strategy routine is called by both character and block
* drivers to do the I/O.
*/
#ifdef SV4
void
#endif
ramdstrategy(bp)
struct buf *bp;
{
raddr_t physdr;
/*
*
* If we slip up with deletion of the ram
* disk for some reason and we get here somehow,
* then this check will stop any reads
* or writes to possibly now unassigned memory.
*
*/
if(ram_state[devnum(bp)] == RAM_CLOSED) {
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
(void)iodone(bp);
return;
}
/*
*
* check its a legal block (007)
*
* changed >= to > "last block gave no space error" (010)
*/
#if i386
if((diskblk(blknum(bp))+bp->b_bcount)>(ramsize[devnum(bp)] * PTSIZE)) {
#else
if(diskblk(blknum(bp)) > diskblk(ramsize[devnum(bp)])) {
#endif
if(bp->b_flags & B_READ)
bp->b_error = EIO;
else
bp->b_error = ENOSPC;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
(void)iodone(bp);
return;
}
/*
* work out which block number in the mapped in RAM array
* and convert to a physical address.
*/
physdr = blktophys(bp);
/*
* If debug is set then send out to the console
*
*/
if(ramDebug)
(void)printf("Ram%d: blk-[%ld] addr-[0x%lx] bytes-[%d] %s\n"
,devnum(bp)
,blknum(bp)
,physdr
,bp->b_bcount
,bp->b_flags & B_READ ? "Read" : "Write");
/*
* Do the physical memory transfer I/O
*/
if(bp->b_flags & B_READ)
(void)bcopy(mapin(physdr,BUFSEL),bp->b_un.b_addr,bp->b_bcount);
else
(void)bcopy(bp->b_un.b_addr,mapin(physdr,BUFSEL),bp->b_bcount);
/*
* because bcopy() does not return anything
* we assume all bytes where copied and there is
* none left in the buffer to transmit
*/
bp->b_resid = 0;
/*
* All finished, free the buffer
*/
(void)iodone(bp);
}
/*
* ramdread
*
* Uses ramstrategy for RAW I/O
*
*/
ramdread(dev)
int dev;
{
#ifdef SV4
physiock(ramdstrategy,NULL,dev,B_READ,RSIZE(dev)*PTSIZE,uio_p);
#else
(void)physio(ramdstrategy,NULL,dev,B_READ);
#endif
}
/*
* ramdwrite
*
* Uses ramstrategy for RAW I/O
*
*/
ramdwrite(dev)
int dev;
{
#ifdef SV4
physio(ramdstrategy,NULL,dev,B_WRITE,RSIZE(dev)*PTSIZE,uio_p);
#else
(void)physio(ramdstrategy,NULL,dev,B_WRITE);
#endif
}
/*
* user interface to I/O control
*
*/
ramdioctl(dev, cmd, arg)
int dev, cmd;
union r_ramst *arg;
{
register x;
int intlevel;
#if i386
#ifndef SV4
caddr_t ptalloc(); /* page table allocation routine */
#endif
/*
* Only super user can set or unset the
* ram disks.
*
* NOTE: TCMEMINFO is only available on 386
*/
if((!suser()) && ((cmd != TCGETRAM) || (cmd != TCMEMINFO)) ) {
#else
if((!suser()) && cmd != TCGETRAM) {
#endif
u.u_error = EACCES;
return;
}
switch(cmd) {
case TCSETRAM :
/*
* This will usually be done by 'ramstat' (hopefully)
*
* If already open then return with errno
*/
if(RSTAT(dev) == RAM_OPEN) {
u.u_error = EBUSY;
return;
}
/*
* arg is the ram size in physical blocks
* with which to create the RAM disk.
*/
if(arg->r_arg < MINRAMSIZ) {
u.u_error = EINVAL;
return;
}
RSIZE(dev) = arg->r_arg;
/*
* turn interrupts off
*/
intlevel = spl6();
/*
* Try to get memory
*
*/
#if i386
#ifdef SV4
if((RADDR(dev) = kmem_zalloc(RSIZE(dev)*PTSIZE,
KM_NOSLEEP)) == 0) {
#else /* SV3 */
if((RADDR(dev) = ptalloc(RSIZE(dev),
PHYSCONTIG|NOSLEEP)) == 0) {
#endif
#else
if((RADDR(dev)=malloc(coremap,RSIZE(dev)))== 0){
#endif
RSIZE(dev) = 0; /* (001) */
u.u_error = ENOMEM;
(void)splx(intlevel);
return;
}
#ifndef i386
/*
*
* Clear the Memory clicks to zero's
*
* not needed on i386
*/
for (x = 0; x < RSIZE(dev); x++)
(void)clearseg(RADDR(dev) + x);
#endif
/*
*
* Initialization is complete at this point
* so set the ram_state flag.
*
*/
RSTAT(dev) = RAM_OPEN;
(void)splx(intlevel);
break;
case TCDELRAM :
/*
* No point in deleting if we don't exist
*
*/
if(RSTAT(dev) == RAM_CLOSED) {
u.u_error = ENXIO;
return;
}
/*
* Cant delete the RAM disk if busy
*
*/
if(ROPEN(dev) > 1) {
u.u_error = EBUSY;
return;
} else
ROPEN(dev) = 0;
/*
* Try to free up the memory
* else GOD HELP THE WORLD
*
*/
intlevel = spl6();
#if i386
/*
* uptfree() and kmem_free() don't return anything
*/
#ifdef SV4
(void)kmem_free(RADDR(dev),RSIZE(dev)*PTSIZE);
#else /* SV3 */
(void)uptfree(RADDR(dev),RSIZE(dev));
#endif
#else
if(mfree(coremap,RSIZE(dev), RADDR(dev)) == -1)
/*
* We have to panic here because if we
* can't free up the memmory then anything
* can happen. (possible hardware fault).
*
* praise be the lord
*/
(void)panic("ram%d: memory de-allocation error",
minor(dev));
#endif
/*
* PHEW ! THAT WAS CLOSE
*
* Reset the parameters to zilch
* so that next initialization is setup ok.
*
*/
RSTAT(dev) = RAM_CLOSED;
RADDR(dev) = 0;
RSIZE(dev) = 0;
(void)splx(intlevel);
break;
case TCGETRAM :
/*
* Get statistics about the RAM disks
*
*/
for(x = 0; x < NRDEVS;x++) {
arg->r_rstat.r_dev[x] = x;
arg->r_rstat.r_blks[x] = ramsize[x];
arg->r_rstat.r_stat[x] =
ram_state[x] == RAM_OPEN ? 1 : 0 ;
arg->r_rstat.r_opns[x] = ram_opened[x];
arg->r_rstat.r_addr[x] = (paddr_t)ramadd[x];
arg->r_rstat.r_dbg = ramDebug == 0 ? 0 : 1 ;
}
break;
case TCRAMDBG :
/*
*
* Toggle ramDebug mode
*
*/
ramDebug = ramDebug == 0 ? 1 : 0;
arg->r_arg = ramDebug;
break;
#if i386
case TCMEMINFO:
/*
* obtain system memory stats
*
*/
arg->r_meminfo.r_maxmem = maxmem;
arg->r_meminfo.r_freemem = freemem;
break;
#endif
default:
u.u_error = EINVAL;
}
}
/*
* Initialize start up logo.
* Done at system boot only
*
*/
ramdinit()
{
(void)printf(bmgid,machtype);
}
/*
* Generic kernel print routine
* called on internal error in strategy
* routine (009)
*/
ramdprint(dev,s)
int dev;
char *s;
{
(void)printf("DANGER: %s on ram disk device %d\n", s, minor(dev));
}
\gux-shar\
else
echo "will not over write ./ramd.c"
fi
if `test ! -s ./ramd.h`
then
echo "writing ./ramd.h"
cat > ./ramd.h << '\gux-shar\'
/*
*
* @(#)ramd.h 2.5 Copyright (C) B.M.Goodheart 1987, 1888, 1989, 1991
*
*
*
* DISCLAIMER OF WARRANTY.
* This software is distributed "as is" and without warranties as to
* performance of merchantability or any other warranties whether expressed
* or implied. In no event shall the author (the copyright holder) be held
* liable for any loss of profit or any other commercial damage resulting
* from the use or misuse of this software, including but not limited to
* special, incidental, consequential or other damages. The user must
* assume the entire risk of using this software.
*
*
* LISCENSE AGREEMENT
* This software is placed into the public domain and
* may be copied or distributed freely provided no profit or
* gain is made and is used for personal use only and the code
* as distributed retains all copyright notices in the code.
* This includes any copyright statements in the target
* binary and executable code produced from the distributed source.
*
*
* DISTRIBUTION NOTE
* This file contains the code for a RAM disk driver for UNIX System 5.2
* and System V.3. It has been designed specifically for Microport's
* System V/AT iAPX286 and Interactive Systems V/386 i386 systems
* but should work with other PC based System V.? ports with only
* minor modifications, specifically the BUFSEL selector on the 80286.
* This driver should work on any V.3 implementation on a PC.
*
*
* IMPORTANT NOTE !!!
* Any files or data stored within the ram disks will be
* LOST FOR EVER if the system is brought down for ANY reason.
*
* There are also two other programs distributed associated
* with the driver, they are ramstat(1M) and raminit(1M).
* These are used to control the ram disk driver in user mode
* See also ram(7).
*
* Berny Goodheart (berny at tndsyd.oz@munnari.oz.au)
*
*/
#define RAM_CLOSED 0
#define RAM_OPEN 1
#define RAMIO ('R'<<8)
#define TCSETRAM (RAMIO|1)
#define TCDELRAM (RAMIO|2)
#define TCGETRAM (RAMIO|3)
#define TCRAMDBG (RAMIO|4)
#if i386
#define TCMEMINFO (RAMIO|5)
#endif
#define NRDEVS 4 /* max number of devs */
/*
* NOTE on the i386 machine
* a block is 4096 bytes
* on the iAPX286 it is 512 bytes
*
* min number of blks/ram disk for a 32k ram disk
*
*/
#if i386
#define MINRAMSIZ 8
#else
#define MINRAMSIZ 64
#endif
/* union for use by all ramdisk drive ioctl calls */
union r_ramst {
int r_arg;
/*
* Ram device status structure
*/
struct {
int r_dev[NRDEVS]; /* index to device */
int r_blks[NRDEVS]; /* physical block count */
dev_t r_stat[NRDEVS]; /* open or closed */
int r_opns[NRDEVS]; /* # of opens */
int r_addr[NRDEVS]; /* mapin memory addr */
dev_t r_dbg; /* debug on or off */
}r_rstat;
#if i386
/*
* r_meminfo is used to request system wide
* memory information using TCMEMINFO as the ioctl arg
* NOTE: not available on 80286
*
*/
struct {
ulong r_maxmem; /* total system mem */
ulong r_freemem; /* available mem */
} r_meminfo;
#endif
};
\gux-shar\
else
echo "will not over write ./ramd.h"
fi
if `test ! -s ./ramd_dfile`
then
echo "writing ./ramd_dfile"
cat > ./ramd_dfile << '\gux-shar\'
ramd 0 4
\gux-shar\
else
echo "will not over write ./ramd_dfile"
fi
if `test ! -s ./ramd_master`
then
echo "writing ./ramd_master"
cat > ./ramd_master << '\gux-shar\'
ramd 0 ocrwis bc ramd 13 14 4
\gux-shar\
else
echo "will not over write ./ramd_master"
fi
if `test ! -s ./ramd_mdev`
then
echo "writing ./ramd_mdev"
cat > ./ramd_mdev << '\gux-shar\'
ramd Iocrwi iobc ramd 2 26 1 4 -1
\gux-shar\
else
echo "will not over write ./ramd_mdev"
fi
if `test ! -s ./ramd_node`
then
echo "writing ./ramd_node"
cat > ./ramd_node << '\gux-shar\'
ramd ctrlram c 0
ramd dsk/ram0 b 0
ramd dsk/ram1 b 1
ramd dsk/ram2 b 2
ramd dsk/ram3 b 3
ramd rdsk/ram0 c 0
ramd rdsk/ram1 c 1
ramd rdsk/ram2 c 2
ramd rdsk/ram3 c 3
\gux-shar\
else
echo "will not over write ./ramd_node"
fi
if `test ! -s ./ramd_sdev`
then
echo "writing ./ramd_sdev"
cat > ./ramd_sdev << '\gux-shar\'
ramd Y 4 0 0 0 0 0 0 0
\gux-shar\
else
echo "will not over write ./ramd_sdev"
fi
if `test ! -s ./raminit`
then
echo "writing ./raminit"
cat > ./raminit << '\gux-shar\'
:
#
#
#
# @(#)raminit 1.5 Copyright (C) B.M.Goodheart 1987, 1888, 1989, 1991
#
#
# SV4.0 MOD R. L. Bolin 5-91
#
# DISCLAIMER OF WARRANTY.
# This software is distributed "as is" and without warranties as to
# performance of merchantability or any other warranties whether expressed
# or implied. In no event shall the author (the copyright holder) be held
# liable for any loss of profit or any other commercial damage resulting
# from the use or misuse of this software, including but not limited to
# special, incidental, consequential or other damages. The user must
# assume the entire risk of using this software.
#
#
# LISCENSE AGREEMENT
# This software is placed into the public domain and
# may be copied or distributed freely provided no profit or
# gain is made and is used for personal use only and the code
# as distributed retains all copyright notices in the code.
# This includes any copyright statements in the target
# binary and executable code produced from the distributed source.
#
#
# DISTRIBUTION NOTE
# This file contains the code for a RAM disk driver for UNIX System 5.2
# and System V.3. It has been designed specifically for Microport's
# System V/AT iAPX286 and Interactive Systems V/386 i386 systems
# but should work with other PC based System V.? ports with only
# minor modifications, specifically the BUFSEL selector on the 80286.
# This driver should work on any V.3 implementation on a PC.
#
#
# IMPORTANT NOTE !!!
# Any files or data stored within the ram disks will be
# LOST FOR EVER if the system is brought down for ANY reason.
#
# There are also two other programs distributed associated
# with the driver, they are ramstat(1M) and raminit(1M).
# These are used to control the ram disk driver in user mode
# See also ram(7).
#
# Berny Goodheart (berny at tndsyd.oz@munnari.oz.au)
#
#
# initialise or remove ram disks ( reads /etc/ramtab )
#
#
trap "echo Interrupt ignored" 1 2 3 15
RAMRC=/etc/ramtab
view=0
if test $# -lt 1
then
echo "Usage: raminit -ir [ -v ]"
exit
fi
if test $# -eq 2
then
if [ "$2" != "-v" ]
then
echo "Usage: raminit -ir [ -v ]"
exit
fi
view=1
fi
case $1 in
"-v")
echo "Usage: raminit -ir [ -v ]"
exit
;;
"-i")
for x in `/bin/cat $RAMRC | /bin/grep "^\/"`
do
block=
raw=
size=
inodes=
label=
mnt=
rnum=
block=`/bin/echo $x | /usr/bin/awk -F: '{print $1}'`
raw=`/bin/echo $x | /usr/bin/awk -F: '{print $2}'`
size=`/bin/echo $x | /usr/bin/awk -F: '{print $3}'`
inodes=`/bin/echo $x | /usr/bin/awk -F: '{print $4}'`
label=`/bin/echo $x | /usr/bin/awk -F: '{print $5}'`
mnt=`/bin/echo $x | /usr/bin/awk -F: '{print $6}'`
rnum=`/bin/echo $x | /usr/bin/awk -F: '{print $7}'`
if [ "$rnum" = "" ]
then
echo "$0: error in /etc/ramtab, can't continue"
exit 1
fi
# test if the driver is already open
ramstat -n${rnum} | grep open > /dev/null
if [ $? = 0 ]
then
continue
fi
if test -f $mnt/*
then
echo "$0: cannot mount on \"$mnt\", directory is not empty"
continue
elif test ! -d $mnt
then
echo "$0: Directory \"$mnt\" does not exist, entry ignored"
continue
else
:
fi
if [ "$block" = "" ]
then
echo "$0: Block device not specified, entry ignored"
continue
fi
if [ "$raw" = "" ]
then
echo "$0: Raw device not specified, entry ignored"
continue
fi
if [ "$size" = "" ]
then
echo "$0: Device size not specified, entry ignored ***"
continue
fi
if [ $view = 1 ]
then
echo "Trying for Space for $size * \c"
if i386
then
echo "4k byte blocks"
else
echo "1k byte blocks"
fi
fi
# test if we have enough space
/bin/ramstat -i $size $raw
if [ $? != 0 ]
then
exit
fi
echo "Please Wait ...."
if i386
then
size=`expr ${size} \* 4096`
size=`expr ${size} / 512`
inodes=`expr ${size} / 10`
fi
if [ $view = 1 ]
then
echo "Making file system on $block"
echo "size = $size, inodes = $inodes\n"
fi
/etc/mkfs $block $size:$inodes > /dev/null
if [ "$label" != "" ]
then
if [ "$mnt" != "" ]
then
j=`basename $mnt`
if [ $view = 1 ]
then
echo "Labeling file system $label\n"
fi
/etc/labelit $block ${j} $label > /dev/null
fi
fi
/etc/fsck $block
if [ "$mnt" != "" ]
then
if [ $view = 1 ]
then
echo "\nMounting file system on $mnt\n"
fi
/etc/mount $block $mnt
fi
done
;;
"-r")
ramstat | grep open > /dev/null
if [ $? != 0 ]
then
exit
fi
for x in `/bin/cat $RAMRC | /bin/grep "^\/"`
do
block=
raw=
mnt=
rnum=
block=`/bin/echo $x | /usr/bin/awk -F: '{print $1}'`
raw=`/bin/echo $x | /usr/bin/awk -F: '{print $2}'`
mnt=`/bin/echo $x | /usr/bin/awk -F: '{print $6}'`
rnum=`/bin/echo $x | /usr/bin/awk -F: '{print $7}'`
if [ "$rnum" = "" ]
then
echo "$0: error in /etc/ramtab, can't continue"
exit 1
fi
# test if the driver is open
ramstat -n${rnum} | grep open > /dev/null
if [ $? != 0 ]
then
continue
fi
if [ "$block" = "" ]
then
echo "$0: Block device not specified, entry ignored ***"
continue
fi
if [ "$raw" = "" ]
then
echo "$0: Raw device not specified, entry ignored ***"
continue
fi
if [ "$mnt" = "" ]
then
/bin/ramstat -r $block $raw
else
if /etc/umount $block
then
/bin/ramstat -r $block $raw
fi
fi
done
;;
*) /bin/echo "$0: illegal option $1" ;;
esac
\gux-shar\
else
echo "will not over write ./raminit"
fi
if `test ! -s ./raminit.1m`
then
echo "writing ./raminit.1m"
cat > ./raminit.1m << '\gux-shar\'
.TH RAMINIT 1M
.SH NAME
.B raminit
\- memory resident disk interface control script
.SH SYNOPSIS
.B raminit -ri [ -v ]
.SH DESCRIPTION
.B Raminit
is the control script program used to configure the Ram disk device.
It reads the file
.B /etc/ramtab
to find out how to configure the ram disks.
.PP
The ram disk interface allows up to 4 ram disks to be resident in
memory at any one time.
.PP
.B Raminit
sets up the ram disks via
.B /bin/ramstat
and then runs
.B mkfs(1M)
and
.B fsck(1M)
to create the file systems and check them before using
.B mount(1M)
to mount them accordingly.
.PP
The option
.B -i
is used to initiate the ram disks, while the
option
.B -r
is used to delete them,
.B -v
is an optional
parameter which turns verbose mode on (default is off).
.PP
Deleting the ram disks frees up memory allowing it to be used
again by user programs.
.PP
The structure of the file
.B /etc/ramtab
is as follows:
.P
.TP 16
.B field 1
The Block device path name.
.br
.TP 16
.B field 2
The Raw device path name.
.br
.TP 16
.B field 3
The size in blocks of the ram disk.
.br
.TP 16
.B field 4
The number of inodes for the new file system.
.br
.TP 16
.B field 5
File system label.
.br
.TP 16
.B field 6
The name of the empty directory to mount the file system on to.
.br
.TP 16
.B field 7
The minor number of the ramdisk associated with the new file system.
.PP
Each field is separated by a ':' character.
.SH EXAMPLES
.PP
.ti+6
/dev/dsk/ram0:/dev/rdsk/ram0:750:200:tmp:/tmp:0:
.PP
This
.B ramtab
entry is used by
.B raminit
to create a ram disk using the block special file
.B /dev/dsk/ram0
and the character special file
.B /etc/rdsk/ram0,
of 750 physical blocks of memory, construct a file
sytem with 200 inodes and label it tmp, mount the new
file system onto /tmp, using minor device 0.
.SH FILES
/dev/ctrlram
.br
/dev/rdsk/ram?
.br
/dev/dsk/ram?
.br
/dev/console
.br
/etc/ramtab
.br
/bin/ramstat
.SH SEE ALSO
fs(4),mkfs(1M),fsck(1M),mount(1M),labelit(1M),ramstat(1M)
.SH AUTHOR
B.M.Goodheart
\gux-shar\
else
echo "will not over write ./raminit.1m"
fi
if `test ! -s ./ramrc.d`
then
echo "writing ./ramrc.d"
cat > ./ramrc.d << '\gux-shar\'
#initialise and install the ram disks
/etc/raminit -i
\gux-shar\
else
echo "will not over write ./ramrc.d"
fi
if `test ! -s ./ramstat.1m`
then
echo "writing ./ramstat.1m"
cat > ./ramstat.1m << '\gux-shar\'
.TH RAMSTAT 1M
.SH NAME
.B ramstat
\- memory resident disk interface control
.SH SYNOPSIS
.B ramstat
.br
.B ramstat -n#
.br
.B ramstat -m
.br
.B ramstat -d
.br
.B ramstat -i blocks char_special
.br
.B ramstat -r block_special char_special
.SH DESCRIPTION
.B Ramstat
is the control program used to configure or get information from
the kernel about the Ram disk devices.
.PP
The meaning of the options are:
.br
.PP
.TP 8
.B -n#
Display statistics on the standard output of a ramdisk,
where '#' represents the minor number associated with the driver,
.TP 8
.B -m
Display statistics on the standard output of current
available memory resources. This option is not available on
80286 processors.
.TP 8
.B -d
Toggles debug mode.
.TP 8
.B -i
This parameter takes a further two arguments; the
block number being the number of physical blocks
to configure the ram disk with and the ram disk
raw interface path name.
.PP
.RS 8
This option is used to configure the ram disk
before building a file system on it.
.RE
.TP 8
.B -r
This parameter also requires a further two
arguments; the path names of the raw and block
interface files. This option is used to delete
the ram disk from existence freeing up memory.
This option will cause ramstat to fail if
the ram disk contains a currently mounted
file system.
.PP
If invoked with no parameters then
.I ramstat
will display status
information about all of the ramdisks on the standard output.
.PP
The meaning of the column headings are as follows:
.PP
RAM The ramdisk minor number.
.PP
BLOCKS The number of physical blocks the ram disk
was configured with.
.PP
STATE The current state of the ram disk open or closed.
.PP
OPENS The number of processes currently holding the
ramdisk open.
.PP
ADDR The physical base address in Hex of the ram disk
in memory.
.PP
The state of the debug mode is also displayed.
.PP
It is better to use the script
.I raminit
to invoke the -i and -r options. Raminit invokes
.I ramstat
in the long run any way. If
.I ramstat
is invoked in this way
it is possible to enter a single line in the /etc/rc file
to configure the ram disks at system boot time.
.SH FILES
/dev/ctrlram
.br
/dev/rdsk/ram?
.br
/dev/dsk/ram?
.br
/dev/console
.SH SEE ALSO
fs(4),mkfs(1M),fsck(1M),volcopy(1M),raminit(1M)
.SH BUGS
On the System V.4.0 version, the -m option gives an incorrect report
(0 is given). This seems to be a BUG in SV4.0 (sysinfo.h).
.SH AUTHOR
B.M.Goodheart
\gux-shar\
else
echo "will not over write ./ramstat.1m"
fi
if `test ! -s ./ramstat.c`
then
echo "writing ./ramstat.c"
cat > ./ramstat.c << '\gux-shar\'
/*
*
* @(#)ramstat.c 1.6 Copyright (C) B.M.Goodheart 1987, 1888, 1989, 1991
*
*
*
* DISCLAIMER OF WARRANTY.
* This software is distributed "as is" and without warranties as to
* performance of merchantability or any other warranties whether expressed
* or implied. In no event shall the author (the copyright holder) be held
* liable for any loss of profit or any other commercial damage resulting
* from the use or misuse of this software, including but not limited to
* special, incidental, consequential or other damages. The user must
* assume the entire risk of using this software.
*
*
* LISCENSE AGREEMENT
* This software is placed into the public domain and
* may be copied or distributed freely provided no profit or
* gain is made and is used for personal use only and the code
* as distributed retains all copyright notices in the code.
* This includes any copyright statements in the target
* binary and executable code produced from the distributed source.
*
*
* DISTRIBUTION NOTE
* This file contains the code for a RAM disk driver for UNIX System 5.2
* and System V.3. It has been designed specifically for Microport's
* System V/AT iAPX286 and Interactive Systems V/386 i386 systems
* but should work with other PC based System V.? ports with only
* minor modifications, specifically the BUFSEL selector on the 80286.
* This driver should work on any V.3 implementation on a PC.
*
*
* IMPORTANT NOTE !!!
* Any files or data stored within the ram disks will be
* LOST FOR EVER if the system is brought down for ANY reason.
*
* There are also two other programs distributed associated
* with the driver, they are ramstat(1M) and raminit(1M).
* These are used to control the ram disk driver in user mode
* See also ram(7).
*
* Berny Goodheart (berny at tndsyd.oz@munnari.oz.au)
*
* The user program /etc/ramstat is used to initialise the RAM disk
*
* -i Initialise the RAM disk.
* -r Delete and remove the RAM disk and all its contents
* -d toggle debug mode on or off
* -n# display stats of ram disk '#'
* -m get system memory info (i386) only
*
*
* 5-10-91 - SV4.0 MOD - R. L. Bolin @ gatech!sbmsg1!bsts00!rlb
* See defines for SV4
*/
#ifdef SV4
static char *bmgid = "@(#)ramstat.c 1.6 (SV4.0) Copyright (C) Berny Goodheart 5/20/91";
#else
static char *bmgid = "@(#)ramstat.c 1.6 Copyright (C) Berny Goodheart 5/20/91";
#endif
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ramd.h>
static int size;
static int fd;
char devnam[128];
extern int errno;
static int ramnum;
union r_ramst state;
#if i386
#define pdetophys(x) (x * 4096)
#endif
#ifdef SV4
static void
_trap(sig)
int sig;
#else
static void
_trap()
#endif
{
(void) signal(SIGINT,_trap);
if(fd > 0)
close(fd);
printf("Aborted\n");
exit(0);
}
main(argc,argv)
int argc;
char *argv[];
{
(void) signal(SIGINT,_trap);
ramnum = -1;
/*
* Allow users to get stats
*/
if(argc != 1)
setuid(getuid());
if((fd = open("/dev/ctrlram",O_WRONLY)) == -1){
perror("/dev/ctrlram");
exit(1);
}
if(argc == 1) {
ramstat(fd,TCGETRAM);
exit(0);
}
if(argv[1][0] != '-')
usage();
switch (argv[1][1]) {
#if i386
case 'm':
if(argc != 2)
usage();
ramstat(fd,TCMEMINFO);
break;
#endif
case 'n':
if(isdigit(argv[1][2])) {
ramnum = atoi(&argv[1][2]);
ramstat(fd,TCGETRAM);
} else usage();
break;
case 'd':
if(argc != 2)
usage();
ramstat(fd,TCRAMDBG);
break;
case 'r':
if(argc != 4)
usage();
close(fd);
if((fd = open(argv[2],O_WRONLY)) == -1){
perror(argv[2]);
exit(1);
}
close(fd);
if((fd = open(argv[3],O_WRONLY)) == -1){
perror(argv[3]);
exit(1);
}
strcpy(devnam,argv[3]);
if(umount(argv[2]) == -1) {
if(errno != EINVAL) {
perror(argv[2]);
exit(1);
}
}
ramstat(fd,TCDELRAM);
break;
case 'i':
if(argc != 4)
usage();
close(fd);
if((fd = open(argv[3],O_WRONLY)) == -1){
perror(argv[3]);
exit(1);
}
strcpy(devnam,argv[3]);
if((size = atoi(argv[2])) < 20) {
fprintf(stderr,"ramstat: illegal block size\n");
exit(1);
}
ramstat(fd,TCSETRAM);
break;
default :
usage();
}
close(fd);
exit(0);
}
ramstat(fd,mode)
int fd, mode;
{
int x,m;
switch(mode) {
#if i386
case TCMEMINFO:
if((x = ioctl(fd,TCMEMINFO,&state)) != -1)
printf("maxmem %ld\nfreemem %ld\n",
pdetophys(state.r_meminfo.r_maxmem),
pdetophys(state.r_meminfo.r_freemem));
break;
#endif
case TCDELRAM:
if((x = ioctl(fd,TCDELRAM,0)) != -1)
printf("Ram disk %s closed\n",devnam);
break;
case TCSETRAM:
state.r_arg = size;
if((x = ioctl(fd,TCSETRAM,&state)) != -1)
printf(
"\nRam disk (%s) initialized (%d Physical Blocks)\n\n"
,devnam,size);
break;
case TCRAMDBG:
if((x = ioctl(fd,TCRAMDBG,&state)) != -1)
printf("Ram disk debug mode %s\n",
state.r_arg == 0 ? "OFF" : "ON");
break;
case TCGETRAM:
if((x = ioctl(fd,TCGETRAM,&state)) != -1) {
if(ramnum == -1)
printf("\n RAM BLOCKS STATE OPENS ADDR\n");
for(x = 0; x < NRDEVS;x++) {
if(ramnum != -1 && ramnum != x)
continue;
printf(
" %d %d %s %d 0x%x%c"
,state.r_rstat.r_dev[x]
,state.r_rstat.r_blks[x]
,state.r_rstat.r_stat[x]
== RAM_OPEN ? "open" : "closed"
,(state.r_rstat.r_opns[x]
== 0 ? 0 : state.r_rstat.r_opns[x] -1)
,state.r_rstat.r_addr[x]
,(ramnum == -1 ? '\n' : ' '));
}
if(state.r_rstat.r_dbg != 0) {
if(ramnum == -1)
printf("\n ");
printf(" Debug ON");
}
putchar('\n');
}/* if */
}
if(x < 0) {
perror("ramstat");
exit(1);
}
close(fd);
}
usage()
{
fprintf(stderr,"Usage: ramstat\n");
fprintf(stderr," ramstat -d\n");
fprintf(stderr," ramstat -n#\n");
#if i386
fprintf(stderr," ramstat -m\n");
#endif
fprintf(stderr," ramstat -r block_special char_special\n");
fprintf(stderr," ramstat -i blocks char_special\n");
exit(1);
}
\gux-shar\
else
echo "will not over write ./ramstat.c"
fi
if `test ! -s ./ramtab`
then
echo "writing ./ramtab"
cat > ./ramtab << '\gux-shar\'
#
# This file contains table information for the ram disk
# configuration program called "raminit".
#
# See manual entries ramstat(1M), raminit(1M), ram(7)
#
# block_dev:char_dev:size:inodes:label:mount directory:driver minor
#
# NOTE: the 80386 uses 4096 bytes in a block so size
# is n * 4096. The 80286 uses 512 byte blocks
#
# inodes and label are optional
/dev/dsk/ram0:/dev/rdsk/ram0:500:150:tmp:/tmp:0:
#/dev/dsk/ram1:/dev/rdsk/ram1:250:50:vbin:/vbin:1:
#/dev/dsk/ram0:/dev/rdsk/ram0:1500:100:tmp:/tmp:0:
#/dev/dsk/ram1:/dev/rdsk/ram1:500:100:ram1:/ram:1:
#/dev/dsk/ram2:/dev/rdsk/ram2:500::::2:
#/dev/dsk/ram3:/dev/rdsk/ram3:500::::3:
\gux-shar\
else
echo "will not over write ./ramtab"
fi
echo "Finished archive 1 of 1"
# if you want to concatenate archives, remove anything after this line
exit
.===========================================================================.
| ACSnet: berny at tndsyd.oz UUCP: uunet!munnari.oz!tndsyd.oz.au!berny |
| INTERNET: berny at tndsyd.oz.au DOMAIN: goodheart_berny at tandem.com |
| PSMAIL: smtpgate @comm(berny at tndsyd.oz@munnari.oz.au) |
TANDEM Computers Incorporated 76 Berry St, North Sydney, NSW, 2060, Australia
More information about the Comp.unix.sysv386
mailing list