Home ·

- Getting started with SAM-BA on SAMA5D2 devices

# Getting started with SAM-BA on SAMA5D2 devices

## Connecting to the SAM-BA monitor

For USB connection, the host running sam-ba should be connected to the USB device port of the SAMA5D2 board design. on SAMA5D2-Xplained boards, this port is labeled A5-USB-A (J23).

The USB device port must not be confused with other USB connectors such as EDBG-USB (J14).

## Predefined boards and customer board designs

The sam-ba program comes with predefined sama5d2-xplained, sama5d2-ptc-ek and sama5d27-som1-ek boards that set default values for different settings such as the applet console or memory controller instances and iosets.

Those predefined boards can be selected wit the -b sama5d2-xplained, -b sama5d2-ptc-ek or -b sama5d27-som1-ek options on the sam-ba command line.

However the -d sama5d2 option should be used instead on customer board designs not to load any default settings. Instead, additionnal parameters may be passed to the -d sama5d2:<console_instance>:<console_ioset> option to select the applet console. The applet console, when enabled, is used by any applet to print its traces.

Also, default memory controller settings, if any, can be overridden too, passing additionnal arguments to the -a <applet> option for the applet managing the memory controller.

## Supported applets

The list of supported applets can be displayed with the following command:

    $ sam-ba -p serial -d sama5d2 -a help
    Known applets: bootconfig, lowlevel, extram, serialflash, qspiflash, nandflash, sdmmc, internalrc, reset, readuniqueid

Applet | Short description | Examples
--- | --- | ---
bootconfig | Manage boot configuration of the device, select boot media | Programming a Boot Configuration word
extram | Initialize the external RAM (not needed by any other applets) |
internalrc | MUST be called once per boot before programming any fuse in SFC_DR[] registers of the Secure Flash Controller (SFC) |
lowlevel | Setup the clock tree (only needed by the extram applet) |
nandflash | Manage raw NAND flash memories connected to the EBI and driven by the SMC | Programming a raw NAND flash
pairingmode | Translate a bootstrap master image into a bootstrap paired image |
qspiflash | Manage (Q)SPI NOR flash memories connected to the QSPI controller | Programming a QSPI NOR flash
readuniqueid | Read the device unique ID |
reset | Reset the target device |
sdmmc | Manage e.MMC and SD Cards connected to some SDMMC instance | Programming a SD Card or e.MMC
serialflash | Manage (Q)SPI NOR flash memories connected to some FLEXCOM SPI instance | Programming a SPI NOR flash

## Boot Configuration

The ROM code of SAMA5D2 devices is the 1st stage boot loader responsible for the system boot. Hence, the ROM code fetches the Boot Configuration word in order to get boot settings such as the ROM code console and the active controllers in the NVM boot sequence.

### Boot Configuration word

On power-on or reset, the ROM code first reads the SFC_DR[16] register of the Secure Flash Controller (SFC) and tests its BSCR_DISABLE bit (bit 22).

This fuse bit is 0 on factory defaults.

If the BSCR_DISABLE bit is set, then the value of the SFC_DR[16] register is used as the Boot Configuration word.

Otherwise, the ROM code samples the value of the BSCR register on power-on or reset. If the VALID bit (bit 2) is set in the sample value, then BSCR[1:0] bits selects which BUREGx register is used by the ROM code to load its Boot Configuration word.

During developments and tests, we recommend the user to configure the BSCR register in order to program the Boot Configuration word into some BUREGx. Indeed, BUREGx registers can be written and updated any number of times, whereas the SFC_DR[16] register is stored in fuses, hence bits set to 1 cannot be reset to 0.

The bootconfig applet provides the user with helper commands to manage the Boot Configuration word and its storage in a SAMA5D2 device.

As BUREGx registers are powered by VDDBBU, hence backed up, their values are kept after reset. However, those registers remain ignored by the ROM code unless the proper value is written into the BSCR register, for intance by executing the writecfg:bscr:buregX,valid command:

    $ sam-ba -p serial -d sama5d2 -a bootconfig -c writecfg:bscr:bureg0,valid

Also the user can check whether the ROM code is configured to fetch its Boot Configuration word from any BUREGx register by reading back the BSCR register with the readcfg:bscr command:

    $ sam-ba -p serial -d sama5d2 -a bootconfig -c readcfg:bscr

WARNING: New values or register selections for the Boot Configuration word are not taken into account by non-secure or secure SAM-BA monitors until the next power-on or reset!

### ROM Code console

The Boot Configuration word tells the ROM code which RS-232 UART is to be used for the console. For instance, the "RomBOOT" string is always printed on power-on or reset on this console. Also, the ROM code console is used by SAM-BA monitors to communicate with the sam-ba program when USB is not available.

On SAMA5D2, the default ROM code console is UART1 but it can be set to another U(S)ART. Please note that the ROM code console may be different from the applet console

### NVM boot sequence

The Non-Volatile Memory (NVM) boot sequence selects the controllers mananing external NVM where the ROM code tries to load the user applicaiton (or 2nd stage boot loader) from.

On SAMA5D2, boot sequence is:

Position | Controller | Memory type | Selected by default
--- | --- | --- | ---
1 | SDMMC1 | e.MMC or SD Card | yes (ioset 1)
2 | SDMMC0 | e.MMC or SD Card | yes (ioset 1)
3 | NFC | raw NAND flash | no
4 | SPI0 (chip-select 0) | SPI NOR flash (AT25/M25P compatible) | no
5 | SPI1 (chip-select 0) | SPI NOR flash (AT25/M25P compatible) | no
6 | QSPI0 | QSPI NOR flash (JESD216B comtabible) | no
7 | QSPI1 | QSPI NOR flash (JESD216B compatible) | no

All the possible values for the memory interfaces and IOsets for SAMA5D2 devices can be obtained by

    $ sam-ba -p serial -d sama5d2 -t 5 -a bootconfig -c help

### Programming a Boot Configuration word

The user can program his first Boot Configuration word with the writecfg:fuse / writecfg:buregx command:

WARNING: Before executing any writecfg:fuse command, the user MUST execute the internalrc applet once per boot.

    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a internalrc
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a bootconfig -c writecfg:fuse:QSPI0_IOSET3,EXT_MEM_BOOT

or

    $ sam-ba -p serial -b sama5d27-som1-ek -t 5 -a bootconfig -c writecfg:bureg0:SDMMC1_IOSET1,QSPI1_IOSET2,EXT_MEM_BOOT

In both examples, UART1 is implicitly chosen as the ROM code console and the boot from external memories is enabled too by the EXT_MEM_BOOT token.

Then the 1st example selects QSPI0 ioset3 on a SAMA5D2 Xplained board as the only boot medium in the boot sequence whereas the 2nd example selects SDMMC1 ioset1 and QSPI1 ioset2 on a SAMA5D2 SOM1 EK board as boot media.

### Reading back the Boot Configuration word

The Boot Configuration word can be read-back from SFC_DR[16] or BUREGx registers with the readcfg:fuse / readcfg:buregx command:

    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a bootconfig -c readcfg:fuse

or

    $ sam-ba -p serial -b sama5d27-som1-ek -t 5 -a bootconfig -c readcfg:bureg0

## Programming a QSPI NOR flash

In the following example, we program the at91bootstrap.bin, u-boot.bin, zImage and at91-sama5d2_xplained.dtb files into the embedded QSPI NOR flash of the SAMA5D2 Xplained board:

    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a qspiflash -c erase
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a qspiflash -c writeboot:at91bootstrap.bin -c verifyboot:at91bootstrap.bin
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a qspiflash -c write:u-boot.bin:0x00040000 -c verify:u-boot.bin:0x00040000
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a qspiflash -c write:at91-sama5d2_xplained.dtb:0x00180000 -c verify:at91-sama5d2_xplained.dtb:0x00180000
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a qspiflash -c write:zImage:0x00200000 -c verify:zImage:0x00200000

Most QSPI NOR flash memories are too small to store the Linux root file-system; this should be programmed into another NVM.

If the QSPI NOR flash memory is connected to a custom board design, then additional parameters should be passed to the -a qspiflash option in above examples.

The list of those parameters is given by the command:

    $ sam-ba -p serial -d sama5d2 -a qspiflash:help
    Syntax: qspiflash:[<instance>]:[<ioset>]:[<frequency>]
    Parameters:
        instance   QSPI controller instance
        ioset      QSPI I/O set
        frequency  QSPI clock frequency in MHz
    Examples:
        qspiflash         use default board settings
        qspiflash:0:3:66  use fully custom settings (QSPI0, IOSET3, 66Mhz)
        qspiflash:::20    use default board settings but force frequency to 20Mhz

Supported <instance> and <ioset> for QSPI on SAMA5D2 devices are listed here.

## Programming a SPI NOR flash

In the following example, we program the at91bootstrap.bin, u-boot.bin, zImage and at91-sama5d2-xplained.dtb files into the embedded SPI NOR flash of the SAMA5D2 Xplained board:

    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a serialflash -c erase
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a serialflash -c writeboot:at91bootstrap.bin -c verifyboot:at91bootstrap.bin
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a serialflash -c write:u-boot.bin:0x00008000 -c verify:u-boot.bin:0x00008000
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a serialflash -c write:at91-sama5d2-xplained.dtb:0x00060000 -c verify:at91-sama5d2-xplained.dtb:0x00060000
    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a serialflash -c write:zImage:0x0006c000 -c verify:zImage:0x0006c000

SPI NOR flashes are likely to be too small to store the Linux root file-system; this should be programmed into another NVM.

If the SPI NOR flash memory is connected to a custom board design, then additional parameters should be passed to the -a serialflash option in above examples.

The list of those parameters is given by the command:

    $ sam-ba -p serial -d sama5d2 -a serialflash:help
    Syntax: serialflash:[<instance>]:[<ioset>]:[<npcs>]:[<frequency>]
    Parameters:
        instance   SPI controller instance
        ioset      I/O set
        npcs       SPI chip select number
        frequency  SPI clock frequency in MHz
    Examples:
        serialflash           use default board settings
        serialflash:0:1:0:66  use fully custom settings (SPI0, IOSET1, NPCS0, 66Mhz)
        serialflash::::20     use default board settings but force frequency to 20Mhz

Supported <instance>, <ioset> and <npcs> for SPI on SAMA5D2 devices are listed here.

## Programming a SDCard or e.MMC user partition

In the following example, the sdcard.img file is a raw image of a SD Card, hence starting with a Master Boot Record (MBR) containing a valid partition table. The first partition is formatted with a FAT32 file-system, which gathers four files in its root directory:

- a boot.bin file: the at91bootstrap.bin file renammed into boot.bin
- a u-boot.bin file: the u-boot binary image, loaded then executed by boot.bin
- a zImage file: the compressed image of a Linux kernel, loaded then executed by u-boot
- a at91-sama5d2-xplained.dtb: the device-tree binary for the Linux kernel, loaded by u-boot at the same time as the zImage file

The second partition is formatted in EXT4 and contains the root file-system used by the Linux kernel

    $ sam-ba -p serial -b sama5d2-xplained -t 5 -a sdmmc -c write:sdcard.img

If the SD Card or e.MMC memory is connected to a customer board design, then additional parameters should be passed to the -a sdmmc option in above examples.

The list of those parameters is given by the command:

    $ sam-ba -p serial -d sama5d2 -a sdmmc:help
    Syntax: sdmmc:[<instance>]:[<ioset>]:[<partition>]:[<bus_width>]:[<voltages>]
    Parameters:
        instance   SDMMC controller number
        ioset      SDMMC I/O set
        partition  Partition number (0=user partition, x>0=boot partition x)
        bus_width  Data bus width (0=controller max, 1=1-bit, 4=4-bit, 8=8-bit)
        voltages   Supported voltages (bitfield: 1=1.8V, 2=3.0V, 4=3.3V)
    Examples:
        sdmmc           use default board settings
        sdmmc:0:1:1:8:5 use fully custom settings (SDMMC0, IOSET1, first boot partition, 8-bit, 1.8V/3.3V)
        sdmmc:0::1      use default board settings but force use of SDMMC0, first boot partition

Supported <instance> and <ioset> for SDMMC on SAMA5D2 devices are listed here.

## Programming a raw NAND flash

In the following example, we program the at91bootstrap.bin, u-boot.bin, zImage, at91-sama5d2-ptc-ek.dtb and rootfs.ubi files into the embedded NAND flash of a SAMA5D2-PTC-EK board:

    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c erase
    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c writeboot:at91bootstrap.bin -c verifyboot:at91bootstrap.bin
    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c write:u-boot.bin:0x00040000 -c verify:u-boot.bin:0x00040000
    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c write:at91-sama5d2-ptc-ek.dtb:0x00180000 -c verify:at91-sama5d2-ptc-ek.dtb:0x00180000
    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c write:zImage:0x00200000 -c verify:zImage:0x00200000
    $ sam-ba -p serial -b sama5d2-ptc-ek -t 5 -a nandflash -c write:rootfs.ubi:0x00800000 -c verify:rootfs.ubi:0x00800000

If the raw NAND flash is connected to a custom board design, then additional parameters should be passed to the -a nandflash option in above examples.

The list of those parameters is given by the command:

    $ sam-ba -p serial -d sama5d2 -a nandflash:help
    Syntax: nandflash:[<ioset>]:[<bus_width>]:[<header>]
    Parameters:
        ioset      I/O set
        bus_width  NAND bus width (8/16)
        header     NAND header value
    Examples:
        nandflash                 use default board settings
        nandflash:2:8:0xc0098da5  use fully custom settings (IOSET2, 8-bit bus, header is 0xc0098da5)
        nandflash:::0xc0098da5    use default board settings but force header to 0xc0098da5
    For information on NAND header values, please refer to SAMA5D2 datasheet section "16.4.7.1 NAND Flash Boot: NAND Flash Detection".

Supported <ioset> for the NAND flash on SAMA5D2 devices are listed here.

## Secure Boot Mode

First step to benefit from secure boot features of SAMA5D2 devices is to enable this secure boot mode by setting the SECURE_MODE bit in the Boot Configuration word.

For instance, if the Boot Configuration word is storing in the BUREG0 register and QSPI0 ioset3 is the only boot medium, then the sam-ba command is:

    $ sam-ba -p serial -d sama5d2 -a bootconfig -c writecfg:bscr:bureg0,valid -c writecfg:bureg0:SECURE_MODE,QSPI0_IOSET3

On the other hand, if the Boot Configuration word is stored in the SFC_DR[16] register (fuses), still with QSPI0 ioset3 as the only boot medium, then the sam-ba command becomes:

    $ sam-ba -p serial -d sama5d2 -a internalrc
    $ sam-ba -p serial -d sama5d2 -a bootconfig -c writecfg:bscr:0 -c writecfg:fuse:SECURE_MODE,QSPI0_IOSET3

Once the SECURE_MODE bit has been set into the Boot Configuration word, the device must be reset so the ROM code executes its secure SAM-BA monitor:

    $ sam-ba -p serial -d sama5d2 -a reset

From this point, the ROM code no longer executes its non-secure SAM-BA monitor but instead runs its secure SAM-BA monitor. Hence, the serial or j-link ports cannot be used; the secure port must be used instead.

Once in the secure SAM-BA monitor, some built-in commands update bits or bit-fields in the Boot Configuration word to enable or disable associated secure-boot features.

Built-in Command | Updated bits or bit-fields of the Boot Configuration word
--- | ---
enable_boot_from_ext_memory | EXT_MEM_BOOT
disable_monitor | DISABLE_MONITOR
store_keys_in_fuses | KEYS_IN_FUSES
write_customer_key | KEYS_WRITTEN
write_full_customer_key | KEYS_WRITTEN, EXPAND_MODE_FULL
write_rsa_hash | SIGN_MODE_RSA
enable_pairing | EXPAND_MODE_UID

Other built-in commands always update bits or bit-fields in the SFC_DR[16] register, even if the Boot Configuration word is stored in some BUREGx register.

Built-in Command | Updated bits or bit-fields of the SFC_DR[16] register
--- | ---
disable_bscr | DISABLE_BSCR
disable_jtag | DISABLE_JTAG
set_secure_debug | SECURE_DEBUG

WARNING: Before running any built-in command that may program fuses through any SFC_DR[] registers, the user MUST execute the internalrc applet once per boot.

### Storing keys in either SECURAM or fuses

The user must decide whether customer keys, and the RSA hash if RSA signature is selected, should be stored either in:

- SECURAM, so they can be reprogrammed if needed.
- fuses (accessed through SFC_DR[] registers), once for all.

By default, the KEYS_IN_FUSES bit is 0 in the Boot Configuration word, hence customer keys and RSA hash are stored in SECURAM.

However, if customer keys and RSA hash must be stored into fuses, then the user must set the KEYS_IN_FUSES bit in the Boot Configuration word before programming the customer keys or the RSA hash.

This should not be done with the writecfg command but should be done with the following sam-ba command instead:

    $ sam-ba -p secure -d sama5d2 -m store_keys_in_fuses

### Programming the Customer Keys

Then, another mandatory step is to program the customer key into the device. This customer key is wrapped into a ciphered and signed customer key message.

This so called customer key message is actually generated from the 256-bit or 384-bit customer key by the secure-sam-ba-cipher.py tool. This tool is distributed under NDA, hence not covered by this documentation.

As stated, the customer key message is ciphered to protect the customer key from eavesdropping during device provisioning in factory and is also signed so the customer key message can be authenticated by the ROM code. Only the secure-sam-ba-cipher.py tool with a license provided by Microchip can generate genuine customer key messages.

Assumming the customer key message is packaged inside a customer-key.cip file, programming the customer key into the SAMA5D2 device must be done by sam-ba with one of those commands:

WARNING: Before programming the Customer Keys, be sure to select the proper storage area.

Customer Key size | sam-ba command
--- | ---
256 bits |
    $ sam-ba -p secure -d sama5d2 -m write_customer_key:customer-key.cip
384 bits |
    $ sam-ba -p secure -d sama5d2 -m write_full_customer_key:customer-key.cip
The Full Customer Key is not compatible with neither RSA signature nor pairing mode

At this point and on further resets, the ROM code expects the bootstrap or user application stored into the external NVM to be both ciphered with AES-256-CBC and signed with AES-256-CMAC.

### Selecting RSA signatures

Optionally, the shared key signature algorithm can be replaced by a public key algorithm. More precisely, the AES-256-CMAC signature is replaced by a RSA signature that will be verified by the ROM code at each boot to authenticate the bootstrap or user application.

Indeed, a chain of X.509 version 3 certificates in DER format is concatenated to the bootstrap and its RSA signature.

The first certicate in this chain is called the root certificate and must be a self-signed certificate.

Besides, except the root certificate, each certificate in the chain is signed, hence authenticated, by the previous certificate in the chain. So the root certificate, more precisely its public key, is the root of trust since it, directly or indirectly, authenticates all certificates in the chain.

The secure-sam-ba-cipher.py tool can compute a SHA-256 digest of the public key of the root certificate. Like the customer key with the customer key message, this digest is wrapped into a ciphered and signed message called the RSA hash message.

The generation of the RSA hash message by secure-sam-ba-ciher.py is not covered by this documentation.

Then, assuming the SHA-256 digest of the public key of the X.509 root certificate is packaged inside a root-cert-hash.cip file, programming the digest into the SAMA5D2 device must be done by sam-ba with the following command:

WARNING: Before programming the SHA-256 digest of the public key, be sure to select the proper storage area.

    $ sam-ba -p secure -d sama5d2 -m write_rsa_hash:root-cert-hash.cip

After that and for each boot, the ROM code still deciphers the bootstrap or the user application with the AES-256-CBC algorithm using the same shared key as before but no longer authenticates it with an AES-256-CMAC signature.

Instead, it computes the SHA-256 digest of the public key of the root certificate with the same algorithm used by the secure-sam-ba-cipher.py tool. Then, the ROM code authenticates the root certificate by comparing the computed digest with the one that has been programmed into the SFC_DR[] registers or SECURAM with the write_rsa_hash command.

If both digests match then the root certificate is authenticated by the ROM code. Next, the ROM code authenticates each X.509 certificate of the chain by verifying its signature with the public key of the previous X.509 certificate in the chain.

Finally, when all X.509 certificates in the chain have been authenticated, the ROM code uses the public key stored into the last certificate of the chain to verify the RSA signature of the bootstrap or user application stored in NVM.

To speed-up the boot process, the X.509 certificate chain can be limited to a single X.509 self-signed certificate. In such case, this certificate is both the root certificate and the certificate used to authenticate the bootstrap or user application.

Both 2048 and 4096-bit RSA signatures are supported by the SAMA5D2 devices.

### Enabling the boot from external NVM

Once customer keys, and the RSA hash if needed, has been programmed in the SAMA5D2 device, the user should set the EXT_MEM_BOOT bit in the Boot Configuration word, if not done yet:

    $ sam-ba -p secure -d sama5d2 -m enable_boot_from_ext_memory

### Disabling the secure SAM-BA monitor

The user can also disable the secure SAM-BA monitor by setting the DISABLE_MONITOR bit in the Boot Configuration word.

This bit is not taken into account by the ROM code until the next power-on or reset.

    $ sam-ba -p secure -d sama5d2 -m disable_monitor

### Persistently disabling the BUREGx registers

The DISABLE_BSCR bit (bit 22) of the SFC_DR[16] register requires the ROM code to ignore the BSCR register, hence any Boot Configuration word value that could have been written into any BUREGx register. Indeed, setting this bit forces the ROM code to fetch its Boot Configuration word from the SFC_DR[16] register only:

    $ sam-ba -p secure -d sama5d2 -m disable_bscr

### Persistently disabling the JTAG port

The DISABLE_JTAG bit (bit 31) of the SFC_DR[16] register disables the JTAG port once for all. Indeed, this fuse controls the hardware lock of the JTAG port.

    $ sam-ba -p secure -d sama5d2 -m disable_jtag

### Setting the SECURE_DEBUG bit

The SECURE_DEBUG bit (bit 30) of the SFC_DR[16 register can be set with the following command:

    $ sam-ba -p secure -d sama5d2 -m set_secure_debug

### Enabling the pairing mode

The pairing mode enhances the secure boot mode with an anti-cloning protection for the target device.

The user can enable this mode by setting the value EXPAND_MODE_UID to the EXPAND_MODE bit-field in the Boot Configuration word with the following command:

    $ sam-ba -p secure -d sama5d2 -m enable_pairing