berny@tndsyd.oz.au (Berny Goodheart) (05/20/91)
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@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@tndsyd.oz@munnari.oz.au DOMAIN: goodheart_berny@tandem.com ACSnet: berny@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@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@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@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@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@tndsyd.oz UUCP: uunet!munnari.oz!tndsyd.oz.au!berny | | INTERNET: berny@tndsyd.oz.au DOMAIN: goodheart_berny@tandem.com | | PSMAIL: smtpgate @comm(berny@tndsyd.oz@munnari.oz.au) | TANDEM Computers Incorporated 76 Berry St, North Sydney, NSW, 2060, Australia