at91bootstrap: Create a Custom Board Configuration

Last modified by Microchip on 2023/11/09 09:01

Introduction

This training topic is for advanced developers who wish to create a custom board configuration (almost from scratch) for the at91bootstap bootloader.

Prerequisites

For an introduction to at91bootstrap, see the at91bootstrap: A Second Stage Bootloader for Microchip MPUs page.

Back to Top

Create a Custom Board Configuration

Step 1: Create a directory for your custom board.

The at91bootstrap bootloader contains the contrib/board/ directory for contributed boards. Within the directory are vendor names. Create a directory with your <vendor> name. Within the <vendor> directory you can create a directory with your individual custom projects’ <board> name(s). You may want to use the board’s unique name (e.g., <board>) or you may want to preface the target device part number ahead of the board’s name (e.g., <sam9x60_board>).

/project_1/
  |-- at91bootstrap/
       |-- contrib/
            |-- board/
                 |-- <vendor>/
                      |-- <board>/

Back to Top

Step 2: Populate the directory with the following files:

There are multiple files that are required in the custom project directory. It is best to copy these files from the default Microchip evaluation kit that closely matches your custom project design and edit them to suit your custom project board.

The key items that you will need to know before you begin are:

  • System Clock source (external, internal)
  • Static RAM
  • Non-Volatile Memory (NVM) Boot Memory: SD Memory Card, e.MMC, NOR Flash (QSPI), NAND Flash memory
  • Which program you will jump to (U-Boot, Linux®, BusyBox, RTOS, MPLAB® Harmony 3 application, Bare Metal Program)

In the following sub-steps, we explain how to set up each file.

 a. <board>_<nvm_boot_memory>_<uboot_or_linux>_defconfig
 b. <board>.c
 c. <board>.h
 d. board.mk
 e. Config.in.board
 f. Config.in.linux_arg
 g. Config.in.<board>
 h. Config.in.boardname

Back to Top

a: Create a default configuration file:

The default configuration file allows the autotools programs to generate a .config file that defines the features make will build into the image.

The default configuration and .config files are text files. You may view them with a text editor of your choice. To edit/alter you can either 1) edit them with a text editor, or 2) alter them using menuconfig.

Loading U-Boot (boot.bin)

Below are three examples for the SAM9X60 that will load U-Boot (boot.bin) from external NVM memory to internal SRAM.

The first example will load U-Boot from SD Memory Card:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_SDCARD=y
4 CONFIG_DEBUG=y
5 CONFIG_THUMB=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: Boots from SD Memory Card.
Line 4: Enables debug/log messages to be displayed on the console.
Line 5: Supports thumb instruction set. This is set only for ARM9 devices and not for Arm® Cortex® A5, which supports Thumb-2 instructions.

Back to Top

The second example will load U-Boot from NAND Flash memory:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_NANDFLASH=y
4 # CONFIG_PMECC_AUTO_DETECT is not set
5 CONFIG_PMECC_CORRECT_BITS_8=y
6 CONFIG_IMG_SIZE="0x000c0000"
7 CONFIG_DEBUG=y
8 CONFIG_THUMB=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: Boots from NAND Flash memory.
Line 4: For an ONFI compliant NAND, the ECC correction is automatically activated. Refer to the SAMA5D2 Series datasheet sections 16.4.7.1 and 16.4.7.2 or SAM9X60 datasheet sections 11.4.7.1 and 11.4.7.2.
Line 5: Specifies the PMECC error correction bits. Used when CONFIG_PMECC_AUTO_DETECT is not set.
Line 6: Size of the U-Boot (boot.bin) image (in HEX) to be loaded by at91bootstrap.
Line 7: Enables debug/log messages to be displayed on the console.
Line 8: Supports thumb instruction set. This is set only for ARM9 devices and not for Arm Cortex A5 which supports Thumb-2 instructions.

Back to Top

The third example will load U-Boot from NOR Flash (QSPI) memory:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_SPI_CLK=50000000
4 CONFIG_IMG_ADDRESS="0x00040000"
5 CONFIG_IMG_SIZE="0x000c0000"
6 CONFIG_DEBUG=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: SPI Clock frequency.
Line 4: Memory location in NOR Flash memory where U-Boot (boot.bin) is stored. The at91bootstrap copies boot.bin from this address location to an address location specified in external RAM.
Line 5: Size of the boot.bin image (in HEX) to be loaded by at91bootstrap.
Line 6: Enables debug/log messages to be displayed on the console.

Back to Top

Loading Linux

Below are three examples for the SAM9X60 that will load a Linux image from external NVM memory to external RAM.

The first example will load Linux image from SD Memory Card:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_SDCARD=y
4 CONFIG_LOAD_LINUX=y
5 CONFIG_IMAGE_NAME="zImage"
6 CONFIG_DEBUG=y
7 CONFIG_THUMB=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: Boots from SD Memory Card.
Line 4: Boots Linux directly.
Line 5: Name of the Linux image file.
Line 6: Enables debug/log messages to be displayed on the console.
Line 7: Supports thumb instruction set. This is set only for ARM9 devices and not for Arm Cortex A5 which supports Thumb-2 instructions.

Back to Top

The second example will load Linux image from NAND Flash memory:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_NANDFLASH=y
4 CONFIG_LOAD_LINUX=y
5 CONFIG_IMAGE_NAME="zImage"
6 # CONFIG_PMECC_AUTO_DETECT is not set
7 CONFIG_PMECC_CORRECT_BITS_8=y
8 CONFIG_IMG_SIZE="0x000c0000"
9 CONFIG_DEBUG=y
10 CONFIG_THUMB=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: Boots from NAND Flash memory.
Line 4: Boots Linux directly.
Line 5: Name of the Linux image file.
Line 6: For an ONFI compliant NAND, the ECC correction is automatically activated. Refer to the SAMA5D2 Series datasheet sections 16.4.7.1 and 16.4.7.2 or SAM9X60 datasheet sections 11.4.7.1 and 11.4.7.2.
Line 7: Specifies the PMECC error correction bits. Used when CONFIG_PMECC_AUTO_DETECT is not set.
Line 8: Size of the Linux image (in HEX) to be loaded.
Line 9: Enables debug/log messages to be displayed on the console.
Line 10: Supports thumb instruction set. This is set only for ARM9 devices and not for Arm Cortex A5 which supports Thumb-2 instructions.

Back to Top

The third example will load Linux image from NOR Flash (QSPI) memory:

1 CONFIG_SAM9X60_<board>=y
2 CONFIG_RAM_256MB=y
3 CONFIG_SPI_CLK=50000000
4 CONFIG_OVERRIDE_CMDLINE=y
5 CONFIG_IMG_ADDRESS="0x00200000"
6 CONFIG_OF_OFFSET="0x00180000"
7 CONFIG_LOAD_LINUX=y
8 CONFIG_JUMP_ADDR="0x26F00000"
9 CONFIG_DEBUG=y

Line 1: Defines the board name. Used in the main makefile. Also used as a macro for board-specific initialization.
Line 2: Memory size of external RAM.
Line 3: SPI Clock frequency.
Line 4: If CONFIG_OVERRIDE_CMDLINE is selected, then you can override the kernel argument set by CONFIG_LINUX_KERNEL_ARG_STRING as shown in the figure below.

at91bootstrap kernel storage setup

Line 5: Memory location in NOR Flash memory where the Linux image is stored.
Line 6: Memory location in NOR Flash memory where the Device Tree is stored.
Line 7: Boots Linux directly.
Line 8: The memory location in the external RAM where the Linux Image should be copied to.
Line 9: Enables debug/log messages to be displayed on the console.

Back to Top

Naming Convention

The suggested naming convention for your custom project default configuration is to concatenate the board name (<board>) with the NVM memory that at91bootstrap will load from SD Memory Card, NOR Flash, NAND Flash, etc. and the program that will be loaded, U-Boot, Linux, BusyBox, etc.

<board>_<nvm_boot_memory>_<uboot_or_linux>_defconfig

Legend:

  • qspi – NOR Flash Memory
  • sd – SD Memory Card
  • if no number is given, boot from port 0
  • if number is given, boot from indicated port (for example, 1 = port 1)
  • nf – NAND Flash Memory
  • df – Serial/DataFlash Memory

Legend:

  • uboot – Third-Stage Bootloader
  • linux_image_dt – Linux kernel and Device Tree

Back to Top

b: Create a <board>.c file:

The <board>.c file performs all the hardware initialization of the custom project board.

Function hw_init() is a mandatory function. It performs all of the peripheral and hardware initialization. Examine the <board>.c file that closely matches your custom project board design. In general, the following peripheral and hardware initializations must be performed:

  • Clock initialization:
    • The PLLA is initialized and the MCK is switched to PLLA output.
    • Peripheral Clocks that are in use are initialized within the respective peripheral initialization routines.
  • External DRAM initialization:
    • The most important function is external DRAM initialization (you will see them inside the #ifdef CONFIG_DDR2).
    • If you are using a similar SRAM from the evaluation kits, you can examine and reuse the DDR RAM configuration and initialization functions.
    • If a different DRAM is used, refer to the DRAM datasheet to gather information needed to alter the configuration and initialization functions.
    • The ddramc_init() function is implemented for external DRAM initialization called by hw_init(). The ddramc_init() function calls the ddramc_reg_config() function to populate the RAM configuration and timings followed by the ddram_initialization.
  • Pin initialization:
    • Pin initializations are initialized.
  • External NVM initialization:
    • The external NVM that contains the third-stage bootloader or program to be loaded by at91bootstrap is initialized.
  • Other initializations:
    • The bus matrix system, timer, debug console, LEDs, or anything specific to the custom project board is initialized.

Back to Top

c: Create a <board>.h file:

The <board>.h file provides definitions for the clock (Main and peripheral) and setting for all of the NVM memory on your custom project board.

Include your custom project <board>.h file to at91bootstrap/include/board.h.

Ensure the clock related to NVM memory settings is set to the values required. The clock settings depend on the choice for the clock source, i.e.:

  • An external source of 8 to 24 MHz crystal oscillator
  • External Clock Source
  • Both external and internal clock 12 MHz RC
  • Internal slow clock and 12 MHz RC

This will determine the clock definition for BOARD_MAINOSC.

Other required definitions are:

  • Bus frequency
  • Main clock frequency
  • PLLA prescaler settings (multiplier and divider)
  • Console UART baud

The NVM-related definitions depend on what type of memory you choose.

For an SD Memory Card, the following definitions are required:

  • CONFIG_SYS_BASE_SDHC: The address location where the peripheral is memory mapped.
  • CONFIG_SYS_ID_SDHC: The peripheral ID.

For a NAND Flash memory, the following definitions are required:

  • CONFIG_SYS_NAND_BASE: The address location where the External Bus Interface with NCS3 (chip select 3) is memory mapped.
  • CONFIG_SYS_NAND_MASK_ALE: The Address Latch Enable line (A21 of the Static Memory Controller).
  • CONFIG_SYS_NAND_MASK_CLE: The Command Latch Enable line (A22 of the Static Memory Controller).

at91bootstrap hsmc block diagram

  • CONFIG_SYS_NAND_ENABLE_PIN: NAND Flash memory Chip Select pin
  • CONFIG_SYS_NAND_OE_PIN: Output Enable pin
  • CONFIG_SYS_NAND_WE_PIN: Write Enable pin
  • CONFIG_SYS_NAND_ALE_PIN: Address Latch Enable pin (A21 of the Static Memory Controller)
  • CONFIG_SYS_NAND_CLE_PIN: Command Latch Enable pin (A22 of the Static Memory Controller)

For DataFlash Memory, the following definitions are required:

  • CONFIG_SYS_SPI_CLOCK: SPI Clock Frequency (typically defined in the defconfig file for the board)
  • CONFIG_SYS_SPI_MODE: SPI mode
  • CONFIG_SYS_BASE_SPI: The address location where the peripheral is memory mapped
  • CONFIG_SYS_SPI_PCS: SPI Chip Select pin

Back to Top

d: Create a board.mk file:

Edit the board.mk file with the compiler and assembler flags.

Back to Top

e: Create a Config.in.board file:

Edit the Config.in.board file with the configuration choices used by menuconfig.

Back to Top

f: If you are loading a Linux Image directly, create a Config.in.linux_arg file:

If you want at91bootstrap to load the Linux image directly, without loading a third-stage bootloader such as U-Boot, you will need to edit the Config.in.linux_arg file with the boot arguments that will be passed to the Linux kernel.

You will also need to update the Config.in.kernel file in the at91bootstrap root directory.

Back to Top

g: Create a Config.in.boardname file:

This file defines CONFIG_BOARDNAME used by menuconfig to display the list of contributed boards a user can choose from. This file is sourced by the contrib/board/Config.in.boardname which is in turn sourced by board/Config.in, sourced by the main Config.in.

Back to Top

Step 3: Update files in contrib/board directory.

Update the following files in the contrib/board folder with the files you created:

Config.in.board file:

source “contrib/board/<vendor_name>/<board_name>/Config.in.board”

Config.in.boardname file:

source “contrib/board/<vendor_name>/<board_name>/Config.in.boardname

Config.in.linux_arg file:

source “contrib/board/<vendor_name>/<board_name>/Config.in.linux_arg”

Back to Top

Building Your Custom Project at91bootstrap

Once you have created your custom project directory and populated it with the required files, you can now build your customized at91bootstrap.

Step 1: Change directory into the at91bootstrap directory:

​$ cd ~/project_1/at91bootstrap

Back to Top

Step 2: Clean and configure make​

$ make mrproper
$ make <board>_defconfig

What is the difference between make clean and make mrproper?

  • make clean - Remove most generated files but keep the config and enough build support to build external modules
  • make mrproper - Remove all generated files + config + various backup files

Anytime the configuration is changed, you should execute make mrproper.

Back to Top

Step 3: You may customize the default configuration setting using menuconfig:

​$ make menuconfig

You may exit menuconfig by repeatedly typing ESC-ESC.

Back to Top

Step 4: Build at91bootstrap:​

$ make

 A working cross-toolchain for Arm-based MPU target is required to build at91bootstrap.

Ensure you set the CROSS_COMPILE=<path_to>/<cross_compiler> and ARCH=arm environment variables.

For example, if your cross-compiler executable is arm-linux-gcc then CROSS_COMPILE=<path_to>/arm-linux-

A second method is you may include these as command variables. For example: $ make ARCH=arm CROSS_COMPILE=<path_to>/<cross_compiler>

The results of the build will be a binary image that can be written to the external memory device selected during configuration.​

$ cd ~/project_1/at91bootstrap/binaries

Back to Top

Summary

In this training, you learned some advanced methods of creating a custom board configuration for at91bootstrap.

Back to Top