Article: Embedding Linux in a DiskOnChip
Nov 27, 2000 — by Rick Lehrbaum — from the LinuxDevices Archive — 1 viewsPlease note: This article is adapted from John Lombardo's upcoming book, Embedded Linux, which will be published by New Rider's press in 2001. The book describes why embedded system developers should seriously consider using Linux in embedded applications, explains how to go about using the Linux kernel in an embedded design, and examines some of the hardware and software choices that need to… be made. This article, and the book, make use of the “Embedded Linux Workshop” — an open source project that was created to simplify the building of embedded applications, by allowing developers to use parts of one embedded project to help in the development of subsequent projects.
Introduction
Sometimes you can't justify the time and expense of developing a dedicated hardware platform for your embedded application. Perhaps the quantities are too small or the market is unproven. However, even under these circumstances you still don't want to ship a big klunky box with a hard drive. Hard drives wear out over time, they draw lots of power and get very hot. Besides, customers know a PC when they see one. Fortunately, manufacturers are starting to produce PC compatible computer systems with form factors that please embedded system designers. Some look like set top boxes (think VCR), some are rack mountable (1 or 2U high). In the future, we'll even see some that look like a desktop hub or modem. However, the hard drive remains a problem.
Currently, Flash memory is the best substitution for a hard drive in an embedded device. It has several advantages over a hard drive; it's faster, it draws much less power, it produces less heat than a hard drive and has no moving parts. Unlike a hard drive, the processor can directly address the bits stored in Flash memory like a RAM or ROM making execution in place (XIP) possible, thus reducing the overall RAM requirements. However, the disadvantages of Flash memory may be prohibitive; it's much more expensive than an equal amount of hard drive space, it has much less capacity, and as you write to Flash memories, they slowly wear out.
In 1994 M-Systems introduced the DiskOnChip, a small Flash memory device that works like a small hard drive. It can plug directly into a properly equipped motherboard, or into an ISA card for development. The DiskOnChip comes in a variety of sizes ranging from 2MB to 512MB, and in a variety of packages; DIP, TSOP-II, or DIMM. Depending on your application, the DiskOnChip may be the perfect storage solution for smaller run embedded Linux devices based on the x86 processor for several reasons:
- It is relatively easy to use.
- Numerous motherboards intended for embedded applications support it.
- It's not too much more expensive than just plain Flash chips.
- It comes with block drivers that make it look like a hard drive.
- You can boot Linux directly from it.
However, for the open-source purist, the DiskOnChip has one really big disadvantage; the driver from M-Systems is not open source. So if you use the driver improperly you will violate the GPL. It is possible to avoid this violation by installing the driver as a module at run time with the insmod
or modprobe
commands. Work is underway on a generic Linux subsystem for memory devices such as Flash. When it's complete, the DiskOnChip driver from M-Systems may no longer be necessary (info).
This article guides you through the process of building a custom Linux image and installing it on the DiskOnChip in such a way that you will not violate the GPL. The image will be bootable and you will be able to distribute the hardware without any sort of spinning media; hard drive, floppy drive or CD-ROM. We'll build the minicom application from the article — this time it'll boot from the DiskOnChip instead of the floppy diskette drive.
Generally, there are two phases to generating a working embedded Linux device based on the DiskOnChip:
- Building the DiskOnChip files
- Installing the files onto the DiskOnChip
Building the DiskOnChip Files
This procedure uses the Embedded Linux Workshop presented in “Embedded Linux”. Originally, the example was put together as a simple list of steps — however, the set of steps would require that we statically link the DiskOnChip driver into the kernel, violating the GPL. Providing a set of steps to build everything required for a dynamic runtime is well beyond the scope of this article, and besides that's exactly what the Embedded Linux Workshop is for.
- Aquire root privileges for your machine if you don't already have them. Because the Embedded Linux Workshop mounts and unmounts file file systems, there is really no way to run it except as root.
- Download the Embedded Linux Workshop. It's available from elw.sourceforge.net or ftp://elw.sourceforge.net/pub/elw. There are a lot of files to download if you want the full source to the ELW. However, for now you only need the workshop itself. It will be named elw-X.Y.Z.tgz, where X.Y.Z is the current version number. If you want to just experiment with the Embedded Linux Workshop, you won't need to download all of the source code to all of the packages. However, if you're targeting a non-x86 cpu or want to do more than fool around with the software, you'll have to download most of the source code over time.
cd /usr/local
Change to the /usr/local directory. This is the easiest place to install the Embedded Linux Workshop. If you decide to install it somewhere else, make sure you point your /usr/local/elw symlink to the right place.tar xvzf /tmp/elw-X.Y.Z.tgz
Install the Embedded Linux Workshop into the /usr/local directory. The example command assumes you downloaded the elw-X.Y.Z.tgz tarball into the /tmp directory.rm -f elw && ln -s elw-X.Y.Z elw
Remove the old elw symbolic link and create a new one that points to the directory you just installed. If you need to revert to a previous version of the Embedded Linux Workshop, you can just point this symlink back to the old version.(cd /usr/bin && rm -f elw && ln -s /usr/local/elw/bin/elw elw)
Remove any old /usr/bin/elw link and create a new one that points to the elw script in the elw package.
cd ~yourhome/projects
Change to the directory where you want your new project to live.elw --newproject minicom
Use the 'elw' command installed in step one to create the new project. Several directories and files are created within the new “minicom” directory.cd minicom/arch/i386/src
Change to the src directory.mkdir minicom
We'll keep the source to minicom here.mkdir DOC
We'll keep the source to the DiskOnChip driver here.cd minicom
Change to the new minicom directory.- Download minicom from here. If it's not there, then use Freshmeat to find it. If you have trouble downloading it, use ftpsearch.lycos.com to search for the file name, then pick a site near you to download from. At the time of this writing, the latest version was 1.83.1.
tar xzf minicom-1.83.1.src.tar.gz
Untar minicom. You can add an “v” after the “x” in xzf to see the files that are created. Minicom is a serial communication program originally written by Miquel van.ln -s minicom-1.83.1 minicom
Create a symbolic link named minicom that points to minicom-1.83.1. This symbolic link will be used in the opt/minicom/Makefile, this way if you decide to upgrade to a later version of Minicom in the future, you can just change the symbolic link to point to the new one.cd minicom/src
Change to the minicom source directory. We have to make a small change to the source code to minicom to make sure it works properly in our mini-environment.- Remove a minicom security feature that is unnecessary in our embedded application:
In minicom.c, search for the line that reads “if (real_uid == 0 && dosetup == 0) {“. Delete about 61 lines — up to, but not including the line that reads “buf[0] = 0;”. If these lines are not removed, then minicom will bail out at this point. Since we don't have to be concerned with permissions and correct users in our embedded environment, it's safe to just skip this code. Save your changes. make
Make the minicom executable file. If everything goes well, you'll end up with an executable file called “minicom.cd ../../../kernel
Change to the kernel source directory.- Download the current production Linux kernel from ftp://ftp.kernel.org/pub/linux/kernel. At the time of this writing, the latest version was 2.2.15. It shouldn't really matter which version of the kernel you use for this exercise. Anything from version 2.0 through 2.4+ should work just fine. However, the binary-only DiskOnChip driver may have trouble with some kernels. It's best to use whichever kernel the DiskOnChip driver is compiled on. That may be difficult to do until you try it with one kernel and it complains.
tar xzf linux-2.2.15.tar.gz
Untar the kernel. When you're done, there will be a new directory named “linux”. Normally, as soon as I untar a kernel I rename it to linux-x.y.z and create a symlink named “linux” back to it so I'll know what it is later on. Be very careful not to blow away your current sources if you already have a “linux” directory. On more than one occasion I've untarred a newly downloaded kernel source tree and blown away another kernel I was already working on. Be careful.cd ../DOC
Change to the DiskOnChip source directory.- Download the latest DiskOnChip drivers from M-Systems' website. You may have to register to do it.
tar xvf DOC_Linux4.2.1.tar
M-Systems is trying to be Linux friendly, but as of the time of this writing they haven't quite figured it out. Every time I test this step, M-Systems has changed the way their download works, so if the file name isn't right or the what you get does not match the instructions, you're on your own a little. The package you get is put together in an un-Linuxey way. It's a tar file containing a License.TXT and a tgz. The tgz contains the actual driver code.tar xvzf driver*tgz
Untar the tgz, you'll get a new tree, the root of which should look something like “Linux_DOC_4.2.1”.cd Linux_DOC_4.2.1/driver
This directory contains the files we need. The README.kit contains a detailed set of instructions for the Linux DiskOnChip driver. We're interested in section 3, the part that talks about compiling a loadable module../create-standalone driver-patch ../../../kernel/linux
The ../../kernel/linux directory should be the Linux directory you created in a previous step. This step is supposed to create a new directory named doc-module in the root of the Linux source tree – the driver files will end up in this new directory.[ -d doc-module ] && mv doc-module ../../../kernel/linux
This step fixes a bug in the create-standalone script. In the current driver version (as of this writing), the doc-module is created in the wrong place. This step puts it where it belongs — in the kernel source tree../mknod_fl
This script creates all of the device entries for the DiskOnChip in the /dev directory. You can't do anything with these devices until you've loaded the driver.[ -d /dev/msys ] && (cd /dev/msys && mv * .. && cd .. && rmdir msys)
The Embedded Linux Workshop expects the devices it uses to be in /dev, so we simply move the devices created in the prior step into the /dev directory.cd ../../../kernel/linux
Change to the kernel directory.make menuconfig
Configure the kernel using the “make menuconfig” command. The following options are based on a 2.2.15 Intel kernel — your kernel configuration may be a bit different. Turn these options on with an asterisk (not an “M”), everything else should be turned off to save space. You will have to go into each of the top level menus, even the ones not listed here, to make sure they're off.
Processor Type and features
– 386 processor family
– 1G Maximum Physical Memory
Loadable module support
– Enable loadable module support
General Setup
– Kernel support for ELF binaries
Block Devices
– Normal PC floppy disk support
– RAM disk support
– Initial RAM disk (initrd) support
Character devices
– Virtual Terminal
– Support for console on virtual terminal
– Standard/generic (dumb) serial support
Filesystems
– DOS FAT fs support
– MSDOS fs support
– VFAT (Windows-95) fs support
– /proc filesystem support
– Second extended fs support
Console Drivers
– VGA text consolemake dep && make bzImage
Build the kernel. We use the “and” continuation (&&) instead of the semicolon so that the second make will not happen if the first fails. I've never personally seen “make dep” fail when building the kernel, but this is good practice for all long software builds with more than one make. This way, if there is an error in one of the “makes”, then the subsequent “makes” will not even start leaving you with any error messages still on the screen. We don't need to make any modules for this kernel, but if we did, I'd simply add it to the command line (make dep && make bzImage && make modules).cd doc-module
Change to the directory created by the create-standalone script from the DiskOnChip distribution.make
Build the doc.o module.cd ~yourname/projects/minicom
Change back to the root directory of your project.mkdir -p opt/minicom/bin opt/minicom/etc/rc
Create the minicom package directories.cat > opt/minicom/Makefile
everytime:
binaries:
@(cd ../../src/minicom/minicom/src && make)
@cp -f ../../src/minicom/minicom/src/minicom bin
@strip bin/minicom
@strip --remove-section=.note --remove-section=.comment bin/minicom
dependencies:
@echo "libncurses"
{type control-D here}In the Embedded Linux Workshop, each opt package can have a Makefile. The Makefile has three targets; everytime, binaries, and dependencies. The everytime target is normally not used. The binaries target is used to re-build any binaries whose source has changed since the last build and then move those binaries into the opt package. Once in the package, the binaries are then stripped. Finally, the dependencies target lists any dependencies the opt package has. For instance, the minicom executable depends on the ncurses library. Obviously, you don't have to use the cat command to build the Makefile, it's just the most convenient way in this how-to.
Note that the indented lines are indented with a single tab.cat > opt/minicom/etc/rc/S99minicom
#!/bin/sh
echo "Press a key for minicom..."
read x
minicom -s
{type control-D here}The Embedded Linux Workshop comes complete with a set of startup-up scripts that work similarly to the RedHat startup scripts. Each script in the /etc/rc directory that begins with the letter S is executed in order of increasing sort order. Naming a script S99{something} implies that it should be the last script to run and that it may not return back to the caller.
We use the -s option so minicom will go directly into setup mode. It defaults to COM2, so you can change it if you need to. In a real device, you would create a minicom configuration file and let start directly.
Also, in a real application we wouldn't force the user to press a key to start, but this way we can see any bootup error messages before minicom erases them.chmod a+x opt/minicom/etc/rc/S99minicom
Make the script executable.mkdir -p opt/doc/modules opt/doc/etc/rc
Create the doc package directories.cat > opt/doc/Makefile
everytime:
binaries:
@cp -f ../../src/kernel/linux/doc-module/doc.o modules
{type control-D here}We don't recompile any part of the kernel or libc by convention — it just takes too long.
cp -P /usr/share/terminfo/l/linux opt/minicom
Create the terminfo for the console. This file contains the definitions of escape sequences for the console for operations like clear screen and drawing lines.cat > opt/doc/etc/rc/P01doc
#!/bin/sh
insmod -f /modules/doc.o
{type control-D here}Each script in the /etc/rc directory that begins with the letter P is executed in increasing sort order before the boot media (Flash file system) is mounted, this is how we're able to load the DiskOnChip module before we ever try to reference it. We use the -f (force) option of insmod because the kernel version encoded in the DiskOnChip driver may not agree with the kernel version we use. This happens because we aren't compiling the DiskOnChip driver from scratch since we don't have the source.
chmod a+x opt/doc/etc/rc/P01doc
Make the script executable.- Modify the “config” file in the root of the project in the following ways:
- $APP_ROOT=”/dev/fla1″;
- After @OPT=(“minicom”); add a new line that says @OPT=(@OPT,”doc”);
elw
Run the elw command.- Choose the “Build binaries” option to build the binaries. Unless you take the time to download all of the source files to the Embedded Linux Workshop, most of the binaries will fail to build. That's OK, the binaries that ship will work. You must re-run this option each time you make a change.
- Choose the “Build image” option to build the Linux files and image.
Congratulations, you've just created a new embedded Linux disk image!
What was built
The “Build image” menu entry created several new files in the obj subdirectory:
- obj/image
- The obj/image file is an image of the bootable 1.44 megabyte diskette. If you were to use the dd command to copy this file to a diskette, it would boot into minicom.
- obj/imageroot/*
- The obj/imageroot directory contains all of the files used to build the obj/image file. These are the files that actually need to get to the DiskOnChip.
- obj/imageroot/banner.txt
- The banner.txt file is displayed on the console as the image boots. The file is built once by the elw –newproject command. Once built, it can be modified to display what you want to see. The source of this file is in mnt/banner.txt.
- obj/imageroot/bzImage
- The bzImage file is the actual Linux kernel. It's copied directly from within the kernel you built in the howto above.
- obj/imageroot/ldlinux.sys
- The ldlinux.sys file is the meat of the syslinux bootloader. It copies the kernel from the boot media into memory then executes it.
- obj/imageroot/readme
- The readme file is a short text file that tells what is on the image. It is built once by the elw –newproject command. It's source is in mnt/readme.
- obj/imageroot/rootfs.gz
- The rootfs.gz file contains the initrd file system. This is the run-time root file system of any elw project. Syslinux uncompresses it into memory as it loads it from the boot media.
- obj/imageroot/syslinux.cfg
- The syslinux.cfg file tells syslinux how to boot the media. It is built once by the elw –newproject command. Normally you shouldn't have to change it, but if you do it's source is in the mnt/syslinux.cfg file. Look to the syslinux documentation for more information about this file.
Installing the image or files onto the DiskOnChip
There are numerous ways to move the files onto the DiskOnChip. Depending on what hardware you have available to you, you may have several options:
- You can put all of the files on a DOS formatted floppy diskette, boot the box with the DiskOnChip using that diskette, then copy the files from the floppy to the DiskOnChip.
- You can put all of the files on a DOS hard disk partition, boot the box with the DiskOnChip using that partition, then copy the files from the floppy to the DOC.
- You can dispense with DOS entirely by re-compiling the Linux kernel on the box with the DiskOnChip and a Hard Drive, including the DiskOnChip drivers from M-Sys. Once you do that, you can copy the files directly from Linux to the DiskOnChip.
- If your DOC box doesn't have a HD or FD controller, you'll have to program the DOC on anther machine, perhaps using the ISA DOC card from M-Systems. Once the DiskOnChip is programmed, you'll move it to the destination box.
This article assumes that the motherboard with the DiskOnChip socket can also accommodate an IDE hard drive. We'll move the files to a bootable DOS partition on the hard drive, then reboot under DOS. It will then be a simple exercise to copy the files to the DiskOnChip and run syslinux.com to make the kernel bootable from the DiskOnChip.
Using a Hard Drive with MS-DOS
- Locate all of the files you will need to install your new Embedded Linux application on the DiskOnChip. You'll need:
- All of the files in the obj/imageroot directory.
- The syslinux.com file. If you installed the Embedded Linux Workshop in the standard place, it'll be in /usr/local/elw/arch/i386/opt/syslinux/nomedia/syslinux.com.
- Install a hard drive with a DOS partition into the machine with the DiskOnChip. Microsoft Windows should also work well if you wish. In fact MS-Windows may be easier to use since you're going to have to copy files from the obj/imageroot directory onto the DOS partition – you may want to use the network. If you do not have access to MS-DOS or MS-Windows, you can use Linux. However, to do so requires that you install the M-Systems drivers into your kernel (or compile them as modules and insmod them). Doing so is beyond the scope of this article (but if you're using Red Hat 6.2, you should be able to use the modules you created above – caveat emptor).
- Boot the machine using DOS. You may have to tweak the BIOS to allow you to boot from the hard drive.
- Get the files from your build machine to the local hard drive. It's up to you how you do this — anything from FTP to the hard drive shuffle will work. I'd think about how you're going to do this a bit since you're probably going to do it many many times. The less time you spend moving files from point A to point B so you can test, the more time you can spend engineering and debugging. Figure that you'll probably rebuild the project at least 100 times for anything more than a trivial project.
- Determine the drive letter of your DiskOnChip device. We'll assume it's D: here, but it could be a different letter for you.
- (Optional) Delete all of the files on the root of the DiskOnChip. You may not need (or want!) to do this.
copy C:imageroot*.* d:
Copy all of the files in the obj/imageroot to the root of the DiskOnChip drive using the DOS copy command. The example above assumes that the files are in the C:imageroot directory of the hard drive and the DiskOnChip was assigned drive letter D:.c:syslinux d:
Make the DiskOnChip bootable with the syslinux.com command — assuming the syslinux.com program is in the root of the C: drive.- Reboot, changing the BIOS so the machine boots from the DiskOnChip.
Conclusion
If all went well, you now have a machine that pretends to be a serial terminal. That is, almost certainly, not what you want to do with your embedded device. However, you can swap out Minicom with your own software and you're well on your way to building your own Embedded Linux device.
Author's bio: John Lombardo has been working with Linux since the “0.9” days. However, he does remember downloading a very early version and thinking: “Yeah, right — how is this Linux thing going to compete with Coherent” (an early 1990's Unix clone from The Mark Williams Company). Lately, John has been working on several embedded Linux projects, including easy-to-use IPSEC routers, ARM7-based NAT routers, and a book entitled Embedded Linux which will soon be published by New Rider's Publishing. You can reach John at [email protected].
This article, adapted from John Lombardo's first book, Embedded Linux (to be published in 2001 by New Rider's press), appears here by permission of the author. Copyright 2000, John Lombardo. All Rights reserved. No portion of this work can be copied without written permission of John Lombardo.
This article was originally published on LinuxDevices.com and has been donated to the open source community by QuinStreet Inc. Please visit LinuxToday.com for up-to-date news and articles about Linux and open source.