# 10010.Building Tiny Linux Systems with Busybox

 ELJ Issue 0: Building Tiny Linux Systems with Busybox--Part IPosted on Tuesday, November 20, 2001 by Bruce Perens

Create a Busybox single-floppy Linux system that includes a kernel, command-line environment and your application.

Because Linux is small and easy to customize, it's a fine kernel for embedded systems. But what about all of the other programs that are needed for a minimum functional GNU/Linux system? The minimum system installed by the Debian or Red Hat set-up disks, exclusive of the kernel, is about 40 megabytes in size. Busybox replaces the GNU/Linux distribution with a large set of command-line tools--all that are needed to boot and run a practical Linux system with networking--in a very small package.

The typical compiled size of Busybox on the i386 architecture is 256 to 500K total for all tools, depending on the C library used and how it is linked. This makes it easily possible to create a single-floppy Linux systems with a full-featured kernel, a command-line environment, plus your application.

I originally wrote Busybox in 1996 for the Debian GNU/Linux setup disk. The goal was to put a complete bootable system on a single floppy that would be both a rescue disk and an installer for the Debian system. A rescue disk is used to repair a Linux system when that system has become unbootable. Thus, a rescue disk needs to be able to boot the system and mount the hard disk file systems, and it must provide the command-line tools needed to bring the hard-disk root file system back to a bootable state. The Debian installer at the time I wrote Busybox was a Bourne shell script using dialogto provide a simple graphical interface on an ANSI terminal or the Linux console.

Since its creation, many people have added to and maintained Busybox, including members of the Debian Boot-Floppies team, the Linux Router Project and Lineo Corporation, where Eric Anderson maintains Busybox today. In the tradition of Free Software projects, contributions by other authors now make up the majority of the project. Busybox is a part of almost every commercial embedded Linux offerings, and is found in such diverse projects as the Kerbango Internet Radio and the IBM Wristwatch that runs Linux.

The name Busybox comes from a child's toy box with a telephone dial and anumber of knobs, buttons and other devices, all of which make noises when operated. This was called a busy boxin the past and is today commonly referred to as an activity center.

The Busybox source code can be found at www.busybox.lineo.com. By default, the Makefile provided builds a dynamic-link executable using the default libc library on your system. However, it is easily adapted to cross-compilation, and one can select static linking and other, specialized libc libraries by editing Makefile variables. Before you exercise the Makefile options or embed Busybox, you should build and run it on your host system just so that you can get familiar with it. If you are on a Linux system with the development tools installed, simply typing make should build it.

Once you build Busybox, it's time to learn about multi-call executable files. This is a trick we use to make Busybox small. There is one executable called busybox that is linked to 107 different names and provides the functions of 107 different programs. To illustrate this, run the following shell commands:

Now, run these commands:

Be sure to type the leading "./" as illustrated above, or you will get the system version of these commands rather than the Busybox version.

The lncommand is used to apply another name to a file. It does not copy the file. The only space it uses in the file system is the small amount that is necessary to store a name in a directory. You can illustrate this using the following ls command:

Be sure to use the -il argument to ls as above. This causes ls to print the inode number, a unique number identifying each file in a file system, along with the usual long listing provided by the -l argument. Linux allows the same file to have more than one name, but a file only has one inode number. You should see something similar to Listing 1.

Note that this is not a listing of four files. It is a listing of one file with four names, as indicated by the inode number in the first column and the link count in the third column. The link count reports how many names a file has. You'll notice that directories in the common Linux file systems always have a link count of two, because they have two names: "." and "..". Most files, however, only have one name and their link count will be 1.

Because there is a fixed overhead of several kilobytes for every executable program, compressing 107 commands into one file saves a significant amount of space. So, just as we have linked Busybox to four different names, we can link it to 107. This provides us with a complete, bootable, runnable Linux system in a very small space. Even static-linking with GNU LIBC 6, which has become the standard for Linux systems, Busybox occupies only half a megabgyte.

If you don't need the internationalization of LIBC 6, the old LIBC 5 is significantly smaller. A new library intended for embedded use, uC-Libc (www.opensource.lineo.com), is even smaller, but use caution if your application is proprietary. Like Busybox, uC-Libc is covered by the GNU GPL (General Public License), and can't be linked to proprietary software. GNU LIBC 5 and 6, in contrast, are under the LGPL (the Lesser General Public License) and can be linked to proprietary applications. So, don't use uC-Libc for the libc library of a non-free program. At this writing, uC-Libc doesn't quite provide all of the functions required by Busybox, but it's only short a few and these may be provided by the time you read this article.

#### Table 1. Tools Provided

On the Debian install floppy, I linked Busybox dynamicaly, and then stripped down the shared libc library so that it only provided the functions necessary to support Busybox and the other executables on the floppy. This was the best way to provide a library shared by several different executables, since the floppy contained other programs besides Busybox. Stripping libc down to only the functions that actually were used cut its size by half. Rather than strip it by hand, I wrote a script that finds all of the library functions referenced by a set of dynamic executables, and then creates a library subset providing those functions (and the functions they depend on). This script has since been completely replaced by a version written by Marcus Brinkmann, which can be found in the Debian boot-floppies package under scripts/rootdisk/mklibs.sh. The script and how it works are properly the subject of another article the size of this one however, until that article is written, one can puzzle out how mklibs.sh works by installing the boot-floppies package on a Debian system, building the floppies and then reading the script carefully. Warning: mklibs.sh is probably the most complex shell script you will ever examine.

So, now that you know how to build and run Busybox, how do you make a small Linux system containing it? You'll need a few pieces: a static-linked Busybox executable, a skeleton root file system and /dev directory populated with the proper special files, and a Linux kernel with the features you need plus two features that will be used to boot and run a small Linux system: RAM disks and the compressed ROM file system. [Look for the details on how to build a small Linux system containing Busybox in a future issue--Ed.]

------------------------------------------------------------------------------------------------
 ELJ Issue 1: Building Tiny Linux Systems with Busybox, Part 2: Building the KernelPosted on Saturday, January 20, 2001 by Bruce Perens

For this example I use Linux kernel version 2.2.17. The 2.4.0-test8 kernel that I tried did not size the RAM disk for the root file system properly, leading to a not enough memory'' message at boot time. That bug will probably be repaired in the 2.4 series of kernels by the time you read this.

We will build our example to run on an i386-architecture PC-compatible system with PC keyboard and VGA display, booting from a floppy disk and running the root file system entirely in RAM once the system is booted. This example should also boot from IDE disks and from FLASH EEPROM devices that masquerade as IDE disks. It can also be configured to boot from a CD-ROM.

Build a bzImage-style kernel with all of the facilities needed for the application, plus these three:

• RAM disk support (in the Block Devices menu)
• Initial RAM disk (initrd) support (also in the Block Devices menu)
• ROM file system support (in the File Systems menu)
Don't use kernel modules, because this example system doesn't support them. Don't put any facilities in the kernel that you don't need, as they will use up space that you need on the floppy disk. A kernel with the facilities you need should be around half a megabyte in size and should fit easily on a floppy along with the ROM root file system. A kernel with many unnecessary bells and whistles will be a megabyte or more and won't leave sufficient room for your ROM root file system.

If you're not familiar with building and installing kernels on a normal Linux PC, you'll need to study up on that. In short, I placed the kernel sources in /usr/src/linux and ran:

This created a compiled Linux kernel in /usr/src/linux/arch/i386/boot/bzImage.

In the busybox source directory, edit the Makefile, changing the variable DOSTATIC from false to true. Then run make. That will create a static-linked version of busybox. Confirm that it is static-linked by running this command:

This should print something like:

It's important to get this right; if you install a dynamic-linked version of Busybox, your system won't run because we aren't installing the runtime dynamic linker and its libraries on the floppy disk for this example.

### Creating a ROM Root File System

We're going to go through all of the steps for creating a minimal root file system by hand so that you will understand just how little is necessary to boot your system rather than copying all of the files from the root of your Linux distribution and then being afraid to remove anything because you don't know whether it's necessary. You will need to become root (the superuser) to perform the following steps because the mknod command requires superuser privilege.

Create the tiny-linux directory and change directory into it:

Create the standard directories in it:

Enter the tiny-linux/dev directory:

Create the generic terminal devices:

Create the virtual terminal device for the VGA display:

Create the RAM disk device:

Create the null device, used to discard unwanted output:

Change directory to tiny-linux/etc/init.d, where startup scripts are stored:

Use an editor to create this shell script in tiny-linux/etc/init.d/rcS. It will be executed when the system boots:

Make the script executable:

Change directory to tiny-linux/etc:

Use an editor to create the file tiny-linux/etc/fstab, which says what file systems should be mounted at boot time:

Set the mode of tiny-linx/etc/fstab:

Use an editor to create the file tiny-linux/etc/inittab, which tells /bin/init, the system startup program, what processes to start:

The above example runs the script /etc/init.d/rcS at boot time and runs an interactive shell on the console device.

Set the modes of tiny-linux/etc/inittab:

That's everything necessary to create your root file system, except for the installation of the programs. Change directory to tiny-linux/bin:

Copy your static-linked version of Busybox from wherever you built it into tiny-linux/bin/busybox with a command similar to this one:

Add another command name ls to Busybox using the ln command:

Run ls, and the result should look like this:

Repeat the above ln command for all of these names:

Are you tired yet? Well, now is a good time to take a break--you've finished creating your ROM root file system.

### Generate the ROM Root File System Image

You'll need the genromfs program to generate the ROM file system image. If you are using Debian or Red Hat, it's already packaged for you as part of the standard system; you'll just need to run the command to install it. If your Linux distribution doesn't include a prepackaged version, at this writing the program can be found at ftp://ibiblio.org/pub/Linux/system/recovery/genromfs-0.3.tar.gz. Install the program, change directory to the directory that contains tiny-linux and run these commands:

This creates the ROM file system image in the file fs. Now, compress the file system image using the gzip command:

That will create the file fs.gz, which is about half the size of the uncompressed version.

### Build the Floppy

We'll need one more program to build our floppy: syslinux. This is an i386 bootstrap program that will load a kernel and a compressed root file system image from a floppy, hard disk or CD. Again, it's prepackaged with Debian or Red Hat and can be found, at this writing, at ftp://ibiblio.org/pub/Linux/system/boot/loaders/syslinux-1.48.tar.gz.

Create an MS-DOS file system on a floppy by using the Linux mformat command (or by another means). Put the floppy in your drive but don't mount it, and install the syslinux bootstrap with this command:

That will copy a first-stage bootstrap onto the first block of the floppy and a second-stage bootstrap into the file LDLINUX.SYS in the MS-DOS file system of the floppy. I'm assuming you have a directory called /mnt; substitute whatever directory you usually use for mounting floppy disks in the shell commands below. Now, it's time to copy our kernel and root file system onto the floppy:

Create the configuration file /mnt/syslinux.cfg with an editor:

This tells syslinux to wait for two seconds and then boot the default system. You can interrupt the default boot during those two seconds by pressing the shift key. Typing linux at the prompt will do the same thing as the default.

The kernel is booted with the arguments root=/dev/ram0 and initrd=fs.gz. These arguments tell the kernel that the root is a RAM disk, and that the RAM disk is loaded from the compressed ROM file system image fs.gz. Although the ROM'' root file system is actually in RAM, it will not be writable because the Linux ROM file system driver used in this example is meant to work with real ROMs and thus doesn't support writing.

### The Smoke Test

Configure an i386 PC to boot from the floppy. Note that this is a setting in the BIOS preferences of most new PCs, and they are often configured to boot from the hard disk without first looking for a bootstrap on the floppy. Place the floppy in the first floppy drive, and restart the system. You should see something like the following:


Uncompressing linux, OK, booting the kernel

Tons of cybercrud about every device driver and facility in the kernel race by too rapidly to read...

RAMDISK: Compressed image found at block 0.
VFS: Mounted root (romfs file system)


You've done it! Press Enter and you should see something like this:

Pop out the floppy disk; it's not being used any longer. The root file system is entirely in RAM. You should be able to look around the system and try out commands, but you won't have any writable storage. This is the simplest, bootable-system, running busybox that I could think of, and thus I've left out the files in /dev that you'd need to mount writable RAM disks, floppies and hard disks. You now should be able to figure out what those devices are, add them and build a tiny Linux system specialized to your application.

-----------------------------------------------------------------------------------------

 ELJ Issue 2: Building Tiny Linux Systems with BusyBox, Part 3Posted on Tuesday, March 20, 2001 by Bruce Perens

Let's get smaller, writable and multiuser! A new library, new kernel and other bells and whistles gives us more practice building a highly functional Linux system with a tiny footprint.

This is the third article in the series Building Tiny Linux Systems with BusyBox''. You'll need to refer to my last article (part 2) on kernel building in the January/February 2001 issue of ELJ if you don't have a paper copy of the previous issue on hand, you can refer to the on-line magazine archive at http://embedded.linuxjournal.com/magazine/issue01/4395/ [Part 1 appeared in the ELJ supplement (November 2000) and is available at http://embedded.linuxjournal.com/magazine/issue00/4335/.]

In this article, we'll add writable storage and a multiuser capability to your tiny Linux system, and when we're done the system will be much smaller than when we started.

### Time Marches On

Progress on BusyBox and its friends has continued since I wrote the first two articles, largely due to the efforts of Erik Andersen, whose name I so horribly misspelled in the first article. Erik's work on BusyBox and associated programs is supported by Lineo and benefits the entire Embedded Linux community. Erik and his colleagues have continued to contribute to BusyBox using the original license I chose, the GPL, and they have made great contributions to other embedded programs under the GPL and LGPL.

In my last article, we used the 2.2 kernel, due to a bug in 2.4. That has now been repaired, and since the 2.4 kernel has been released, let's try it. syslinux has also been updated to cope with the new kernel.

### Getting Comfortable with the 2.4 Kernel

Take the time to install the 2.4 kernel on a BusyBox floppy, just to get comfortable with configuring and running it. We'll use some scripts in the elj-3 directory to spare you most of the typing you did in the kernel article.

If you still have the tiny Linux directory that we used in the second article, move it out of the way. We're about to create a new one.

Extract the kernel source and configure it as we configured the kernel in my last article under the subhead Build the Kernel'', but add two new features to the kernel if they are not already in it: the DOS FAT filesystem and the VFAT (Windows 95) filesystem. These are in the filesystems menu of the kernel configuration. You will need to use these filesystems on both your development system and your tiny Linux system, so you may end up building and installing two kernels. Remember, you need to keep the kernel on your tiny Linux system small, so it probably won't be the same kernel you run on your development system.

Go to the BusyBox source directory and edit the Makefile, setting DOSTATIC to true to build a statically linked version of BusyBox. Build BusyBox with the make command, and then run:

This will create the tiny Linux directory in the directory above the BusyBox directory and will create the bin, sbin and /usr/sbin directories within the tiny Linux directory. The Makefile will install BusyBox in that directory tree and will create all of the links for the various command names, automatically doing much of the work we performed manually in Part 2. It won't install scripts and files and won't create the /dev directory. One of the scripts you downloaded will do that. Change directory to ../elj-3 and run:

That will create the contents of the /dev and /etc directories and anything else you need to make a ROM filesystem.

Now, follow the instructions in my January/February 2001 article under the subheadings Generate the ROM Root Filesystem Image'' and Build the Floppy''. Finally, boot the floppy to test it.

### Let's Get Small

Now, go back to the BusyBox source, edit the Makefile and look for the lines that say to compile vs. an alternative libc, you may need to use/adjust the following lines of source to meet your needs''. Below that section are lines that define LIBCDIR, LDFLAGS, LIBRARIES, CROSS_CFLAGS and GCCINCDIR. Most or all of these definitions are commented out. Uncomment the definitions to enable linking with uClibc. Change the definition of LIBCDIR to be the location of your uClibc source. Edit Config.h, and comment out the BB_GETOPT and BB_FEATURE_NFSMOUNT definitions to disable the getopt command and the ability to mount remote NFS filesystems with the mount command. As I write this, there's a bug preventing the BusyBox getopt command from working with uClibc, but that might be fixed by the time you read this article. uClibc does not currently include network support, although I'm sure that someone will add it eventually.

Now, rebuild all of BusyBox with the make clean and make commands. On my system, the result is a statically linked executable of 297,620 bytes in size.

Remove the file tiny-linux/bin/getopt. That file won't be generated this time because we turned off the definition of BB_GETOPT. If we don't remove it, we'll end up with two versions of BusyBox and a lot of wasted space.

Use the instructions above under Getting Comfortable with the 2.4 Kernel'', starting with the command:

This generates another floppy. Boot the floppy to test it.

Probably the biggest missing feature in your tiny Linux system so far is the lack of writable storage. Let's fix that now. We'll use a VFAT filesystem for the writable storage. This is an extension of the old DOS FAT filesystem to handle long and mixed-case filenames, introduced for Windows 95. Since your floppy already uses a DOS filesystem to hold the kernel and the compressed ROM image file, it's easiest to use VFAT to extend that filesystem for this example. Become root. Create a tiny var directory. This directory tree will hold files that will be writable on your tiny Linux system. You will copy it to the floppy later on, and it will be mounted on /floppy/var when your tiny Linux system boots.

Move your entire tiny-linux/etc directory to tiny-var/etc using the command:

Create two other directories: tiny-var/shm and tiny-var/home. The first directory is used by the mount command as a placeholder when providing shared memory, and the second is used to hold home directories for users.

Now we'll create symbolic links in tiny Linux to redirect some directories to /var so that you will have access to your writable storage and then redirect /var to /floppy/var. We do the symbolic links in two levels here so that the location of all of the writable storage can be changed by replacing only one link:

Create the shell script startup.sh as shown below:

This script will run when the system starts, instead of init, because we'll provide a special command-line argument to the kernel. It will mount the floppy so that the contents of /etc are correct before init starts. Note that exec/sbin/init is different from simply running /sbin/init. The exec command says to replace the shell with the given program, rather than run the program as a subprocess of the shell. Thus, init will run in the same process-ID as the shell, which in this case will be process-ID 1. This is important as the kernel gives process-ID 1 some special properties, and init will not run properly unless it's in process-ID 1.

Change the mode of the script so that it is executable:

Change directory up one level (cd ..):

Use an editor to modify the file tiny-var/etc/inittab, which tells /bin/init, the system startup program, which processes to start. The entire contents of the file should look like this:

We're adding lines here to cleanly unmount filesystems at shutdown time, so that the floppy filesystem containing the writable files will be unmounted. Tasks on lines that start with ::ctrlaltdel: will be executed just before the system halts. We also turn off any swap partitions that are activated, just in case they live on a mounted filesystem.

Create the special device file necessary to mount the floppy:

Now, regenerate the ROM filesystem from the tiny Linux directory, using genromfs as before, and compress it using gzip to create a new fs.gz.

Mount your floppy with this command:

and copy the new fs.gz to your tiny Linux floppy, replacing the old ROM filesystem.

Copy the tiny var directory tree to your floppy with the commands:

Tell the kernel to run /startup.sh instead of /sbin/init by editing the file /mnt/syslinux.cfg. Change the line that says

to say

Change directory to /, and unmount the floppy with this command

You should now be able to boot the floppy, and the directories /var, /etc and /home should be writable.

### A Multiuser System on One Floppy

Your tiny Linux system currently just logs you in as root. Let's make a more versatile system that supports user and group names, the login command, support for logins via the console, a modem or a serial line, and utilities to add and delete users. Let's also make the disk writable, unlike the system we made in the second article. Let's fit all of this, and our BusyBox toolkit of more than 100 general-purpose UNIX commands, on one floppy with room to spare!

Go into the TinyLogin source directory and edit the Makefile. We'll be using uClibc to build TinyLogin, so set DOSTATIC to true, comment out the -lcrypt in the definition of LIBRARIES, and set USE_SYSTEM_PWD_GRP to true. Look in the Makefile for the lines that say To compile vs. an alternative libc, you may need to use/adjust the following lines to meet your needs.'' Change the lines below that in the same way that you changed the BusyBox Makefile to enable building with uClibc.

Warning: if you ever link TinyLogin with a C library that uses the Name Service Switch (NSS), including GNU LIBC and probably the default libc on your development system, you must set USE_SYSTEM_PWD_GRP to false in the Makefile. That will replace the functions that read the /etc/passwd and /etc/group files, etc., with a version that does not use NSS. Our tiny Linux system doesn't provide the files and other facilities needed for NSS to work, and thus TinyLogin will fail when built with it. This is the most-often-reported bug'' for TinyLogin, and its author is rather weary of explaining how NSS works to everyone who reports this bug''.

Build TinyLogin with the make command. The result should be about 58K in size.

Change directory up one level (cd ..).

Use an editor to modify the file tiny-var/etc/inittab, which tells /bin/init, the system startup program, which processes to start. The entire contents of the file should look like this:

This configures the system to offer a login on the first four console virtual terminals and on the first two serial ports at 9,600 baud. Create the file tiny-var/etc/passwd containing this line:

Create tiny-var/etc/group containing this line:

Create the terminal devices:

Change directory up two levels (cd ../..).

Regenerate the compressed ROM filesystem, and install it on the floppy, as you have done before. Copy the new tiny var to the floppy using this command:

Feel free to add the missing files and test the other programs in the TinyLogin package. To have a fully functional system, you'll need /etc/shadow, /etc/gshadow, /etc/securetty and the utmp file. The location of the utmp file is defined in /usr/include/paths.h on your development system.

Security will be nonexistent because the VFAT filesystem doesn't support the ownership and mode information needed to provide security. You'll have to replace VFAT with another filesystem if you actually need this system to be secure. The USMSDOS filesystem is a good replacement for VFAT. Other filesystems are just a bit more complicated because they aren't compatible with the MS-DOS FAT filesystem used by syslinux to load the kernel and the ROM filesystem image. You could replace the FAT filesystem entirely with the MINIX or EXT2 filesystems, but you'd have to switch your boot loader from syslinux to LILO or grub. You could also mount the writable filesystem from another disk drive.

### Coming Up

In the next issue, we'll work on security, and we'll provide the remaining facilities used by TinyLogin. Don't let that keep you from experimenting between now and then--you'll understand how the system works much better if you figure it out by yourself. We'll add dynamic linking and shared libraries and some other exciting new facilities. So, stay tuned!

• 本文已收录于以下专栏：

## 移植busybox-1.21.1

1、解压 # tar jxvf busybox-1.21.1.tar.bz2 2、配置 # cd busybox-1.21.1 # make menuconfig Busybox Settings  ...
• zjhsucceed_329
• 2014年06月28日 16:41
• 2081

## BusyBox制作tiny linux

• danforn
• 2006年12月07日 17:49
• 1423

## tiny linux: 内核精简的根文件系统制作

tiny linux要求实现以下两点： 精简linux内核镜像，要求在支持TCP/IP数据传输的情况下，内核镜像和正常运行所需内存能够做到尽可能的小。 采用busybox制作根文件系统，利用kerne...
• SunliyMonkey
• 2015年06月16日 20:51
• 2622

## BusyBox simplifies embedded Linux systems

The birth of BusyBoxBusyBox was first written by Bruce Perens in 1996 for the Debia...
• 2011年03月02日 16:57
• 512

## 使用Busybox做一个小巧的Linux操作系统

http://www.iwillup.com/oracle/tech/117.html
• bytxl
• 2014年05月26日 14:45
• 1086

## 嵌入式Linux中BusyBox的使用

BusyBox是很多标准 Linux 工具的一个单个可执行实现，主要应用于嵌入式linux系统，是一个开源的“万能工具”。接下来我们一起来看看这个工具的魅力。 万能的BusyBox BusyBox...
• binchel
• 2014年03月01日 11:49
• 4867

## 用busybox搭建最简单的Linux文件系统

• Robot__Man
• 2015年09月09日 19:53
• 3745

## 在Virtual Box中搭建Tiny Core Linux SSH服务器

• winniezheng
• 2014年03月26日 10:47
• 1997

## 编译／安装busybox

1、下载最新版本busybox-1.22.1.tar.bz2  2、解压源码   # tar xvjf busybox-1.22.1.tar.bz2   3、进入源码修改Makefile  ...
• yakehy
• 2014年07月14日 19:52
• 664