NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
U-boot Debug in CCSv5
U-boot Debug Overview
Sometimes it is useful to debug the early stages of a system before even the hardware is completely initialized and running. In TI's System-on-a-chip devices (SoC) the early stages are performed by a bootloader code named u-boot.
The u-boot can be either loaded automatically by the SoC ROM (stored in Flash or in a SD card) or the user can manually load the code to the device memory (similar to a typical embedded application).
This page contains examples of how to properly configure Code Composer Studio v5.1 to perform source-code debugging of u-boot. At the moment there is just one example, but more are still to come. Stay tuned for changes.
Although the procedure is valid for all SoC devices, the configuration used that perfectly reproduces the method shown uses the following components:
- Code Composer Studio 5.1 M6 (beta)
- EZSDK 5.01.01.80 (beta)
- Spectrum Digital 816x/389x EVM DDR3 Rev C
- BlackHawk BH560v2 emulator
- Linux Debug in CCSv5
- DM816x C6A816x_AM389x PSP User Guide
- DM816x C6A816x AM389x PSP U-Boot
- Understanding u-boot-min startup for DM814x
U-boot debug setup and procedure
To properly debug u-boot a binary with complete debug symbols is absolutely necessary. This file is typically named u-boot (no extensions) and its size is usually around 700kB on the disk.
Depending on the Linux SDK distribution or if the u-boot used is obtained straight from the open source community, it may be necessary to rebuild it. Check the References section above for details.
Important! When debugging a target running any High-level OS (Linux, WinCE, Android, etc.) or its support/initialization routines (u-boot, WinCE bootloader, etc.) you should not rely on GEL files in the target configuration (.ccxml) for device and peripheral initializations that will disrupt your environment. Details on how to add/remove GEL files are shown in the section Advanced target configurations --> Adding GEL files to a target configuration of the CCSv5 Getting Started Guide.
The debugger does have a slight quirk in the way it disassembles code. In order for the disassembly window to work properly around device memory boundaries, you will need to establish the debugger memory map in a GEL file. This essentially tells the debugger which regions of memory are valid and which are not, and the attributes of each memory region (read only, read/write, etc). This is not the same as a memory map for the code generation tools. By default, the full memory reach of the device is defined as R/W. To setup the memory map, use the GEL_MapAdd() GEL function in the GEL file. For example:
GEL_MapAdd(0x00020000, 0, 0xFFFE0000, 1, 1);
adds a memory region from 0x20000 with a length of 0xFFFE0000 as read/write (thus, 0x0-0x20000 is invalid from the debugger's perspective). See the GEL_MapAdd() function in CCS help for more details on the parameters of the function. You will add multiple GEL_MapAdd() functions based on the memory map of your device. Then, to enable the memory mapping, use the GEL_MapOn() as the final GEL instruction. You can find some GEL files at OMAP and Sitara CCS support.
Debugging u-boot loaded automatically
The procedure below is an autonomous system that uses a bootable SD card for the proper bootload process.
- Flash video (FLV format)
- Run time: 08:02 (mm:ss)
- Resolution: 1280x992 (video) 1440x1047 (with playback controls and table of contents)
- Total size: 23.06MB
One of the things that U-Boot does is that after performing low-level initialization it relocates itself from the address it was linked to and into system memory. When this happens you need to tell CCS what has happened in order to continue to do symbolic debugging. Assuming you have watched the video in the previous section and are able to debug prior to relocation, the steps for this are:
- Set a breakpoint for board_init_f, and step the code until just prior to the call to relocate_code
- Alternatively you can just set a breakpoint at this location directly, but the line number will vary, the function names do not.
- Before the code calls relocate_code, switch to the Variables view and examine the value of id->id->relocaddr, copy this value (normally shown in decimal, but this is OK).
- In the Run menu, navigate to Load and then Add Symbols....
- Set the code and data offset values to the value of relocaddr
At this point you can now set breakpoints in later parts of U-Boot by name and continue to debug as normal.