Quickly Adapting U-Boot to a Custom Board

Almost every company manufacturing Embedded Systems produce their own boards with their very own peripherals, which of course, need to be initialized when the boards is powered up.

They can go from simple leds, to amplifiers or external appliances, but what they usually share is that they depend on GPIOs so they need to be properly set to a specific output. It is pretty ugly to see leds blinking or a fan that starts without meeting the requirements.

This of course needs to be done during the whole boot process till the Embedded Application takes control of the hardware.

I am going to show how to quickly add this custom modifications to U-Boot so you can save some quality time looking around. For this example I will be using my old, but always nice, at91sam9263ek.

You have to have in mind that depending on the board, there might be other bootloader before u-boot comes into play. For this post I am assuming we are booting from NOR flash so we don’t need at91bootstrap before, everything is initialized by u-boot.

The file we need to modify at board/atmel/at91sam9263ek/at91sam9263ek.c which contains the initialization code for the EK board including LCD, MAC & NAND.

During boot process the function board_init() is called by the boot loader so there we will add a call to our own initialization function:

int board_init(void)
{
        /* arch number of AT91SAM9263EK-Board */
        gd->bd->bi_arch_number = MACH_TYPE_AT91SAM9263EK;
        /* adress of boot parameters */
        gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
#ifdef CONFIG_CMD_NAND
        at91sam9263ek_nand_hw_init();
#endif
#ifdef CONFIG_HAS_DATAFLASH
        at91_set_pio_output(AT91_PIO_PORTE, 20, 1);     /* select spi0 clock */
        at91_spi0_hw_init(1 << 0);
#endif
#ifdef CONFIG_MACB
        at91sam9263ek_macb_hw_init();
#endif
#ifdef CONFIG_USB_OHCI_NEW
        at91_uhp_hw_init();
#endif
#ifdef CONFIG_LCD
        at91sam9263ek_lcd_hw_init();
#endif
 
        at91sam9263ek_custom_hw_init();
 
        return 0;
}

We could add a conditional preprocessor to keep it configurable but as this is supposed to be for a custom board, I never end up using them.

The function for setting up the pins looks like this:

static void at91sam9263ek_custom_hw_init(void)
{
        printf("Initializing Custom GPIOs...\n");
 
        /* Configure LED_A to 0*/
        at91_set_gpio_output(AT91_PIN_PC0, 0);
 
        /* Configure LED_B to 1*/
        at91_set_gpio_output(AT91_PIN_PC7, 1);
 
        /* Configure PERIPHERAL_A to 0*/
        at91_set_gpio_output(AT91_PIN_PC10, 0);
}

The you should just compile u-boot and flash the image to your board to get everything up and running:

$ export CROSS_COMPILE=/path/to/arm-
$ make at91sam9263ek_norflash_boot_config
$ make