Section 2.2. Anatomy of an Embedded System


2.2. Anatomy of an Embedded System

Figure 2-1 shows a block diagram of a typical embedded system. This is a very simple example of a high-level hardware architecture that might be found in a wireless access point. The system is centered on a 32-bit RISC processor. Flash memory is used for nonvolatile program and data storage. Main memory is synchronous dynamic random-access memory (SDRAM) and might contain anywhere from a few megabytes to hundreds of megabytes, depending on the application. A real-time clock module, often backed up by battery, keeps the time of day (calendar/wall clock, including date). This example includes an Ethernet and USB interface, as well as a serial port for console access via RS-232. The 802.11 chipset implements the wireless modem function.

Figure 2-1. Example embedded system


Often the processor in an embedded system performs many functions beyond the traditional CPU. The hypothetical processor in Figure 2-1 contains an integrated UART for a serial interface, and integrated USB and Ethernet controllers. Many processors contain integrated peripherals. We look at several examples of integrated processors in Chapter 3, "Processor Basics."

2.2.1. Typical Embedded Linux Setup

Often the first question posed by the newcomer to embedded Linux is, just what does one need to begin development? To answer that question, we look at a typical embedded Linux development setup (see Figure 2-2).

Figure 2-2. Embedded Linux development setup


Here we show a very common arrangement. We have a host development system, running your favorite desktop Linux distribution, such as Red Hat or SuSE or Debian Linux. Our embedded Linux target board is connected to the development host via an RS-232 serial cable. We plug the target board's Ethernet interface into a local Ethernet hub or switch, to which our development host is also attached via Ethernet. The development host contains your development tools and utilities along with target filesnormally obtained from an embedded Linux distribution.

For this example, our primary connection to the embedded Linux target is via the RS-232 connection. A serial terminal program is used to communicate with the target board. Minicom is one of the most commonly used serial terminal applications and is available on virtually all desktop Linux distributions.

2.2.2. Starting the Target Board

When power is first applied, a bootloader supplied with your target board takes immediate control of the processor. It performs some very low-level hardware initialization, including processor and memory setup, initialization of the UART controlling the serial port, and initialization of the Ethernet controller. Listing 2-1 displays the characters received from the serial port, resulting from power being applied to the target. For this example, we have chosen a target board from AMCC, the PowerPC 440EP Evaluation board nicknamed Yosemite. This is basically a reference design containing the AMCC 440EP embedded processor. It ships from AMCC with the U-Boot bootloader preinstalled.

Listing 2-1. Initial Bootloader Serial Output

U-Boot 1.1.4 (Mar 18 2006 - 20:36:11) AMCC PowerPC 440EP Rev. B Board: Yosemite - AMCC PPC440EP Evaluation Board          VCO: 1066 MHz          CPU: 533 MHz          PLB: 133 MHz          OPB: 66 MHz          EPB: 66 MHz          PCI: 66 MHz I2C:   ready DRAM:  256 MB FLASH: 64 MB PCI:   Bus Dev VenId DevId Class Int In:    serial Out:   serial Err:   serial Net:   ppc_4xx_eth0, ppc_4xx_eth1 =>

When power is applied to the Yosemite board, U-Boot performs some low-level hardware initialization, which includes configuring a serial port. It then prints a banner line, as shown in the first line of Listing 2-1. Next the processor name and revision are displayed, followed by a text string identifying the board type. This is a literal string entered by the developer in the U-Boot source code.

U-Boot then displays the internal clock configuration (which was configured before any serial output was displayed). When this is complete, U-Boot configures any hardware subsystems as directed by its static configuration. Here we see I2C, DRAM, FLASH, PCI, and Network subsystems being configured by U-Boot. Finally, U-Boot waits for input from the console over the serial port, as indicated by the => prompt.

2.2.3. Booting the Kernel

Now that U-Boot has initialized the hardware, serial port, and Ethernet network interface, it has only one job left in its short but useful lifespan: to load and boot the Linux kernel. All bootloaders have a command to load and execute an operating system image. Listing 2-2 presents one of the more common ways U-Boot is used to manually load and boot a Linux kernel.

Listing 2-2. Loading the Linux Kernel

=> tftpboot 200000 uImage-440ep ENET Speed is 100 Mbps - FULL duplex connection Using ppc_4xx_eth0 device TFTP from server 192.168.1.10; our IP address is 192.168.1.139 Filename 'uImage-amcc'. Load address: 0x200000 Loading: ####################################################          ###################################### done Bytes transferred = 962773 (eb0d5 hex) => bootm 200000 ## Booting image at 00200000 ...    Image Name:   Linux-2.6.13    Image Type:   PowerPC Linux Kernel Image (gzip compressed)    Data Size:    962709 Bytes = 940.1 kB    Load Address: 00000000    Entry Point:  00000000    Verifying Checksum ... OK    Uncompressing Kernel Image ... OK Linux version 2.6.13 (chris@junior) (gcc version 4.0.0 (DENX ELDK 4.0 4.0.0))   #2 Thu Feb 16 19:30:13 EST 2006 AMCC PowerPC 440EP Yosemite Platform ... < Lots of Linux kernel boot messages, removed for clarity > ... amcc login:    <<< This is a Linux kernel console command prompt

The tftpboot command instructs U-Boot to load the kernel image uImage-440ep into memory over the network using the TFTP[2] protocol. The kernel image, in this case, is located on the development workstation (usually the same machine that has the serial port connected to the target board). The tftpboot command is passed an address that is the physical address in the target board's memory where the kernel image will be loaded. Don't worry about the details now; we cover U-Boot in much greater detail in Chapter 7.

[2] This and other servers you will be using are covered in detail in Chapter 12, "Embedded Development Environment."

Next, the bootm (boot from memory image) command is issued, to instruct U-Boot to boot the kernel we just loaded from the address specified by the bootm command. This command transfers control to the Linux kernel. Assuming that your kernel is properly configured, this results in booting the Linux kernel to a console command prompt on your target board, as shown by the login prompt.

Note that the bootm command is the death knell for U-Boot. This is an important concept. Unlike the BIOS in a desktop PC, most embedded systems are architected in such a way that when the Linux kernel takes control, the bootloader ceases to exist. The kernel claims any memory and system resources that the bootloader previously used. The only way to pass control back to the bootloader is to reboot the board.

One final observation is worth noting. All the serial output in Listing 2-2 up to and including this line is produced by the U-Boot bootloader:

Uncompressing Kernel Image ... OK

The rest of the boot messages are produced by the Linux kernel. We'll have much more to say about this later, but it is worth noting where U-Boot leaves off and where the Linux kernel image takes over.

2.2.4. Kernel Initialization: Overview

When the Linux kernel begins execution, it spews out numerous status messages during its rather comprehensive boot process. In the example being discussed here, the Linux kernel spit out more than 100 lines before it issued the login prompt. (We omitted them from the listing, for clarity of the point being discussed.) Listing 2-3 reproduces the last several lines of output before the login prompt. The goal of this exercise is not to delve into the details of the kernel initialization (this is covered in Chapter 5, "Kernel Initialization"), but to gain a high-level understanding of what is happening and what components are required to boot a Linux kernel on an embedded system.

Listing 2-3. Linux Final Boot Messages

... Looking up port of RPC 100003/2 on 192.168.0.9 Looking up port of RPC 100005/1 on 192.168.0.9 VFS: Mounted root (nfs filesystem). Freeing init memory: 232K INIT: version 2.78 booting ... coyote login:

Shortly before issuing a login prompt on our serial terminal, Linux mounts a root file system. In Listing 2-3, Linux goes through the steps required to mount its root file system remotely (via Ethernet) from an NFS[3] server on a machine with the IP address 192.168.0.9. Usually, this is your development workstation. The root file system contains the application programs, system libraries, and utilities that make up a GNU/Linux system.

[3] We cover NFS and other required servers in Chapter 12.

The important point in this discussion should not be understated: Linux requires a file system. Many legacy embedded operating systems did not require a file system, and this is a frequent surprise to engineers making the transition from legacy embedded OSs to embedded Linux. A file system consists of a predefined set of system directories and files in a specific layout on a hard drive or other medium that the Linux kernel mounts as its root file system.

Note that there are other devices from which Linux can mount a root file system. The most common, of course, is to mount a partition from a hard drive as the root file system, as is done on your Linux workstation. Indeed, NFS is pretty useless when you ship your embedded Linux widget out the door and away from your development environment. However, as you progress through this book, you will come to appreciate the power and flexibility of NFS root mounting as a development environment.

2.2.5. First User Space Process: init

One more important point should be made before moving on. Notice in Listing 2-3 this line:

INIT: version 2.78 booting.

Until this point, the kernel itself was executing code, performing the numerous initialization steps in a context known as kernel context. In this operational state, the kernel owns all system memory and operates with full authority over all system resources. The kernel has access to all physical memory and to all I/O subsystems.

When the Linux kernel has completed its internal initialization and mounted its root file system, the default behavior is to spawn an application program called init. When the kernel starts init, it is said to be running in user space or user space context. In this operational mode, the user space process has restricted access to the system and must use kernel system calls to request kernel services such as device and file I/O. These user space processes, or programs, operate in a virtual memory space picked at random[4] and managed by the kernel. The kernel, in cooperation with specialized memory-management hardware in the processor, performs virtual-to-physical address translation for the user space process. The single biggest benefit of this architecture is that an error in one process can't trash the memory space of another, which is a common pitfall in legacy embedded OSs and can lead to bugs that are difficult to track down.

[4] It's not actually random, but for purposes of this discussion, it might as well be. This topic will be covered in more detail later.

Don't be alarmed if these concepts seem foreign. The objective of this section is to paint a broad picture from which you will develop more detailed knowledge as you progress through the book. These and other concepts are covered in great detail in later chapters.



Embedded Linux Primer(c) A Practical Real-World Approach
Embedded Linux Primer: A Practical Real-World Approach
ISBN: 0131679848
EAN: 2147483647
Year: 2007
Pages: 167

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net