The process of porting U-Boot to a new board consists of the following steps:
| Old name | New name |
|---|---|
| board/<existing-board> | board/<new-board> |
| include/configs/<existing-board>.h | include/configs/<new-boad>.h |
Very early in the boot sequence, the bootstrap calls the function init_ram to configure all the critical SoC and board devices. This is in order to enable U-Boot to be copied from Flash to SDRAM and start executing. This function is normally defined in the file board/init-<boardname>.S.
For ST40 targets the structure of this file is typically as follows:
#define _SH4REG_ASM_ /* Include some register definitions for this device */ #include "asm/stb7100reg.h" /* Include the common memory initialization code for this SOC. This file contains the "init_ram" function which uses the __memory_setup_table defined below to do the appropriate memory setups. */ #include "../../cpu/sh4_2xx/stb7100/init-stb7100common.S" .balign 32 __memory_setup_table: /* Define memory config table */ POKE_LONG(STB7100_CLOCKGENA_LOCK, 0xc0de) OR_LONG(STB7100_CLOCKGENA_PLL0_CFG, 0x00100000) UPDATE_LONG(STB7100_CLOCKGENA_PLL0_CFG, 0xfff7ffff, 0) UPDATE_LONG(STB7100_CLOCKGENA_PLL0_CFG, 0xfff80000, 0x06 | (0x3b << 8) | (0x0 << 16)) OR_LONG(STB7100_CLOCKGENA_PLL0_CFG, 0x00080000) WHILE_NE(STB7100_CLOCKGENA_PLL0_STATUS, 0x00000001, 0x00000001) UPDATE_LONG(STB7100_CLOCKGENA_PLL0_CFG, 0xffefffff, 0) POKE_LONG(STB7100_CLOCKGENA_LOCK, 0x0) ... END_MARKER
The initialization of the configuation registers is carried out using __memory_setup_table. This table defines a sequence of memory operations that are executed in order, with a suitable time delay between each operation.
The memory operations currently supported are as follows:
| Operation | Function |
|---|---|
| POKE_LONG(A, V) | *(*long)(A) = V; |
| POKE_SHORT(A, V) | *(*short)(A) = V; |
| POKE_CHAR(A, V) | *(*char)(A) = V; |
| OR_LONG(A, V) | *(*long)(A) |= V; |
| UPDATE_LONG(A, MASK, V) | *(*long)(A) = (*(*long)(A) & MASK) | V; |
| POKE_UPDATE_LONG(A1, A2, MASK, SHIFT, V) | *(*long)(A1) = ((*(*long)(A2) & MASK) << SHIFT) | V; |
| WHILE_NE(A, MASK, V) | while( (*(*long)(A1) & MASK) != V) {;} |
| IF_DEVID(V) | If the device ID config register matches V then do the following memory operations until the next ELSE or ENDIF, otherwise execute the operations between the next ELSE and ENDIF. Currently supported for 710X targets only |
| IF_NOT_DEVID(V) | If the device ID config register does NOT match V then do the following memory operations until the next ELSE or ENDIF, otherwise execute the operations between the next ELSE and ENDIF. Currently supported for 710X targets only |
| ELSE | |
| ENDIF | |
| END_MARKER | marks end of table |
Modify this table to match the target SoC target board combination.
The ST200 memory setup is very similar to the ST40, expect that it has an extra table _xpu_mmu_setup_table. This table sets up the MMU (and may also require changing).
After U-Boot has been relocated to SDRAM, the initial bootstrap code sets up a stack and calls the C function start_<cpu>boot (see lib_<cpu>/board.c). This function then calls a number of initialization functions including the function board_init (which is defined in the file board/<boardname>/<boardname>.c).
The file board/<boardname>/<boardname>.c contains a number of functions that must be modified to match the target board. Typically, these functions set up PIO pins for serial ports, do any EPLD programming required, reset devices and provide functions for enabling or disabling writes to Flash.