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 4: Configuring and Building the Kernel

The kernel is the third element of embedded Linux. It is the component that is responsible for managing resources and interfacing with hardware, and so affects almost every aspect of your final software build. It is usually tailored to your particular hardware configuration, although, as we saw in Chapter 3, All About Bootloaders, device trees allow you to create a generic kernel that is tailored to particular hardware by the contents of the device tree.

In this chapter, we will look at how to get a kernel for a board, and how to configure and compile it. We will look again at Bootstrap, this time focusing on the part the kernel plays. We will also look at device drivers and how they pick up information from the device tree.

We will cover the following main topics:

  • What does the kernel do?
  • Choosing a kernel
  • Building the kernel
  • Booting the kernel
  • Porting Linux to a new board

Technical requirements

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

  • A Linux-based host system
  • The crosstool-NG toolchains from Chapter 2, Learning About Toolchains
  • A microSD card reader and card
  • The microSD card with U-Boot installed from Chapter 3, All About Bootloaders
  • A USB to TTL 3.3V serial cable
  • Raspberry Pi 4
  • A 5V 3A USB-C power supply
  • BeagleBone Black
  • A 5V 1A DC power supply

All of the code for this chapter can be found in the Chapter04 folder from the book's GitHub repository: https://github.com/PacktPublishing/Mastering-Embedded-Linux-Programming-Third-Edition.

What does the kernel do?

Linux began in 1991 when Linus Torvalds started writing an operating system for Intel 386- and 486-based personal computers. He was inspired by the Minix operating system written by Andrew S. Tanenbaum 4 years earlier. Linux differed in many ways from Minix; the main difference being that it was a 32-bit virtual memory kernel and the code was open source, later released under the GPL v2 license. He announced it on August 25, 1991, on the comp.os.minix newsgroup in a famous post that began with the following:

Hello everybody out there using minix—I'm doing a (free) operating system (just a hobby, won't be big and professional like GNU) for 386(486) AT clones. This has been brewing since April, and is starting to get ready. I'd like any feedback on things people like/dislike in minix, as my OS resembles it somewhat (same physical layout of the filesystem (due to practical reasons) among other things).

To be strictly accurate, Linus...

Choosing a kernel

The next step is to choose the kernel for your project, balancing the desire to always use the latest version of software against the need for vendor-specific additions and an interest in the long-term support of the code base.

Kernel development cycle

Linux is developed at a fast pace, with a new version being released every 8 to 12 weeks. The way that the version numbers are constructed has changed a bit in recent years. Before July 2011, there was a three-number version scheme with version numbers that looked like 2.6.39. The middle number indicated whether it was a developer or stable release; odd numbers (2.1.x, 2.3.x, 2.5.x) were for developers and even numbers were for end users.

From version 2.6 onward, the idea of a long-lived development branch (the odd numbers) was dropped, as it slowed down the rate at which new features were made available to the users. The change in numbering from 2.6.39 to 3.0 in July 2011 was purely because Linus felt that...

Building the kernel

Having decided which kernel to base your build on, the next step is to build it.

Getting the source

All three of the targets used in this book, the Raspberry Pi 4, BeagleBone Black, and the ARM Versatile PB, are well supported by the mainline kernel. Therefore, it makes sense to use the latest long-term kernel available from https://www.kernel.org/, which at the time of writing was 5.4.50. When you come to do this for yourself, you should check to see if there is a later version of the 5.4 kernel and use that instead since it will have fixes for bugs found after 5.4.50 was released.

Important note

If there is a later long-term release, you may want to consider using that one, but be aware that there may have been changes that mean that the following sequence of commands does not work exactly as given.

To fetch and extract a release tarball of the 5.4.50 Linux kernel, use the following:

$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5...

Compiling – Kbuild

The kernel build system, Kbuild, is a set of make scripts that take the configuration information from the .config file, work out the dependencies, and compile everything that is necessary to produce a kernel image. This kernel image contains all the statically linked components, possibly a device tree binary, and possibly one or more kernel modules. The dependencies are expressed in makefiles that are in each directory with buildable components. For instance, the following two lines are taken from drivers/char/Makefile:

obj-y += mem.o random.o
obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o

The obj-y rule unconditionally compiles a file to produce the target, so mem.c and random.c are always part of the kernel. In the second line, ttyprintk.c is dependent on a configuration parameter. If CONFIG_TTY_PRINTK is y, it is compiled as a built-in; if it is m, it is built as a module; and if the parameter is undefined, it is not compiled at all.

For most targets...

Booting the kernel

Booting Linux is highly device-dependent. In this section, I will show you how it works for the Raspberry Pi 4, BeagleBone Black, and QEMU. For other target boards, you must consult the information from the vendor or from the community project, if there is one.

At this point, you should have the kernel image files and the device tree blobs for the Raspberry Pi 4, BeagleBone Black, and QEMU.

Booting the Raspberry Pi 4

Raspberry Pis use a proprietary bootloader provided by Broadcom instead of U-Boot. Unlike previous Raspberry Pi models, the Raspberry Pi 4's bootloader resides on an onboard SPI EEPROM rather than on a microSD card. We still need to put the kernel image and device tree blobs for the Raspberry Pi 4 on a microSD to boot our 64-bit kernel.

To begin, you need a microSD card with a FAT32 boot partition large enough to hold the necessary kernel build artifacts. The boot partition needs to be the first partition on the microSD card. A partition...

Porting Linux to a new board

Porting Linux to a new board can be easy or difficult, depending on how similar your board is to an existing development board. In Chapter 3, All About Bootloaders, we
ported U-Boot to a new board, named Nova, which is based on the BeagleBone Black. Very few changes need to be made to the kernel code, so it is very easy. If you are porting to completely new and innovative hardware, there will be more to do. We will delve
deeper into the topic of additional hardware peripherals in Chapter 12, Prototyping with Breakout Boards.

The organization of architecture-specific code in arch/$ARCH differs from one system to another. The x86 architecture is pretty clean because most hardware details are detected at runtime. The PowerPC architecture puts SoC and board-specific files into subdirectory platforms. The ARM architecture, on the other hand, is quite messy, in part because there is a lot of variability between the many ARM-based SoCs. Platform-dependent code...

Summary

What makes Linux so powerful is the ability to configure the kernel however we need to. The definitive place to get the kernel source code is https://www.kernel.org/, but you will probably need to get the source for a particular SoC or board from the vendor of that device or a third party that supports that device. The customization of the kernel for a particular target may consist of changes to the core kernel code, additional drivers for devices that are not in mainline Linux, a default kernel configuration file, and a device tree source file.

Normally, you start with the default configuration for your target board and then tweak it by running one of the configuration tools, such as menuconfig. One of the things you should consider at this point is whether the kernel features and drivers should be compiled as modules or built in. Kernel modules are usually no great advantage for embedded systems, where the feature set and hardware are usually well defined. However, modules...

Additional reading

The following resources have more information about the topics introduced in
this chapter:

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}