AT91Bootstrap

Introduction

AT91Bootstrap is the 2nd level bootloader for Atmel AT91 SoC providing a set of algorithms to manage the hardware initialization such as clock speed configuration, PIO settings, DRAM initialization, to download your main application from specified boot media (NAND FLASH, serial FLASH (both AT25-compatible of DataFlash), serial EEPROM, SD Card, etc.) to main memory and to start it.

This page is dedicated to AT91Bootstrap 4.0.0 and newer. For older versions of AT91Bootstrap, check this page AT91Bootstrap.

AT91Bootstrap 4 only supports these devices:

  • SAMA5D3
  • SAMA5D4
  • SAMA5D2
  • SAM9X60
  • SAMA7G5

Boot strategies

AT91 chips embed a boot ROM code. It is enabled depending on BMS (Boot Mode Select) pin state on reset. The ROM code scans the contents of different media like serial FLASH, NAND FLASH, SD/MMC Card and serial EEPROM. If a valid application is available then it downloads this application into the chip internal SRAM and runs it. To determine if a valid application is present the ROM code checks the eight ARM exception vectors.

If no valid application is available then SAM-BA Monitor is executed. It waits for transactions either on the USB device, or on the DBGU serial port, then the SAM-BA tool can be used to program FLASH or EEPROM present on your board.

For more information on this topic, please check the corresponding SAM product datasheet section Boot Strategies.

ROM Code boot Sequence example

This is an example of boot sequence when BMS=1 taken from the sama5 product family:

nvm_boot_sequence.png

By programming BSC_CR register, we can bypass some steps in above sequence.

Pointing hand Note need a reset to make BSC_CR effective. And BSC_CR will be restored to factory value if power is removed.

Build AT91Bootstrap from sources

Setup ARM Cross Compiler

Warning, important We always recommend using up-to-date toolchains. Check the README file inside the source code for known issues.

  • Ubuntu:
    In Ubuntu 22.04 LTS, you can install the ARM Cross Compiler by doing:
    sudo apt-get install gcc-arm-linux-gnueabi
    export CROSS_COMPILE=arm-linux-gnueabi-
       

  • Others:
    For others, you can download the ARM cross compiler and setup the environment by doing:
    wget -c https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz?rev=ffc49e4af4cb4c298c2110a4d887716c&hash=4999788F321A7617C04CA172E31F6B22520741FF
    export CROSS_COMPILE=`pwd`/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-
       

Other dependencies

Warning, important Python3 is required for the scripts that generate PMECC headers.

Build AT91Bootstrap

This section describes how to get source code from the git repository, how to configure with the default configuration, how to customize AT91Bootstrap based on the default configuration and finally to build AT91Bootstrap to produce the binary. take the default configuration to download U-Boot from NandFlash for example.

Get AT91Bootstrap Source Code

You can easily download AT91Bootstrap source code on the at91bootstrap git repository.

To get the source code, you should clone the repository by doing:

$ git clone https://github.com/linux4sam/at91bootstrap.git
Cloning into 'at91bootstrap'...
remote: Enumerating objects: 17621, done.
remote: Counting objects: 100% (3324/3324), done.
remote: Compressing objects: 100% (1029/1029), done.
remote: Total 17621 (delta 2465), reused 3102 (delta 2285), pack-reused 14297
Receiving objects: 100% (17621/17621), 5.65 MiB | 4.65 MiB/s, done.
Resolving deltas: 100% (13459/13459), done.
$ cd at91bootstrap/

Configure AT91Bootstrap

Assuming you are at the AT91Bootstrap root directory, you will find a configs folder which contains several default configuration files:

sam9x60ekqspi_uboot_defconfig
sam9x60eksd_uboot_defconfig
sam9x60eknf_uboot_defconfig

TIP Tips: qspi means to read quad-SPI serial flash, sd means to read mmc card, nf means to read nand flash

You can configure AT91Bootstrap to load U-Boot binary from SD Card by doing:

$ make mrproper
$ make sam9x60eksd_uboot_defconfig
If the configuring process is successful, the .config file can be found at AT91Bootstrap root directory.

Customize AT91Bootstrap

If the default configuration doesn't meet your need, after configuring with the default configuration, you can customize it by doing:
$ make menuconfig
Now, in the menuconfig dialog, you can easily add or remove some features to/from AT91Bootstrap as the same way as kernel configuration.
Move to <Exit> with arrows and press this button hitting the Enter key to exit from this screen.

Build AT91Bootstrap

Then you can build the AT91Bootstrap binary by doing:
$ make

If the building process is successful, the final .bin image is build/binaries/at91bootstrap.bin.

Customizing and tailoring AT91Bootstrap to your specific board

Unlike the 3.x series of AT91Bootstrap, the 4.x series allows the user to completely configure a new board from existing code, without the need to add a new board under the contrib directory.

Pointing hand AT91Bootstrap 4.x no longer has the concept of 'board' . Board was a file that had plenty of duplicate code from one board to another, which was completely redundant. The idea is to have the concept of 'device', and then to tailor the device for the needs of each board. The support for a device includes all peripherals, all iosets, and each board can select which of the configurations is used. The concept of board now switched to a defconfig concept: the board will be just a simple defconfig that picks parts of the code that are applicable to the specific board.

Pointing hand It is possible that the existing code does not fully cover all possible cases that are needed for a specific board. In this case, we add what is called a 'board quirk' and we have specific code that can be selected in the defconfig.

Step 1: Starting the menuconfig

To start the menuconfig operation, you have to

make menuconfig

You will see a screen similar with the following:

bs41.jpg

Step 2: Selecting the goal of the bootloader

The first thing that one has to choose is the goal of the bootloader.
The goal of the bootloader can be :

  1. Load and launch next software
    This is the most used purpose of a bootloader. The bootloader should initialize the device (the MPU), and the required peripherals to copy the next software stage from non-volatile media (NVM) to the external RAM (DRAM) and then launch the next piece of software.
    In other words, load a software image from external media to RAM then, depending on the type of software, prepare the required boot parameters, and finally jump to the entry point of this software in RAM. Alternatively, if XIP is enabled, execute the software in place.
  2. Launch externally loaded software
    This is a mode that asks the bootloader to only initialize the MPU and have other external tools load the software into memory, and then launch them. It is equivalent with the previous step with the mention of skipping the copy of next software image from NVM to DRAM.
    This is available because in some cases we cannot copy the software from external media to RAM. Then, we can skip copying any software image from external media to RAM. In this mode, we expect the required images and boot parameters to be present in RAM already. For instance they will have been loaded by a debugger via JTAG, or by the SAM-BA boot assistant. Jump directly to the entry point of the software in RAM.
  3. Configure and stop
    This mode is similar with the previous with the difference that the bootloader will no longer copy the next software image and as well do not jump to any address after configuration is done. This mode can be used for debugging, for the user to connect with a hardware probe (JTAG) to take control of the MPU once the bootloader configures the MPU correctly.
    The bootloader will : configure essential peripherals. Do not not load any image. Once the system is configured, trigger a breakpoint, and enter an infinite loop. Wait there until a debugger takes control. Resort to the debugger (attached via JTAG) for taking control and possibly loading/running a software application. In order to load code into DRAM from a debugger, a bootloader is required to configure the clocks, PIOs, and memory correctly. Selecting this option builds a bootstrap image that can be used for this purpose.

bs42.jpg

Step 3: Selecting the device

In this step, one selects the supported MPU device for the configuration.

bs43.jpg

Step 4: Selecting the Clock configuration

In the next step, one can select the clock signals that feeds the MPU, both the main clock and the slow clock. One has to choose the CPU operating frequency and the bus clock frequency of the product. The bootloader will configure the desired frequencies in the initialization sequence.

bs44.jpg

Step 5: Console and debug

In the next menu, one selects the desired console output of the bootloader, and the debug verbosity level, as well as the bootstrap banner.

bs45.jpg

The console is selected with a number, and it's worth mentioning that there is a table in the help menu that explains exactly which console index corresponds to which UART or Flexcom interface of the product, and to which ioset/pinout of the specific interface. For each product, the numbers differ. To see the exact values, press h on the menuconfig interface to check the exact numbers. In the screenshot below an example is visible.

bs46.jpg

Step 6: DRAM configuration

In this step one can configure the DRAM controller and the DRAM timings for the DRAM initialization.

bs47.jpg

There are three different ways to select the possible DRAM configuration that one can choose.

  1. DRAM part number
    This allows one to use the configuration tailored for a specific DRAM chip, selectable by part number (manufacturer and model ).
  2. JEDEC profile
    With this method, one can choose the JEDEC recommended configuration and timings for specific DRAM family , like DDR2, DDR3, etc. These are the failsafe timings recommended by JEDEC and should work with all DRAM parts that are compliant with JEDEC specification.
  3. Customized timings
    This method allows complete custom configuration of all the parameters and timings of the DRAM interface.

bs48.jpg

Step 7: NVM configuration

In this step one has to select the NVM media which stores the next stage software. The next stage binary will be loaded from this NVM and copied into the DRAM.

AT91Bootstrap supports various NVMs like SD-Card, NAND flash, SPI flash, etc.

bs49.jpg

Step 8: Next stage configuration

In this step one has to configure the next stage software. This section includes the offset inside the NVM or the file name inside the NVM file system, and the DRAM address where to copy the data. It also includes other type of software specific configuration (registers before jump, etc).

bs51.jpg

Step 9: Board workaround options

In this step one can configure different board specific quirks and other options that have not been previously determined. For example, configuring the PMIC driver can be done in this menu (voltage setting for different PMIC rails), or which LEDs are present on the board and the pinout to this leds. I2C busses can also be selected here and the specific bus on which different i2c devices are connected to (like the PMIC, HDMI device, i2c EEPROMs, etc.)

bs52.jpg

Step 10: Saving configuration

Once the configuration is completed, save the configuration and exit the menuconfig.
With the following command, one can save the configuration in a minimal text file named defconfig

make savedefconfig
Once this is done, a file named defconfig will be created and this can be added to the configs/ directory and sent as a patch for inclusion in AT91Bootstrap mainline.

Program AT91Bootstrap binary into NVMs

Using SAM-BA to flash AT91Bootstrap to board NVMs

SAM-BA tool can be used to flash the boot.bin binary file on the board, using your Linux or Windows computer and an USB cable.
SAM-BA (SAM Boot Assistant) is a tool you can find on microchip website, and can be used from command line to flash all NVMs on the boards: SPI flashes, eMMCs, NAND flashes, QSPI flashes, etc.
SAM-BA can be used to write to SD-Cards as well, but it's easier to remove the card, mount the first partition as it has a simple FAT file system and copy the boot.bin file directly to the filesystem using your Linux or Windows computer.

Setup PMECC header for different type of board

When ROM code loads AT91Bootstrap from nandflash, it will first check the header to know what kind of Error Correction Code (ECC) the nand flash uses. This is also useful for other nand flash manufacturer parameters. The header is made of 52 times the same 32-bit word, total in 0xd0 bytes, each 32-bit word in made in following format:

pmecc header

For different EK boards, the pmecc header is listed in following:


# sama5d3_xplained
# 4 bit pmecc in 512 byte sector, one page has 4 sectors, spare size: 64, ecc offset: 36
setenv pmecc_header 0xc0902405

# sama5d4 xplained
# 8 bit pmecc in 512 byte sector, one page has 8 sectors, spare size: 224, ecc offset: 120
setenv pmecc_header 0xc1e04e07

The ROM code expects this header written in NAND Flash, before the actual boot.bin file.

AT91Bootstrap has a pmecc header generator that can prepend the boot.bin file with the expected pmecc header. Thus, you can write the boot.bin directly with any tool to the nand flash, once you used this script to prepend the pmecc header.

If you do not have the pmecc header prepended to the binary, it will be automatically prepended to the binary by SAM-BA, when you write the boot.bin using the writeboot command from the nandflash applet.

Using U-Boot to flash AT91Bootstrap

One can use U-boot tools to flash AT91Bootstrap binary to an NVM.

Load AT91Bootstrap binary and setup the 6th vector (offset is 0x14) as the file size

  • Following is U-Boot commands that can flash at91bootstrap to nand flash, by copying it from mmc into DRAM and then into nand flash
    setenv load_addr 22000000                            # load_addr started by pmecc header
    setenv load_addr_bootstrap 220000d0                  # load_addr + 0xd0
    setenv load_addr_bootstrap_vector 220000e4           # load_addr + 0xd0 + 0x14
    
    setenv erase_bootstrap 'nand erase 0 10000'          # erase first 64k nand.
    
    setenv mmc_bootstrap_file 'boot.bin'                 # at91bootstrap file name in mmc card
    setenv load_mmc_bootstrap 'mw.b ${load_addr} 0xff 0x10000; mw.l ${load_addr} ${pmecc_header} 0x34; fatload mmc 0 ${load_addr_bootstrap} ${mmc_bootstrap_file};'
    
    setenv flash_bootstrap_from_mmc 'run erase_bootstrap; run load_mmc_bootstrap; mw.l ${load_addr_bootstrap_vector} ${filesize}; nand write ${load_addr} 0 0x10000;'
    
    setenv tftp_bootstrap_file 'u-boot/boot.bin'         # at91bootstrap file name in tftp server folder
    setenv load_tftp_bootstrap 'mw.b ${load_addr} 0xff 0x10000; mw.l ${load_addr} ${pmecc_header} 0x34;tftp ${load_addr_bootstrap} ${tftp_bootstrap_file};'
    
    setenv flash_bootstrap_from_tftp 'run erase_bootstrap; run load_tftp_bootstrap; mw.l ${load_addr_bootstrap_vector} ${filesize}; nand write ${load_addr} 0 0x10000;'
       

  • Now we can run following commands to programming at91bootstrap to nandflash in U-Boot:
    run flash_bootstrap_from_tftp or run flash_bootstrap_from_mmc

Contributing to AT91Bootstrap

If the system board that you have is not listed, then you will need to port AT91Bootstrap to your hardware platform. To do this, you need to customize your bootstrap as in chapter 5 of this documentation.

Once you are done customizing, you can do

$ make savedefconfig

Then you will have a saved 'defconfig' file that can be placed into configs/ directory, after you rename it according to the rule described in chapter 3.

The configuration file can be send as a patch for review to the github pull-request facility directly.

You should be able to do the above steps without requiring to write any actual C code. However your board may require specific 'board quirks', as some boards do. In this case you will have to implement your quirk into AT91Bootstrap and send this board quirk as a separate patch. Board quirks include for example: resetting of certain devices on the board, reconfiguring specific I/O pins, or blocking the TWI access on some busses.

Maintainers:

Eugen Hristev eugen.hristev at microchip dot com

Nicolas Ferre nicolas.ferre at microchip dot com

Recent FAQ

AT91Bootstrap

SDCard Boot Notice: How to boot up the board from SD card. (Sama5d29Curiosity, Sam9x75Curiosity, Sam9x60Curiosity, Sama5d2-icp, Sam9x60EK, Sama5d27WLSom1EK, Sama5d27Som1EK, Sama5d2PtcEK, Sama5d2Xplained, Sama5d4Xplained, Sama5d4ek, Sama5d3Xplained, Sama5d3xek, AT91sam9x5-ek)
SOM 1 EKe MMCSupport: . (Sama5d27Som1EK)
Audio Clocks On SAM 9 X 60: How to configure PLLA in AT91bootstrap to generate clocks for SAM9X60. (Sam9x60EK)
AT 91 Bootstrap Debug Eclipse: Debug AT91Bootstrap. (Sama5d4Xplained, Sama5d4ek, Sama5d3Xplained, Sama5d3xek)
I Attachment ActionSorted descending Size Date Who Comment
JPEGjpg bs41.jpg manage 77.4 K 2021-08-02 - 08:13 UnknownUser  
JPEGjpg bs42.jpg manage 31.5 K 2021-08-02 - 08:23 UnknownUser  
JPEGjpg bs43.jpg manage 26.8 K 2021-08-02 - 08:33 UnknownUser  
JPEGjpg bs44.jpg manage 31.3 K 2021-08-02 - 08:50 UnknownUser  
JPEGjpg bs45.jpg manage 35.7 K 2021-08-02 - 08:52 UnknownUser  
JPEGjpg bs46.jpg manage 73.1 K 2021-08-02 - 08:56 UnknownUser  
JPEGjpg bs47.jpg manage 36.1 K 2021-08-02 - 11:02 UnknownUser  
JPEGjpg bs48.jpg manage 29.8 K 2021-08-02 - 11:06 UnknownUser  
JPEGjpg bs49.jpg manage 29.2 K 2021-08-02 - 11:48 UnknownUser  
JPEGjpg bs51.jpg manage 33.7 K 2021-08-02 - 12:45 UnknownUser  
JPEGjpg bs52.jpg manage 41.1 K 2021-08-02 - 12:48 UnknownUser  
PNGpng nvm_boot_sequence.png manage 39.8 K 2022-08-17 - 07:41 UnknownUser nvm boot sequence example