On this page
- CF Card or Microdrive?
- Setting Up the Root Filesystem
- Initialize the Partitions and Mount
- Installing the Voyage Linux 2.6.15 Kernel
- Configuration (Post-boot)
- Neat WRAP Tricks
BUILDING A PC ENGINES WRAP SYSTEM FOR GENERAL-PURPOSE USE
KEYWORDS: PC ENGINES WRAP WRAP BOARD WRAP PLATFORM LINUX DEBIAN SBC SOC LINUX ON WRAP LOW-POWER SMALL SILENT SERVER
Author: Nathan L. Cutler
Date: 18 June 2006
This document is provided in the hope that it may prove useful to someone. However, if you follow the procedures described in this document, you do so AT YOUR OWN RISK. The Author issues no guarantee that following the instructions herein will lead to the desired result. The Author accepts no responsibility for anything that happens to anyone who reads or otherwise uses this document.
I have run linux more or less as a user for over ten years now. For the
past few of those years I haven't really done much with it. In May 2006
my friend Chip Coldwell
(http://frank.harvard.edu/~coldwell) told me about an ARM-based Single
Computer (SBC) he had acquired and was turning into an answering
machine. He was doing neat things with it like enabling DMA transfers
in the kernel's serial driver. I had heard the term "embedded
computing" before but until
then I didn't realize what it meant. When I saw the pictures of Chip's
SBC (based on an Atmel "System-on-a-Chip" (SoC) chip (pun intended))
and read on the
net about people running Linux on these tiny, stripped down computers I
was captivated by the idea of having a linux system that consumes less
than 10W of power, with no spinning fans and disks. I eventually did
get a system working with no spinning fans, but I did have to relent
and get a spinning disk for it.
I spent about a week
looking at various options, but it basically boiled down to three:
- the WRAP platform from the Swiss-based PC Engines (http://www.pcengines.ch)
- a VIA EPIA board (Mini-ITX form factor) based on the C3 Eden chip
- resurrecting an old Pentium 90 board (with a passive heatsink), installing a USB adapter and running it with a flash drive instead of a hard disk
These are listed in the order that I considered them. At first I was
gung-ho for the WRAP but soon started worrying that it would be
underpowered for my needs, since I dreamed of using it to play MP3s and
run X, and stuff like that, and the WRAP has no sound or VGA capability
and no way to add them. So I got turned on to VIA's line of EPIA
boards, one of which has an on-board DC-DC converter and can be run
from a "wall wart". Again, after a couple days of research I was all
ready to buy components and build a system. But then my wife suggested
it might be better to wait before making an investment like that and I
got cold feet and started to consider the ultra-low-cost alternative
(third in the list above). For that, however, I'd have to buy one of
the new fanless switching power supplies and a USB adapter, adding
significant cost, and I knew that such a system would consume a lot
more power than the WRAP or the VIA EPIA.
Later I came to realize that solid-state memory cards and flash drives
are really not appropriate for running a general-purpose system. They
can be good for routers and other embedded applications that can get
away with a read-only drive + a small ramdisk, but for your day-to-day
Linux computing needs, you really need to have a spinning hard drive.
Luckily, there are affordable Microdrives now that plug right into the
WRAP's CF slot, which accepts both Type I and Type II CF cards.
I Take the Plunge
I eventually decided for the WRAP, for the following reasons:
- Lowest power consumption of the 3 options, by far
- Extreme miniaturization - makes it seem cooler
- Support small business - the board is designed by a guy in Switzerland, not a corporation
- It can be modified to support USB, so I can connect printers and the CDMA modem to it.
- It has more memory (128MB) than the old Pentium 90 board, for which it would be difficult to find memory modules
- I could live without the audio and video capabilities, since I can always do A/V stuff on my regular linux box
So I bought the WRAP board. Since I want and need my system to have USB capability, I was pleasantly surprised to hear they had a dual USB adapter for it on-hand, so I got that as well. More on adding the USB option later. I also bought a Compact Flash-IDE adapter, which (purportedly) allows you to plug a CF card into a regular IDE interface and have it look like a hard disk.
After I got home I realized two critical components were still missing:
(1) a CF card for the root filesystem, and (2) a NULL Modem cable,
without which I would not be able to watch the boot messages. For power
I decided to use a "Universal" AC/DC power adapter that I had in
storage. I got it out, found a connector that fit the board, and tested
the output using my multimeter. It was dead-on at 12V, and I'm assuming
that the 6VA that it produces will be enough to power the WRAP board.
The NULL Modem cable you need has 9-pin female connectors on both ends. Since the WRAP board does not have any VGA capability, the only way to get into BIOS setup and watch the boot messages is through the serial port (hence the NULL Modem cable), using a terminal emulator on a second computer.
CF Card or Microdrive?
At first I had the mistaken notion that I would have the root filesystem on a 512MB CF card and have the rest of my data on a 1GB flash drive connected via USB 1.1 (the WRAP does not support USB 2.0). Luckily I didn't buy the flash drive, though I did buy the CF card - still, it was cheap (less than 400 CZK) and I can keep a Voyage Linux installation on it if I ever decide to use the WRAP as a dedicated router.
After trying to install a Debian system on the CF card and running aground when it came to making it work read-only with only certain mission-critical files and directories on a tmpfs (RAM disk) filesystem, I gave up and installed Voyage Linux 0.2. That was relatively painless, and it was nice to see my little WRAP board boot and give me a linux prompt, but gradually it dawned on me that I really need to have a hard drive, because I want to use the system on a day-to-day basis and need the root filesystem to be read-write all the time. After some research, I arrived at three different options for adding a HDD to the WRAP:
- Build my own CF-to-IDE adapter (i.e. one that will allow me to plug an IDE drive into the CF slot on the WRAP board)
- Buy a NASD (Network Attached Storage Device), reflash the firmware on it to make it run Linux, export NFS shares to the WRAP
- Buy a Microdrive and plug it into the CF slot on the WRAP
I wrote them in the order they came to me. The first option was the
most interesting to me, since I figured I've got three or four 3.5"
drives lying around, I could use one of them. However, incredible as it
may seem, there is no readily-available adapter that will make a CF
slot into an IDE port, even though the CF slot operates in "True IDE"
mode. Part of the problem is the voltage - the WRAP board only supplies
3.3V to the CF, while an IDE drive needs 5V. That makes it more of a
hardware hacking type of proposition, involving soldering up 44 wires.
Would be difficult with the standard IDE connector but with the CF
connector, which is much smaller, it would be nigh on impossible.
As of yesterday I had no idea that there was such a thing as an NAS. I
found out about them because I thought maybe there exists an adapter to
hook an IDE drive to an RJ45 Ethernet port. I figured since I have an
extra LAN interface I'm not using, I could hook the HDD to that. Sure
enough I found a bunch of little boxes that have hard drives in them -
you just plug them into your LAN and go. Thing is, these boxes are
significantly more expensive than a 3.5" HDD because inside they
contain SBCs (Single-Board Computers). But, I said to myself, a SBC is
what I'm trying to build here - it doesn't make much sense to have two
of them. Still, I was tempted to buy a Linksys LSLU2 Network Storage
Link, because I found there is an active community of enthusiasts out
there working on hacking it. They even have several different versions
of new firmware for it, so you can completely reflash the firmware and
turn it into a Linux box. This solution seemed interesting, but I had
to admit it was a sidetrack.
From my correspondence with Pascal Dornier, the WRAP board's designer,
I learned that you can just plug a Microdrive into the WRAP, and that
it will work. I hadn't considered this possibility, because (1) I only
had a vague notion of what a "Microdrive" is, and (2) I figured it
would require too much power for the WRAP board's power supply and (3)
I thought the WRAP only took CF Type I cards.. Turns out the Microdrive
is an ideal solution - Pascal was adamant that it would work so I went
out and bought one. With this hurdle overcome, the way to turning my
little WRAP board into a general-purpose Linux box was open.
According to the technical specifications, the IBM/Hitachi 4GB Microdrive consumes 395mA at 3.3V for writing, which is 1.3 watts.
Setting Up the Root Filesystem
Since I had time over the weekend, I poked around on the net and found a HOWTO (actually a blog entry) by Jan Willem (http://www.lextreme.nl) for installing a regular Debian system on the WRAP board. This appealed to me since the alternatives, like Voyage Linux, while explicitly supporting the WRAP, are geared for wireless routing applications and running the root filesystem from a CF card. I was looking for a more general-purpose solution, and just plain Debian seemed ideal. The installation is straightforward. You need a CF-to-IDE adapter to allow the Microdrive to be plugged into a computer that's already running Linux and has an Internet connection or a Debian installation CD. Essentially, it comes down to the following basic steps, which are just a slightly modified version of Jan Willem's procedure:
- Using fdisk, create two partitions on the Microdrive, swap and root
- Format the Microdrive using mkfs.ext3 (I will use a journaling filesystem) and mkswap
- Mount the Microdrive, say, under /mnt
- Using debootstrap, download and install a minimal Debian system in /mnt
- Install the 2.6.15 kernel from Voyage Linux 0.2, set up modules
- run lilo -r /mnt to install lilo bootloader
- Move Microdisk over to the WRAP
- Boot the WRAP
fdiskAfter plugging my CF-to-IDE card into my Linux box's IDE1 port, inserting the Microdrive into the CF slot, and powering up the Linux box, dmesg sees the Microdrive as /dev/hdc:
hdc: HMS360404D5CF00, CFA DISK drive ... hdc: max request size: 128KiB hdc: 7999488 sectors (4095 MB) w/128KiB Cache, CHS=7936/16/63, UDMA(33) hdc: cache flushes supported hdc: hdc1So I run "fdisk /dev/hdc" as root. The Microdrive comes pre-formatted with a FAT32 filesystem.
Disk /dev/hdc: 4095 MB, 4095737856 bytes 128 heads, 63 sectors/track, 992 cylinders Units = cylinders of 8064 * 512 = 4128768 bytes Device Boot Start End Blocks Id System /dev/hdc1 * 1 992 3999712+ b W95 FAT32Thus, the first step is to deep six that baby and create a swap partition and root partition in its place.
Disk /dev/hdc: 4095 MB, 4095737856 bytes 128 heads, 63 sectors/track, 992 cylinders Units = cylinders of 8064 * 512 = 4128768 bytes Device Boot Start End Blocks Id System /dev/hda1 1 32 128992+ 82 Linux swap / Solaris /dev/hda2 33 992 3870720 83 Linux
As you can see, I put the swap partition at the beginning of the disk. I could probably get away without any swap, but what the heck? 128MB is only about 3% of the disk. With a single-disk system the swap partition is "supposed" to be in the center of the disk, but having done this before I'd rather have all my data in a single filesystem than to spread it out over two.
Initialize the Partitions and Mount
Anyway, the next commands are to initialize the new partitions:
mount -t ext3 /dev/hdc2 /mnt
Install Minimal Debian System Using debootstrap
Then it occurred to me that either (1) ext3 support has to be compiled
into the kernel, or, (2) I have to use initramfs to load the ext3
module at boot time. This might pose a problem with the Voyage Linux
kernel, which is of the monolithic variety, if it doesn't have ext3
compiled in. But a quick look at
"voyage-0.2/boot/config-2.6.15-486-voyage" calmed me. ext3 is there. I
debootstrap sid /mnt ftp://ftp.cz.debian.org/debian/I wanted to install "sid", which is newer, but it failed at the point where it tried to download the "base-config" passage. For some reason, the sid package list includes "base-config" but the sid repository doesn't contain that package. Later, however, I learned that to install sid on a sarge system like mine, I have to upgrade to the sid version of debootstrap, which actually makes a lot of sense. After doing that, it worked, with nary an error.
In my previous attempt to get Debian running on the WRAP (using a CF card), I immediately chrooted to /mnt at this point and tried to configure the system while the CF card was still in my installation machine. This didn't work too well, especially when it came to running "base-config". The problem was locales - in the chroot jail, base-config didn't see any locale support, but it could see my locale environment variables. So it spewed a lot of warnings. Wanting to avoid this, I will dispense with the initial configuration and go right ahead to installing the kernel and running lilo.
Installing the Voyage Linux 2.6.15 KernelAfter a feeble attempt to compile a kernel package for the WRAP I gave up and downloaded Voyage Linux 0.2, which includes a pre-compiled kernel which has been patched to work well with the WRAP. One nice feature of this kernel (in addition to compiled-in ext3 support, as mentioned above), is that it has literally everything included as modules. So you don't have to recompile - if you need to activate a kernel feature, you just add the module's name to /etc/modules.
First, I unpacked the voyage-0.2 tarball and started poking around in it. I executed the following commands to get the Voyage kernel over to my CF root filesystem:
cp -a boot/* /mnt/boot
cp -a lib/modules/* /mnt/lib/modules
Basic Setup (Pre-boot)
Kernel ModulesThe first configuration file I tackled was /etc/modules. Here is the /etc/modules created by the Voyage Linux distribution setup script for the WRAP board, minus the WLAN drivers, which are not covered by this document:
# LAN interfacesAnother thing that occurred to me to do is "depmod" but then I realized that the modules.dep file is already there in /mnt/lib/modules/2.6.15-486-voyage, so there's no need.
# watchdog timer included in Geode
# Uncomment the following line if you are running watchdog daemon
# wd1100 sysctl_wd_graceful=0 sysctl_wd_timeout=30
# thermal monitor hardware
# National Semiconductor SCx200 ACCESS.bus (needed for temperature reading)
/etc/inittabThe next configuration file to edit is /etc/inittab. THIS IS CRUCIAL, OTHERWISE YOU WON'T GET A SERIAL CONSOLE. For obvious reasons, the standard Debian installation assumes you will have a keyboard and VGA as your linux console. But the WRAP needs a serial console. That means we edit /etc/inittab to get rid of the virtual consoles and enable a serial console. This is very straightforward, but you have to be careful with the baud rate - if it doesn't match what the WRAP BIOS is expecting, you won't see anything in the terminal emulator at boot. To find out what the WRAP is set to, hit the "s" key while the WRAP is doing its initial memory test. This will get you to the BIOS menu, where you can set 9600, 38400, or even higher baud rate. I went for 38400. Here's the full /etc/inittab file:
# /etc/inittab: init(8) configuration.The last line runs getty on the serial port, allowing one to log in as root.
# $Id: index.html,v 1.2 2006/06/19 08:52:38 livingston Exp $
# The default runlevel.
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
# What to do in single-user mode.
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
# Normally not reached, but fallthrough in case of emergency.
# What to do when the power fails/returns.
# Serial console for WRAP
T0:23:respawn:/sbin/getty -L ttyS0 38400 vt100
/etc/fstabHere we go with the KISS strategy (Keep It Simple, Stupid). Since we have a Microdrive, we can dispense with the notion of minimizing the number of writes to the root filesystem.
# WRAP with Microdrive
/dev/hda1 swap swap defaults, 1 1
/dev/hda2 / ext3 defaults, 0 0
proc /proc proc defaults
/etc/apt/sources.listThis file is used by "apt-get" to find repositories of deb packages. We only need one entry at this point:
deb http://ftp.debian.cz/debian/ sid mainOnce we have this file created in the /mnt tree, we chroot in and install additional packages. Some, like "less", are conveniences, but others, like "lilo", are critical and you won't be able to boot the WRAP without them.
chroot /mnt /bin/bash
apt-get install watchdog # goes with wd1100 module
apt-get install less
apt-get install lilo # CRITICAL! THIS IS A MUST!
apt-get install udev # CRITICAL! THIS IS A MUST!
apt-get install [your favorite package that you can't live without]
elsewhere, though, not speaking from experience.
/etc/lilo.confThe next step is to install lilo (have I really gotten this far?!). Here is how I did it. After hacking away and RTFMing I came up with this for the configuration file:
boot = /dev/hdc # Microdrive shows up as /dev/hdc on my systemIf you are using "sid", there is a hitch: the chroot in "sid" works differently from the one in sarge. In the chroot environment, there is no "/dev/hda" or "/dev/hdc" at all. When you run "df" you get this:
disk = /dev/hdc # Microdrive
bios = 0x80 # WRAP's BIOS will see this as Primary Master
lba32 # set LBA in WRAP BIOS setup - but I tried it with CHS and it works, too
serial=0,38400n8 # No way to set duplex, so I get doubling of each character on boot. Sigh.
# initrd=/initrd.img # Voyage Linux does not use initramfs (Thank God!)
root=/dev/hda2 # This is how the Microdrive will appear on the WRAP
Filesystem 1K-blocks Used Available Use% Mounted onWhich is the Microdrive, but not as "/dev/hdc". Peeking into the /dev directory, I see there is only a minimal set of device files that does not include /dev/hdc. So "lilo -t" produces an error that it can't find /dev/hdc. Also, the symlink "vmlinuz" in the root directory needs to be created. The workaround I came up with for this is the following, assuming we are already chrooted to /mnt:
sysfs 3809936 220184 3396216 7% /sys
ln -si boot/vmlinuz-2.6.15-486-voyage vmlinuz
Next I did:
lilo -v # went without errors
umount /proc # don't know if this is necessary
exit # leave the chroot
umount /dev/hdc2 # unmount the Microdrive
shutdown -h now
The Moment of Truth
All that remains is to stick the Microdrive in the WRAP board and power
up. However, if you want to watch it boot (and I'm sure you do), you
have to connect the WRAP board's serial port to another computer using
a DB9(female)-to-DB9(female) NULL modem cable (also known as a Laplink
These can still be purchased, though they are usually a special-order item. Once you have connected the NULL modem cable on both ends, you run a terminal emulator program such as (on Winblows) TuTTY (which is MUCH better than Hyperterminal) or (under Linux) minicom. The correct settings are:
baud rate: 38400 (or whatever the WRAP board is configured for)This is the moment we've been waiting for! In my case, it booted right up and rewarded me with a login prompt:
data bits: 8
stop bits: 1
flow control: XON/XOFF
Debian GNU/Linux testing/unstable wrap ttyS0The first time you login there is no root password, so you should get a root prompt just by typing "root".
Configuration (Post-boot)Having got the WRAP booted from the Microdrive is just the beginning. There's oodles of configuration left to do.
Watchdog DaemonThere are a couple things to keep in mind here. First, if you put the wd1100 line in /etc/modules, you MUST run the watchdog daemon, otherwise the wd1100 module will reboot your system after no later than 30 seconds! So be careful about activating the wd1100 kernel module.
If you do activate it (using the parameters given above), all you have to do is "apt-get install watchdog" while the Microdrive is still in the installation machine (before you boot the WRAP) and there will be no problem. The watchdog daemon is set up to automatically write to /dev/watchdog every 10 seconds, while the wd1100 module reboots only if /dev/watchdog has NOT been written to in 30 seconds or more. So you're safe. You can adjust "interval" in /etc/watchdog.conf to 15 seconds if you like.
Another thing to look at is at what point during startup is the watchdog daemon getting started. On my system, it's the very last thing to start. That means if any other startup item is delayed or times out, the wd1100 module would be running but the watchdog daemon would not get started in time to keep it from rebooting the system. So, on my system, I moved watchdog startup to an earlier point in the boot process. I wanted to make sure it gets started before ntpdate, which is susceptible to delay because it connects to an Internet server to get the current time.
NetworkConfiguring the network is beyond the scope of this document. The bare minimum you need is to set up a fixed IP interface in /etc/network/interfaces and pointers to nameservers in /etc/resolv.conf. Also it's good to set up /etc/hostname and /etc/hosts (if you have other fixed-IP machines on your network, you can put their IP addresses in /etc/hosts and map the addresses to human-readable names such as "daisy" or "patty").
If you are using Hyperterminal to communicate with the WRAP, you will
soon be longing to use PuTTY instead. For that to work, you need to set
up either telnet (obligatory security warning: telnet is not secure -
passwords are not encrypted, theoretically someone could capture your
password by listening in on the telnet port) or ssh. I needed a
quick and dirty solution, so I did telnet. First, add the following
#:STANDARD: These are standard services. telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetdThen install the telnetd package using "apt-get install telnetd" and get the inetd superserver running ("/etc/init.d/openbsd-inetd start" in Debian "sid"). Setting up ssh on sid is arguably even easier. All you have to do is:
apt-get install openssh-server
It takes up 2 MB of disk space but if there is even a remote chance that someone from outside could connect to your machine's telnet port, then, well, I'll leave it up to you to decide which is better.
Before you can use either telnet or ssh, however, you have to set up a user account via "adduser". It's also a good idea to set a root password via "passwd".
From here, it's just a matter of firing up PuTTY and choosing either telnet or SSH. Obviously, you have to be able to see the WRAP from your Winblows box. If you have TCP/IP enabled and the WRAP and the Winblows box are on the same subnet (I use 192.168.0.0/24, the WRAP is 192.168.0.7 and the Winblows box is 192.168.0.5 - all these are fixed IP addresses, DHCP is not used), then just type in the WRAP's IP address and it should work.
exim4Use the "dpkg-reconfigure exim4-config" command to set it up.
ntpdateSince the WRAP doesn't have a battery, you lose your time setting everytime you reboot. To ensure that the WRAP knows what time it is, and assuming you have an "always-on" Internet connection, you can just install the ntpdate package. This will automatically consult a timeserver and set your system clock at bootup.
NFS clientEarly on I had a need to access my linux box's files from the WRAP. The linux box is running NFS kernel server version 2. To get the WRAP to access it, I did the following:
apt-get install portmap
apt-get install nfs-common
/home/livingston wrap(rw)(wrap is set up in /etc/hosts to point to the WRAP box)
On the WRAP, I did this:
mount -o nfsvers=2,rw f216:/home/livingston /mnt(f216 is the server.) For more detailed information, refer to the NFS-HOWTO.
Neat WRAP TricksTo find out the current system temperature:
cat /sys/bus/i2c/devices/0-0048/temp1_input(multiply the result by 1000 to get degrees Celsius). Here's a little bash script that will provide more user-friendly output (requires "bc", so do "apt-get install bc" first):
t2=`echo scale=1\;$t/1000|bc -l`
echo "System temperature: "$t2" degrees Celsius"