The procedure outlined in this chapter uses the components shown in the following table.
Component | Description |
---|---|
Linux 2.2 kernel | By the time you read this, the 2.4 kernel will be available and somewhat bug free. You may want to use the 2.4 kernel instead of the 2.2 kernel. If you do, you may have to modify the following procedure somewhat. |
Minicom | Minicom is a great little serial communications utility. Because it’s a simple application, anyone with a standard PC can use and test it. If you want to use a different application in the following procedure, you can do so, but remember that the procedure will need to change somewhat to accommodate that application. |
SYSLINUX | The procedure uses SYSLINUX to boot the floppy disk. If you prefer, you can use GRUB or LILO. |
You should create a directory for each of your projects so that the files that comprise each project are kept in a well-defined place.
It’s best to keep the source code for the components of your project along with the project itself. For instance, in the following steps you’ll download the Linux kernel, Minicom, and SYSLINUX. But what happens if you make some changes to your copy today, and then you need to upgrade to new versions three years from now? You’ll need the original source code to create patches to the new versions. Because it’s so important to the Linux community at large, even three years from now you’ll be able to download the sources for the exact version of the kernel you used with this procedure. However, you may not be able to get old versions of Minicom or SYSLINUX. It really depends on whether the maintainer of each package keeps all the old versions.
For this procedure, begin by creating a directory called eminicom to store the Minicom software.Then change to that directory in preparation for downloading Minicom:
mkdir eminicom cd eminicom
Minicom is a serial communications program originally written by Miquel van Smoorenburg. It’s a lot like the old MS-DOS programs PROComm and Telix, which were used by many people in the days before the Internet to connect to bulletin board systems with a serial modem. It can also be used to connect a PC to devices such as routers and switches for initial configuration.
Minicom is a powerful program with a lot of configuration options. Help is available using the Alt+A Z key sequence. It will be helpful to read the man page for Minicom on the system on which you build the floppy disk, to familiarize yourself with Minicom’s features. For instance, a Minicom configuration file could be added that enables Minicom to save its dial list to the floppy disk, so the dial list would be kept through reboot cycles.
Download the source code for Minicom from www.pp.clinet.fi/∼walker/minicom.html. If it’s not there, use www.freshmeat.net to find it. If you have trouble downloading it, use http://ftpsearch.lycos.com to search for the filename, and then pick a site near you to download from. At the time of this writing, the latest version was 1.83.0.
Caution: Be careful when downloading files that end in .gz with Netscape. You should shift-click or right-click and Save As when attempting to download the files in this section. See the Netscape documentation for more information.
If you want to build a boot floppy for some other simple, single-binary application, you could download that application instead.
The documentation for SYSLINUX describes it like this:
What SYSLINUX Is
SYSLINUX is a boot loader for the Linux operating system which operates off an MS-DOS/Windows FAT filesystem. It is intended to simplify first-time installation of Linux, and for creation of rescue and other special-purpose boot disks.
SYSLINUX can be used, when properly set up, [to] completely eliminate the need for distribution of raw diskette images for boot floppies. A SYSLINUX floppy can be manipulated using standard MS-DOS (or any other OS that can access an MS-DOS filesystem) tools once it has been created.
What SYSLINUX Is Not
SYSLINUX is probably not suitable as a general purpose boot loader. It can only boot Linux from a FAT filesystem, and not, for example, ext2. Since a native Linux implementation will typically use ext2, another boot loader (e.g. LILO) is probably more suitable. In a system which actually contains DOS or Windows, LOADLIN may be simpler to use. However, SYSLINUX has shown itself to be quite useful in a number of special-purpose applications.
Download the latest version of SYSLINUX from ftp://ftp.kernel.org/pub/linux/utils/boot/syslinux. At the time of this writing, the latest version was 1.48. It’s also possible to use GRUB or LILO, but SYSLINUX is a bit easier.
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.19. It doesn’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.
Use the following commands to untar the minicom and SYSLINUX files and the Linux kernel:
tar xzf minicom-1.83.0.src.tar.gz tar xzf syslinux-1.48.tar.gz tar xzf linux-2.2.15.tar.gz
If you’re using different versions, substitute the correct filenames in the commands above. When you’re done, there will be a new directory named linux.
Tip: When untarring, change xzf to xvzf if you want to see the files that are created.
Caution: Be very careful not to blow away your current sources if you already have a linux directory. Normally, as soon as I untar a kernel I rename it to linux-x.y.z. 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!
You have to make a few small changes to the source code for Minicom to make sure that it works properly in your mini-environment. Begin by changing to the Minicom source directory:
cd minicom-1.83.0/src
You need to modify the Makefile so that a static executable is produced. When you compile an application on a modern Linux system, it creates a dynamic executable that needs shared libraries for common functions such as read(), write(), and printf(). The whole point of this exercise is to create a static embedded application; this way, you don’t have to worry about creating the shared libraries and setting them up so they’ll work at runtime.
Look for the line that begins with minicom: and add -static somewhere on the next line.This single switch causes all the code necessary to run the application to be contained in the single executable. For instance, if the line says this:
$(CC) $(LFLAGS) -o minicom $(MOBJS) $(LIBS)
change it to look like this:
$(CC) -static $(LFLAGS) -o minicom $(MOBJS) $(LIBS)
Next, you need to remove a Minicom security feature that’s unnecessary in this embedded application. In minicom.c, remove the entire if clause that contains the string “You don’t exist. Go away.” If this logic is not removed, Minicom will bail out when execution gets to this point. Since you don’t have to be concerned with permissions and correct users in your embedded environment, it’s safe to simply remove this logic.
Now make the Minicom executable file:
make
If everything goes well, you’ll end up with a static executable file called minicom. You can make sure it’s static with the ldd command:
$ ldd src/minicom libc.so.6 => /lib/libc.so.6 (0x4001e000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Change directories back to the root of your project (eminicom) and create a blank initrd image by using the dd command:
cd ../.. dd if=/dev/zero of=fs bs=1k count=600
This command creates a file with 600 1KB blocks in it. Each block is filled with zeros. It’s important to create this file from scratch each time because you want it to compress as much as possible. If you just keep using the same file over and over again, blocks that really have no data in them wouldn’t compress well because they no longer are filled with only zeros. (When files are deleted, the contents of these files are still left inside the initrd.)
Now you’re ready to create the filesystem in the fs file. We’ll use the e2fs filesystem because it’s the best-tested filesystem in Linux:
mkfs.ext2 ./fs
Tip: You have a choice of several filesystem types for your root filesystem. The choice usually boils down to ext2 or minix. I typically use the ext2 filesystem, although the minix filesystem is quite a bit smaller.
Now mount the filesystem. Linux mount is pretty good at determining the file-system type from the filesystem itself. If it has a problem, you may need to tell it what filesystem type it’s dealing with, using the -t option.
mount -o loop fs /mnt
You’re ready to create the special files needed for your embedded environment. You must use the -a option of the cp command so that the directory entries are copied but the files themselves are not.
mkdir -p /mnt/dev (cd /dev && cp -a console full kmem loop0 loop1 mem null port ram0 ram1 tty tty0 tty1 tty2 ttyS0 ttyS1 ttyS2 ttyS3 urandom zero /mnt/dev) (cd /mnt/dev && ln -s /proc/kcore core) (cd /mnt/dev && ln -s ram1 ram)
Now, create the terminfo for the console. This file contains the definitions of escape sequences for the console for operations such as clearing the screen and drawing lines:
cp -P /usr/share/terminfo/l/linux /mnt
Copy the Minicom executable to the initrd filesystem and name it /linuxrc:
cp minicom-1.83.0/src/minicom /mnt/linuxrc
You name the executable /linuxrc in your filesystem because that’s the name of the script (or program in this case) that the Linux kernel will run when it’s done booting. You might expect to name it init instead. But since you’re using the initrd feature of the Linux kernel to load your application into memory, you must name it linuxrc, since that’s what Linux expects when starting an initrd process.
Test the setup by running the linuxrc program with /mnt set as the root directory. This way, you know that /linuxrc runs in the same environment it will run with on your device:
chroot /mnt /linuxrc
chroot runs the command specified by the third parameter, using the directory specified in the second parameter as its root directory. The command has no access to any files on the computer other than those under the specified root directory. The reason you run /linuxrc instead of /mnt/linuxrc is that the chroot happens before the execution of the command, and once the chroot happens the linuxrc file is then in the root of the new directory structure.
If everything goes okay, the Minicom program should start. If you’re adventurous, you could attach a modem and put Minicom through its paces. To exit Minicom, press Ctrl+A X.
Now, unmount the initrd filesystem and compress it as much as possible (the -9 option sacrifices speed for better compression):
umount /mnt gzip -9 fs
Change to the kernel directory:
cd linux
Configure the kernel using the make menuconfig command. The following options are based on a 2.2 Intel kernel; your kernel configuration may be a bit different. Turn off all options except the following:
Processor Type and features
386 processor family
General setup
Kernel support for ELF binaries
Block Devices
Normal PC floppy disk support
Enhanced IDE/MFM/RLL disk/CD-ROM/tape/floppy 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
Second extended fs support
Console drivers
VGA text console
Build the kernel with the following command:
make dep && make bzImage
We use the “and” continuation (&&) instead of the semicolon (;) so that the second make won’t happen if the first fails. I’ve never 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 an error occurs in one of the makes, the subsequent makes won’t 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 like this:
make dep && make bzImage && make modules
Change back to the root directory of your project:
cd ..
Insert a floppy disk into the drive.We’ll assume it’s /dev/fd0 (/dev/fd0H1440).
The rest of this procedure assumes that you’re using a 3½-inch floppy of 1.44MB capacity. If this assumption is incorrect, change the commands accordingly.
Perform a low-level format of the floppy disk. If you’re sure the floppy is already formatted for 1.44MB, you can safely skip this step:
fdformat /dev/fd0H1440
Create an MS-DOS filesystem on the floppy disk and mount the floppy as an MS-DOS disk:
mkfs.msdos /dev/fd0 mount -t msdos /dev/fd0 /mnt
The mkfs.msdos command has a couple of parameters that you can tweak to get more room. If you’re really pressed for space, add -f 1 to reduce the number of FAT tables to one.
Now copy the compressed kernel, the initrd filesystem, and the SYSLINUX MS-DOS floppy boot loader system file to the floppy disk:
cp linux/arch/i386/boot/bzImage /mnt cp fs.gz /mnt cp syslinux-1.48/ldlinux.sys /mnt cat > /mnt/syslinux.cfg LABEL linux KERNEL bzimage APPEND initrd=fs.gz
End the cat command with Ctrl+D.This command creates the syslinux.cfg file on the floppy disk.
Tip: Of course, you can use a more powerful editor such as vi or emacs to create this file, but for demonstration purposes this is the simplest way to describe how to create the file. For a lot more information about what can go in this file, see the syslinux.doc file in the SYSLINUX distribution.
Unmount the floppy disk, make it bootable, and use the sync command to make sure that all writes are synchronized to the floppy:
umount /mnt syslinux-1.48/syslinux /dev/fd0 sync
Wait until the command prompt reappears. Then remove the floppy disk from your build machine and boot your test bed machine with it. If all goes well, Minicom should appear within a few seconds of booting.