This recipe will talk about the installation of the BusyBox binary on our desktop development system. Later on, a minimal filesystem will be built with BusyBox and demonstrated with chroot
.
After creating a virtual Android device in the next recipe, we will learn how to install BusyBox on a real embedded platform.
Just as a Swiss Army knife has multiple blades, a single BusyBox executable can be used to invoke many applets. BusyBox applets can be invoked in a number of different ways, explained as follows:
Pass the applet name as the first argument. We use the
echo
applet as an example.$ ./busybox echo 'Hello, Busybox.' Hello, Busybox.
The
busybox
binary can be renamed with the applet's name as follows:$ cp ./busybox du $ ./du -sh busybox du 664.0K busybox 664.0K du
This method may be useful if only one single applet is configured and built into the
busybox
binary. This avoids the need to pass the argument mentioned in the first point and avoids the creation of the extra links required in the following point.Hard links or soft links (symbol links) with applet names can also invoke applets.
$ ln -s busybox wc $ echo "Hello, Busybox." | ./wc -w 2
This also avoids the need to pass the argument in the previous point; if more than one applet is configured, it is more lightweight than renaming the
busybox
binary as the links cost less storage than a real hard copy.
The installation of BusyBox means creating soft links for all of its built-in applets.
Busybox can be installed at runtime or at the earlier compiling stage.
Installing BusyBox at runtime with the
--install
command:To install it separately, rather than overwriting the original system utilities, enter its compiling directory and create a directory to store its applets, as follows:
$ cd ~/tools/busybox $ mkdir -p ~/busybox/bin
Afterwards, install it with the
--install
option.$ ./busybox --install ~/busybox/bin
Soft links will be created for all of the built-in applets, to execute the recent installed applets, set the
PATH
variable in the shell startup script, and load it for immediate use.$ echo "export PATH=~/busybox/bin:\$PATH" >> ~/.bashrc $ source ~/.bashrc
This installation method is used if there is a need to use BusyBox applets on an existing embedded system; for example, if we want to use the lightweight BusyBox
httpd
command on an Android system to build a web service: we can simply take BusyBox on board an Android system and install it at runtime. See the Playing BusyBox on a virtual Android device (Intermediate) recipe for more details.
Installing BusyBox at the compiling stage with
make install
:We can also install it during the compiling stage. We just need to configure the target directory as follows:
Busybox Settings ---> Installation Options ("make install" behavior) ---> (~/tools/busybox/ramdisk/) BusyBox installation prefix
Then type in
make install
and all the applets will be installed in~/tools/busybox/ramdisk/
.$ ls ~/tools/busybox/ramdisk/ bin linuxrc sbin usr
This installation method is often used when we want to build a minimal embedded filesystem with BusyBox, because it creates the basic directory architecture for us automatically during the compiling stage. See the Building BusyBox-based embedded system (Intermediate) recipe for more information.
With --install
, hard links are created. To create soft links (symbolic links), the -s
option should be appended. Soft links must be used if the target installation directory (for example, /bin/
provided by the Android ramdisk filesystem) is not in the same device as the directory (for example, /data/
provided by another filesystem of Android) storing the BusyBox binary; if they are not, we will get the following failure errors:
busybox: /bin/[: Invalid cross-device link
busybox: /bin/[[: Invalid cross-device link
busybox: /bin/acpid: Invalid cross-device link
busybox: /bin/add-shell: Invalid cross-device link
To use the -s
option, it should be enabled with the following configuration:
Busybox Settings ---> General Configuration ---> [*] Support --install [-s] to install applet links at runtime
Apart from the --install
option, the make install
command will install the bin/busybox
binary in the target directory specified by CONFIG_PREFIX
, and it classifies the applets and puts them into different directories based on the applets' setting in include/applets.src.h
; for example, the following line specifies that ls
should be installed to /bin
:
IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls))
To demonstrate quickly how to experiment with the previous filesystem, we use the chroot
command, which allows us to switch to a new root filesystem. In the Building BusyBox-based embedded system (Intermediate) recipe, we'll talk about how to fulfill such filesystems and make it bootable on virtual Android devices.
If BusyBox is dynamically linked, the shared libraries should be installed manually.
Use the shared libraries for our desktop development environment listed by ldd
in the Configuring BusyBox recipe as an example.
$ ldd busybox linux-vdso.so.1 => (0x00007fff9edff000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1cf2cb4000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1cf28f5000) /lib64/ld-linux-x86-64.so.2 (0x00007f1cf2fcf000)
Except the virtual linux-vdso.so.1
(or linux-gate.so.1
), we should create the same directory architecture:
$ cd ~/tools/busybox/ramdisk $ mkdir lib lib64 $ mkdir lib/x86_64-linux-gnu/
The directory architecture looks as follows:
lib
└── x86_64-linux-gnu
├── ld-2.15.so
├── libc-2.15.so
├── libc.so.6 -> libc-2.15.so
├── libm-2.15.so
└── libm.so.6 -> libm-2.15.so
lib64
└── ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.15.so
Then, copy libraries under /lib
and /lib64
of our desktop development environment to the directories under ~/tools/busybox/ramdisk
and create the corresponding soft links as follows:
$ cp /lib/x86_64-linux-gnu/libc-2.15.so lib/x86_64-linux-gnu/ $ cp /lib/x86_64-linux-gnu/libm-2.15.so lib/x86_64-linux-gnu/ $ cp /lib/x86_64-linux-gnu/ld-2.15.so lib/x86_64-linux-gnu/ $ ln -s lib/x86_64-linux-gnu/ld-2.15.so lib64/ld-linux-x86-64.so.2 $ cd lib/x86_64-linux-gnu/ $ ln -s libc-2.15.so libc.so.6 $ ln -s libm-2.15.so libm.so.6
After the installation of the shared libraries, we can start the BusyBox ash
shell in a new root filesystem with chroot
. chroot
needs root permission with sudo
.
$ sudo SHELL=/bin/ash chroot ~/tools/busybox/ramdisk/
The SHELL
environment variable specifies the default shell interpreter for chroot
; in our example, we use BusyBox ash
.
With chroot
, we are able to emulate the target embedded scene.
The installation of the shared libraries for ARM BusyBox is similar, so we will not give an example here. If BusyBox is statically linked, no need to install the extra libraries; we can simply install them and use chroot
to perform the experiment.