ELJonline: Using CompactFlash Cards in Your Embedded Linux System Jay Sissom ?

来源:百度文库 编辑:神马文学网 时间:2024/04/19 00:28:23
ELJonline: Using CompactFlash Cards in Your Embedded Linux SystemJay Sissom ? (May, 2001)
Use a CompactFlash card as a nonmechanical alternative to a disk drive.
Whendesigning embedded systems, the designer has many choices to make. Ifyou sell thousands of units, you spend lots of time designing aroundthe most inexpensive parts you can find. You design custom circuitboards and search high and low for the best components that you can getfor the cheapest price.
If you build only one or two units, thetime and cost needed to design the perfect circuit board and find thebest parts can eat up the entire budget for your product. In this case,off-the-shelf parts are the best choice.
Most of my projects arefor one or two units, so I‘m always looking for inexpensive items I canuse. The 25? MP3 playing chip that can only be bought in lots of 10,000doesn‘t help me at all. If there was a $25 chip that I could get insingle quantities, I might be interested.
I am an amateur radiooperator and a member of the Tucson Amateur Packet Radio organization(TAPR). This organization is dedicated to the support and advancementof amateur radio digital communications by providing publications,meetings and electronic kits. I recently purchased a couple of IDECompactFlash adapters from them (see Figure 1). This product is acircuit board that allows you to use standard CompactFlash memory cardsas an IDE device in a PC.

Figure 1. IDE CompactFlash Card Adapter
Ifyou have a digital camera or a portable MP3 player, you might have seena CompactFlash card (see Figure 2). My Nikon digital camera uses thesecards to store images. The cards contain between 2MB and 192MB of Flashmemory. Flash memory is read/write memory that does not lose itscontents when the power is disconnected.

Figure 2. A Dimensionally Indicative Photo of a CompactFlash Card
Whenbuilding an embedded system based on the Linux operating system, thefirst problem to solve is how to boot the operating system. It might bepossible to purchase an ISA or PCI card that has ROM on it and placeyour code in these ROMs. I haven‘t tried this because I haven‘t foundaffordable boards to do this.
You could use a floppy drive orhard drive in your embedded device, but I‘ve found that anytime you canreduce the number of moving parts, you increase reliability. Thesedrives also draw a lot of current and generate heat, so they couldcause other problems.
Using the TAPR CompactFlash adapter wouldlet you boot the operating system off of a CompactFlash card. Thesecards aren‘t terribly expensive, and they are very small. They have nomoving parts, so they could be a good solution for embedded projects.
Forthis article, I show how to build a Linux system on the CompactFlashcard. When you boot this system, it starts up a web server. Of course,I have bigger plans for the future, but there just isn‘t enough room inthis article.
Installing the Hardware
TheCompactFlash adapter has three connectors and one jumper. It has an IDEconnector, a CompactFlash card connector and a power connector. Thejumper is used to make this device the master or slave IDE device. Itis very easy to install in a system. I used a development system tobuild the software and a target system to test and run the software. Iinstalled the CompactFlash adapter on the secondary IDE connector of mydevelopment box. It is configured as the master device on thiscontroller, so Linux will see the CompactFlash adapter as /dev/hdc onmy development box. My development box has a hard drive for the/dev/hda device that has Mandrake Linux 7.2 on it. Almost any Linuxdistribution should work, though. I also have an IDE CD-ROM on mydevelopment system that is the /dev/hdb device on the primary IDEcontroller.
I am using a 32MB CompactFlash card for my device,but if you want to duplicate my results from this article, an 8MB cardwill work. The CompactFlash will be used when the target system boots,so it would need to be device /dev/hda on the target. It should beconnected to the primary IDE controller and configured as a masterdevice. In this application, it is the only IDE device in the targetsystem. You could connect other needed devices.
If your BIOSsupports autodetection of drive parameters, it should detect the card.If it doesn‘t, you‘ll have to enter parameters for the cylinders, headsand sectors. Check the TAPR web site for some example parameters youcan use. Make sure that you do not install or remove a CompactFlashcard while the system is powered on. This could cause data corruption.At the very least, it will confuse the operating system if a devicedisappears or appears with no warning.
My target system willhave an NE2000-compatible Ethernet card in it. Make sure you have theproper drivers for the network card you have in your target system. Ifyou installed the driver as a module, you‘ll need to modify the/etc/init.d/rcS file also.
Installing the Software
After reading Bruce Perens‘ articles ("Building Tiny Linux Systems with Busybox, Parts 1 and 2") in the first two issues of Embedded Linux Journal,I decided to build my own system. It would be impossible to use one ofthe full-size major distributions like Red Hat or Mandrake on such asmall CompactFlash card. There are some small distributions that mightwork, such as Tom‘s Root/Boot disk or the LEM distribution. You alsocould use BlueCat or Hard Hat Linux. I decided that Bruce had given meenough information to build my own, so I chose that path. It was abumpy road, but you can learn from my mistakes and build your ownsystem. I recommend that you try it to learn how the system works.
Partition and Format CompactFlash Card
I used the fdisk command to create two partitions on the CompactFlash card. The command you run isfdisk /dev/hdc.I created a partition for the root directory and one for the /vardirectory. The root directory should be mounted read-only, so none ofthe files will get changed even if a program goes crazy when yoursystem is running. The /var directory is writable, so any parameters orchangeable data can be placed under /var. I created each of thesepartitions as 16MB partitions, even though only 5MB of space is used onthe root partition. If you are using an 8MB CompactFlash card, be sureto make the root partition 5MB in size and the /var partition 3MB insize.
Build the Embedded Kernel
The second thingyou will want to do is build a kernel. I chose the 2.2.18 kernel.Version 2.4 has been released, but I didn‘t need any of its extrafeatures and I already had the source code to version 2.2.18. If yourtarget system is low on memory, you might consider a 2.0 kernel if ithas all the drivers you need. My target system is a Pentium, but ifyours is a 386 or 486, make sure you build a kernel that will run onyour processor. If you use a 386, you‘ll probably need to enable MathEmulation because this processor doesn‘t have a built-in mathcoprocessor.
It is always a good practice to include only thedrivers you need in your kernel. Remember, your target device isn‘t a30GB hard drive! You can use modules if you like, but you‘ll need toload them in your code when you need them. Most distributions give youutilities like depmod and others to make sure all the propermodules are loaded in the right order. If you depend on utilities likethese, you‘ll need to make sure they are installed on your embeddeddevice.
The only driver you‘ll need to support the CompactFlashcard is the IDE disk driver. Linux thinks your CompactFlash card is anIDE hard drive. No other drivers are needed to access it.
Build the Root Filesystem
Afterbuilding your kernel, you need to build a root filesystem. I won‘t gointo all the details you need to build a filesystem as this is coveredin Bruce Perens‘ article. I added a web server and some networkingtools to my filesystem though. Here‘s the list of software packages Iused: linux-2.2.18.tar.gz -- the Linux kernel
busybox-0.48.tar.gz -- many Linux utilities
net-tools-1.57.tar.gz -- network support applications
lilo-21.6.1.tar.gz -- a boot loader for the kernel
thttpd-2.20b.tar.gz -- a small web server
ash-0.2 -- a small /bin/sh compatible shell
I also copied the following library files from /lib on my Mandrake system. These libraries were used by the packages above: ld-linux.so.2, libcrypt.so.1, libnss_files.so.2, libc.so.6, libnsl.so.1 and libpwdb.so.0.
I used two utilities to help me determine what libraries were needed on my embedded system. The ldd command tells which libraries are dynamically linked to an executable. If we were trying to get our system to run on a 2MB CompactFlash card or a floppy disk, we would need to be very careful how we compiled our code to make sure they were as small as possible. I‘m using a 32MB card, so there is a little breathing room. I made almost all of my executables dynamic and copied the proper libraries to my system. If disk space is a problem, you might consider a replacement library. There are libraries that are much smaller than the standard libc library included in most distributions.
The other utility I needed to use includes the strace command. The web server software needs to become the user "nobody" on your embedded system. The code needs a few extra libraries to read the /etc/passwd file. For some reason, ldd didn‘t tell me the web server needed these extra libraries. The strace command will run your target program and tell you every file it tries to open. This is how I discovered the additional libraries that were needed.
There are around 200 files in my embedded Linux filesystem. We don‘t have the space to cover every one in this article. Please refer to Bruce Perens‘ article for details on most of these files. I will summarize which files belong in each directory of our filesystem. You can download these files from the Embedded Linux Journal web site: /bin -- the bin directory contains user utilities. Most of these come from the BusyBox program.
/boot -- the boot directory contains the kernel and the LILO boot loader files.
/dev -- the dev directory contains device files needed in our system. The MAKEDEV command can help you create these. Remember that these take up disk space, so only include the ones you will need.
/etc -- the etc directory contains configuration files needed for your system. We‘ll need eight files for our system. I will go into detail about these files a little later.
/lib -- shared libraries go in this directory. Also, if you use modules in your kernel, they will go under the modules directory in /lib.
/mnt -- this directory is normally empty, but can be used if you need to mount another filesystem.
/proc -- this directory is empty. The kernel will put system status files in this directory.
/sbin -- system utilities go in this directory. These utilities affect the entire system. In our embedded system, they are from the BusyBox and the net-tools packages.
/tmp -- this directory should be a soft link to /var/tmp. /tmp should be a writable directory. When a program needs to write a temporary file, it will do so in the /tmp directory. Our root filesystem is read-only, so programs cannot write to /tmp. We will mount the /var filesystem as read/write, so we can make a tmp directory under /var.
/usr -- the /usr directory contains user program files. Most of the files in our /usr directory come from the BusyBox package. I chose to put the web server and its associated files under the /usr directory.
/var -- the /var directory normally contains log files and other writable directories. On our system, the /var directory will be mounted read/write. The only files we‘ll need to have in our /var directory is a tmp subdirectory and a file that contains our networking configuration. The reason this file is in var is so we can change the networking configuration in the field.
The first program run by the kernel after loading is /sbin/init. This program initializes the system and handles the console terminals and system shutdown. The BusyBox application will provide a basic init program for our embedded system. The init program gets its parameters from the /etc/inittab file:
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
::ctrlaltdel:/bin/umount -a -r
The first line tells init to run the rcS script immediately. The second line tells it to start a shell on the console when initialization is complete. The third line tells it to unmount any filesystems when the system goes down.
The rcS script is shown in Listing 1. It should mount all the filesystems, start up the network and start the web server. Notice that we look to see if the file /var/etc/network exists. If it does, we source the file. This allows us to change the networking parameters, such as the IP address and gateway address on the fly. If the file doesn‘t exist, there are default parameters in the script. Using DHCP might be a good idea also, but I didn‘t implement it in my system. Here are the contents of the /var/etc/network file:
NETWORK_IP=192.168.1.2
NETWORK_MASK=255.255.255.0
NETWORK_BROADCAST=192.168.1.255
NETWORK_GATEWAY=192.168.1.254
Make sure to change the IP addresses to match your network.
Listing 1. Filesystem Mounting, Network and Web Server Initialization Script
There are a few other configuration files that you will need on your system. The /etc/fstab file is needed so the mount command knows where each filesystem should be mounted:
proc /proc proc defaults 0 0
/dev/hda2 /var ext2 defaults 1 1
/etc/thttpd.conf, /etc/nsswitch.conf, /etc/passwd and /etc/group are needed by the web server. When the web server starts, it becomes a non-root user. The nsswitch.conf tells it where to find user and group information. Users are in /etc/passwd, and groups are in /etc/group. You can copy the /etc/passwd and /etc/group file from your system. Only include the users and groups that are needed. The nsswitch.conf file is shown in Listing 2. It tells applications to look in files to find users and passwords.
Listing 2. Suggested nsswitch Configuration
Setting up the Web Server
For this application I chose the tiny-turbo web server. This web server is very small and takes up very little memory. It also allows CGI programs, so you can write web programs. This would let you write a web application as the user interface to your devices. The web server is installed in the /usr/httpd directory. The configuration file is in /etc/thttpd.conf file and is listed as:
dir=/usr/heepd/html
chroot
cgipat=/cgi-bin/*
Installing the Boot Loader
Now that the partitions are made, the filesystem created and the kernel built, you need to install a boot loader. The BIOS in PC hardware will load the first sector of the first hard drive when the system boots. You need to have software on your system that will load your Linux kernel from the code in this first sector of the hard drive. I used the LILO boot loader because I‘ve been using this loader for years. It can do so much more than just load a single Linux kernel, but it can do our simple task also.
I had problems making it load the boot-loader software on the CompactFlash card in my development system because the card was addressed at /dev/hdc in my development box. The card will be located at /dev/hda in the target system. Fortunately, there is a way to do it. I found instructions in the LILO mini-HOWTO. See Listing 3 for the contents of the /etc/lilo.conf file. Assuming that you have mounted your CompactFlash card as /mnt/hda1 on your development system, the command to load the boot loader on your CompactFlash card is:
/mnt/hda1/sbin/lilo -r /mnt/hda1 -C etc/lilo.conf
Be very careful with this command. It is possible to replace the boot loader on your development system by mistake. It could cause your development system not to boot properly. It‘s always a good idea to keep a boot floppy around just in case.
Listing 3. A LILO configuration that will make the CompactFlash card bootable.
Test It Out
You should now be ready to test your CompactFlash boot device. Shut down your development system and remove the CompactFlash card. Install the card in your target system and turn it on. For testing purposes, it is best to have a display adapter in your target system. If this isn‘t possible, you can configure the kernel to use a serial port as the console device. If you have a display connected to your target, you should see the kernel messages as the kernel boots. When the kernel is finished booting, it will prompt you to press Enter to start a shell.
Congratulations! You have built a Linux operating system for an embedded device from scratch. You can now test the web server. You can check the web server from another computer. Go to the URL http://192.68.1.2/ in a browser on another computer. Make sure to substitute your IP address in the URL. If you get a welcome screen, it worked. There is a very simple CGI program on the embedded system at http://192.68.1.2/cgi-bin/test.cgi that you can try.
Conclusion
As you can see, installing an embedded Linux system isn‘t very difficult. Now that the OS is installed and working, you just need to write the code for your embedded system and copy it to the CompactFlash card. This is something that anyone with a little knowledge of Linux can accomplish. Good luck building your embedded system!
Resources
About the author: Jay Sissom is a systems analyst in the computing department at Indiana University in Bloomington, Indiana. He is very busy finishing an Electrical Engineering degree. Amateur radio and playing the piano are two of his hobbies. He likes building electronic things in what little spare time he has between work and school. You can send him e-mail at jsissom@indiana.edu.
Copyright ? 2001 Specialized Systems Consultants, Inc. All rights reserved. Embedded Linux Journal Online is a cooperative project of Embedded Linux Journal and LinuxDevices.com.