Easy embedded Linux

18 Sep 2005

The notes below (14 August 2005) describe how I installed Debian 3.0 ("Woody") on a Toshiba 350cdt laptop.  Here are additional notes for installing Debian 3.1 ("Sarge") on that same laptop.

I decided to upgrade my laptop (see below) to Debian 3.1 ("Sarge").  I ordered a set of CDs from Linux Central ($30 for 14 CDs); they arrived within a few days.

I chose to do a full install, overwriting everything I already had in place on the 384 MB flash drive.  I put the first CD in the CDROM drive and rebooted the laptop.  At the prompt, I entered linux26 and hit Enter.  This starts the novice installation process for the 2.6 kernel.  If you want to see what other installation options are available, press F1 at the prompt.

The novice installation is amazingly full-featured and very accurate.  I had to press Enter a few times to take the default values for some initialization, mostly keyboard related.  After that, I just let the automated system run on its own.  When it came time to partion the hard drive, I again set it up as a single partition with no swap space, spanning all 384 MB available.  Note that on another system, I did this same installation with a 1 GB Toshiba laptop drive, in which case I created a second partition for swap space.  Again, don't use a swap partition on a flash drive; the drive will wear out very quickly.

After creating the partition, I had the system erase and format it for ext3 file system, then continue with the installation.  The install process loaded in the base kernel, then began adding drivers needed by the system hardware.  It correctly detected and installed drivers for everything on my system, including a newly purchased AirLink 101 Cardbus Ethernet adapter.  (If you install this card manually, you will need to use the 8139too kernel module to make it work, as the device uses the RealTek 8139 chipset.)

Now the system was ready to reboot from the newly installed system and do the configuration.  This part looked a lot like the original 3.0 install.  I set up the time zone, created root and user accounts, then shuffled CDs into the drive so apt could index them for later use.  I got bored at CD #10, so the last four didn't get indexed.  If you want to continue this indexing operation later, without having to do the reinstall, just enter apt-cdrom add at the command prompt for each CD you want to add.

One very pleasant surprise in the 3.1 installer was the use of aptitude for selecting and installing packages, rather than dselct.  Aptitude has a more intuitve interface, including drop-down package lists on a text display.  I had no problems selecting the packages I wanted to install, including gcc 2.95.3, make, flite, zgv (a graphics viewer using svgalib), cdtool, aumix (a Soundblaster-compatible audio mixer), joe (a console text editor), and others.  Aptitude properly installed the selected packages plus all dependent libraries.  If you want to run aptitude after installation is complete, just enter aptitude at the command prompt.

That was about it!  After aptitude ended, I answered some basic questions to finish configuration, and my system was ready to use.  Far easier than the 3.0 install, and very accurate, even on my 1998 Toshiba platform.  No mucking about with kernel modules, no assigning I/O ports or IRQ levels; it just works.  The Debian group has made great strides on the install process over 3.0.


18 Sep 2005

Application-specific issues

The above notes cover the installation process, but there is always more than installation to get the system fully running.  Here are some random notes on setting up different applications.

aumix

This is a program that sets up a multi-channel audio mixer for use by other apps.  Once configured, it lets you control volume and balance on your stereo output, as well as setting volume on several subsystems, including PCM (used by flite, the text-to-speech synthesizer), microphone input, and others.

Unfortunately, it looks like aumix hasn't been maintained, which is a shame, because it is a perfectly serviceable text-based mixer controller.  The problem lies in the names aumix uses for accessing the audio devices it wants to control.  aumix wants to access the mixers as /dev/sound/mixer1, for example.  But kernel 2.6 (and possibly earler ones) use /dev/mixer1.  This means the aumix init script, found in /etc/init.d/aumix, always fails, leaving the mixer output at default.  This default setting has a very low PCM volume, which meant that flite's output was too faint to hear.

I could have modified the aumix init shell script, but I'm not that good (yet) with shell scripts.  Instead, I chose to make a very simple script of my own (named KarlsAumix) and run it during runlevel 2 startup.  The script looks like this:

#! /bin/sh
#
# Karl's aumix setup script
# The setup script supplied with aumix looks for /dev/sound/mixern,
# and is not compatible with kernel 2.6. This is a stop-gap
# solution.
echo "Setting aumix using KarlsAumix script."
aumix -d /dev/mixer1 -v90 -m90 -c90 -w90 -q q

This file lives in /etc/init.d.  To run it during runlevel 2 startup, I added a symbolic link to it in /etc/rc2.d named S95KarlsAumix.  If that last sentence was Greek to you, do a bit of web searching or pick up a copy of Running Linux by O'Reilly Press; the 4th edition has a good discussion of startup files around page 133.

Now when I boot up, /dev/mixer1 gets set to the values in the aumix invocation line above, which are reasonable for daily use.

networking configuration

During one install, I did not let the ethernet system configure itself.  I was left with a system that could not reach the network.  The ethernet hardware was properly recognized and the right drivers were loaded, but the system did not know how to find the network.

The file /etc/network/interfaces is a text file holding information about your ethernet interfaces.  Here is what mine looks like, set up for the main ethernet interface (eth0) to use DHCP for address generation:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# This is a list of hotpluggable network interfaces.
# They will be activated automatically by the hotplug subsystem.
mapping hotplug
        script grep
        map eth0

# The primary network interface
iface eth0 inet dhcp

The first two sections, for loopback and hotpluggable interfaces, were prebuilt during the installation process.  I added the third section for the primary network interface to get eth0 up and running.

Note that you can use the same file to assign a static IP address to eth0.  Here is what that interfaces file might look like:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# This is a list of hotpluggable network interfaces.
# They will be activated automatically by the hotplug subsystem.
mapping hotplug
        script grep
        map eth0

# The primary network interface
iface eth0 inet static
        address  192.168.1.6
        netmask  255.255.255.0
        gateway  192.158.1.100
        network  192.168.1.0
        broadcast  192.168.1.255

The above assigns a fixed IP address of 192.168.1.6 to my system and tells my system that the address to the network gateway to the Internet is 192.168.1.100.  Your values will likely differ.

Reboot your system with the ethernet connection attached.  Now you should be able to enter the command ifconfig and see eth0 listed, with the correct IP address assigned.

My gateway at 192.168.1.100 is also my nameserver for the house network.  It resolves a computer name, such as "320cdt" to the proper IP address, such as 192.168.1.2.  In order for my system to use this gateway as a nameserver, I had to make a small change to the file /etc/resolv.conf.  Here is how I specified the address of my nameserver:

search
nameserver  192.168.1.100

zgv

zgv is a graphics display program that is suitable for use in a console system.  This lets you display JPEGs or GIFs without having to load in a full X environment.  zgv uses the svgalib library to handle talking to the display, and I had to make some minor changes to the file /etc/vga/libvga.conf.  (Yes, I know that isn't the file name given in the zgv info page, but zgv hasn't been updated since 2003, and things have changed.)  In particular, I added

mouse none                and
chipset vga

in the appropriate places in the file.


Installing Debian 3.0 on a Toshiba 320cdt laptop

14 August 2005  (This is the first entry in this series...)

I've long wanted to play with embedded Linux, but the options haven't been very good.  I'm not a Linux black-belt by any means; I've done a shell script or two, but never built the kernel and don't know much about system admin.  Still, I wanted to try using the Linux platform for robotics.

The problem is that I find most of the commercially available embedded Linux platforms to be unsuitable.  Most are too expensive (as in several hundred dollars) for what you get.  They often use non-mainstream processors, forcing you to use a single kernel and configuration supplied by the vendor, or cross-build a new kernel and system using a separate Linux box.  And cross-building a toolchain, I've found, is a daunting challenge.

I did spend some time playing with Linux-based appliances, such as the Linksys WRT54G, but finally gave up in frustration.  Those hackers who posted details on how they used such boxes include off-hand comments such as "Build such-and-such version of the kernel" or "You'll need to tweak a few scripts."  At first, such incomplete instructions frustrated me.  I have since realized that Linux instructions are, by their nature, incomplete.  Too many tiny details can impact some larger operation to the point that it won't work, and providing trouble-shooting info to cover all of those tiny details is simply too much work.  (Consider this a warning; I will likely leave out a few tiny details in my description, as well!)

Finally, I decided the best approach for me would be to hack an old laptop computer.  Just throw away the display and keyboard, bolt the main board to a platform of some kind, cable in the floppy drive and hard drive, and do the install on that.  Since I would be using an 80x86 board, I could use a plain vanilla Linux.  In fact, if I chose my embedded system properly, it would also be my development system, removing any need for a second Linux box.


The laptops and the Linux

So I rooted through the used laptop table at RE-PC in Seattle and picked up a couple of old Toshiba laptops.  The 305CDS and 320CDT both had floppy drives, CDROMs, and 16 or 32 MB of RAM.  Both lacked a hard drive, but that wasn't a problem; since these were for embedded use, I was going to replace the hard drive with a compact flash (CF) card of some kind anyway.  Total cost for both machines: $35.

After I got the laptops home, I reduced both Toshibas to a pile of scrap plastic, various metal bits, and the good stuff; main board, CDROM drive, and floppy drive.  I mounted each main board on a 12" by 12" piece of 1/4-inch thick white Sintra (a foamed ABS plastic), using hardware from my junk box.  On each board, I attached a flash drive I had picked up at a local surplus shop (384 MB for $17!), using hardware and brackets to align it with the main board's notebook drive connector.  I didn't mount the floppy drives to the boards, but I did make a small bracket for each CDROM drive and bolted them down.

I figured I would need a bit more memory, so I ordered a pair of 64 MB PC100 modules from Data Memory Systems, my favorite memory supplier.  Cost was $29 each.  This means that the 320CDT has 96 MB of RAM and the 305CDS has 80 MB.

Each laptop now boasts the following features:

I chose to install Debian 3.0 ("woody") as my embedded Linux.  Not because Debian is particularly good for embedded work, but because its package system is easy for beginners to use and supports over 8000 different applications.  I ordered my version from Linux Central.  The seven-CD set  cost $16 and included 2.2 and 2.4 kernels.

At this point I have about $80 invested in each embedded system.  If you've done any embedded Linux pricing, try and match that feature list and see what it will cost you.  Granted, this is a physically larger system than most embedded platforms, but it's cheap and easy to use, which were two of my main goals.

I power either of these systems with a 12 VDC, 1 amp wall-wart from Radio Shack.  Both machines run the flash drive and CDROM from this supply with no dropouts or crashes due to low power.


Configuring the BIOS and installing Debian Linux

Now I'll go through the steps needed to install Debian Linux on these machines.  For the rest of this discussion, I'll treat both of these machines as the same; if a relevant difference comes by, I'll let you know.

Start by plugging in a PS/2 keyboard and a VGA terminal, assuming you discarded them as described above.  You will also need a suitable power supply.  I did not have the original Toshiba supply for either machine, so I removed the original plug from the main board and installed a coaxial plug on a short two-wire cable.  If you go this route, be sure to insulate the connections on the coaxial plug, to prevent shorting your power supply to something critical.

When you furst apply power, you have a VERY short time to press the ESC key to halt the boot process.  If you succeed, press F1 to access the BIOS configuration utility., otherwise cycle power and try again.  Once in the BIOS config utility, move through the menus and make the following settings:

Put CD #1 in the CDROM drive and boot the laptop with the above settings.  This will begin the Debian installation process.  When you see the Debian boot: prompt, enter bf24 to start installing the 2.4 kernel.

I found installing Debian to be simple and straightforward.  When the installer prompts you for a choice, it usually makes reasonable suggestions.  Even installing kernel modules, used to customize the system, went pretty smoothly.  In nearly all cases, the kernel modules I chose to install did not need any extra options; the modules correctly autoprobed the hardware and installed themselves.

One of the first items in the install process is setting up the hard drive.  I chose to create a single partition on drive /dev/hda, the flash drive; this partition spanned the entire drive.  I then formatted /dev/hda1 as a Linux ext3 file system.  I've tried ext2 (the default) file systems before, but if anything goes wrong with the file system, such as a system crash or unexpected power fail, you get to sit through a lengthy file check process on the next boot.  The ext3 file system, which uses journalling, reduces that file check to a few seconds.

Note that I did not create a swap partition.  Swap partitions on flash drives are not a good idea; you can burn out a flash drive pretty quickly using it for swap space.  When the installer prompts you with choices about a swap partition, just choose no swap partition.

When I got to the prompt to begin installing kernel modules, I instead chose the alternate option to set up the PCMCIA system.  The Toshibas use an Intel 82365 PCMCIA controller, which I selected.  I then took defaults on all remaining options.  Eventually, I found myself back at the prompt to begin installing kernel modules again.

Here is a list of the kernel modules I installed.  Some of these are intended for robotics designs I want to try and may not be suitable for everyone.  With one exception, none of these modules required me to enter any arguments.  Note that in some cases, you will find some of these already chosen for you, based on previous selections.

Note:  When you select the sb kernel module, you must provide arguments describing the SoundBlaster Pro system.  On the argument line provided, enter:  irq=5 io=0x220 dma=1.  This matches the configuration set earlier in the BIOS.


Up and running

The above set of kernel modules should get you up and running.  You can always go back later and add/remove kernel modules without having to redo the install process.  Just run /usr/sbin/modconf from a command prompt.  For example, I picked up an Airlink 101 USB-to-serial adapter at the local Fry's and needed to add a kernel module to support it.  I used modconf to try out various USB-to-serial modules until I got to the PL2303 serial adapter, which worked perfectly.  Now, when I plug in my Airlink 101 USB adapter, a message pops up announcing that the serial port is available as ttyUSB0.

From this point on, you are running a fairly stock Debian installation.  You will need to do the routine system administration tasks of setting up accounts and configuring security.  Because this is a true Debian install, you can also do most of the tasks available on desktop installations.  For example, I installed the Flite text-to-speech system with the standard Debian command: apt-get install flite.  (NOTE: This was anything but routine the first time I tried it.  I didn't have the sound system configured correctly at first, and repeated attempts to get Flite running all failed.  The short list of options above for the kernel sound module represents many hours of frustrating work.)

I also installed the GCC tools so I could compile and link my programs directly on the Toshiba.  This removes the need for a second Linux box, and also means the source for my programs is immediately available during testing.  In fact, I also installed gdb, the GNU debugger, so I can do source-level debugging of my programs right on the target!  You can have just about any editor you want, as well.  I installed joe and have been happy with it.  And of course I installed Midnight Commander (apt-get install mc), a tool I consider indispensable for any console-based Linux system.

One package I installed has provided lots of fun for experimenting with embedded Linux.  The parapin package gives access to the individual pins on the parallel port.  I modified the supplied sample programs to create a bit-banged SPI system, which I then wired up to a MAX1204 10-bit A/D converter.  Now I can have my Linux system call out voltages to me as I probe a circuit; great fun.

If you try to install Debian on platforms other than the above Toshibas, you will face many of the problems described above.  I hope these paragraphs help get you over the hurdles.  Be sure to check on the web for similar projects.

My home page