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 Geode SC1100 processor
# 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 I came up with
this for the configuration file:
boot = /dev/hdc # Microdrive shows up as /dev/hdc on my system
disk = /dev/hdc # Microdrive
bios = 0x80 # WRAP's BIOS will see this as Primary Master
#compact
lba32 # set LBA in WRAP BIOS setup - but I tried it with CHS and it works, too
install=text
map=/boot/map
vga=normal
delay=1
timeout=50
prompt
serial=0,38400n8 # No way to set duplex, so I get doubling of each character on boot. Sigh.
default=Linux
image=/vmlinuz
# initrd=/initrd.img # Voyage Linux does not use initramfs (Thank God!)
root=/dev/hda2 # This is how the Microdrive will appear on the WRAP
label=Linux
append="console=ttyS0,38400n8 reboot=bios"
read-only
# restricted
# alias=1
If 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:
Filesystem 1K-blocks Used Available Use% Mounted on
sysfs 3809936 220184 3396216 7% /sys
Which 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:
cd /
ln -si boot/vmlinuz-2.6.15-486-voyage vmlinuz
cd dev
./MAKEDEV hda
./MAKEDEV hdc
lilo -t
On my system, this was enough to get through lilo -t without errors.
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
it
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
cable).
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)
data bits: 8
parity: none
stop bits: 1
flow control: XON/XOFF
This is the moment we've been waiting for! In my case, it booted right
up and rewarded me with a login prompt:
Debian GNU/Linux testing/unstable wrap ttyS0
wrap login:
The 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 Daemon
There 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.
Network
Configuring 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").
Telnet/ssh
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
line to
/etc/inetd.conf:
#:STANDARD: These are standard services.
telnet stream tcp nowait telnetd.telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
Then 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.
exim4
Use the "dpkg-reconfigure exim4-config" command to set it up.
ntpdate
Since 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 client
Early 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
On the SERVER side, I set up an /etc/exports file like so:
/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 Tricks
To 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):
#!/bin/sh
t=`cat /sys/bus/i2c/devices/0-0048/temp1_input`
t2=`echo scale=1\;$t/1000|bc -l`
echo "System temperature: "$t2" degrees Celsius"
Recent comments
7 hours 36 min ago
9 hours 18 min ago
11 hours 44 min ago
11 hours 50 min ago
16 hours 24 min ago
18 hours 25 min ago
21 hours 48 min ago
23 hours 55 min ago
1 day 6 min ago
1 day 2 hours ago