Preface Chapter 1: Starting Out Selecting the right operating system The players Project lifecycle The four elements of embedded Linux Open source Licenses Hardware for embedded Linux Hardware used in this book The BeagleBone Black QEMU Software used in this book Summary Chapter 2: Learning About Toolchains What is a toolchain? Types of toolchain—native versus cross toolchain CPU architectures Choosing the C library Finding a toolchain Building a toolchain using crosstool—NG Installing crosstool—NG Selecting the toolchain Anatomy of a toolchain Finding out about your cross compiler The sysroot,library,and header files Other tools in the toolchain Looking at the components of the C library Linking with libraries: static and dynamic linking Static libraries Shared libraries Understanding shared library version numbers The art of cross compiling Simple makefiles Autotools An example: SQLite Package configuration Problems with cross compiling Summary Chapter 3: All About Bootloaders What does a bootloader do? The boot sequence Phase 1: ROM code Phase 2: SPL Phase 3: TPL Booting with UEFI firmware Moving from bootloader to kernel Introducing device trees Device tree basics The reg property Phandles and interrupts Device tree include files Compiling a device tree Choosing a bootloader U—Boot Building U—Boot Installing U—Boot Using U—Boot Environment variables Boot image format Loading images Booting Linux Automating the boot with U—Boot scripts Porting U—Boot to a new board Kconfig and U—Boot Boarduspecific files Configuration header files Building and testing Falcon mode Barebox Getting Barebox Building Barebox Summary Chapter 4: Porting and Configuring the Kernel What does the kernel do? Choosing a kernel Kernel development cycle Stable and long term support releases Vendor support Licensing Building the kernel Getting the source Understanding kernel configuration Using LOCALVERSION to identify your kernel Kernel modules Compiling Compiling the kernel image Compiling device trees Compiling modules Cleaning kernel sources Booting your kernel BeagleBone Black QEMU Kernel panic Early user space Kernel messages Kernel command line Porting Linux to a new board With a device tree Without a device tree Additional reading Summary Chapter 5: Building a Root Filesystem What should be in the root filesystem? Directory layout Staging directory POSIX file access permissions File ownership permissions in the staging directory Programs for the root filesystem The init program Shell Utilities BusyBox to the rescue! Building BusyBox ToyBox—an alternative to BusyBox Libraries for the root filesystem Reducing size by stripping Device nodes The proc and sysfs filesystems Mounting filesystems Kernel modules Transfering the root filesystem to the target Creating a boot ramdisk Standalone ramdisk Booting the ramdisk Booting with QEMU Booting the BeagleBone Black Mounting proc Building a ramdisk cpio into the kernel image Another way to build a kernel with ramdisk The old initrd format The init program Configuring user accounts Adding user accounts to the root filesystem Starting a daemon process A better way of managing device nodes An example using devtmpfs An example using mdev Are static device nodes so bad after all? Configuring the network Network components for glibc Creating filesystem images with device tables Putting the root filesytem onto an SD card Mounting the root filesystem using NFS Testing with QEMU Testing with BeagleBone Black Problems with file permissions Using TFTP to load the kernel Additional reading Summary Chapter 6: Selecting a Build System No more rolling your own embedded Linux Build systems Package formats and package managers Buildroot Background Stable releases and support Installing Configuring Running Creating a custom BSP U—Boot Linux Build Adding your own code Overlay Adding a package License compliance The Yocto Project Background Stable releases and support Installing the Yocto Project Configuring Building Running Layers BitBake and recipes Customizing images via local.conf Writing an image recipe Creating an SDK License audit Further reading Summary Chapter 7: Creating a Storage Strategy Storage options NOR flash NAND flash Managed flash MultiMediaCard and secure digital cards eMMC Other types of managed flash Accessing flash memory from the bootloader U—Boot and NOR flash U—Boot and NAND flash U—Boot and MMC,SD and eMMC Accessing flash memory from Linux Memory technology devices MTD partitions MTD device drivers The MTD character device,mtd The MTD block device,mtdblock Logging kernel oops to MTD Simulating NAND memory The MMC block driver Filesystems for flash memory Flash translation layers Filesystems for NOR and NAND flash memory JFFS2 Summary nodes Clean markers Creating a JFFS2 filesystem YAFFS2 Creating a YAFFS2 filesystem UBI and UBIFS UBI UBIFS Filesystems for managed flash Flashbench Discard and TRIM Ext4 F2FS FAT16/32 Read—only compressed filesystems squashfs Temporary filesystems Making the root filesystem read—only Filesystem choices Updating in the field Granularity: file,package,or image? Atomic image update Further reading Summary Chapter 8: Introducing Device Drivers The role of device drivers Character devices Block devices Network devices Finding out about drivers at runtime Getting information from sysfs The devices:/sys/devices The drivers:/sys/class The block drivers:/sys/block Finding the right device driver Device drivers in user—space GPIO Handling interrupts from GPIO LEDs I2C SPI Writing a kernel device driver Designing a character device interface Anatomy of a device driver Compile and load Loading kernel modules Discovering hardware configuration Device trees Platform data Linking hardware with device drivers Additional reading Summary …… Chapter 9: Starting up—the init Program Chapter 10: Learning About Processes and Threads Chapter 11: Managing Memory Chapter 12: Debugging with GDB Chapter 13: Profiling and Tracing Chapter 14: Real—time Programming