Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Mastering Embedded Linux Programming - Third Edition

You're reading from  Mastering Embedded Linux Programming - Third Edition

Product type Book
Published in May 2021
Publisher Packt
ISBN-13 9781789530384
Pages 758 pages
Edition 3rd Edition
Languages
Authors (2):
Frank Vasquez Frank Vasquez
Profile icon Frank Vasquez
Chris Simmonds Chris Simmonds
Profile icon Chris Simmonds
View More author details

Table of Contents (27) Chapters

Preface Section 1: Elements of Embedded Linux
Chapter 1: Starting Out Chapter 2: Learning about Toolchains Chapter 3: All about Bootloaders Chapter 4: Configuring and Building the Kernel Chapter 5: Building a Root Filesystem Chapter 6: Selecting a Build System Chapter 7: Developing with Yocto Chapter 8: Yocto Under the Hood Section 2: System Architecture and Design Decisions
Chapter 9: Creating a Storage Strategy Chapter 10: Updating Software in the Field Chapter 11: Interfacing with Device Drivers Chapter 12: Prototyping with Breakout Boards Chapter 13: Starting Up – The init Program Chapter 14: Starting with BusyBox runit Chapter 15: Managing Power Section 3: Writing Embedded Applications
Chapter 16: Packaging Python Chapter 17: Learning about Processes and Threads Chapter 18: Managing Memory Section 4: Debugging and Optimizing Performance
Chapter 19: Debugging with GDB Chapter 20: Profiling and Tracing Chapter 21: Real-Time Programming Other Books You May Enjoy

Chapter 13: Starting Up – The init Program

We looked at how the kernel boots up to the point where it launches the first program, init, in Chapter 4, Configuring and Building the Kernel. In Chapter 5, Building a Root Filesystem, and Chapter 6, Selecting a Build System, we looked at creating root filesystems of varying complexity, all of which contained an init program. Now, it is time to look
at the init program in more detail and discover why it is so important to the rest of
the system.

There are many possible implementations of init. I will describe the three main ones in this chapter: BusyBox init, System V init, and systemd. For each one, I will give an overview of how it works and the types of systems it suits best. Part of this is balancing the trade-off between size, complexity, and flexibility. We will learn how to launch a daemon using both BusyBox init and System V init. We will also learn how to add a service to systemd that does the same.

In this chapter,...

Technical requirements

To follow along with the examples, make sure you have the following:

  • A Linux-based host system
  • Buildroot 2020.02.9 LTS release
  • Yocto 3.1 (Dunfell) LTS release

You should have already installed the 2020.02.9 LTS release of Buildroot for Chapter 6, Selecting a Build System. If you have not, then refer to the System requirements section of The Buildroot user manual (https://buildroot.org/downloads/manual/manual.html) before installing Buildroot on your Linux host according to the instructions from Chapter 6.

You should have already built the 3.1 (Dunfell) LTS release of Yocto for Chapter 6, Selecting a Build System. If you have not, then refer to the Compatible Linux Distribution and Build Host Packages sections of the Yocto Project Quick Build guide (https://www.yoctoproject.org/docs/current/brief-yoctoprojectqs/brief-yoctoprojectqs.html) before building Yocto on your Linux host according to the instructions from Chapter 6.

All of the...

After the kernel has booted

We saw in Chapter 4, Configuring and Building the Kernel, how the kernel bootstrap code seeks to find a root filesystem, either initramfs or a filesystem specified by root= on the kernel command line, and then executes a program that, by default, is /init for initramfs and /sbin/init for a regular filesystem. The init program has root privilege, and since it is the first process to run, it has a process ID (PID) of 1. If, for some reason, init cannot be started, the kernel will panic.

The init program is the ancestor of all other processes, as shown here by the pstree command running on a simple embedded Linux system:

# pstree -gn
init(1)-+-syslogd(63)
        |-klogd(66)
        |-dropbear(99)
        `-sh(100)---pstree(109)

The job of the init program is to take control of the boot process in user space and set it running. It...

Introducing the init programs

The three init programs that you are most likely to encounter in embedded devices are BusyBox init, System V init, and systemd. Buildroot has options to build all three with BusyBox init as the default. The Yocto Project allows you to easily choose between System V init and systemd with System V init as the default. While Yocto's Poky-tiny distribution ships with BusyBox init, most other distribution layers do not.

The following table gives some metrics to compare the three:

(*) BusyBox init is part of BusyBox's single executable, which is optimized for size
on disk.

(**) Based on the Buildroot configuration of systemd.

Broadly speaking, there is an increase in flexibility and complexity as you go from BusyBox init to systemd.

BusyBox init

BusyBox has a minimal init program that uses a configuration file, /etc/inittab,
to define rules to start programs at bootup and to stop them at shutdown. Usually,
the actual work is done by shell scripts, which, by convention, are placed in the
/etc/init.d directory.

init begins by reading /etc/inittab. This contains a list of programs to run, one per line, with this format:

<id>::<action>:<program>

The role of these parameters is as follows:

  • id: This is the controlling terminal for the command.
  • action: This includes the conditions to run this command, as shown in the following list.
  • program: This is the program to run.

The actions are as follows:

  • sysinit: Runs the program when init starts before any of the other types
    of actions.
  • respawn: Runs the program and restarts it if it terminates. It is typically used to run a program as a daemon.
  • askfirst: This is the same as respawn, but it prints the message...

System V init

This init program was inspired by the one from Unix System V and so dates back to the mid-1980s. The version most often found in Linux distributions was written initially by Miquel van Smoorenburg. Until recently, it was the init daemon for almost all desktop and server distributions and a fair number of embedded systems as well. However, in recent years, it has been replaced by systemd, which I will describe in the next section.

The BusyBox init daemon I have just described is just a trimmed-down version of System V init. Compared to BusyBox init, System V init has two advantages:

  • Firstly, the boot scripts are written in a well-known, modular format, making it easy to add new packages at build time or runtime.
  • Secondly, it has the concept of runlevels, which allow a collection of programs to be started or stopped in one go when switching from one runlevel to another.

There are eight runlevels, numbered from 0 to 6, plus S:

  • S: Runs startup...

systemd

systemd, https://www.freedesktop.org/wiki/Software/systemd/, defines itself as a system and service manager. The project was initiated in 2010 by Lennart Poettering and Kay Sievers to create an integrated set of tools for managing a Linux system based around an init daemon. It also includes device management (udev) and logging, among other things. systemd is state of the art and is still evolving rapidly. It is common on desktop and server Linux distributions and is becoming popular on embedded Linux systems too, especially on more complex devices. So, how is it better than System V init for embedded systems?

  • The configuration is simpler and more logical (once you understand it). Rather than the sometimes convoluted shell scripts of System V init, systemd has unit configuration files that are written in a well-defined format.
  • There are explicit dependencies between services, rather than a two-digit code that merely sets the sequence in which the scripts are run...

Summary

Every Linux device needs an init program of some kind. If you are designing a system that only has to launch a small number of daemons at startup and remains fairly static after that, then BusyBox init is sufficient for your needs. It is usually a good choice if you are using Buildroot as the build system.

If, on the other hand, you have a system that has complex dependencies between
services at boot time or runtime, and you have the storage space, then systemd would be the best choice. Even without the complexity, systemd has some useful features in the way it handles watchdogs, remote logging, and so on, so you should certainly give it serious thought.

Meanwhile, System V init lives on. It is well understood, and there are init scripts already in existence for every component that is important to us. It remains the default init for the Yocto Project reference distribution (Poky).

In terms of reducing boot time, systemd is faster than System V init for a similar workload...

Further reading

lock icon The rest of the chapter is locked
You have been reading a chapter from
Mastering Embedded Linux Programming - Third Edition
Published in: May 2021 Publisher: Packt ISBN-13: 9781789530384
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 €14.99/month. Cancel anytime}