
Debugging tools need every developer. However, there are no universal solutions that are suitable for those who create user-level applications and for those who write low-level programs, such as hardware drivers. The closer to the "hardware" - the more hardcore in debugging and testing.
From this material, you will learn how to debug code and analyze exceptions at the kernel level of the Linux Android OS on systems based on the Intel architecture. Namely, we will look at the JTAG Debugger debugging tool, which is part of Intel System Studio Ultimate Edition. We will talk about the JTAG standard, about the Intel JTAG debugger mentioned above, about exception handling. As an example, we will use the MinnowBoard MAX mini-computer with an Intel Atom on board.
JTAG Overview
JTAG (pronounced jay tag, jay tag) is short for Joint Test Action Group. Usually, when they say “JTAG”, they imply the IEEE Standard Test Access Port and the Boundary-Scan Architecture standard. This standard sets the rules for debugging and testing single-chip systems (SoC, System on Chip) and microprocessor software (Microprocessor Software).
When JTAG debugging is used, the tool kit consists of three parts: a software JTAG debugger installed on the host computer, a hardware JTAG adapter (sensor) and an on-chip debugger (OCD, On Chip Debug) with which the tested chip is equipped.
')
Software JTAG Debugger
The JTAG debugger is a software tool installed on the host computer. It receives data and address information from the JTAG adapter and displays it in the user interface. The developer, in turn, can send commands to the JTAG adapter, which is connected to the host computer via USB or using another interface.
Using this tool, you can monitor the execution of the program and debug it at the source code level. This is realized through symbol files that correspond to binary images loaded onto target systems. These tools give the developer the following options: start (run) and stop (stop) code execution, execute a step-by-step and a step-into step during debugging, step breaks, breakpoints, and memory access.
Using the above tools, the programmer can debug the program part of the target system, examine the system memory and registers.
Intel JTAG Debugger (known as XDB) is included with Intel System Studio Ultimate Edition. XDB is the same JTAG debugging software tool that should be installed on the host computer.
JTAG hardware adapter
A JTAG adapter is a device that converts JTAG signals to a format suitable for transmission to a computer. Interfaces of adapters and PCs use interfaces such as USB, parallel port, RS-232, Ethernet. USB is the most popular among them. It is used to connect many JTAG adapters with computers. The standard provides for the minimum number of JTAG contacts to connect target devices to JTAG adapters, however, in practice, a variety of interfaces are used. For example, these are 10- and 20-pin connectors for ARM, 14-pin for ST, 16-pin for OCDS.
The bundle from the Intel JTAG debugger and MinnowBoard MAX, referred to in this material, uses a 60-pin connector to connect the target device. Intel's ITP-XDP3 is used as the JTAG adapter for MinnowBoard MAX. The Intel JTAG debugger is also compatible with third-party JTAG adapters. For example - with Macraigor Systems usb2Demon and OpenOCD.
In-circuit debugger (target microchip)
The main components of the in-circuit debugger are TAP (Test Access Point, Test Port) and TDI (Test Data In, Test Data Input) / TDP (Test Data Out, Test Data Output). Using TAP you can reset, read and write the status of registers, use the instruction BYPASS. The main technology used in JTAG is the so-called
Boundary Scan using TDI / TDO signal lines.
Configuration from JTAG adapter and target system. It also shows an expansion card used to connect Intel ITP-XDP3 and MinnowBoard MAX.Intel Architecture Exception Overview
An exception is a synchronous event that is generated when the processor detects one or more predefined conditions when executing instructions. The IA-32 architecture provides three exception classes: fault (fault), trap (trap), and fault (abort). Usually, in the event of failures and traps, it is possible to continue interrupted work, while in case of accidents - no. When an exception occurs, it is processed in the same way as interrupts are handled. This means that after stopping and saving the current process, the system switches to the exception handler, and after the handler has completed its work, it returns to the previously executed task.
Exceptions and interrupts protected modeVector | Short name | Description | Type of | Error code | A source |
0
| #DE
| Division error
| Renouncement
| Not
| DIV and IDIV instructions
|
one
| #DB
| Reserved
| Failure / trap
| Not
| Intel use only
|
2
| - | NMI interrupt
| Interrupt
| Not
| External nonmaskable interrupt
|
3
| #BP
| Breakpoint
| Trap
| Not
| INT 3 instruction
|
four
| #OF
| Overflow
| Trap
| Not
| INT0 instruction
|
five
| #BR
| Out of range
| Renouncement
| Not
| BOUND instruction
|
6
| #UD
| Incorrect (undefined) opcode
| Renouncement
| Not
| UD2 instruction or reserved opcode
|
7
| #NM
| Device unavailable (No math coprocessor)
| Renouncement
| Not
| Floating-point instructions or WAIT / FWAIT instructions
|
eight
| #DF
| Double failure
| Crash
| Yes (zero)
| Any instruction that can generate an exception, NMI or INTR
|
9
| | Going beyond the coprocessor segment (reserved)
| Renouncement
| Not
| Instruction that performs floating point calculations
|
ten
| #TS
| Invalid TSS
| Renouncement
| Yes
| Task switching or TSS access
|
eleven
| #NP
| No segment
| Renouncement
| Yes
| Load segment registers or access system segments
|
12
| #SS
| Stack segment failure
| Renouncement
| Yes
| Stack Operations and SS Register Loading
|
13
| #GP
| General security error
| Renouncement
| Yes
| Errors related to memory, security checks
|
14
| #PF
| Page failure
| Renouncement
| Yes
| Work with memory
|
15
| -
| Reserved by Intel, not intended to be used.
| | Not
| |
sixteen
| #MF
| X87 FPU floating point error (Calculation Error)
| Renouncement
| Not
| Calculations with floating point on x87 FPU or instructions WAIT / FWAIT
|
17
| #AC
| Alignment check failed
| Renouncement
| Yes (zero)
| Work with data in memory
|
18
| #MC
| Hardware error
| Crash
| Not
| Error codes (if any) and their source are hardware dependent
|
nineteen
| #XM
| SIMD floating point exceptions
| Renouncement
| Not
| SSE, SSE2, SSE3 Floating Point Instructions
|
20
| #VE
| Virtualization exception
| Renouncement
| Not
| EPT violations
|
21 - 31
| - | Reserved by Intel, not intended to be used.
| | | |
32 - 255
| - | Developer Interrupts (Not Reserved)
| Interrupt
| | External interrupts or INT instructions n.
|
Preparing MinnowBoard MAX and Intel ITP-XDP3 for USB connection to host computer
First you need to install on Android's MinnowBoard MAX. To do this, refer to the article “
Intel System Studio Developer Article: Configuring, Building, and Profiling the Android Linux Core Using VTune .” It contains instructions for building, installing and configuring Android on MinnowBoard MAX.
After installing the OS, connect the MinnowBoard MAX to the Intel JTP-ITP-XDP3 adapter using the expansion card. JTAG-adapter will connect to the PC via USB. The host computer must have Intel System Studio Ultimate Edition installed, which includes the USB driver for Intel ITP-XDP3.
MinnowBoard MAX is connected to the Intel JTP-ITP-XDP3 adapter, which, in turn, is connected to the host computer with Intel's JTAG debugger (XDB) installed on itUse Intel's JTAG Debugger (XDB) to debug the Android kernel on MinnowBoard MAX
Consider the step by step procedure for using XDB in debugging the Linux kernel of the Android OS.
1. Run the Intel JTAG debugger. To do this, go to the folder where it is installed, and run the batch file (for example, start_xdb_legacy_products.bat).
2. Connect to the target device. To do this, in the JTAG debugger interface, execute the File> Connect command and select, first, the hardware JTAG adapter. In our case, this is Intel ITP-XPD3. Secondly - you need to specify the target platform. We are interested in Intel Atom Processor E38xx, Z3680, X37xx - 2 cores (ValleyView).
Selection of hardware JTAG adapter and target platform in XDB3. Load the symbol files and specify the source file directory. To do this, run the File> Load / Unload Symbol command in the Intel JTAG debugger and specify symbol files. For source code files, run the Options> Source Directories command and specify the rules for matching source code files and symbol files, as well as the corresponding directories. The rules allow you to customize the correspondence between the paths in the file of characters that are written at compile time and the current locations of the source code files.
4. Find the entry-file in which there is an exception handler. Use the menu command JTAG debugger Intel View> Source files and open the file entry_64.S.
Find file entry_64.S5. Set a breakpoint at the entry point of the exception. For this we find the string ENTRY (error_entry), which is the entry point of the exception with the error code in the register RAX. Each exception handler is defined as a zeroentry or errorentry macro. Thus, you can set a breakpoint in error_entry or in a particular handler. In this article we use for testing "zeroentry invalid_op do_invalid_op".
ENTRY(error_entry) XCPT_FRAME CFI_ADJUST_CFA_OFFSET 15*8 cld movq_cfi rdi, RDI+8 movq_cfi rsi, RSI+8 movq_cfi rdx, RDX+8 movq_cfi rcx, RCX+8 movq_cfi rax, RAX+8 movq_cfi r8, R8+8 movq_cfi r9, R9+8 movq_cfi r10, R10+8 movq_cfi r11, R11+8 movq_cfi rbx, RBX+8 movq_cfi rbp, RBP+8 movq_cfi r12, R12+8 movq_cfi r13, R13+8 movq_cfi r14, R14+8 movq_cfi r15, R15+8 xorl %ebx,%ebx testl $3,CS+8(%rsp) je error_kernelspace error_swapgs: SWAPGS error_sti: TRACE_IRQS_OFF ret <....> zeroentry divide_error do_divide_error zeroentry overflow do_overflow zeroentry bounds do_bounds zeroentry invalid_op do_invalid_op zeroentry device_not_available do_device_not_available paranoiderrorentry double_fault do_double_fault zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun errorentry invalid_TSS do_invalid_TSS errorentry segment_not_present do_segment_not_present zeroentry spurious_interrupt_bug do_spurious_interrupt_bug zeroentry coprocessor_error do_coprocessor_error errorentry alignment_check do_alignment_check zeroentry simd_coprocessor_error do_simd_coprocessor_error
Now, as an example, we will raise an exception, and check if the handler on which we set the breakpoint worked. Set a breakpoint at “zeroentry invalid_op do_invalid_op” and call the block of the BUG code () that executes the ud2 instruction that causes the fault “Invalid operation code”.
#define BUG() \ do { \ asm volatile("ud2"); \ unreachable(); \ } while (0)
Call BUG ()
The BUG () macro must be added to the kernel’s own test code in order for an exception to be thrown. In this example, we added it to keyboard.c so that an exception is triggered when special sequences of characters entered from the keyboard appear.
The result of the macro call BUG ()
Result of the call of the BUG () macro, enlarged fragment of the screen copyStop at Invalid_op
If you set a breakpoint in the "invalid operation code" exception handler or at the entrance to the exception handler, you can see the exception message and, during debugging, get to the place of the error.
Breakpoint in exception handler “Invalid opcode”
Breakpoint in the exception handler “Invalid opcode”, enlarged fragment of the screen copyConclusion
Some exceptions are critical system hardware and software errors. Therefore, it is very important to know how, why and where they occur. Using Intel's JTAG debugger, such errors are easy to detect and get to their root causes. All this is possible because this debugger provides the developer with powerful features. Among them - easy access to compiled and source code, view the stack of calls and registers.
useful links
Intel 64 and IA-32 Architects Software Developer's ManualJTAG Tutorial: IEE 1149.x and Software Debug