phyCORE-AM64x

The phyCORE-AM64x is a SoM (System on Module) featuring TI’s AM64x SoC. It can be used in combination with different carrier boards. This module can come with different sizes and models for DDR, eMMC, SPI NOR Flash and various SoCs from the AM64x family.

A development Kit, called phyBOARD-Electra is used as a carrier board reference design around the AM64x SoM.

Quickstart

  • Download sources and TI firmware blobs

  • Build Trusted Firmware-A

  • Build OP-TEE

  • Build U-Boot for the R5

  • Build U-Boot for the A53

  • Create bootable uSD Card

  • Boot

Sources

Note

The TI Firmwares required for functionality of the system are (see platform specific boot diagram for further information as to which component runs on which processor):

  • SYSFW - System firmware - consists of both TIFS and DM both running on the security enclave.

Build procedure

Setup the environment variables:

Generic environment variables

S/w Component

Env Variable

Description

All Software

CC32

Cross compiler for ARMv7 (ARM 32bit), typically arm-linux-gnueabihf-

All Software

CC64

Cross compiler for ARMv8 (ARM 64bit), typically aarch64-linux-gnu-

All Software

LNX_FW_PATH

Path to TI Linux firmware repository

All Software

TFA_PATH

Path to source of Trusted Firmware-A

All Software

OPTEE_PATH

Path to source of OP-TEE

Board specific environment variables

S/w Component

Env Variable

Description

U-Boot

UBOOT_CFG_CORTEXR

Defconfig for Cortex-R (Boot processor).

U-Boot

UBOOT_CFG_CORTEXA

Defconfig for Cortex-A (MPU processor).

Trusted Firmware-A

TFA_BOARD

Platform name used for building TF-A for Cortex-A Processor.

Trusted Firmware-A

TFA_EXTRA_ARGS

Any extra arguments used for building TF-A.

OP-TEE

OPTEE_PLATFORM

Platform name used for building OP-TEE for Cortex-A Processor.

OP-TEE

OPTEE_EXTRA_ARGS

Any extra arguments used for building OP-TEE.

Set the variables corresponding to this platform:

export CC32=arm-linux-gnueabihf-
export CC64=aarch64-linux-gnu-
export LNX_FW_PATH=path/to/ti-linux-firmware
export TFA_PATH=path/to/trusted-firmware-a
export OPTEE_PATH=path/to/optee_os
$ export UBOOT_CFG_CORTEXR=phycore_am64x_r5_defconfig
$ export UBOOT_CFG_CORTEXA=phycore_am64x_a53_defconfig
$ export TFA_BOARD=lite
$ # we don't use any extra TFA parameters
$ unset TFA_EXTRA_ARGS
$ export OPTEE_PLATFORM=k3-am64x
# we don't use any extra OPTEE parameters
unset OPTEE_EXTRA_ARGS
  1. Trusted Firmware-A:

# inside trusted-firmware-a source
make CROSS_COMPILE=$CC64 ARCH=aarch64 PLAT=k3 SPD=opteed $TFA_EXTRA_ARGS \
     TARGET_BOARD=$TFA_BOARD
  1. OP-TEE:

# inside optee_os source
make CROSS_COMPILE=$CC32 CROSS_COMPILE64=$CC64 CFG_ARM64_core=y $OPTEE_EXTRA_ARGS \
      PLATFORM=$OPTEE_PLATFORM
  1. U-Boot:

  • 3.1 R5:

# inside u-boot source
make $UBOOT_CFG_CORTEXR
make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH
  • 3.1.1 Alternative build of R5 for DFU boot:

As the SPL size can get too big when building with support for booting both from local storage and DFU an extra config fragment should be used to enable DFU support (and disable storage support)

export UBOOT_CFG_CORTEXR="${UBOOT_CFG_CORTEXR} am62x_r5_usbdfu.config"
# inside u-boot source
make $UBOOT_CFG_CORTEXR
make CROSS_COMPILE=$CC32 BINMAN_INDIRS=$LNX_FW_PATH
  • 3.2 A53:

# inside u-boot source
make $UBOOT_CFG_CORTEXA
make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \
       BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \
       TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin

Note

It is also possible to pick up a custom DM binary by adding TI_DM argument pointing to the file. If not provided, it defaults to picking up the DM binary from BINMAN_INDIRS. This is only applicable to devices that utilize split firmware.

  • 3.2.1 Alternative build of A53 for Android bootflow:

Since the Android requires many more dependencies, it is disabled by default. An extra config fragment should be used to enable Android bootflow support.

export UBOOT_CFG_CORTEXR="${UBOOT_CFG_CORTEXA} am62x_a53_android.config"
# inside u-boot source
make $UBOOT_CFG_CORTEXA
make CROSS_COMPILE=$CC64 BINMAN_INDIRS=$LNX_FW_PATH \
       BL31=$TFA_PATH/build/k3/$TFA_BOARD/release/bl31.bin \
       TEE=$OPTEE_PATH/out/arm-plat-k3/core/tee-raw.bin

Note

It is also possible to pick up a custom DM binary by adding TI_DM argument pointing to the file. If not provided, it defaults to picking up the DM binary from BINMAN_INDIRS. This is only applicable to devices that utilize split firmware.

uSD Card creation

Use fdisk to partition the uSD card. The layout should look similar to:

$ sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 7.56 GiB, 8120172544 bytes, 15859712 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6583d9a3

Device         Boot  Start     End Sectors   Size Id Type
/dev/mmcblk0p1 *      2048  264191  262144   128M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      264192 1934953 1670762 815.8M 83 Linux

Once partitioned, the boot partition has to be formatted with a FAT filesystem. Assuming the uSD card is /dev/mmcblk0:

$ mkfs.vfat /dev/mmcblk0p1

To boot from a micro SD card on a HSFS device simply copy the following artifacts to the FAT partition:

  • tiboot3.bin from R5 build

  • tispl.bin from Cortex-A build

  • u-boot.img from Cortex-A build

Boot

Put the uSD card in the slot on the board and apply power. Check the serial console for output.

Flash to SPI NOR

Below commands can be used to flash the SPI NOR flash; assuming tiboot3.bin, tispl.bin and u-boot.img are stored on the uSD card.

mtd list
fatload mmc 1 ${loadaddr} tiboot3.bin
mtd write ospi.tiboot3 ${loadaddr} 0 ${filesize}
fatload mmc 1 ${loadaddr} tispl.bin
mtd write ospi.tispl ${loadaddr} 0 ${filesize}
fatload mmc 1 ${loadaddr} u-boot.img
mtd write ospi.u-boot ${loadaddr} 0 ${filesize}

UART based boot

To boot the board via UART, set the switches to UART mode and connect to the micro USB port labeled as “Debug UART”. After power-on the build artifacts needs to be uploaded one by one with a tool like sz.

Example bash script sequence for running on a Linux host PC feeding all boot artifacts needed to the device. Assuming the host uses /dev/ttyUSB0 as the main domain serial port:

stty -F /dev/ttyUSB0 115200
sb --xmodem tiboot3.bin > /dev/ttyUSB0 < /dev/ttyUSB0
# Resend tiboot3.bin a 2nd time due to ErrataID:i2331
sb --xmodem tiboot3.bin > /dev/ttyUSB0 < /dev/ttyUSB0
sb --ymodem tispl.bin > /dev/ttyUSB0 < /dev/ttyUSB0
sb --ymodem u-boot.img > /dev/ttyUSB0 < /dev/ttyUSB0

Boot Modes

The phyCORE-AM64x development kit supports booting from many different interfaces. By default, the development kit is set to boot from the micro-SD card. To change the boot device, DIP switches S5 and S6 can be used. Boot switches should be changed with power off.

Boot Modes

Switch Label

SW3: 12345678

SW4: 12345678

uSD

11000010

01000000

eMMC

11010010

00000000

OSPI

11010000

10000000

UART

11011100

00000000

Environment

Variables Set at Runtime

At runtime the boot environment variable is set to reflect the source from which the board was booted. This ensures that the correct boot path is followed for further system initialization.

Environment Storage Selection

The environment is loaded from a storage location based on the boot device:

  • If booted from eMMC or uSD card, the environment is retrieved from FAT or a fixed offset if configured.

  • If booted from SPI, the environment is retrieved from SPI flash if enabled.

For all other boot devices, the environment is not stored persistently (ENVL_NOWHERE).

Saving the Environment

The saveenv command will store the environment on the same device the board was booted from, ensuring consistency between boot sources and stored configurations.

Capsule Updates

Capsules for each of these binaries are automatically generated as part of the build process and are named <binary>-capsule.bin. For example, the capsule for u-boot.img is named uboot-capsule.bin.

Performing an Update

Each board has a dynamically generated GUID. To retrieve it, run:

efidebug capsule esrt

To update the firmware, follow these steps on the board. Ensure the capsule binaries are available on a uSD card.

load mmc 1:1 $loadaddr tiboot3-capsule.bin
efidebug capsule update $loadaddr

load mmc 1:1 $loadaddr tispl-capsule.bin
efidebug capsule update $loadaddr

load mmc 1:1 $loadaddr uboot-capsule.bin
efidebug capsule update $loadaddr

These commands load the capsule binaries into memory and trigger the EFI capsule update process.

Important Notes

The updates are applied to the boot device from which the board is currently running. For eMMC, updates are always applied to the first boot partition. Capsule updates can be performed on eMMC, OSPI NOR, or a uSD card, depending on the boot device. For any additional configuration or troubleshooting, refer to Enabling UEFI Capsule Update feature.

Further Information

Please see AM64 Platforms chapter for further AM64 SoC related documentation and https://docs.phytec.com/projects/yocto-phycore-am64x/en/latest/ for vendor documentation.