Spend a few moments perusing Appendix C, "BusyBox Commands," where you can find a summary of each BusyBox command. After you have done so, you will have a better appreciation for the capabilities of BusyBox and how it might be applicable to your own embedded Linux project.
As mentioned at the beginning of this chapter, many of the BusyBox commands contain a limited subset of features and options compared to their full-featured counterparts. In general, you can get help on any given BusyBox command at runtime by invoking the command with the --help option. This produces a usage message with a brief description of each supported command option. The BusyBox gzip applet is a useful example of a BusyBox command that has support for a limited set of options. Listing 11-10 displays the output from gzip-help on a BusyBox target.
Listing 11-10. BusyBox gzip Applet Usage
/ # gzip --help
BusyBox v1.01 (2005.12.01-21:11+0000) multi-call binary
Usage: gzip [OPTION]... [FILE]...
Compress FILE(s) with maximum compression.
When FILE is '-' or unspecified, reads standard input. Implies -c.
Options:
-c Write output to standard output instead of FILE.gz
-d Decompress
-f Force write when destination is a terminal
The BusyBox version of gzip supports just three command line options. Its full-featured counterpart contains support for more than 15 different command line options. For example, the full-featured gzip utility supports a --list option that produces compression statistics for each file on the command line. No such support exists for BusyBox gzip. This is usually not a significant limitation for embedded systems. We present this information so you can make an informed choice when deciding on BusyBox. When the full capabilities of a utility are needed, the solution is simple: Delete support for that particular utility in the BusyBox configuration and add the standard Linux utility to your target system.
• BusyBox is a powerful tool for embedded systems that replaces many common Linux utilities in a single multicall binary.
• BusyBox can significantly reduce the size of your root file system image.
• BusyBox is easy to use and has many useful features.
• Configuring BusyBox is straightforward, using an interface similar to that used for Linux configuration.
• BusyBox can be configured as a statically or dynamically linked application, depending on your particular requirements.
• System initialization is somewhat different with BusyBox; those differences were covered in this chapter.
• BusyBox has support for many commands. Appendix C itemizes all the available BusyBox commands from a recent release.
11.4.1. Suggestions for Additional Reading
BusyBox Project home
www.busybox.net/
BusyBox man page
www.busybox.net/downloads/BusyBox.html
Chapter 12. Embedded Development Environment
The configuration and services enabled on your host development system can have a huge impact on your success as an embedded developer. This chapter examines the unique requirements of a cross-development environment and some of the tools and techniques that an embedded developer needs to know to be productive.
We begin by examining a typical cross-development environment. Using the familiar "hello world" example, we detail the important differences between host-based applications and those targeted at embedded systems. We also look at differences in the toolchains for native versus embedded application development. We then present host system requirements and detail the use of some important elements of your host system. We conclude this chapter with an example of a target board being hosted by a network-based host.
12.1. Cross-Development Environment
Developers new to embedded development often struggle with the concepts and differences between native and cross-development environments. Indeed, there are often three compilers and three (or more) versions of standard header files such as stdlib.h. Debugging an application on your target embedded system can be difficult without the right tools and host-based utilities. You must manage and separate the files and utilities designed to run on your host system from those you intend to use on your target.
When we use the term host in this context, we are referring to the development workstation that is sitting on your desktop and running your favorite Linux desktop distribution. [79] Webster's defines nonsense as "an idea that is absurd or contrary to good sense." It is my opinion that developing embedded Linux platforms on a non-Linux/UNIX host is nonsensical.
Conversely, when we use the term target we are referring to your embedded hardware platform. Therefore, native development denotes the compilation and building of applications on and for your host system. Cross-development denotes the compilation and building of applications on the host system that will be run on the embedded system. Keeping these definitions in mind will help you stay on track through this chapter.
Figure 12-1 shows the layout of a typical cross-development environment. A host PC is connected to a target board via one or more physical connections. It is most convenient if both serial and Ethernet ports are available on the target. Later when we discuss kernel debugging, you will realize that a second serial port can be a very valuable asset.
Figure 12-1. Cross-development setup
In the most common scenario, the developer has a serial terminal on the host connected to the RS-232 serial port, possibly one or more Telnet terminal sessions to the target board, and potentially one or more debug sessions using Ethernet as the connection medium. This cross-development setup provides a great deal of flexibility. The basic idea is that the host system provides the horsepower to run the compilers, debuggers, editors, and other utilities, while the target executes only the applications designed for it. Yes, you can certainly run compilers and debuggers on the target system, but we assume that your host system contains more resources, including RAM, disk storage, and Internet connectivity. In fact, it is not uncommon for a target embedded board to have no human-input devices or output displays.
12.1.1. "Hello World"Embedded
A properly configured cross-development system hides a great deal of complexity from the average application developer. Looking at a simple example will help uncover and explain some of the mystery. When we compile a simple "hello world" program, the toolchain (compiler, linker, and associated utilities) makes many assumptions about the host system we are building on and the program we are compiling. Actually, they are not assumptions, but a collection of rules that the compiler references to build a proper binary.
Listing 12-1 reproduces a simple "hello world" program.
Listing 12-1. Hello World Again
#include
int main(int argc, char **argv) {
printf("Hello World\n");
return 0;
}
Even the casual application developer will realize some important points about this C source file. First, the function printf() is referenced but not defined in this file. If we omit the #include directive containing the prototype for the printf() function, the compiler emits the familiar message:
Читать дальше