This document discusses embedded Linux, including its history, advantages, common distributions, architecture, and key components. Embedded Linux was invented in the 1960s and is now widely used in devices like mobile phones, routers, and IoT devices due to advantages like open source flexibility, hardware support, and large developer community.
This document discusses embedded Linux, including its history, advantages, common distributions, architecture, and key components. Embedded Linux was invented in the 1960s and is now widely used in devices like mobile phones, routers, and IoT devices due to advantages like open source flexibility, hardware support, and large developer community.
Introduction - Advantages- Embedded Linux Distributions - Architecture
of Embedded Linux - Linux kernel architecture - User space - Linux startup sequence -GNU cross platform Tool chain - Device Driver: Introduction and Types-Tracing and Profiling tools. Introduction
Embedded Linux systems often operate in
real-time environments, where they are expected to respond to events or inputs within a certain time frame.
Real-time operating systems (RTOS) are
designed to ensure 1. Time constraints are met 2. Making them a critical part of many embedded Linux systems When was embedded Linux invented?? 1. In 1965, Autonetics, now a part of Boeing, developed the D-17B, the computer used in the Minuteman I missile guidance system. 2. It is widely recognized as the first mass-produced embedded system. Why embedded Linux?? 1. Open source nature 2. Flexibility and scalability 3. Support for a wide range of hardware architectures robustness 4. Stability 5. Its large community of developers and users. where embedded Linux used?? 1. Mobile devices 2. Routers 3. Other internet of things (iot) devices.. What is embedded Linux?? • Embedded Linux system is one that uses Linux as the operating system that sits between the hardware and the application of an embedded device. There are five key components to an embedded Linux system:
1. Hardware processor 2. Hardware abstraction layer (HAL) 3. Linux operating system 4. Service layer 5. Application layer Advantage of embedded Linux Embedded Linux distributions
•Embedded Linux is a specialized version of
the Linux operating system that is designed to run on embedded systems such as mobile devices, routers, and other Internet of Things (IoT) devices. Debian 1. Debian is an example of a desktop Linux distribution that also has a version embedded on Raspberry Pi devices.
2. Raspberry is the Debian-based
operating system used to power the compact Raspberry Pi computing device. Redhat CentOS • CentOS (Community Enterprise Operating System • It is a discontinued Linux distribution • provides 1. free and open-source community-supported computing platform 2. functionally compatible with its upstream source 3. Red Hat Enterprise Linux (RHEL). Raspberry pi OS • This OS is based on Debian GNU/Linux which is just one of the many Linux distributions that you can boot into your device. yocto • The Yocto Project (YP) is an open source collaboration project that helps developers create custom Linux- based systems regar dless of the hardware architecture Architecture • Application: 1. designed to perform a specific task or set of tasks within a broader domain. 2. These systems are typically designed to perform a specific function, such as controlling a washing machine, a traffic light, or a robotic arm. •Library: •1. It defines a. set of containers, algorithms, and utilities. •C library: 1.source file. — source.c. — implementations. 2.header file. — header.h. — prototype listings. 3.call. — how we interact with the library. •Linux kernal: •1. To run on embedded systems such as mobile devices, routers, and other Internet of Things (IoT) devices. • 2.It ensures the high speed of product development due to the availability of a readymade TCP/IP stack, Linux Kernel, SPI libraries, graphics libraries, and many more features. • Bootloader: • 1. Bootloader is the first piece of firmware which gets executed once the Embedded System is turned- on/reset. • The primary objective of the Bootloader is to initialise the Embedded System and provide control to the Application/RTOS. • The other objective of the Bootloader is also to support the data loading feature. Architecture of traditional RTOS. Architecture of monolithic kernel. Architecture of microkernel. Linux Kernel Architecture Introduction The Linux kernel can be split into the following subsystems. • The hardware abstraction layer • Memory manager • Scheduler • File system • IO subsystem • Networking subsystem • IPC Hardware Abstraction Layer (HAL) • The hardware abstraction layer (HAL) virtualizes the platform hardware so that the different drivers can be ported easily on any hardware. • The HAL is equivalent to the BSP provided on most of the RTOSs except that the BSP on commercial RTOSs normally has standard APIs that allow easy porting. Some embedded processors • MIPS • PowerPC • ARM • M68K • CRIS • V850 • SuperH Hardware Abstraction Layer (Cont..) The HAL has support for the following hardware components. • Processor, cache, and MMU • Setting up the memory map • Exception and interrupt handling support • DMA • Timers • System console • Bus management • Power management Memory Manager • The memory manager on Linux is responsible for controlling access to the hardware memory resources. The memory manager is responsible for providing dynamic memory to kernel subsystems such as drivers, file systems, and networking stack. • It also implements the software necessary to provide virtual memory to user applications. Each process in the Linux subsystem operates in its separate address space called the virtual address. • By using virtual address, a process can corrupt neither another process’s nor the operating system’s memory. • Any pointer corruptions within the process are localized to the process without bringing down the system; thus it is very important for system reliability. Memory Manager(cont..) • The Linux kernel divides the total memory available into pages. The typical size of a page is 4 KB. Though all the pages are accessible by the kernel, only some of them get used by the kernel; the rest are used by applications. • Note that the pages used by the kernel are not part of the paging process; only the application pages get pulled into main memory on demand. This simplifies the kernel design. • When an application needs to be executing, the entire application need not be loaded into memory; only the used pages flip between memory and storage. Memory Manager(cont..) • The presence of separate user and kernel memory is the most radical change that a developer can expect when moving from a proprietary RTOS. • For the former all the applications form a part of the same image containing the OS. Thus when this image is loaded, the applications get copied to memory too. • On Linux, however, the OS and applications are compiled and built separately; each application needs its own storage instance, often referred to as the program. Scheduler • The Linux scheduler provides the multitasking capabilities and is evolving over the kernel releases with the aim of providing a deterministic scheduling policy. ❑ Kernel thread: These are processes that do not have a user context. They execute in the kernel space as long as they live. ❑User process: Each user process has its own address space thanks to the virtual memory. They enter into the kernel mode when an interrupt, exception, or a system call is executed. Note that when a process enters the kernel mode, it uses a totally different stack. This is referred to as the kernel stack and each process has its own kernel stack. ❑User thread: The threads are different execution entities that are mapped to a single user process. The user space threads share a common text, data, and heap space. They have separate stack addresses. Other resources such as open files and signal handlers are also shared across the threads File System • On Linux, the various file systems are managed by a layer called the VFS or the Virtual File System. • The virtual file system provides a consistent view of data as stored on various devices on the system. • It does this by separating the user view of file systems using standard system calls but allowing the kernel developer to implement logical file systems on any physical device. • Thus it abstracts the details of the physical device and the logical file system and allows users to access files in a consistent way. File System(Cont..) • The Linux necessity of file systems stems from two facts. • The applications have separate program images and hence they need to have storage space in a file system. • All low-level devices too are accessed as files. • It is necessary for every Linux system to have a master file system, the root file system. This gets mounted at system start-up. • Later many more file systems can be mounted using this file system. If the system cannot mount the root file system over the specified device it will panic and not proceed with system start-up. File System (Cont..) The following are some of the commonly used embedded file systems. • EXT2: A classical Linux file system that has a broad user base CRAMFS: A compressed read-only file system • ROMFS: A read-only file system • RAMFS: A read-write, memory-based file system • JFFS2: A journaling file system built specifically for storage on flash • PROCFS: A pseudo file system used for getting system information • DEVFS: A pseudo file system for maintaining the device files IO Subsystem • The IO subsystem on Linux provides a simple and uniform interface to onboard devices. • Three kinds of devices are supported by the IO subsystem. • Character devices for supporting sequential devices. • Block devices for supporting randomly accessible devices. Block devices are essential for implementing file systems. • Network devices that support a variety of link layer devices. Networking Subsystems • One of the major strengths of Linux has been its robust support for various networking protocols. IPC • The interprocess communication on Linux includes signals (for asynchronous communication), pipes, and sockets as well as the System V IPC mechanisms such as shared memory, message queues, and semaphores. User Space • Program: This is the image of an application. It resides on a file system. When an application needs to be run, the image is loaded into memory and run. Note that because of virtual memory the entire process image is not loaded into memory but only the required memory pages are loaded. • Virtual memory: This allows each process to have its own address space. Virtual memory allows for advanced features such as shared libraries. Each process has its own memory map in the virtual address space; this is unique for any process and is totally independent of the kernel memory map. • System calls: These are entry points into the kernel so that the kernel can execute services on behalf of the application User Space (Cont..) User Space (cont..) • The steps involved are: ❑Compiling and making an executable program ❑Getting the executable program on a file system on the target board ❑Running the program by executing it on the shell For a MIPS-based target the following command is used to generate the executable.
Four steps are involved in it: Generating preprocessed output,
followed by generating assembly language output, which is followed by generating object output, and then the last stage of linking. User Space (cont..) • All executable files have two formats: binary format and script files. • Executable binary formats that are most popular on embedded systems are the COFF, ELF, and the flat format. • COFF was the earlier default format and was replaced by the more powerful and flexible ELF format. • The ELF format consists of a header followed by many sections including the text and the data. You can use the nm command to find the list of symbols in an executable. User Space (cont..) • Libc contains a list of commonly used functions. • For example, the printf function is used in almost all applications. • Thus instead of having it reside in every application image, the library becomes a common placeholder for it. • If the library is used as a shared library then not only does it optimize storage space, it optimizes memory too by making sure that only one copy of the text resides in memory. • An application can have more libraries either shared or static; this can be specified at the time of linking. User Space (cont..) • The list of dependencies can be found by using the following command (the shared library dependencies are the runtime dynamic linker ld.so and the C library). User Space (cont..) • If you do the symbol listing of the file as shown above, the printf function is given an address. Using static libraries has the disadvantage of wasting storage and memory at the cost of faster application start-up speed. Now let us run the program on the board and examine its memory map. Linux Start-Up Sequence • The Linux start-up sequence describes the series of steps that happen right from the moment a Linux system is booted on until the user is presented with a log-in prompt on the console. • The understanding of the start-up sequence is essential to mark milestones in the development cycle. • Also once the start-up is understood, the basic pieces necessary for building a Linux system such as the boot loader and the root file system will be understood. • On embedded systems the start-up time often has to be as small as possible; understanding the details will help the user to tweak the system for a faster start-up. Linux Start-Up Sequence (Cont..) • The Linux start-up sequence can be split into three phases. • Boot loader phase: Typically this stage does the hardware initialization and testing, loads the kernel image, and transfers control to the Linux kernel • Kernel initialization phase: This stage does the platform-specific initialization, brings up the kernel subsystems, turns on multitasking, mounts the root file system, and jumps to user space. • User- space initialization phase: Typically this phase brings up the services, does network initialization, and then issues a log-in prompt Boot Loader Phase • The boot loader is the piece of software that starts executing immediately after the system is powered on. • The boot loader is an important part of the development process and one of the most complicated ones too. • Most of the boot-loading issues are specific to the CPU and the boards shipped out. • Eliminating the boot loader and flashing the kernel that bootstraps itself is an approach provided by many RTOSs including VxWorks, which provides boot initialization routines to do POST, set up chip selects, initialize RAM and memory caches, and transfer the image from ROM to RAM. • Hardware Initialization
• Downloading Kernel Image and Initial Ram Disk
• Setting Up Arguments • Jumping to Kernel Entry Point Kernel Start-Up The kernel start-up can be split into the following phases. • CPU/Platform-Specific Initialization • Subsystem Initialization • This includes • Scheduler initialization • Memory manager initialization • VFS initialization • Driver Initialization • Mounting Root File System • There are three kinds of root file systems that are normally used on embedded systems: • The initial ram disk • Network-based file system using NFS • Flash-based file system • Doing Initcall and Freeing Initial Memory • Moving to User Space User Space Initialization • User space initialization is distribution dependent. The responsibility of the kernel ends with the transition to the init process. What the init process does and how it starts the services is dependent on the distribution. The init process is a very special process to the kernel; it has the following capabilities. • It can never be killed. Linux offers a signal called SIGKILL that can terminate execution of any process but it cannot kill the init process. • When a process starts another process, the latter becomes the child of the former. This parent–child relationship is important. In case the parent dies before the child then init adopts the orphaned processes. • The kernel informs the init of special events using signals. For example: if you press the Ctrl-Alt-Del on your system keyboard, this makes the kernel send a signal to the init process, which typically does a system shutdown. GNU Cross-Platform Toolchain One of the initial steps in the embedded Linux movement is setting up the toolchains for building the kernel and the applications. The toolchain that is used on embedded systems is known as the cross- platform toolchain. What exactly does a cross-platform mean? • The target on which the application and kernel need to run may not have enough memory and disk space to house the build tools. • most cases the target may not have a native compiler. In such cases cross- compilation is the solution. Cross-compilation generally happens on the desktop (usually an x86-based one) by using a compiler that runs on Linuxx86 (HOST) and generates code that is executable on the embedded (TARGET) platform. This process of compiling on a HOST to generate code for the TARGET system is called cross-compilation and the compiler used for the purpose is called a cross-compiler. • The most reliable open source compiler toolkit available across various platforms is the GNU compiler and its accessory tools are called the GNU toolchain. • These compilers are backed up by a host of developers across the Internet and tested by millions of people across the globe on various platforms. A cross-platform toolchain has the components listed below.
• Binutils: Binutils are a set of programs necessary for
compilation/linking/ assembling and other debugging operations. • GNU C compiler: The basic C compiler used for generating object code (both kernel and applications). • GNU C library: This library implements the system call APIs such as open, read, and so on, and other support functions. All applications that are developed need to be linked against this base library. Utilities that constitute binutils are the following. • addr2line: It translates program addresses into file names and line numbers. Given an address and an executable, it uses the debugging information in the executable to figure out which file name and line number are associated with a given address. • ar: The GNU ar program creates, modifies, and extracts from archives. An archive is a single file holding a collection of other files in a structure that makes it possible to retrieve the original individual files (called members of the archive). • as: GNU as is a family of assemblers. If you use (or have used) the GNU assembler on one architecture, you should find a fairly similar environment when you use it on another architecture. Each version has much in common with the others, including object file formats, most assembler directives (often called pseudo-ops), and assembler syntax. • c++filt: The c++filt program does the inverse mapping: it decodes low-level names into user-level names so that the linker can keep these overloaded functions from clashing. • gasp: The GNU assembler macro preprocessor. • ld: The GNU linker ld combines a number of object and archive files, relocates their data, and ties up symbol references. Often the last step in building a new compiled program to run is a call to ld. • nm: GNU nm lists the symbols from object files. • objcopy: The GNU objcopy utility copies the contents of an object file to another. objcopy uses the GNU BFD library to read and write the object files. It can write the destination object file in a format different from that of the source object file. The exact behavior of objcopy is controlled by command-line options. • objdump: The GNU objdump utility displays information about one or more object files. The options control what particular information to display, such as symbol table, GOT, and the like. • ranlib: ranlib generates an index to the contents of an archive, and stores it in the archive. The index lists each symbol defined by a member of an archive that is a relocatable object file. • readelf: It interprets headers on ELF files. • size: The GNU size utility lists the section sizes and the total size for each of the object files in its argument list. By default, one line of output is generated for each object file or each module in an archive. • strings: GNU strings print the printable character sequences that are at least characters long and are followed by an unprintable character. By default, it only prints the strings from the initialized and loaded sections of object files; for other types of files, it prints the strings from the whole file. • strip: GNU strip discards all symbols from the target object file(s). The list of object files may include archives. At least one object file must be given. strip modifies the files named in it. Building Toolchain • Building a cross-platform toolchain is slightly tricky • it is advisable to download prebuilt cross-platform toolchains directly for your target platform. • although the binutils and the C compiler can be used for both kernel and applications build, the C library is used only by the applications. Links --the latest cross-platform toolchain. • ARM: http://www.emdebian.org/ • PPC: http:// www.emdebian.org/ • MIPS: http://www.linux-mips.org/ • M68K: http://www.uclinux.org/ Compiling a cross-platform • 1. Decide the TARGET. • 2. Decide on the Kernel/GCC/Glibc/Binutils version combo. • 3. Procure patches for all the above, if any available. • 4. Decide PREFIX variable, where to put the image. • 5. Compile binutils. • 6. Obtain suitable KERNEL HEADERS for your platform. • 7. Compile minimal GCC. • 8. Build Glibc. • 9. Recompile full-featured GCC. Picking a Target Name (The target name decides the compiler that used for building and its output)
• some of the basic types.
• arm-linux: Support for ARM processors such as armV4, armv5t, and so on. • mips-linux: Support for various MIPS core such as r3000, r4000, and so on. • ppc-linux: Linux/PowerPC combination with support for various PPC chips. • m68k-linux: This targets Linux running on the Motorola 68k processor.
• A complete list can be found at http://www.gnu.org.
Picking the Right Version Combination • trickiest portion of all steps and most likely the cause of all problems • Check up on the most active mailing list archives to guide you • For example, ARM/Kernel 2.6/GCC 2.95.1, GCC 3.3/BINUTILS 2.10.x or ARM / Kernel 2.4/GCC 2.95.1/BINUTILS 2.9.5 are known good combinations for arm-linux. Choosing a Directory Structure and Setting Variables • The directory tree for storing the tools and the kernel headers must be decided. • The directory tree is also exported using certain specified variables to make the job of building smoother Variables used are • TARGET: This variable represents the machine target name. For example, TARGET=mips-linux. • PREFIX: This is the base directory containing all the other subdirectories of your toolchain; the default for the native toolchain on any system is almost always /usr. This means, you will find gcc (binary) in BINDIR = $PREFIX/bin and headers in INCLUDEDIR= $PREFIX/include. To keep from stepping on your system’s native tools when you build a crosscompiler you should put your cross- development toolchain in some path other than the default /usr. For example, PREFIX=/usr/local/mips/. • KERNEL_SOURCE_DIR: This is the place where your kernel source (or at least kernel headers) is stored. Especially if you are cross-compiling this may well be different from the native set of files. It is good practice to keep the Linux kernel files under the PREFIX/TARGET directory. For example, KERNEL_SOURCE_DIR = PREFIX/TARGET/linux (i.e., /usr/ local/mips/linux). • NATIVE: The host platform (usually x86). Building Binutils – The first step is to build GNU binutils. Version 2.9.5 is stable but the latest release is recommended. • Download and unpack: Download the latest version from ftp://ftp.gnu.org/ gnu/binutils/. Unpack the archive using the commands: cd $PREFIX/src tar -xzf binutils-2.10.1.tar.gz • There may be target-specific patches available for binutils that resolve various bugs; it’s usually a good idea to apply these to the source, if they exist. The best place to get up-to- date information is the toolchain mailing list. • Configure: The configure script sets up a lot of compilation parameters, installed binaries, and machine configuration. The commands to cross compile on HOST for some TARGET are: ./configure --target=$TARGET --prefix=$PREFIX For example, ./configure --target=mips-linux --prefix=/usr/local/mips. • Build: Invoke make in the binutils directory to compile binutils • Install: Invoke make install in the binutils folder to install the toolchain. Before you install, ensure that the install path does not replace existing binutils if you already have them, unless and until you really want to force that. You’ll notice your new set of tools in PREFIX/TARGET/. Obtain Suitable Kernel Headers
• The first step in building a GCC is to set up kernel headers. Cross-
compiling the toolchain requires the kernel headers. • The list of steps 1. Download a Linux kernel from ftp.kernel.org. Unpack the tar. We suggest $PREFIX/linux (e.g., /usr/local/mips/linux). 2. Apply kernel patches if necessary. 3. Set the architecture for which you are extracting the header files. This is done by setting the ARCH variable in the top-level Makefile such as ARCH=mips. 4. Configure the kernel even though you won’t necessarily want to compile from it. Issue make menuconfig in the top-level kernel source directory: make menuconfig This will bring up the kernel build configuration program. If you have X running on your system, you may run make xconfig. Select the option: System and processor type, and select a system consistent with the tools you’re building. 5. Build dependencies (This step is only needed for 2.4 kernels). Exit the configuration program saving the changes, and then run: make dep Building Minimal GCC • Minimal GCC is the compiler that has only basic C language support. Once the minimal GCC is built, the glibc can be built for the target. • Glibc is then used for building full-featured GCC with C++ support. • After setting up the kernel headers we can now build minimal GCC. The steps are as follows. 1. Download and unpack: Download the latest version of GCC from http:// gcc.gnu.org. Unpack the downloaded GCC. You may then choose to apply patches if they exist. 2. Configure: This could be done in a similar way as done for binutils. ./configure --target=$TARGET --prefix=$PREFIX -–with-headers=$KERNEL_SOURCE_DIR/include --enable-languages=c For example, ./configure --target=mips-linux --prefix=/usr/local/mips/ --with-headers=/usr/local/mips/linux/include --enable-languages=c The last option given to configure -enable-languages=c is necessary because the minimal GCC can support languages other than C and currently we need C language support. 3.Build: For compiling the minimal GCC you need to just invoke the make command. If you are compiling for the first time this may result in the following error. ./libgcc2.c:41: stdlib.h: No such file or directory ./libgcc2.c:42: unistd.h: No such file or directory make[3]: *** [libgcc2.a] Error 1 4. Install: Assuming that making the cross-compiler worked, you can now install your new cross-compiler: make install