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)

Speeding up the system boot of an embedded (Android) system (Advanced)


For most embedded systems, particularly for consumer electronics like smartphone systems, to reduce the wait time of system power on or start up, the system must be fast enough.

Most embedded devices have strict time limits from power on to showing graphic UI, so speeding the boot time should be considered an important feature.

Getting ready

The following are the basic methods to speed system booting:

  • Disable unused features and functions in all booting components (bootloader, Linux kernel, system, and applications) of an embedded Linux system. This means let the system perform less but necessary jobs.

  • Some initialization procedures can be deferred to the background after the device has booted to a basically workable state.

  • If a multicore CPU is being used, parallize the boot process with multithreads.

  • Based on the considerations of power-cost optimization, set CPU frequency, bus frequency, memory frequency, and even external device working frequency (such as EMMC) as high as possible.

  • Measure the boot procedure and find out the time-cost bottlenecks.

How to do it...

Bootchart (http://www.bootchart.org/) is for performance analysis and visualization of the Linux boot process; it can be used for boot speedup optimization.

Android does include the init method's built-in bootchartd support, but requires the init application to be rebuilt; for more details, visit http://elinux.org/Using_Bootchart_on_Android.

In our example, we introduce the BusyBox built-in bootchartd support to measure the Android system boot procedure.

  1. Configure Bootchart in BusyBox:

    First, enable the Bootchart applet in BusyBox.

       Init Utilities  --->
          [*] bootchartd
           [*]   Compatible, bloated header
           [*]   Support bootchartd.conf
    
  2. Install BusyBox with bootchartd in Android ramdisk.img:

    Then, copy the busybox binary to Android ramdisk.img, create a link /bootchartd to busybox, and create a var/log directory.

    $ cd ramdisk/
    $ ln -sf busybox /bootchartd
    $ mkdir var/log
    

    Recompress the ramdisk/ to ramdisk.img with the following:

    $ find . | cpio -H newc -o | gzip -9 > ../ramdisk.img
    

    The link is for directly using bootchartd as the init process; the var/log directory is for saving the boot log generated by bootchartd.

  3. Measure the Android system booting with BusyBox bootchard:

    Now start the Android emulator.

    $ emulator @busybox-avd -shell -show-kernel -kernel ./zImage \
       -ramdisk ./ramdisk.img \
       -qemu -append "rdinit=/bootchartd bootchard_init=/init"
    

    The -qemu -append options allow us to pass extra arguments to the Linux kernel; the preceding rdinit=/bootchartd support replaces the default ramdisk init with bootchartd, and then bootchartd_init=/init tells bootchartd to start the real /init process.

  4. Get the bootchartd measuring log:

    After a while, the Android UI will be started and a new file will be created to save the boot logs.

    shell@android # ls -l /var/log
    total 72
    -rw-r--r--    1 0        0            73334 Jul  5 17:24 bootlog.tgz
    

    Then, pull the logfile into our development system.

    $ adb pull /var/log/bootlog.tgz
    
  5. Draw the bootchartd log with pybootchartgui, and analyze it.

    Analyze the boot log with pybootchartgui. This tool can generate a readable graphic output based on the previous boot logfile. In Ubuntu, we can install it simply with the following:

    $ sudo apt-get install bootchart pybootchartgui
    

    Then draw a graph with it.

    $ bootchart ./bootlog.tgz
    

    It may generate an error, such as the header file format is not compatible with the original larger version of the bootchart:

      File "/usr/lib/pymodules/python2.7/pybootchartgui/draw.py", line 341, in draw_header
          txt = headertitle + ': ' + mangle(headers.get(headerkey))
          TypeError: cannot concatenate 'str' and 'NoneType' objects
    

    To work around it, just let the draw.py file of pybootchartgui ignore the errors with except handling.

    $ vim /usr/lib/pymodules/python2.7/pybootchartgui/draw.py
    338     for (headerkey, headertitle, mangle) in toshow:
    339         header_y += ctx.font_extents()[2]
    340         try:
    341                 txt = headertitle + ': ' + mangle(headers.get(headerkey))
    342         except:
    343                 continue
    344         draw_text(ctx, txt, TEXT_COLOR, off_x, header_y)
    

    If there are no other issues, we should get results successfully, as shown in the following screenshot:

At last, it's time to analyze the graph.

A bootchart picture will have a few of different bits of information that are of interest, especially the CPU and disk load graphs at the top.

There is a timeline running from left to right, with processes shown starting (and sometimes stopping) underneath it. The process CPU loads are indicated by the coloration of its process bar. The things to look for are the start and stop times of the different processes, and their CPU load. Long gaps with low load may mean a timeout or some other issue.

Once you have found out which processes are consuming time during the initialization, we can further check these by looking at the system logs with the logcat tool of Android; running them with strace, a profile (of Android), or perf; and reviewing the corresponding source code.

How it works...

To speed system booting means to reduce the time cost at the system booting stage and also to increase the working frequency of all related devices and meanwhile reduce time cost resources. But, in real practice, the maximal frequency of the devices should be limited to reduce the power cost.

There's more...

The whole booting procedure of an embedded system includes bootloader startup, kernel decompression and bootup, init process launching, and system booting. bootchartd is mainly for optimization of the booting stage after the init process launches.

To measure the boot time of bootloader or the Linux kernel, we can use the Grabserial tool from http://elinux.org/Grabserial. For more related resources, visit http://www.elinux.org/Boot_Time.