There are basically three types of interfaces that developers use to link a target to a host for debugging: a serial line, a networking interface, and special debugging hardware. Each debugging interface has its own benefits and applications. We will discuss the detailed use of some of these interfaces in Chapter 11. This section briefly reviews the benefits and characteristics of each type.
Using a serial link is the simplest way to debug a target from a host, because serial hardware is simple and is often found, in some form or another, in embedded systems. There are two potential problems in using a serial link, however. First, the speed of most serial links is rather limited. Second, if there's only one serial port in the embedded system or if the serial link is the embedded system's only external interface, it becomes impossible to debug the system and interact with it using a terminal emulator at the same time. The absence of terminal interaction is not a problem in some cases, however. When debugging the startup of the kernel using a remote kernel debugger, for example, no terminal emulator is required, since no shell actually runs on the target until the kernel has finished booting.
The use of a networking interface, such as TCP/IP over Ethernet, provides much higher bandwidth than a serial link. Moreover, the target and the host can use many networking connections over the same physical network link. Hence, you can continue to interact with the target while debugging applications on it. You can also debug over a networking link while interacting with the target using a terminal emulator over the embedded system's serial port. However, the use of a networking interface implies the presence of a networking stack. Since the networking stack is found in the Linux kernel, a networking link cannot be used to debug the kernel itself. In contrast, kernel debugging can be and is often carried out over a serial link.
Both the use of a serial link and the use of a networking interface requires that some minimal software be taking care of the most primitive I/O hardware available on the target. In some cases, such as when porting Linux to a new board or when debugging the kernel itself, this assumption does not hold. In those case, it is necessary to use a debugging interface that provides direct hardware control over the software. There are several ways to achieve this, but most are quite expensive.
Currently, the preferred way to obtain direct control over hardware for debugging purposes is to use a BDM or JTAG interface. These interfaces rely on special BDM or JTAG functionality embedded in the CPU's silicon. By connecting a special debugger to the JTAG or BDM pins of the CPU, you can take complete control of its behavior. For this reason, JTAG and BDM are often used when bringing up new embedded boards or debugging the Linux kernel on such boards.
Though the BDM and JTAG debuggers are much less expensive and much less complicated, in terms of their technical operation, than In-Circuit Emulators (ICEs), they still require the purchase of special hardware and software. Often, this software and hardware is still relatively expensive because CPU manufacturers are not keen to share the detailed information regarding the use of the JTAG and BDM interfaces included in their products. Obtaining this information often involves establishing a trust relationship with the manufacturer and signing stringent NDAs.
 Have a look at some of the books listed in Appendix B if you are not familiar with the various hardware tools commonly used for debugging embedded systems, including ICEs.
Though it would probably be too expensive to equip each member of an engineering team with her own BDM or JTAG debugger, I highly recommend that you have at least one such debugger available throughout your project for debugging the very difficult problems that a serial or networking debugger cannot deal with appropriately. When selecting such a debugger, however, you may want to evaluate its compatibility with the GNU development toolchain. Some BDM and JTAG debuggers, for instance, require the use of specially modified gdb debuggers. A good BDM or JTAG debugger should be able to deal with the standard GNU development toolchain, and the binary files generated using it, transparently.