Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Instant Optimizing Embedded Systems Using BusyBox

You're reading from  Instant Optimizing Embedded Systems Using BusyBox

Product type Book
Published in Nov 2013
Publisher Packt
ISBN-13 9781783289851
Pages 72 pages
Edition 1st Edition
Languages

Compiling BusyBox (Simple)


After configuration, BusyBox can be compiled into a single binary for different architectures, with different compilers and with static or dynamic linking.

This recipe will compile BusyBox for our desktop development system as a quick demonstration, and meanwhile, build BusyBox for an ARM target platform as an embedded system case.

Getting ready

Before compiling a software, we must get a compiler and the corresponding libraries, a build host, and a target platform. The build host is the one running the compiler. The target platform is the one running the target binary built by the compiler from the software source code. Here, our desktop development system is our build host, and an ARM Android system will be used as our target platform.

To compile BusyBox on our desktop development system, we need a local compiler. Generally, most Linux operating systems ship with a working C compiler, and it's usually GCC (the GNU Compiler Collection is by far the most widely used C compiler on Linux, and can be downloaded from http://gcc.gnu.org/) and the corresponding Glibc (the GNU C Library by far is the most widely used C library on Linux and can be downloaded from http://www.gnu.org/software/libc/). If it isn't present, get one from our system's package manager for Ubuntu.

$ sudo apt-get install gcc g++ make build-essential
$ sudo apt-get install ia32-libs ia32-libs-multiarch

To compile BusyBox on our desktop development system for a different target architecture (for example, an ARM Android system), we need a cross-compiler.

ARM, as the most popular architecture on embedded system, is being used by more and more portable devices, such as the embedded Raspberry Pi board and the Android mobile phone or tablet, so we will concern ourselves with this alone.

The gcc-arm-linux-gnueabi cross-compiler can be installed directly on Ubuntu with the following command:

$ sudo apt-get install gcc-arm-linux-gnueabi

On other Linux distributions, Google's official NDK is a good choice if you want to share Android's Bionic C library, but since Bionic C library lacks of many POSIX C header files, and because we want to get the most out of BusyBox applets building, the prebuilt version of Linaro GCC with Glibc is preferable. We can download it from http://www.linaro.org/downloads/; for example, http://releases.linaro.org/13.04/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.7-2013.04-20130415_linux.tar.bz2.

How to do it...

Let's compile BusyBox with the default configuration for our desktop development system as a quick demonstration of the compiling procedure and cross-compile it for the ARM platform as a real embedded system building example.

  1. Compiling BusyBox for a desktop development system can be done as follows:

    $ make defconfig
    $ make
    $ file busybox
    busybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs)...
    $ 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)
    

    The previous lines of code compiled a binary for our x86-64 development system (the output may differ if you are using a different development system) and dynamically linked it with libm.so and libc.so.

  2. To get a quick start, simply run the echo applet as an example.

    $ ./busybox echo "Hello, Busybox."
    Hello, Busybox.
    
  3. To get help from BusyBox and its applets, we can append the --help command as follows:

    $ ./busybox --help
    

    We see the following output:

    BusyBox v1.21.0 (2013-09-06 01:24:09 CST) multicall binary.
    BusyBox is copyrighted by many authors between 1998-2012. Licensed under GPLv2. See source distribution for detailed copyright notices.
    Usage: busybox [function [arguments]...]
       or: busybox --list[-full]
       or: busybox --install [-s] [DIR]
       or: function [arguments]...
    BusyBox is a multicall binary that combines many common Unix utilities into a single executable file. Most people will create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as. Currently defined functions:
    [, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, 
    chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio, crond, crontab, cryptpw, cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd, false, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flock, fold, free, freeramdisk, fsck, fsck.minix, fsync, ftpd, ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostid, hostname, httpd, hush, hwclock, id, ifconfig, ifdown, ifenslave, ifplugd, ifup, inetd, init, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd, od, openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readahead, readlink, readprofile, realpath, reboot, reformime, remove-shell, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-parts, runlevel, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch, setconsole, setfont, setkeycodes, setlogcons, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, slattach, sleep, smemcap, softlimit, sort, split, start-stop-daemon, stat, strings, stty, su, sulogin, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl, ubiattach, ubidetach, ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, umount, uname, unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xz,xzcat, yes, zcat, zcip.
    

    Also we can use the echo command as follows:

    $ ./busybox echo --help
    BusyBox v1.21.0 (2013-10-16 01:24:09 CST) multi-call binary.
    Usage: echo [-neE] [ARG]...
    Print the specified ARGs to stdout
    
       -n	Suppress trailing newline
       -e	Interpret backslash escapes (i.e., \t=tab)
       -E	Don't interpret backslash escapes (default)
    
  4. Now cross-compile it for the ARM platform. To compile it for the ARM platform, the cross-compiler arm-linux-gnueabi-gcc should be configured with make menuconfig, as we demonstrated in the previous recipe. After configuration, we can simply compile it as follows:

    $ make
    
  5. Then a BusyBox binary is compiled for ARM with dynamic linking as follows:

    $ file busybox
    busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
    
  6. The previous ldd command of our development system doesn't work for listing the shared libraries required by the BusyBox binary for ARM,. Another command should be used instead, arm-linux-gnueabi-readelf, as follows:

    $ arm-linux-gnueabi-readelf -d ./busybox | grep "Shared library:" \
       | cut -d'[' -f2 | tr -d ']'
    libm.so.6
    libc.so.6
    ld-linux.so.3
    
  7. To get the full path, we should first use the library search path.

    $ arm-linux-gnueabi-ld --verbose | grep SEARCH \
       | tr ';' '\n' | cut -d'"' -f2 | tr -d '"'
    /lib/arm-linux-gnueabi
    /usr/lib/arm-linux-gnueabi
    /usr/arm-linux-gnueabi/lib
    
  8. Then we find out that /usr/arm-linux-gnueabi/lib is the real search path in our platform and we get the full path of the libraries as follows:

    $ ls /usr/arm-linux-gnueabi/lib/{libm.so,libc.so,ld-linux.so.3}
    /usr/arm-linux-gnueabi/lib/ld-linux.so.3  /usr/arm-linux-gnueabi/lib/libc.so  /usr/arm-linux-gnueabi/lib/libm.so
    

Using BusyBox on an ARM platform needs an ARM device. This will be introduced in the Creating a virtual Android device (Simple) and Playing BusyBox on a virtual Android device (Intermediate) recipes.

How it works...

The configuration not only generates a .config file with enabled features, but also produces a C header file, include/autoconf.h, that enables or disables the features with C macros. Based on these macros, the compiler determines which C context should be built in the last binary.

There's more...

By default, the binary is dynamically linked. To avoid the installation of shared libraries, to reduce the whole system size, and to reduce the time cost of runtime linking, static linking is often used for embedded system compiling.

To enable static linking, configure BusyBox as follows:

   Busybox Settings --->
      Build Options --->
          [*] Build BusyBox as a static binary (no shared libs)

We get the following error when using a new Glibc to compile BusyBox with static linking:

inetd.c:(.text.prepare_socket_fd+0x7e): undefined reference to `bindresvport'

We need to disable CONFIG_FEATURE_INETD_RPC, as follows, to avoid it:

   Networking Utilities  --->
       [*] inetd
           [ ]   Support RPC services

Then, recompile it as follows:

$ make

Because it is statically linked, the required libraries will be linked into the last BusyBox binary. To run it on the target system, you only need to install the BusyBox binary (no shared libraries need to be installed).

The installation of BusyBox will be discussed in next recipe and the Creating a virtual Android device (Simple) recipe.

arrow left Previous Chapter
You have been reading a chapter from
Instant Optimizing Embedded Systems Using BusyBox
Published in: Nov 2013 Publisher: Packt ISBN-13: 9781783289851
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}