Template:ArticleMainWriter Template:ArticleApprovedVersion
1. Introduction[edit source]
The coprocessor firmware can be loaded and started by:
- the second stage boot loader = U-Boot (see Boot_chains_overview for details)
- the Linux® kernel (see Linux_remoteproc_framework_overview for details)
This article explains how this coprocessor firmware is loaded by U-Boot and started before the Linux kernel.
2. Location of the coprocessor firmware[edit source]
Note: the default name for this firmware used in this WIKI is rproc-m4-fw.elf
U-Boot searches and loads the needed binaries in the first bootable partition (generic DISTRO configuration) which is bootfs in the OpenSTLinux distribution (see STM32MP15_Flash_mapping).
So the coprocessor firmware must be installed in that bootfs partition. The simplest way to do this, consists in copying the firmware from the rootfs partition to the bootfs partition as follows:
mount /dev/mmcblk0p4 /boot
cp rproc-m4-fw.elf /boot/
sync
As an alternate method, you can also use the Eclipse IDE, or transfer the firmware over the serial console or over the network.
3. Starting the coprocessor firmware[edit source]
U-Boot can boot the coprocessor before the kernel (coprocessor early boot) with remoteproc uclass :
- Manual start by using rproc commands
- Automatic start, at each boot by using
- the bootcmd (needing U-Boot recompilation)
- a generic DISTRO boot script
- the FIT image
3.1. Manual start[edit source]
You can load and start the coprocessor firmware by using the rproc command in the U-Boot console (to access to the U-boot console: press any key during the U-Boot execution).
rproc
rproc - Control operation of remote processors in an SoC
Usage:
rproc [init|list|load|start|stop|reset|is_running|ping]
Where:
[addr] is a memory address
<id> is a numerical identifier for the remote processor
provided by 'list' command.
Note: Remote processors must be initalized prior to usage
Note: Services are dependent on the driver capability
'list' command shows the capability of each device
Subcommands:
init - Enumerate and initalize the remote processors
list - list available remote processors
load <id> [addr] [size]- Load the remote processor with
image stored at address [addr] in memory
load_rsc <id> [addr] [size]- Load resource table from remote
processor provided image at address [addr]
start <id> - Start the remote processor(must be loaded)
stop <id> - Stop the remote processor
reset <id> - Reset the remote processor
is_running <id> - Reports if the remote processor is running
ping <id> - Ping the remote processor for communication
In this example, the firmware is loaded from SDCARD in RAM (at ${kernel_addr_r}), and then started
-> SDCARD is mmc 0, bootfs is ext4 partition number 4) rproc init -> initializes all coprocessors rproc load 0 ${kernel_addr_r} ${filesize} -> loads firmware for coprocessor 0 (code part found in .elf) rproc load_rsc 0 ${kernel_addr_r} ${filesize} -> loads resource table for coprocessor 0 (found in .elf) rproc start 0 -> starts coprocessor 0ext4load mmc 0:4 ${kernel_addr_r} rproc-m4-fw.elf
You can then resume the normal boot process:
run bootcmd
3.2. Automatic start[edit source]
3.2.1. Start from the bootcmd[edit source]
You can update the bootcmd which is exectued automatically: modify CONFIG_EXTRA_ENV_SETTINGS in include/configs/stm32mp1.h and then recompile U-Boot.
Example : boot a firmware on the SDCARD:
#define CONFIG_EXTRA_ENV_SETTINGS \
"stdin=serial\0" \
"stdout=serial\0" \
"stderr=serial\0" \
...
BOOTENV \
"m4fw_name=rproc-m4-fw.elf\0" \
"m4fw_addr=${kernel_addr_r}\0" \
"boot_m4fw=rproc init; rproc load 0 ${m4fw_addr} ${filesize}; rproc load_rsc 0 ${m4fw_addr} ${filesize}; rproc start 0\0" \
"boot_m4_mmc0=if ext4load mmc 0:4 ${m4fw_addr} ${m4fw_name} ; then run boot_m4fw; fi;\0"
"bootcmd=run boot_m4_mmc0; run bootcmd_mmc0\0"
NB: check STM32MP15_U-Boot for compilation.
3.2.2. Start from a generic DISTRO boot script[edit source]
Without U-boot recompilation, you can also use a DISTRO boot script boot.scr.uimg to automatically load and run the firmware.
For example, use the following script for boot from mmc 0, boot.scr.cmd:
env set m4fw_name "rproc-m4-fw.elf"
env set m4fw_addr ${kernel_addr_r}
#load M4 firmware
if ext4load mmc 0:4 ${m4fw_addr} ${m4fw_name}
then
rproc init
rproc load 0 ${m4fw_addr} ${filesize}
rproc load_rsc 0 ${m4fw_addr} ${filesize}
rproc start 0
fi
#load kernel and device tree
ext4load mmc 0:4 ${kernel_addr_r} uImage
ext4load mmc 0:4 ${fdt_addr_r} ${board_name}.dtb
# start kernel
env set bootargs root=/dev/mmcblk0p6 rootwait rw console=ttySTM0,115200
bootm ${kernel_addr_r} - ${fdt_addr_r}
Then generate associated image using mkimage U-Boot tool:
mkimage -T script -C none -A arm -d boot.scr.cmd boot.scr.uimg
Finally, install boot.scr.uimg in the bootfs partition (following the same procedure used for coprocessor firmware)
sudo cp boot.scr.uimg /media/$USER/bootfs
sync
sudo rm -r /media/$USER/bootfs/extlinux
sync
3.2.3. Start from the FIT image[edit source]
The coprocessor firmware can be also included in the new U-Boot image format = Flattened uImage Tree (FIT) and then this firmware will be loaded automatically when detected by U-Boot.
See chapter 'Coprocessor firmware' in board/st/stm32mp1/README :
- example of '.its' file is provided < U-Boot directory>/board/st/stm32mp1/fit_copro_kernel_dtb.its
- you generate the FIT with U-Boot mkimage tool:
mkimage -f fit_copro_kernel_dtb.its fit_copro_kernel_dtb.itb
You can load the generated FIT with:
- 'bootm' command (see doc/uImage.FIT/command_syntax_extensions.txt )
- extlinux.conf in bootfs in extlinux directory to automatically load the FIT by generic DISTRO,
for example: < U-Boot directory>/board/st/stm32mp1/extlinux.conf
To go deeper:
- doc/README.pxe
- doc/uImage.FIT/howto.txt
- support of firmware in FIT is done in board_stm32copro_image_process() function in board/st/stm32mp1/stm32mp1.c associated to image type IH_TYPE_STM32COPRO.