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
Disclaimer
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.
Background
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 Board 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
This is just a generalized list of the steps. The details follow.
fdisk
After 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: hdc1
So 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 FAT32
Thus, 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:
mkswap /dev/hdc1
mkfs.ext3 /dev/hdc2
These two went without a hitch, so I mounted /dev/hdc2 as /mnt:
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 can continue.
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.
What next?
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 Kernel
After 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:
cd voyage-0.2
cp -a boot/* /mnt/boot
cp -a lib/modules/* /mnt/lib/modules
Basic Setup (Pre-boot)
Kernel Modules
The 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 interfaces
natsemi
# watchdog timer included in GeodeSC1100processor
# Uncomment the following line if you are running watchdog daemon
# wd1100 sysctl_wd_graceful=0 sysctl_wd_timeout=30
# thermal monitor hardware
lm77
# National Semiconductor SCx200 ACCESS.bus (needed for temperature reading)
scx200_acb base=0x820,0
Another 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.
/etc/inittab
The 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.
# $Id: index.html,v 1.2 2006/06/19 08:52:38 livingston Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /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.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
# Serial console for WRAP
T0:23:respawn:/sbin/getty -L ttyS0 38400 vt100
The last line runs getty on the serial port, allowing one to log in as root.
/etc/fstab
Here 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.list
This 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 main
Once 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
mount /proc
apt-get update
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]
Note that, as far as I know, grub will not work with the WRAP and you have to use LILO. I'm only repeating what I read
elsewhere, though, not speaking from experience.
/etc/lilo.conf
The next step is to install lilo (have I really gotten this far?!). Here is how I did it. After hacking away and RTFMing