Book Image

Instant Optimizing Embedded Systems Using BusyBox

Book Image

Instant Optimizing Embedded Systems Using BusyBox

Overview of this book

As hundreds of millions of people have started using Android smartphones, embedded Linux systems are becoming more and more popular. To get more market share, not only for hardware and function piling up, smartphone manufacturers gradually realized the importance of user experience. To improve user experience, the back-end Linux system must be optimized in many ways. Instant Optimizing Embedded System Using BusyBox is a practical, hands-on guide that provides you with a number of clear, step-by-step exercises to help you take advantage of the real power behind Busybox, and give you a good grounding for using it to optimize your embedded (Android Linux) systems. Moving on from the basics, this book will teach you how to configure and compile it from source code, including cross-compiling it with static linking and dynamic linking. You will also learn how to install and use Busybox on the Android emulator. You will learn to replace the simple Android mksh console with Busybox ash console and start a telnet and HTTP service provided by Busybox. You will also build embedded Linux file system from scratch and start it on Android emulator. We will take a look at how to add functionality to Busybox based system, including adding external applets to Busybox, as well as building development environments (like Bash and C) for it manually or with the automatic Buildroot system. If want to learn how to take advantage of using Busybox applets to optimize your embedded system, then this is the book for you for it will also show you how to use the powerful applets to optimize multiple aspects of an embedded (Android Linux) system.This book will teach you how to build an embedded (Android Linux) system with Busybox, enhance its functionality to meet diverse system requirements, and optimize it to provide a better user experience for embedded products.
Table of Contents (8 chapters)

Building BusyBox-based embedded systems (Intermediate)


BusyBox can be used as a toolbox on existing systems, and it is also often used to build a bootable embedded system.

Let's build a standalone system with BusyBox from scratch and launch it on a virtual Android device with an Android emulator.

Getting ready

This recipe will use BusyBox to build our own filesystem and compress it to a gzipped cpio package, just like ramdisk.img, which we used in the previous recipe.

To boot such a new system, a new Linux kernel image should be compiled from Google Android-specific Linux kernel source code. Clone the source code for preparation.

$ cd ~/tools/busybox/
$ git clone https://android.googlesource.com/kernel/goldfish.git

The source code is specifically designed for Android goldfish hardware; the Android emulator won't run on other hardware.

To cross-compile an Android Linux kernel, the cross-compiler arm-linux-gnueabi-gcc should have been installed when going through the Compiling BusyBox recipe.

How to do it...

Based on the Installing BusyBox recipe, let's build our own filesystem: ramdisk.img with BusyBox from scratch, cross-compile our own Linux kernel image, and then boot them on the Android emulator:

  1. Build a minimal Linux filesystem with BusyBox. To build a minimal bootable filesystem, the standard Linux filesystem directory architecture should be prepared at first.

    Apart from the /bin, /sbin, and /usr directories that are created by default, the /dev, /proc, /sys, and /etc directories must be created manually:

    $ cd ~/tools/busybox/ramdisk/
    $ mkdir dev sys etc proc
    

    /etc contains the configuration files for the Linux system. It includes two important files: inittab and fstab. inittab can be used by init to determine which programs should be run and fstab describes the filesystems mounting parameters. The init process is the first process invoked by the Linux kernel after the kernel finishes its initialization (to learn more about the generic boot sequence of a Linux system, read the manual page of the boot process by running the man boot command):

    $ cat > ./etc/inittab
    ::sysinit:/etc/init.d/rcS
    ttyS2::askfirst:/bin/sh
    ::restart:/sbin/init
    
    $ cat > ./etc/fstab
    proc /proc proc defaults 0 0
    sysfs /sys sysfs defaults 0 0
    
    $ mkdir ./etc/init.d
    $ cat > ./etc/init.d/rcS
    #!/bin/sh
    mount -a
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s
    
    $ chmod 777 ./etc/init.d/rcS
    $ ln -s ./sbin/init init
    

    With the previous setting, during the booting of our Linux system, the init process parses our inittab file and runs /etc/init.d/rcS as the first action. It mounts all filesystems specified in fstab, and starts the minimal mdev device management tool (like the more famous tool, udev) to create all device nodes exported by low-level drivers under /dev for late operations. It also creates a console with /bin/sh, and attaches it at ttyS2. Since /sbin/init is the first user process, the /etc/inittab also let it respawn for system availability.

    Lastly, the console based on /bin/sh is provided as the basic shell environment for the user interaction.

  2. Package the filesystem into an image and name it ramdisk.img.

    Now, let's compress it with the following command:

    $ cd ramdisk/
    $ find . | cpio -H newc -o | gzip -9 > ../ramdisk.img
    
  3. Cross-compile a new Android Linux kernel.

    To start our own ramdisk, since it doesn't work with the prebuilt kernel image (zImage) in Android ADT (Android Development Toolkit), we should build our own Linux kernel image from the Android Linux kernel source code. Go to the just downloaded goldfish/ directory and compile it as follows:

    $ cd ~/tools/busybox/goldfish/
    $ git checkout android-goldfish-3.4
    $ make goldfish_armv7_defconfig
    $ export CROSS_COMPILE=arm-linux-gnueabi-
    $ make zImage
    $ cp arch/arm/boot/zImage ~/tools/busybox/
    
  4. Run our new embedded system on a virtual Android device.

    Now, start our own kernel image with the just-built minimal filesystem as follows:

    $ emulator @busybox-avd -shell -show-kernel -no-window \
    -kernel ./zImage -ramdisk ./ramdisk.img
    Uncompressing Linux... done, booting the kernel.
    ...
    
    Please press Enter to activate this console.
    

    According to this message, we can press Enter to activate the console terminal and execute the commands that we want to run.

How it works...

The ramdisk.img is an archive of format gzipped cpio, which is extracted as the default root filesystem when the kernel boots up. It generally contains a file named init, which will run after the kernel boots up. This init command parses the initialization configuration, /etc/inittab, and eventually starts the console based on the ash shell, and provides the applets' running environment.

There's more...

In real embedded development with the minimal filesystem built with BusyBox and their built-in applets, we are able to verify the function and robustness of their device drivers through their exported /dev, /sys, and /proc interfaces.

With the help of the ash applet, shell scripts can be written to perform test automation to enhance the stability of an embedded system. With the help of the built-in PowerTop, bootchartd, top, iostat, devmem, and some other external utilities, the other aspects of an embedded system can be optimized to provide better user experience. The test automation and system optimization will be discussed in the coming recipes.