NIP [c000d058] strcpy+0x10/0x1c
LR [c0085650] register_disk+0xec/0xf0
Call trace:
[c00e170c] add_disk+0x58/0x74
[c90061e0] loop_init+0x1e0/0x430 [loop]
[c002fc90] sys_init_module+0x1f4/0x2e0
[c00040a0] ret_from_syscall+0x0/0x44
Segmentation fault
Notice that the register dump includes symbolic information, where appropriate. Your kernel must have KALLSYSMS enabled for this symbolic information to be available. Figure 13-4 shows the configuration options under the General Setup main menu.
Figure 13-4. Symbol support for oops

Much of the information in a kernel oops message is directly related to the processor. Having some knowledge of the underlying architecture is necessary to fully understand the oops message.
Analyzing the oops in Listing 13-14, we see right away that the oops was generated due to a 'kernel access of bad area, sig: 11'. We already know from previous examples in this chapter that signal 11 is a segmentation fault.
The first section is a summary showing the reason for the oops, a few important pointers, and the offending task. In Listing 13-14, NIP is the next instruction pointer, which is decoded later in the oops message. This points to the offending code that led to the oops. LR is a PowerPC register and usually indicates the return address for the currently executing subroutine. SP is the stack pointer. REGS indicates the kernel address for the data structure containing the register dump data, and TRAP indicates the type of exception that this oops message relates to. Referring to the PowerPC architecture reference manual referenced at the end of Chapter 7, 'Bootloaders,' we see that a TRAP 0300 is the PowerPC Data Storage Interrupt, which is triggered by a data memory access error.
On the third line of the oops message, we see additional PowerPC machine registers, such as MSR (machine state register) and a decode of some of its bits. On the next line, we see the DAR (data access register), which often contains the offending memory address. The DSISR register contents can be used in conjunction with the PowerPC architecture reference to discover much detail about the specific reason for the exception.
An oops message also contains the task pointer and the decoded task name to quickly determine what task or thread was running at the time of the oops. We also see a detailed processor register dump, which can be used for additional clues. Again, we need knowledge of the architecture and compiler register usage to make sense of the clues from the register values. For example, the PowerPC architecture uses the r3 register for return values from C functions.
The last part of the oops message provides a stack backtrace with symbol decode if symbols are enabled in the kernel. Using this information, we can construct a sequence of events that led to the offending condition.
In this simple example, we have learned a great deal of information from this oops message. We know that it was a PowerPC Data Storage Exception, caused by an error in a data memory access (as opposed to an instruction fetch memory access). The DAR register tells us that the data address that generated this exception was 0x0000_0000. We know that the modprobe process produced the error. From the backtrace and NIP (next instruction pointer), we know that it was in a call to strcpy() that can be traced directly back to the loop_init() function in the loop.ko module, which modprobe was trying to insert at the time of the exception. Given this information, tracking down the source of this errant null pointer dereference should be quite trivial.
13.5. Binary Utilities
Binary utilities, or binutils, are a critical component of any toolchain. Indeed, to build a compiler, you must first have successfully built binutils. In this section, we briefly introduce the more useful tools that the embedded developer needs to know about. As with most of the other tools in this chapter, these are cross-utilities and must be built to execute on your development host while operating on binary files targeted to your chosen architecture. Alternatively, you could compile or obtain versions of these to run on your target, but we assume a cross- development environment for these examples.
13.5.1. readelf
The readelf utility examines the composition of your target ELF binary file. This is particularly useful for building images targeted for ROM or Flash memory where explicit control of the image layout is required. It is also a great tool for learning how your toolchain builds images and for understanding the ELF file format.
For example, to display the symbol table in an ELF image, use this command:
$ readelf -s <elf-image>
To discover and display all the sections in your ELF image, use this command:
$ readelf -e <elf-image>
Use the -S flag to list the section headers in your ELF image. You might be surprised to learn that even a simple seven-line 'hello world' program contains 38 separate sections. Some of them will be familiar to you, such as the .text and .data sections. Listing 13-15 contains a partial listing of sections from our 'hello world' example. For simplicity, we have listed only those sections that are likely to be familiar or relevant to the embedded developer.
Listing 13-15. readelf Section Headers
$
ppc_82xx-readelf -S hello-ex
There are 38 section headers, starting at offset 0x32f4:
Section Headers:
[ Nr] Name Type Addr Off Size ES Flg Lk Inf Al
...
[11] .text PROGBITS 100002f0 0002f0 000568 00 AX 0 0 4
...
[13] .rodata PROGBITS 10000878 000878 000068 00 A 0 0 4
...
[15] .data PROGBITS 100108e0 0008e0 00000c 00 WA 0 0 4
...
[22] .sdata PROGBITS 100109e0 0009e0 00001c 00 WA 0 0 4
[23] .sbss NOBITS 100109fc 0009fc 000000 00 WA 0 0 1
...
[25] .bss NOBITS 10010a74 0009fc 00001c 00 WA 0 0 4
...
The .text section contains the executable program code. The .rodata section contains constant data in your program. The .data section generally contains initialized global data used by the C library prologue code and can contain large initialized data items from your application. The .sdata section is used for smaller initialized global