BusyBox
BusyBox is an open
source project that is a key part of many embedded systems. It supplies limited
functionality implementations of most of the command-line executables found on
a desktop Linux system; BusyBox calls these applets. What the applets lack in
functionality is more than compensated for in their size: a complete,
full-featured BusyBox system weighs in at 1.5MB and can be much smaller when
unused applets are dropped.
Download the Software
The BusyBox project resides at
www.busybox.net, and the www.busybox.net/download.html page contains a history
of releases and any follow-on patches. As an example, you’ll use the 1.14.1
release on this page, but understand that the release will be different by the
time this book makes it to press:
$ wget http://busybox.net/downloads/busybox-1.14.1.tar.bz2
$ tar xjf busybox-1.14.1.tar.bz2
At this point, the busybox-1.14.1
directory has the sources for BusyBox ready for compilation. The source is also
available using Git, by doing the following:
$ git clone git://busybox.net/busybox.git busybox
This creates a clone of the Git
repository in the directory ./busybox. The Git clone process takes a few
minutes, even with a fast Internet connection. If you want to follow a certain
branch of BusyBox, use this command to fetch the changes for the branch
$ git checkout remotes/origin/1_<branch>_stable
where <branch> is the
version of BusyBox. In this example, using 14 for the branch fetches the
changes
for the 1.14.x line of development:
$ git branch -a
* (no branch)
master
origin/0_60_stable
origin/1_00_stable
origin/1_00_stable_10817
origin/1_10_stable
origin/1_11_stable
origin/1_12_stable
origin/1_13_stable
origin/1_14_stable
(more output clipped)
You should run these commands
from the directory containing the Git repository; in this example, it’s
./busybox. Following a branch makes sense when you want to get just the minor
changes for a release and not larger-scale changes that may affect your
project.
Configure
BusyBox must be configured before
being built. In the configuration process, you specify what applets to
compile and how to build the
project. The system used is the same as the Linux kernel, so when you do
the following
$ make
menuconfig
Fig: The Busybox Configuration GUI.
$ make defconfig
The configuration process shows how it’s
configured by producing the following output:
(output clipped)POSIX math support
(SH_MATH_SUPPORT) [Y/n/?] y
Extend POSIX math support to 64 bit
(SH_MATH_SUPPORT_64) [Y/n/?] y
Hide message on interactive shell startup
(FEATURE_SH_EXTRA_QUIET) [Y/n/?] y
cttyhack (CTTYHACK) [Y/n/?] y
*
* System Logging Utilities
*
syslogd (SYSLOGD) [Y/n/?] y
Rotate message files (FEATURE_ROTATE_LOGFILE)
[Y/n/?] y
Remote Log support (FEATURE_REMOTE_LOG) [Y/n/?]
y
Support -D (drop dups) option
(FEATURE_SYSLOGD_DUP) [Y/n/?] y
Circular Buffer support (FEATURE_IPC_SYSLOG)
[Y/n/?] y
Circular buffer size in Kbytes (minimum 4KB)
(FEATURE_IPC_SYSLOG_BUFFER_SIZE) \
[16] 16 logread (LOGREAD) [Y/n/?] y
Double buffering (FEATURE_LOGREAD_REDUCED_LOCKING)
[Y/n/?] y
klogd (KLOGD) [Y/n/?] y
logger (LOGGER) [Y/n/?] y
The default configuration isn’t the smallest
configuration. It contains nearly all of the applets, but it’s the fastest and
easiest way to get started. When you need to economize on space, you can reduce
the number of applets to what your system needs, but that’s a matter of
economization.
Build
BusyBox is now ready to be built. Building
the project is much like building any other project that relies on standard make
files:
$ make
CROSS_COMPILE=arm-linux-uclibc-
BusyBox is targeted for embedded developers,
so cross-compiling has been baked into the project from the start. Just set the
CROSS_COMPILE symbol to the prefix of the toolchain, and don’t forget the trailing
dash.
The default installation directory is
_install. It contains the start of a root file system, which follows the
pattern of building the root file system for the target board in a directory
and later using a tool that creates a file suitable for the flash, or other
mass storage, device on the board:
$ make
install
--------------------------------------------------
You
will probably need to make your busybox binary
setuid
root to ensure all configured applets will
work
properly.
--------------------------------------------------
The installation step points out one of the
things you need to do in order to have a working BusyBox root file system.
There are a few more steps, as outlined here at a high level so you can
understand the basic process:
1. Copy libraries. If the BusyBox project was
built with shared libraries, those
need to be located and copied into the root
file system. You also need the
dynamic library loader.
2. Update init scripts. If they aren’t
present, BusyBox uses a minimal
initialization script when the system starts.
The script allows a system to boot
with reasonable defaults.
3. Update permissions. The BusyBox build and
installation runs as a regular user
(if you’re usually logged in as root, shame
on you!), and you must set the
ownership of the files to root.
4. Create additional folders. Some standard
folders need to be created. These are
used to mount file systems like proc and
temp.
5. Create required device nodes. Every Linux
system requires two device nodes:
/dev/null and /dev/console.
Copy Libraries
If BusyBox was built with shared libraries,
you need to copy them into the root file system and place them into the /lib
directory. These files can be copied from the sysroot directory of the
toolchain. BusyBox links against the m and c libraries, but you can prove this
for yourself by doing the following from the directory where BusyBox was built,
assuming installation in the default directory:
$ strings _install/bin/busybox | grep ^lib
libm.so.6
libc.so.6
This command says, “Get all the strings from
the file, and only show the lines that begin with lib.” The program ldd can’t
be used, because the program has been cross-compiled and won’t run on the
development host. These files should be fetched from the sysroot directory of
the toolchain. Most modern toolchains have been configured with a sysroot,
which is a directory that contains the files from the toolchain likely to
appear on a root file system of a system targeted by the toolchain. To check if
your toolchain has sysroot support, try the following:
$ arm-linux-gcc -print-sysroot
<install
dir>/arm-unknown-linux-gnueabi/bin/arm-linux-gcc
If this is a valid path, this is where the
files should be copied from. If no path is displayed, use find to locate a
sysroot directory in <install dir>, or use find to look for libc.so:
$ find . -name libc.so
After you’ve located libc and libm, create
the _install/lib directory and copy them there. The files are likely symlinks
to other files, so be sure to gather them all. The next file to get is the
dynamic loader, normally called ld-linux-<version>, which also resides in
the lib directory along with libc.so.*. Copy that to the _install/lib
directory. Your system now has all the shared libraries and the loader, so BusyBox
can run.
Update Permissions
When the files are created in the
installation directory, the owner and group equal that of you running the
command. When running on a target system, the owner of some of these files
should be root or some other privileged user rather than the random user
account used for installation. Some file systems allow you to force all the
files to be owned by root, and others use the permissions and ownership of the
files as they are on the file system. Most embedded systems have a root user as
well as the individual owner and the group owner of the files. You can do this
with the following command:
$ sudo chown -R root:root _install/
Create Additional Folders
The system needs directories that
serve as mount points for file systems required by the kernel or your application.
Most systems need /dev, /proc, and /tmp directories. Creating these is a matter
of using the
mkdir command:
$ sudo mkdir _install/tmp
$ sudo mkdir _install/proc
$ sudo mkdir _install/dev
The tmp directory is necessary to
mount a file system where temporary files are stored. This file system is
usually a small RAM disk. The /dev file system contains the device nodes for
the system.
Create Device Nodes
Linux requires just two device
nodes: console and null. Your system may require more nodes, say for flash file
devices or serial ports:
$ sudo mknod _install/dev/console c 5 1
$ sudo mknod _install/dev/null c 1 3
Like changing the file owners,
some file systems allow you to create the device nodes when creating the file
system image. Which approach you take depends on your ability to become a
privileged user, because the file system tools that create device nodes can’t
be run by a regular user.
No comments:
Post a Comment