How to debug uBoot?
u-boot
Solution
Assuming that you have configured a U-Boot version such as `u-boot-2013.07` with the `mx28evk_config` configuration and built the `u-boot.sb` Makefile target using a toolchain such as `arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2`, and converted the target to an `.sd` file using `./tools/mxsboot sd u-boot.sb u-boot.sd`, then the most likely problem is that you have a mistake in your PMU or SDRAM configuration. A mistake in these configurations is likely to cause a reset loop where the reset occurs before you reach the U-Boot banner printout.
Make sure that you have set the EVK switches as specified in the Denx U-Boot `doc/README.mx28evk` file: Set the boot mode DIP switches as:
- Boot Mode Select: 1 0 0 1 (Boot from SD card Slot 0 - U42)
- JTAG PSWITCH RESET: To the right (reset disabled)
- Battery Source: Down
- Wall 5V: Up
- VDD 5V: To the left (off)
- Hold Button: Down (off)
The next step that you need in order to debug this type of problem is to put serial output early, in the SPL SRAM code. Start by putting `putc` statements in `arch/arm/cpu/arm926ejs/mxs/spl_boot.c:mxs_common_spl_init()`. For example:
void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
const unsigned int iomux_size)
{
struct mxs_spl_data *data = (struct mxs_spl_data *)
((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
debug_putc('a');
uint8_t bootmode = mxs_get_bootmode_index();
debug_putc('b');
mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
debug_putc('c');
mxs_power_init();
debug_putc('d');
mxs_mem_init();
debug_putc('e');
data->mem_dram_size = mxs_mem_get_size();
data->boot_mode_idx = bootmode;
mxs_power_wait_pswitch();
}
The `putc` that I use for this is borrowed from the Freescale i.MX28 bootlet code:
void debug_putc(char ch)
{
int loop = 0;
while (((*(volatile hw_uartdbgfr_t *) ((0x80000000 + 0x74000) + 0x18)).U)&0x00000020)
{
loop++;
if (loop > 10000)
break;
};
((*(volatile hw_uartdbgdr_t *) ((0x80000000 + 0x74000) + 0x0)).U = (ch));
}
The types that you need are:
typedef unsigned int reg32_t;
typedef unsigned short reg16_t;
typedef unsigned char reg8_t;
typedef union
{
reg32_t U;
struct
{
unsigned DIV_EMI : 6;
unsigned RSRVD1 : 2;
unsigned DIV_XTAL : 4;
unsigned RSRVD2 : 4;
unsigned DCC_RESYNC_ENABLE : 1;
unsigned BUSY_DCC_RESYNC : 1;
unsigned RSRVD3 : 8;
unsigned BUSY_SYNC_MODE : 1;
unsigned BUSY_REF_CPU : 1;
unsigned BUSY_REF_EMI : 1;
unsigned BUSY_REF_XTAL : 1;
unsigned SYNC_MODE_EN : 1;
unsigned CLKGATE : 1;
} B;
} hw_clkctrl_emi_t;
typedef union
{
reg32_t U;
struct
{
unsigned TRG : 5;
unsigned RSRVD1 : 3;
unsigned BO_OFFSET : 3;
unsigned RSRVD2 : 1;
unsigned LINREG_OFFSET : 2;
unsigned RSRVD3 : 2;
unsigned DISABLE_FET : 1;
unsigned ENABLE_LINREG : 1;
unsigned DISABLE_STEPPING : 1;
unsigned PWDN_BRNOUT : 1;
unsigned RSRVD4 : 12;
} B;
} hw_power_vddactrl_t;
typedef union
{
reg32_t U;
struct
{
reg8_t DATA;
unsigned FE : 1;
unsigned PE : 1;
unsigned BE : 1;
unsigned OE : 1;
unsigned RESERVED : 4;
reg16_t UNAVAILABLE;
} B;
} hw_uartdbgdr_t;
typedef union
{
reg32_t U;
struct
{
unsigned CTS : 1;
unsigned DSR : 1;
unsigned DCD : 1;
unsigned BUSY : 1;
unsigned RXFE : 1;
unsigned TXFF : 1;
unsigned RXFF : 1;
unsigned TXFE : 1;
unsigned RI : 1;
unsigned RESERVED : 7;
reg16_t UNAVAILABLE;
} B;
} hw_uartdbgfr_t;
void debug_putc(char c);
I put the types in `arch/arm/cpu/arm926ejs/mxs/mxs_init.h` and the `putc` implementation in `spl_boot.c`. I also tend to put a lot of `putc` statements in `spl_power_init.c` and `spl_mem_init.c`.
Note that mis-programming the PMU `spl_power_init.c` can cause a reset that will only show up later when you get to `spl_mem_init.c`. Don't let this fake you out.
Problem
I am trying to get Uboot running on a Freescale mx28evk board. It compiles fine and gives me an image, that I can dd copy to a SD-card. When I turn on the board I get no output from the serial debug console, not even an error message. I can confirm though that the board works fine with another working image on the card. What would be the appropriate next step to find out what causes the problem? Are there any patterns or magic numbers on the uBoot partition that I can look for to confirm it is a valid uBoot?