Baton is the name of the mini-ITX computer, originally used for the orchestra laboratory course. Here the installation procedure is summarized.

Basic Installation

The installation has to be made two times. First on a 1GB partition and second on a bigger partition of an external hard disk. The bigger one is just for testing, but the first one will be copied to a flash disk later and contains the independent operating system for Baton. In the following only the installation of the small system for the flash disk will be described because there have to be made some changes to get the system read-only.

  • Install Debian GNU Linux 3.1. Use the DVD Iso Image from Use "testing" version, because "stable" is too old (2.4.x by now) and does not support the VIA ethernet adapter. Also don't install any further packages, only the base system! Do the installation without swap space, even if you get a warning!
  • Add user "baton":
  • To get the newest packages it is useful to have an internet-connection via wired ethernet. Wireless-LAN will be installed later. Add a mirror to /etc/apt/sources.list and comment out the entries for the CD. It should look like this: # deb cdrom:[Debian GNU/Linux testing _Etch_ - Official Snapshot i386 Binary-1 (20060925)]/ etch contrib main deb etch main deb-src etch main deb etch/updates main contrib deb-src etch/updates main contrib
  • Update the whole system (e.g. with aptitude).
  • Add necessary packages via aptitude or apt-get: apt-get install ssh less xorg lwm make nano


To get ugly kernel messages away from the console, do the following:

  • Remove the comment signs after "I like to have messages..." and comment out the paragraph below in /etc/syslog.conf: # # I like to have messages displayed on the console, but only on a virtual # console I usually leave idle. # daemon,mail.*;\

news.=crit;news.=err;news.=notice;\ *.=debug;*.=info;\ *.=notice;*.=warn /dev/tty12

# The named pipe /dev/xconsole is for the `xconsole' utility. To use it, # you must invoke xconsole' with the -file' option: # # $ xconsole -file /dev/xconsole [...] # # NOTE: adjust the list below, or you'll go crazy if you have a reasonably # busy site.. # #daemon.*;mail.*;\ # news.crit;news.err;news.notice;\ # *.=debug;*.=info;\ # *.=notice;*.=warn |/dev/xconsole

  • Also change the log level for kernel messages in /etc/sysctl.conf by uncommenting following line: # Uncomment the following to stop low-level messages on console kernel.printk = 4 4 1 7


The Wireless-LAN Adapter is an Allnet PCI-Card based on an Artheros chipset, so the madwifi drivers are needed, which weren't part of the Debian distribution. Install them by hand, but on the big system! Later the compiled modules will simply be copied to the small system.

  • To compile the sources, the kernel sources are needed, too. In the following the building of the kernel is described. We use version 2.6.17.

Building a Debian kernel

  • First install the kernel-sources. You'll also need some other tools, if they haven't been installed already. apt-get install build-essential kernel-package libncurses5-dev linux-source-2.6.17
  • Build a standard kernel with the basic Debian configuration (or specified for Baton, if you've got the time), but ensure that Wireless-LAN support will be compiled in: cd /usr/src/linux-source-2.6.17 make menuconfig make-kpkg --initrd kernel_image dpkg -i /usr/src/linux-image-2.6.17_....deb
  • Copy the new kernel and additional files from /boot/ to the same location on the small system: cd /boot cp vmlinuz-2.6.16 initrd.img-2.6.17 /wherever/thesmallsystem/ismounted/boot/
  • Ensure that there's an entry in /boot/grub/menu.lst for the new kernel and reboot the (big!) system.

Installation of the madwifi driver

  • Get the latest madwifi sources from the  Madwifi Homepage and save them to /usr/src/, extract the archive and compile the sources. Here we used version 0.9.2. tar xvzf madwifi-0.9.2.tar.gz cd madwifi-0.9.2 make make install update-modules
  • Update /etc/modules in adding the four needed modules (on both systems): wlan wlan_wep ath_hal ath_pci
  • Copy the compiled modules to the small system and boot the small system. Don't forget to make a modules update. cp -r /lib/modules/2.6.17/net/ /wherever/thesmallsystem/ismounted/lib/modules/2.6.17/ reboot update-modules

Now Wireless-LAN is ready to work, but it still has to be configured. Use wpa_supplicant as described in the following.

Installation of wpa_supplicant

  • Install wireless-tools and wpa_supplicant. apt-get install wireless-tools wpa_supplicant
  • Configure wpa_supplicant in editing /etc/wpa_supplicant.conf:

ctrl_interface=/var/run/wpa_supplicant ctrl_interface_group=0

eapol_version=1 ap_scan=1 fast_reauth=1


ssid="rtsys-wifi" key_mgmt=WPA-PSK psk="rTsYs2410" auth_alg=OPEN


  • Add the following to /etc/network/interfaces:

# The wireless network interface allow-hotplug ath0 iface ath0 inet dhcp

wpa-driver madwifi wpa-conf /etc/wpa_supplicant.conf

After a reboot, the system should have access to the internet via Wireless-LAN.

FireWire camera

Baton should run BIAS applications with a camera which is connected via FireWire. There is no problem with that, except that BIAS was designed for SuSE based systems and in SuSE the device names are a bit different.

  • To support SuSE-like device names for FireWire cameras, the best way is to edit /etc/udev/devfs.rules. Search for the following entry: KERNEL=="video1394*", NAME="video1394/%n"

Edit it to become:

KERNEL=="video1394*", NAME="video1394/%n", SYMLINK+="video1394-%n"

  • Do the same with /etc/udev/udev.rules.

Now, after a reboot, plugging the FireWire camera will generate /dev/video1394/0 with a symlink /dev/video1394-0 which is the SuSE-like name.

At last, the user baton should get access to the devices /dev/raw1394 and /dev/video1394/0.

  • This could simply be done by adding baton to the groups video and disk: adduser baton video adduser baton disk

Running an X application automatically after boot

Baton is designed to run an application automatically without any user interactivity, especially Baton should run a user application automatically after booting without a login. To achieve this behaviour we have to do an automatic login followed by starting X and running the application.

  • First, install rungetty: apt-get install rungetty
  • Edit /etc/inittab. Search for the "/sbin/getty invocations" and edit the entry for tty6: 6:23:respawn:/sbin/rungetty tty6 -u root -- login -f baton
  • Add the following line to /home/baton/.bash_profile: startx ~/launchdefault
  • Create a script which exactly does the things, which should be done automatically after boot, e.g. starting an application

Now, baton will be automatically logged in on tty6 and X will be started with the desired application.

Optional: NTP daemon

It can be useful to have the system time synchronized with the real time:

  • Install openntpd: apt-get install openntpd
  • Configure openntp: Add following line in /etc/openntpd/ntpd.conf: server

Making the system read-only

The hardest point is to get the system read-only so that it won't crash the flash disk it will be copied to, caused by too many writing actions. This will be realized by using the unionfs which is also used by Knoppix, for example. Unionfs will make the filesystem writable in the users view, but in reality all changes will be made to the RAM and the disk will stay read-only, so after a reboot all changes will be lost.

  • Please boot the small system, which will be made read-only, first and login as root, if you haven't done that before.

Installation of the unionfs module

  • Create a directory where the filesystem can be remounted writable again, to apply permanent changes to the disk:

mkdir /mnt/root-rw

  • You have to install the unionfs module and you need the initramfs-tools: apt-get install unionfs-modules-2.6.17-2-486 initramfs-tools
  • After the install it is possibly located wrong. Move the module in /lib/modules/2.6.17-2-486/extras/unionfs/unionfs.ko to the location of modules of the kernel which is desired to run, e.g. /lib/modules/2.6.17. Please create any directory which is needed and doesn't exist. mv /lib/modules/2.6.17-2-486/extras/unionfs /lib/modules/2.6.17/extras/
  • Don't forget to update the module database: update-modules

Change the rootfs to unionfs

  • The unionfs module has to be made accessable by the init process, so it has to be added to the initial ramdisk: echo unionfs >> /etc/initramfs-tools/modules
  • Tell init that it has to mount root on a read-only disk overlaid by a writable ramdisk with unionfs. Edit the script /usr/share/initramfs-tools/scripts/local to do that:


mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}


mkdir /REALROOT mkdir /RAMDISK mount ${roflag} -n -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /REALROOT mount -n -t tmpfs -o size=256M none /RAMDISK mount -t unionfs -o dirs=/RAMDISK=rw:/REALROOT=ro none ${rootmnt} mount -o bind /REALROOT ${rootmnt}/mnt/root-rw

  • Now the initial ramdisk has to be built again. Get your exact kernel version. It is the same as of its module directory, e.g. 2.6.17. Then use update-initramfs. The tool will print an error message if there already exists an initial ramdisk. Please remove it in that case. update-initramfs -c -k 2.6.17
  • The tool automatically copies the new ramdisk to /boot. You may only need to update your entries in /boot/menu.lst if necessary. Then reboot to have a try.

Testing the read-only filesystem

Now, changes on the rootfs should only be made to the ram and not to the disk. To try this you may add a file in any directory (e.g. a user's home) and look if it appears at the same location on the disk (which is mounted at /mnt/root-rw):

/home/baton# touch testfile /home/baton# ls testfile /home/baton# cd /mnt/root-rw/home/baton /mnt/root-rw/home/baton# ls /mnt/root-rw/home/baton#

Additionally, writing in /mnt/root-rw should not be possible:

/mnt/root-rw/home/baton# touch testfile2 touch: cannot touch `testfile2': Read-only file system /mnt/root-rw/home/baton#

Write access on the read-only system

Anyway, to apply changes permanently to the disk, we have to remount /mnt/root-rw writable. This can only be done by root, so no abuse can be made by a normal user. It is useful to create a little script for that.

  • Create following script, call it "makewritable" and post it in /root: #!/bin/bash mount -o remount,rw /mnt/root-rw echo "The root filesystem is now writable in /mnt/root-rw/."
  • Change the permissions to make it executable for root, but not for users: chmod 744 ~/makewritable
  • Create an analog script to make the disk read-only again. Call it "makereadable" and post it in /root: #!/bin/bash mount -o remount,ro /mnt/root-rw echo "The root filesystem is now read-only in /mnt/root-rw/ again."
  • Do the permission change: chmod 744 ~/makereadable

Now, have a try again:

/mnt/root-rw/home/baton# ~/makewritable The root filesystem is now writable in /mnt/root-rw/. /mnt/root-rw/home/baton# touch testfile2 /mnt/root-rw/home/baton# ls testfile2 /mnt/root-rw/home/baton# cd /home/baton /home/baton# ls testfile testfile2 /home/baton#

Please don't forget to make the disk read-only again, because once it is made writable any user has write access in its /home equivalent in /mnt/root-rw. This could easily be abused!

/home/baton# ~/makereadable The root filesystem is now read-only in /mnt/root-rw/ again. /home/baton#

Avoiding an inconsistent filesystem

Because the file system is not being cleanly unmounted on a reboot or halt (I'm sorry for that, but I still don't know why) you should ensure that the disk is not writable when the system goes down to protect it from an inconsistent state. You could edit an init script to do that. For a read-only system, there is no problem with that, because no changes could have been made.

  • So, edit the function do_stop() in /etc/init.d/umountroot: do_stop () {
[ "$VERBOSE" = no ]
log_action_begin_msg "Mounting root filesystem read-only"

MOUNT_FORCE_OPT= [ "$(uname -s)" = "GNU/kFreeBSD" ] && MOUNT_FORCE_OPT=-f # This: # mount -n -o remount,ro / # will act on a bind mount of / if there is one. # See #339023 and the comment in # If remounting / read only doesn't work, it will try # mount -n -o remount,ro /mnt/root-rw/ # because /mnt/root-rw/ should be a mirror of the real root-device. mount $MOUNT_FORCE_OPT -n -o remount,ro -t dummytype dummydev / 2>/dev/null \

mount $MOUNT_FORCE_OPT -n -o remount,ro dummydev / 2>/dev/null \
mount $MOUNT_FORCE_OPT -n -o remount,ro /
mount $MOUNT_FORCE_OPT -n -o remount,ro /mnt/root-rw/


[ "$VERBOSE" = no ]
log_action_end_msg $ES


Installation on the flash disk

In the following it is suggested that the flash disk is /dev/hdc and the small system is on /dev/sda1.

  • First, make sure there is an entry for the flash system in /boot/grub/grub.conf
  • Create a partition of the whole flash disk, e.g. with fdisk fdisk /dev/hdc
  • Create an ext2 Filesystem on this partition. We don't need a filesystem like reiserfs or ext3 which supports journaling because there is no write access anyway. mke2fs /dev/hdc1
  • Now mount (or remount) the source partition on any mount point, like /mnt/usb/ and the flash disk on another, like /mnt/flash/. Make sure that the mount points exist. mount /dev/sda1 /mnt/usb mount /dev/hdc1 /mnt/flash
  • Copy the whole filesystem using cp -a. Don't forget the -a (archive) option. It is for preserving file permissions, copying directories recursively and not following any links, but copying them. cp -a /mnt/usb/* /mnt/flash/
  • Install the bootloader (grub) on the flash disk: grub-install --root-directory=/mnt/flash /dev/hdc

Now, the system is ready to boot from flash! I hope, I didn't forget anything... ;-)

Further Administration