This tutorial on embedded Linux will give a breif introduction of a very popular field of embedded systems that is the use of open-source OS such as Linux in embeded systems. We will start with a defintion of Embedded Linux. After that main components of Embedded Linux will be discussed.
What is Embedded Linux?
Before defining embeded linux, lets first see the defintion of embedded systems.
What is Embedded System?
We can define embedded systems in many ways. But the easiest way to define is that it is a special-purpose computer designed for specific applications. In other words, it is a system with a small computer such as a microcontroller or a microprocessor integrated inside it. Unlike the general-purpose computer such as desktop or laptop, this processor performs only specific functionalities.
Embedded system is more than 50 years old market. Embedded systems are fundamentally single board computers. But the functions are limited and specific. Embedded processors are the special type of microprocessor designed specifically for embedded applications. Embedded processors consist of all components like memory unit, microprocessors, input/output unit, etc. are embedded on a single board. Their functionality is subject to constraints such as less memory, processing speed and is embedded as a part of the complete device including the hardware, in contrast to the Desktop and Laptop computers.
You can find more information about embedded system in the following article:
Embedded Linux Introduction
Embedded Linux is nothing but the usage of Linux kernel and other open-source software development tools such as open-source libraries in embedded systems applications development. Hence, instead of using a bare-metal embedded systems approach where we have to write every piece of the software ourselves, we make use of the Linux operating system to design embedded applications.
It will make our embedded development process quick and effortless. Because Linux provides support for all types of software that we need to use in our embedded applications such as TCP/IP stack, serial communication protocols, graphics libraries, etc. We only have to configure Linux and create an image according to our underlying processor architecture and this process is known as a board support package.
There is no specific Linux kernel image for embedded devices. An extensive range of devices, workstations, and embedded systems can be built up by the same Linux kernel code by configuring and porting it to different processor architectures. Mentor Graphics is one of the leading embedded Linux service providers. The following diagram shows its commercial platforms and services.
Why Choose Linux for Embedded Systems?
There are many reasons why Linux is being used so widely in embedded systems applications such as mobile phones, agriculture, modern vehicles, multimedia systems and many more. Let’s discuss some of them.
Because Linux is an open-source Kernel and anyone can view and modify its source code according to their requirement. On top of that, while creating an Linux image for your targeted embedded hardware, you can remove or add components of Linux Kernel as per your requirement. In this way, we can create a Kernel image for memory constrained embedded devices.
Open-source software components and libraries allow the design and development of embedded products quickly by making use of open-source software components. Because Linux has a large support community and they make all widely used software components freely available and we will not need to redevelop already available components from scratch such as graphics libraries, TCP/IP stack, Linux Kernel, I2C, SPI libraries, and other device drivers, etc.
In short, we only need to focus on our main application instead of developing already available software components.
Free or Low cost
Due to open-source nature, we can deploy these software components in our embedded application with or without modification free of cost. It will significantly reduce the price of our embedded device.
Linux supports a wide range of processor architectures such as ARM, x86, PowerPC, RiscV, MIPS, SuperH. Although Linux mainly works on MMU architecture microprocessor. However, non-MMU architecture is also supported with limitations.
Examples of Embedded Linux based Systems
- Wireless Routes
- Smart Phones
- Wireless hotspots
- Video and Multimedia systems
- Wearable Sensors such as smartwatches and biomedical equipment
Minimum Hardware Requirement to use Linux on Embedded Processors
Linux Kernel supports 32-bit and 64-bit processor architectures and it supports almost all modern popular processor architectures such as:
- ARM ( used in almost types of applications)
- X86 ( Multimedia and industrial applications)
- MIPS ( networking applications such as routers and hotspots)
- PPC/PowerPC ( hard real-time and deadline constrained applications)
- SH ( Multimedia applications)
In order to run Linux on a target embedded processor, a minimum of 8MB of RAM is required. But a real practical application requires at least 32MB RAM. But the actual requirement of RAM memory depends on your embedded application size.
Other than RAM, a minimum of 4MB storage memory is also required. The storage memory can be one of the following types:
- NAND or NOR Flash
- SD or MMC cards
A lightweight Linux such as uCLinux is also available which can run on microprocessors or microcontrollers which do not have a memory management unit.
Embedded Linux Architecture
The following block diagram shows the architecture of embedded Linux based systems.
The embedded system build process is usually done on the host PC using cross-compilation tools. Because target hardware does not have enough resources to run tools that are used to generate a binary image for target embedded hardware. The process of compiling code on one system ( host system) and generated source code runs on the other system is known as cross-compilation.
Main Components of Embedded Linux Systems
- Cross development toolchain ( installed on a host system)
- Device Tree
- Root file system
- System Programs
Now, let’s review each component and its purpose in embedded Linux based systems development.
A toolchain is a collection of development tools, such as GCC compiler, C libraries, and GNU debugger, which are used to create source code for the target embedded hardware. Normally, cross-compilation toolchains are utilized in embedded Linux, because the target embedded processor does not have sufficient resources for these toolchains. In cross-compilation systems, development is performed on the host system (a powerful PC), and then source code is deployed on the target device using different interfaces such as serial, ethernet, etc. Serial communication is the most commonly used interface between the host system and a target device.
The tools that are used for communication available in Linux are Minicom, Picocom, Gtkterm, Putty, and HyperTerminal in windows.
This is a piece of code that runs when we apply power to the embedded hardware first time. Bootloader performs various hardware initialization steps before loading the operating system. When a processor boots up or resets, each processor has a number of predefined hardware steps and configurations.
Followings are the main roles of a bootloader:
- Target hardware initialization
- Load the application binary ( operating system, root file system, device tree ) from the non-volatile external storage to the RAM memory
- RAM connects externally to the SOC and it stores run-time data, operating system, root file system, application software, and stack/heap.
- After that execute the main operating system code from the RAM memory
Different microprocessors may have a distinct process of booting sequence but the underlying concepts remain the same.
In embedded Linux, two generic or universal bootloaders are popular such as Uboot and barebox.
Embedded Linux Boot flow Process
What exactly are the steps and what is required to successfully boot the Linux kernel of embedded Linux boards such as BeagleBone, Raspberry Pi, etc? If we take the example of Beaglebone Black, this board has an AM335x SoC manufactured by Texas instruments. In order to boot Linux on this Soc followings are the four main components as shown in the figure below:
- The first component is a first stage bootloader or a ROM bootloader. This is usually stored inside the flash memory of SoC by the manufacturer and we cannot change it.
- The main role of RBL is to load the second stage bootloader that is SPL (a secondary program loader) or MLO (memory loader) from the internal SRAM of SoC.
- The job of MLO is to load and execute a third stage bootloader such as U-Boot from the DDR memory of the development board but DDR is off the SoC.
- The third stage bootloader which is U-boot loads the Linux kernel from persistent storage such as an SD card to DDR memory of the development board.
- After that system starts to execute its first process initi and mounts the root file system.
It is a software or operating system kernel that manages resources of embedded processors optimally and efficiently. The main core component of embedded Linux is the Linux Kernel. It is a layered operating system architecture that means it divides into two layers such as user space and kernel space memory space.
It provides various services such as:
- Process management ( Allocates CPU resources concurrently to processes/tasks through scheduler)
- Process scheduling ( Schedules concurrently running process to run on the CPU using scheduling algorithms)
- Memory management ( Manage memory for different processes through virtual memory support)
- Interprocess communication (Sometimes tasks require to share data with each other and the interprocess communication feature provides this support through shared memory)
- File management (Manage how information is stored and accessed by the system)
- I/O management ( Supported through device drivers such as character, block, and USB device drivers)
- Networking ( Support for network device drivers )
- Interface with hardware through device drivers
To add and remove code from the Linux kernel at rum time we use a machine called loadable kernel module. They are responsible for communication between kernel and hardware without having to know the functionality of hardware and they are perfect for the drivers of the device. Kernel module run in kernel space. Memory addresses of kernel space and user space are unique and they don’t overlap. This methodology shows that the applications that run in user space have reliable view of hardware, irrespective of the platform of hardware.
The embedded linux based hardware platforms also contains peripherals which do not have the ability to acknowledge their existence to the operating system kernel. There must be a way to inform Linux kernel about these hardware peripherals.
The Linux kernel contains thousands of device drivers and during the boot-up process, the kernel should know which non-discoverable hardware devices are connected with your embedded Linux based system. The question is how does the kernel find the details of the connected hardware devices? The answer is the device tree.
A device tree is a tree data structure that provides information about the connected hardware devices that are not discoverable themself and other on-chip peripherals of an SoC. Some of the automatically non-discoverable on-chip peripherals are I2C, UART, SP, ethernet, etc. On the contrary, the USB device has the capability or intelligence to inform its presence to the operating system dynamically.
DT describes these devices using a special hardware description language. It decides which drivers to initialize and configure the device parameters such as registers addresses and IRQs. A DT source is combined with the Device Tree Blob and combines with the kernel during the embedded hardware booting process. The bootloader also loads the Device Tree Blob into RAM memory along with the Kernel and it runs before the kernel. In short, DT manages hardware resources of embedded Linux based systems.
Root File systems
In Linux, Filesystems organize data into files and directories inside the storage device. In fact, everything in Linux is a file, store, and accesses through a file. These files and directories are available in the form hierarchy.
During the boot-up process, Linux kernel needs one more component that is a root filesystem. A root filesystem is a special type of filesystem and it contains all the configuration files that are required to prepare the execution environment for the embedded device, for example, preparing graphical displays etc. . It also contains the first parent process running on Linux (initi).
The Linux kernel works with the root file system. This is the file system on which the roots can be mounted. There are two types of file systems for desktop and server distributions. These are the initial root system and real root system. The initial root system is used for mounting and running the latter. The initial root system is used to load drivers on a desktop. The switch between the initial root file system and the real root file system is called a pivot.
The kernel needs configuration files to know the users and groups in the system. It also needs configuration files to manage file permissions. These files are not read by programs and are used by the kernel to provide a function by a system library.
Classification of embedded Linux system
The classification of embedded Linux systems has been made by considering the structure of the system. It may also be classified on the basis of size and time limits.
Linux features a micro architecture which usually consume small memory (100 KB). It combined with the networking stacks and a few basic utilities can fit in very efficiently in 500 K of memory and it is adaptable to work with minute RAM and ROM. ETLinux, LEM, uClinux, uLinux, ThinLinux are some examples of footprint embedded Linux. The apparent size of an embedded system determines the capabilities offered by the hardware. On the basis of size, embedded system has been categorized in three embedded Linux that are small, medium and large.
Small systems have low powered CPU, ROM is less than 4 MB and RAM is 8 to a 16 MB.
Medium size system
Medium size systems contain medium powered CPU, RAM of 32 MB and removable memory cards.
Large size systems
Large size systems contain powerful CPU or multi CPUs, large RAM and permanent storage.
To start learning embedded Linux, one should have familiarity with the Linux operating system, Linux kernel internals, and different distribution of Linux. Linux is an open-source operating system. It’s a vast platform for the development of embedded systems. Embedded systems are everywhere and available in all ranges, small control applications require smaller microprocessors and large parallel processors have colossal memory requirements.