Installation

Caldera Open Linux 1.2 lite was installed with a minimum of packages and no X11. The kernel was updated to 2.0.35 to be able to mount Juliet formated CD's.

The Xaudio binary rxaudio was copied to /bin and the aumix rpm was installed.

Two devices was created (one pty and one tty)  /dev/ptyuf and /dev/ttyuf for communication with rxaudio.

The playcom program is placed in /root/mp3-stereo together with the script mp3stereo for starting up. Another small program was written to print information on the LCD during boot-up (lcd_echo) this program was placed in /bin.

The total space required for the installation is 95MB, leaving about 300MB for mp3-files.

A directory called /mp3 was created for holding "local" mp3 files (files played from harddrive).

Running Linux on a read-only root directory

To be able to turn off the power of the MP3CD without trashing the filesystem I wanted to run linux with a read only root. This was accomplished by creating a few ramdisks during bootup and copying relevant files to the ramdisks at boot (kernel must be compiled with ramdisk support). To be able to do changes on the harddisk the rc.boot looks at the magic file "noramdisk"  in the root (/). If present the root directory is mounted rw and no ramdisks are created.

To do changes on the filesystem the following commands are issued after the system is booted.

mount -o remount,rw /
touch /noramdisk
sync
sync
sync
mount -o remount,ro /
reboot

Make required changes on filesystem and issue the following commands to be back on a read-only system.

rm /noramdisk
reboot

Changes in rc.boot and rc.local (/etc/rc.d)

Below are the changes I made to rc.local and rc.boot

rc.boot

#! /bin/sh
#
# /etc/rc.d/rc.boot - run once at boot time
#
# Taken in part from Miquel van Smoorenburg's bcheckrc.
# Modified for COL by Raymund Will <ray@lst.de>.
#

# Set the path
# don't use 'usr' until *all* filesystems are mounted!
PATH=/bin:/sbin
export PATH
umask 022

lcd_echo -c "Booting...\n"
# setting up IDE hard drives
if [ `uname -m` = alpha ]; then
  echo "Setting up IDE hard drives on an Alpha"
  for n in hda hdb hdc hdd; do
    hdparm -m 16 /dev/$n 2>/dev/null >/dev/null
  done
fi

## collect configuration variables
# Time files in /tmp are kept.
TMPTTL=`get_val CONF_INIT_TMP_TTL`
# Set to yes if you want sulogin to be spawned on bootup
SULOGIN=`get_val CONF_INIT_SULOGIN`
# Set to no if you want to be able to login over telnet/rlogin
# before system startup is complete (as soon as inetd is started)
DELAYLOGIN=`get_val CONF_INIT_DELAYLOGIN`
# Set GMT="-u" if your system clock is set to GMT, and GMT="-l" if you lose.
GMT="`get_val CONF_KERNTZ_FLAG`"
# Get tuneable critical system resources...
MAXFILES="`get_val CONF_INIT_MAX_FILES`"
MAXINODES="`get_val CONF_INIT_MAX_INODES`"


# Read in config data.
. /etc/sysconfig/network

# Enable multiple devices.  We do this here because we may be
# swapping to them, or something.  If /etc/mdtab doesn't exist
# or is empty we don't bother; likewise if mdadd isn't installed.
if [ -s /etc/mdtab -a -f /sbin/mdadd ]; then
  mdadd -ar
fi

# Activate the swap device(s) in /etc/fstab. This needs to be done
# before fsck, since fsck can be quite memory-hungry.
echo "Activating swap..."
swapon -a 2>&1 | sed -e '/busy/d'

# Ensure that bdflush (update) is running before any major I/O is
# performed (the following is a good example of such activity :).
update

# Set the hostname.
hostname ${HOSTNAME}

# Check filesystems
if [ -f /fastboot ]; then
  echo "*** WARNING!  File systems are NOT being checked!"
  echo
else
  # Ensure that root is quiescent and read-only before fsck'ing.
  mount -n -o remount,ro /
  if [ $? != 0 ]; then
    echo "*** ERROR!  Cannot fsck because root is not read-only!"
    echo
  else
    lcd_echo "Checking fs...\n"
    echo "Checking filesystems..."
    fsck -A -V -a
    # If there was a failure, drop into single-user mode.
    #
    # NOTE: "failure" is defined as exiting with a return code of
    # 2 or larger.  A return code of 1 indicates that file system
    # errors were corrected but that the boot may proceed.
    if [ $? -gt 1 ]; then
      lcd_echo "fsck failed!\n"
      echo
      echo "fsck failed.  Please repair manually and reboot.  Please note"
      echo "that the root file system is currently mounted read-only.  To"
      echo "remount it read-write:"
      echo
      echo "   # mount -n -o remount,rw /"
      echo
      echo "CONTROL-D will reboot the system."
      echo
      # Start a single user shell on the console
      export PS1="(Repair filesystem) #"
      /sbin/sulogin $CONSOLE
      sync
      echo "Automatic reboot in progress."
      reboot
    fi
    echo
  fi
fi

############################################
# Create required RAMDISKS
# K.Elmby
############################################
lcd_echo "Creating ramdisks\n"
# /etc
if [ ! -f /noramdisk ]
then
   echo "Creating Ramdisk 0 (/etc)"
   dd if=/dev/zero of=/dev/ram0 bs=1k count=2048 > /dev/null 2> /dev/null
   mkfs -t ext2 /dev/ram0 2048 > /dev/null 2> /dev/null
   mount -n /dev/ram0 /mnt > /dev/null 2> /dev/null
   echo "Copying /etc to ramdisk"
   cp -a /etc/. /mnt
   umount -n /mnt
   mount -n /dev/ram0 /etc
   #
   # Remount filesystems
   #
   rm -f /etc/mtab /etc/mtab~ /etc/nologin /fastboot
   mount /dev/ram0 /etc -o remount,rw
   mount -o remount,ro /
   # /tmp
   echo "Creating Ramdisk 1 (/tmp)"
   dd if=/dev/zero of=/dev/ram1 bs=1k count=256 > /dev/null 2> /dev/null
   mkfs -t ext2 /dev/ram1 256 > /dev/null 2> /dev/null
   mount /dev/ram1 /tmp > /dev/null 2> /dev/null
   # /var/lock
   echo "Creating Ramdisk 2 (/var)"
   dd if=/dev/zero of=/dev/ram2 bs=1k count=1024 > /dev/null 2> /dev/null
   mkfs -t ext2 /dev/ram2 1024 > /dev/null 2> /dev/null
   mount /dev/ram2 /mnt
   echo "Copying /var to ramdisk"
   cp -a `ls -d /var/* | /usr/bin/grep -v lib` /mnt
   umount /mnt
   mount /dev/ram2 /var 
   lcd_echo "Starting daemons\n"
else
   # Remount the root file system in read-write mode,
   # then cleanup and ensure /etc/mtab is up-to-date.
   mount -n -o remount,rw /
   rm -f /etc/mtab /etc/mtab~ /etc/nologin /fastboot
   mount -o remount,rw /
fi
# Put a nologin file in /etc to prevent people from
# logging in before system startup is complete.
if [ "$DELAYLOGIN" = yes ]; then
  echo "System bootup in progress - please wait" > /etc/nologin
  cp /etc/nologin /etc/nologin.boot
fi

# Mount local file systems in /etc/fstab.
# Contrary to standard usage, filesystems are NOT unmounted in
# single user mode.
echo "Mounting local file systems..."
mount -avt nonfs

# Modify critical resources provided they're non-nil...
if [ -d /proc/sys/kernel ]; then
  [ $RC_VERBOSE ] && echo -n "Modifying critical system resources: "
  if [ "x$MAXFILES" != "x" ]; then
    [ $RC_VERBOSE ] && echo -n " file-max=$MAXFILES"
    echo $MAXFILES > /proc/sys/kernel/file-max
    [ "x$MAXINODES" = "xx3" ] && MAXINODES=`do_calc $MAXFILES x 3 2>/dev/null`
  fi
  if [ "x$MAXINODES" != "x" ]; then
    echo $MAXINODES > /proc/sys/kernel/inode-max
  fi
fi

# Execute swapon command again, in case we want to swap to
# a file on a now mounted filesystem.
swapon -a 2>&1 | sed -e '/busy/d'

# Setup the network interfaces. Note that /var/run and /var/lock
# are cleaned up after this, so don't put anything in the "network"
# script that leave a pidfile or a lockfile.
if [ -x /etc/rc.d/init.d/network ]; then
  rm -f /var/lock/subsys/network
  /etc/rc.d/init.d/network start
fi

# Now that TCP/IP is configured, mount the NFS file systems in /etc/fstab.
echo "Mounting remote file systems..."
mount -a -t nfs

# Finally we can use a more complete path...
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

# tell kernel local timezone and whether CMOS clock ticks UTC/GMT or not...
ktzset $GMT

# Now that /usr/lib/zoneinfo should be available, announce the local time.
#echo
#echo "Local time: `date`"
#echo

echo -n "Cleaning up:"
if [ "`echo "$TMPTTL" | sed -n 's/^[0-9][0-9]*$/OK/p'`" = "OK" ]; then
  # Wipe /tmp (and don't erase `lost+found', `quota.user' or `quota.group')!
  # Note that files _in_ lost+found _are_ deleted.
  echo -n " /tmp"
  ( cd /tmp && \
    find . -xdev \
    ! -ctime -$TMPTTL \
    ! -name . \
    ! \( -name lost+found -uid 0 \) \
    ! \( -name quota.user -uid 0 \) \
    ! \( -name quota.group -uid 0 \) \
      -depth -exec rm -rf -- {} \; )
fi

echo -n " /var/lock"
# Clean up any stale locks.
# HACK ALERT! We need to save the 'subsys/network' lock...
mv -f /var/lock/subsys/network /var/adm/network.$$ 2> /dev/null
( cd /var/lock && find . -type f -exec rm -f -- {} \; )
# HACK ALERT! We need to restore the 'subsys/network' lock...
mv -f /var/adm/network.$$ /var/lock/subsys/network 2> /dev/null

# Load the random generator.
if [ -c /dev/urandom -a -f /var/run/random-seed ]; then
  cat /var/run/random-seed > /dev/urandom
fi

echo -n " /var/run"
# Clean up /var/run and create /var/run/utmp so that we can login.
( cd /var/run && find . ! -type d -exec rm -f -- {} \; )
: > /var/run/utmp

# Save the random seed.
if [ -c /dev/urandom ]; then
  ( umask 077;
    dd if=/dev/urandom of=/var/run/random-seed count=1 >/dev/null 2>&1
  )
fi
echo "."

if [ -f /initrd/free_initrd ]; then
  echo -n "initrd:"
  [ -d /initrd/proc ] && umount /initrd/proc >/dev/null 2>&1
  if [ -f /initrd/save_initrd -a ! -d /var/tmp/initrd ]; then
    # saving original initrd contents to /var/tmp/initrd for debugging
    echo -n " save"
    cp -aR /initrd /var/tmp/initrd 
  fi

  # freeing initrd memory
  echo -n " umount"
  umount /initrd >/dev/null 2>&1
  if [ -x /bin/freeramdisk ]; then
    echo -n " free"
    freeramdisk
  fi
  echo "."
fi

if [ -x /etc/rc.d/unconfigured.sh ]; then
  /etc/rc.d/unconfigured.sh
fi

# Initialize the serial ports.
if [ -f /etc/rc.d/rc.serial ]; then
  sh /etc/rc.d/rc.serial
fi

# Load modules (for backward compatibility with VARs)
if [ -f /etc/rc.d/rc.modules ]; then
  /etc/rc.d/rc.modules
fi

rc.local

#!/bin/sh

# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

if [ -r /etc/.issue ]; then
	cat /etc/.issue > /etc/issue
else
	cat << EOI > /etc/issue

Caldera OpenLinux(TM)
Copyright (C) 1996-1998 Caldera, Inc.

EOI
fi

cp -f /etc/issue /etc/issue.net
echo >> /etc/issue

# --- Startup of MP3-Player
echo "Starting MP3-Player"
cd /mp3
/usr/bin/aumix -v 99 -w 99
/root/mp3-stereo/mp3stereo 2> /dev/null > /dev/null &