Difference between revisions of "How to cross-compile with the Distribution Package"

[quality revision] [quality revision]
imported>Cayale
(Modifying the Linux kernel device tree)
m (Modifying the U-Boot)
 

Template:ArticleMainWriter Template:ArticleApprovedVersion

Applicable for STM32MP13x lines, STM32MP15x lines

1 Article purpose[edit]

This article provides simple examples for the Distribution Package of the OpenSTLinux distribution, that illustrate the cross-compilation with the devtool and BitBake tools:

  • modification with Linux® Kernel (configuration, device tree, driver, ...)
  • modification of an external in-tree Linux Kernel module
  • modification of U-Boot
  • modification of TF-A
  • addition of software

These examples also show how to deploy the results of the cross-compilation on the target, through a network connection to the host machine.


Info white.png Information
All the examples described on this page use devtool and/or bitbake from OpenEmbededded, see OpenEmbedded - devtool and BitBake cheat sheet for more information.
Info white.png Information
There are many ways to achieve the same result; this article aims to provide at least one solution per example. You have the liberty to explore other methods that are better adapted to your development constraints.

2 Prerequisites[edit]

The prerequisites from Installing the OpenSTLinux distribution must be executed.

The board and the host machine are connected through an Ethernet link, and a remote terminal program is started on the host machine: see How to get Terminal.

The target is started, and its IP address (<board ip address>) is known.

3 Modification with kernel[edit]

3.1 Preamble[edit]

To start modification with a module, you need to initialize your Distribution Package environment.

 cd <working directory path of distribution>
 DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh

You are now in the build directory, identified by <build dir> in the following paragraphs.

Initialize devtool for kernel component:

 devtool modify virtual/kernel
NOTE: Starting bitbake server...
NOTE: Creating workspace layer in /mnt/internal_storage/oetest/oe_openstlinux_rockokirkstone/build-openstlinuxweston-stm32mp1/workspace
NOTE: Enabling workspace layer in bblayers.conf
Parsing recipes: 100% |########################################################################################| Time: 0:00:54
Parsing of 2401 .bb files complete (0 cached, 2401 parsed). 3282 targets, 88 skipped, 0 masked, 0 errors.
NOTE: Mapping virtual/kernel to linux-stm32mp
NOTE: Resolving any missing task queue dependencies
...
Info white.png Information
For the case of virtual/<something> component, you need to get the name of mapping between virtual component and associated recipe. In this example, the name of kernel recipe is indicated in the trace, but you can also get it by calling devtool status

A minority of devtool command supports the virtual/<something> component, like devtool modify, it is why you need to get the recipe name associated to virtual/component.
In this example, the name of kernel recipe is indicated in the trace (linux-stm32mp)

Info white.png Information
The source code of kernel is located on <build dir>/workspace/sources. You can change the path where the source code is extracted by customizing the devtool modify command
Info white.png Information
For all the work around the kernel, we strongly encourage some usage for deploying the binaries on board

The difference of usage comes from the number of files to deploy on board. When there is only one or two files to put on board, the easiest way to do it is to deploy only the desired files .

3.2 Modifying kernel configuration[edit]

This simple example modifies the kernel configuration via menuconfig for the CMA size.

  • Get the current value of the CMA size (128 Mbytes here) through the analysis of the target boot log
 dmesg | grep -i cma
[    0.000000] cma: Reserved 128 MiB at 0xf0000000
  • Navigate to "Device Drivers - Generic Driver OptionsLibrary routines"
    • select "Size in Megabytes"
    • modify its value to 256
    • exit and save the new configuration
  • Check that the configuration file (.config) has been modified
 grep -i CONFIG_CMA_SIZE_MBYTES <build dir>/workspace/sources/<name of kernel recipe>/.config.new
CONFIG_CMA_SIZE_MBYTES=256
  • Get the new value of the CMA size (256 Mbytes) through the analysis of the target boot log
 dmesg | grep -i cma
[    0.000000] cma: Reserved 256 MiB at 0xe0000000

3.3 Modifying the Linux kernel device tree[edit]

Info white.png Information
The example given below is associated with the STM32MP15 Evaluation board, but the method is independent of the board.

This simple example modifies the default status of a user LED.

  • With the board started; check that the user LED (LD3) is disabled
  • Go to the <build dir>/workspace/sources/<name of kernel recipe>/ directory
 cd <build dir>/workspace/sources/<name of kernel recipe>/
  • Edit the arch/arm/boot/dts/stm32mp157cstm32mp15xx-ed1edx.dtsdtsi Device Tree Source file for evaluation board or

Edit the arch/arm/boot/dts/stm32mp157cstm32mp15xx-dk2dkx.dtsdtsi" Device Tree Source file for discovery board or

Change

  • modify led node for adding green ledChange the status of the "stm32mp:green:user" led to "okay", and set its default state to "on"
	led {
		compatible = "gpio-leds";

		status = "okay";
		red led-blue {
			label = "stm32mp:red:statusheartbeat";
			gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;

			status......>;
			linux,default-trigger = "heartbeat";
			default-state = "disabledoff";
		

};

		
led-green {
			label = "stm32mp:green:user";
			gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
			default-state = "on";

			status = "okay";
		};
	};
  • Go to the <build directory>build directory
 cd <build directory>dir>

  • Generate the device tree blobs (*.dtb)
 bitbake <name of recipe> virtual/kernel -C compile
Info white.png Information
we use here bitbake command instead of devtool build because the build makes compile, compile_kernemodules and install commands whereas we only need only compile command to generate the kernel image and the device tree
  • Update the device tree blobs on the board
 scp <build dir>/tmp-glibc/deploy/images/<machine name>/*.dtb root@<board ip address>:/boot
Info white.png Information
If the /boot mounting point doesn't exist yet, please see how to create a mounting point
  • Reboot the board
 cd /boot; sync; systemctl reboot
  • Check that the user LED (LD3) is enabled (green)

3.4 Modifying a built-in Linux kernel device driver[edit]

This simple example adds unconditional log information when the display driver is probed.

  • Check that there is no log information when the display driver is probed
 dmesg | grep -i stm_drm_platform_probe


  • Go to the <build dir>/workspace/sources/<name of kernel recipe>/
 cd <build dir>/workspace/sources/<name of kernel recipe>/
  • Edit the ./drivers/gpu/drm/stm/drv.c source file
  • Add a log information in the stm_drm_platform_probe function
static int stm_drm_platform_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct drm_device *ddev;
	int ret;
	[...]

	DRM_INFO("Simple example - %s\n", __func__);

	return 0;
	[...]
}
  • Go to the <build directory>build directory
 cd <build directory>dir>

  • Cross-compile the Linux kernel
 bitbake <name of recipe> virtual/kernel -C compile
  • Update the Linux kernel image on board
 scp <build dir>/tmp-glibc/deploy/images/<machine name>/kernel/uImage root@<board ip address>:/boot
Info white.png Information
If the /boot mounting point doesn't exist yet, please see how to create a mounting point


  • Reboot the board
 cd /boot; sync; systemctl reboot
  • Check that there is now log information when the display driver is probed
 dmesg | grep -i stm_drm_platform_probe
[    5.005833] [drm] Simple example - stm_drm_platform_probe

3.5 Modifying/adding an external Linux kernel module[edit]

Most device drivers (modules) in the Linux kernel can be compiled either into the kernel itself (built-in/internal module) or as Loadable Kernel Modules (LKM/external module) that need to be placed in the root file system under the /lib/modules directory. An external module can be in-tree (in the kernel tree structure), or out-of-tree (outside the kernel tree structure).

This simple example adds an unconditional log information when the virtual video test driver (vivid) kernel module is probed or removed.

  • Go to the <build dir>/workspace/sources/<name of kernel recipe>/
 cd <build dir>/workspace/sources/<name of kernel recipe>/
  • Edit the ./drivers/media/platform/vivid/vivid-core.c source file
  • Add log information in the vivid_probe and vivid_remove functions
static int vivid_probe(struct platform_device *pdev)
{
	const struct font_desc *font = find_font("VGA8x16");
	int ret = 0, i;
	[...]

	/* n_devs will reflect the actual number of allocated devices */
	n_devs = i;

	pr_info("Simple example - %s\n", __func__);

	return ret;
}
static int vivid_remove(struct platform_device *pdev)
{
	struct vivid_dev *dev;
	unsigned int i, j;
	[...]

	pr_info("Simple example - %s\n", __func__);

	return 0;
}
  • Go to the <build directory>build directory
 cd <build directory>dir>


  • Cross-compile the Linux kernel modules
 bitbake <name of recipe> virtual/kernel -C compile
  • Update the vivid kernel module on the board
 devtool deploy-target -Ss <name of kernel recipe> root@<board ip address>:/home/root
 ssh root@<board ip address> cp -afr /home/root/lib/modules/* /lib/modules/
 ssh root@<board ip address> cp -f /home/root/boot/uImage /boot/
 ssh root@<board ip address> cp -f /home/root/boot/*.dtb /boot/
 ssh root@<board ip address> rm -rf /home/root/lib/ /home/root/etc /home/root/boot

Info white.png Information
due to the multiple mount points Take care to have enought place available on board and space associated to this mount point, it's not possible to push directly the binaries on the final location on board, but we can pass by a temporary space (here /home/root/) to receive the binaries deployed via deploy-target command.

The binaries (mainly kernel modules) are not stripped on deploy-target command and take a lot of place.

  • Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
 /sbin/depmod -a
 sync
  • Insert the vivid kernel module into the Linux kernel
 modprobe vivid                   
[...]
[ 3412.784638] Simple example - vivid_probe
  • Remove the vivid kernel module from the Linux kernel
 rmmod vivid
[...]
[ 3423.708517] Simple example - vivid_remove

4 Adding an external out-of-tree Linux kernel module[edit]

This simple example adds a "Hello World" external out-of-tree Linux kernel module to the Linux kernel.

  • Create a directory for this kernel module example
 mkdir kernel_module_example
 cd kernel_module_example
  • Create the source code file for this kernel module example: kernel_module_example.c
// SPDX-identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2018
 *
 * Authors: Jean-Christophe Trotin <jean-christophe.trotin@st.com>
 *
 */

#include <linux/module.h>    /* for all kernel modules */
#include <linux/kernel.h>    /* for KERN_INFO */
#include <linux/init.h>      /* for __init and __exit macros */

static int __init kernel_module_example_init(void)
{
	printk(KERN_INFO "Kernel module example: hello world from STMicroelectronics\n");
	return 0;
}

static void __exit kernel_module_example_exit(void)
{
	printk(KERN_INFO "Kernel module example: goodbye from STMicroelectronics\n");
}

module_init(kernel_module_example_init);
module_exit(kernel_module_example_exit);

MODULE_DESCRIPTION("STMicroelectronics simple external out-of-tree Linux kernel module example");
MODULE_AUTHOR("Jean-Christophe Trotin <jean-christophe.trotin@st.com>");
MODULE_LICENSE("GPL v2");

  • Create the makefile for this kernel module example: Makefile
Info white.png Information
All the indentations in a makefile are tabulations
# Makefile for simple external out-of-tree Linux kernel module example

# Object file(s) to be built
obj-m := kernel_module_example.o

# Path to the directory that contains the Linux kernel source code
# and the configuration file (.config)
KERNEL_DIR ?= <Linux kernel path>

# Path to the directory that contains the source file(s) to compile
PWD := $(shell pwd) 
  
default:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
  • Add a new recipe to the workspace
 cd <build directory>dir>
 devtool add mymodule kernel_module_example/
  • Adapt recipe to kernel module build
 devtool edit-recipe mymodule
Modify the recipe according the following changes (see highlighted lines)
 1 # Recipe created by recipetool
 2 # This is the basis of a recipe and may need further editing in order to be fully functional.
 3 # (Feel free to remove these comments when editing.)
 4 
 5 # Unable to find any files that looked like license statements. Check the accompanying
 6 # documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
 7 #
 8 # NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
 9 # this is not accurate with respect to the licensing of the software being built (it
10 # will not be in most cases) you must specify the correct value before using this
11 # recipe for anything other than initial testing/development!
12 LICENSE = "CLOSED"
13 LIC_FILES_CHKSUM = ""
14 
15 # No information for SRC_URI yet (only an external source tree was specified)
16 SRC_URI = ""
17 
18 # NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
19 # recipe automatically - you will need to examine the Makefile yourself and ensure
20 # that the appropriate arguments are passed in.
21 DEPENDS = "virtual/kernel"
22 inherit module
23 
24 EXTRA_OEMAKE  = "ARCH=arm"
25 EXTRA_OEMAKE += "KERNEL_DIR=${STAGING_KERNEL_BUILDDIR}"
26 
27 S = "${WORKDIR}"
28 
29 do_configure () {
30 	# Specify any needed configure commands here
31 	:
32 }
33 
34 do_compile () {
35  	# You will almost certainly need to add additional arguments here
36 	oe_runmake
37 }
38 
39 do_install () {
40 	# NOTE: unable to determine what to put here - there is a Makefile but no
41 	# target named "install", so you will need to define this yourself
42         install -d ${D}/lib/modules/${KERNEL_VERSION}
</font>

43         install -m 0755 ${B}/kernel_module_example.ko ${D}/lib/modules/${KERNEL_VERSION}/
</font>

44 }

  • Go to the <build directory>build directory
 cd <build directory>dir>

  • Generated kernel module example
 devtool build mymodule
  • Push this kernel module example on board
 devtool deploy-target -Ss mymodule root@<board ip address>
  • Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
 /sbin/depmod -a
 sync
  • Insert the kernel module example into the Linux kernel
 modprobe kernel_module_example
[18167.821725] Kernel module example: hello world from STMicroelectronics
  • Remove the kernel module example from the Linux kernel
 rmmod kernel_module_example
[18180.086722] Kernel module example: goodbye from STMicroelectronics

5 Modifying the U-Boot[edit]

This simple example adds unconditional log information when U-Boot starts. Within the scope of the trusted optee boot chain, U-Boot is used as second stage boot loader (SSBL).

  • Have a look at the U-Boot log information when the board reboots
 reboot
[...]
U-Boot <U-Boot version>

CPU: STM32MP1STM32MP157FAC rev1Rev.0Z
Model: STMicroelectronics STM32MP157C [...]STM32MP157F-DK2 Discovery Board
Board: stm32mp1 in trusted mode (st,stm32mp157f-dk2)
[...]


  • Go to <build directory>the build directory
 cd <build directory>dir>

  • Search U-boot recipe
 devtool search u-boot*
u-boot-stm32mp-extlinux  Generate 'extlinux.conf' file for U-boot u-boot-trusted-stm32mp  Universal Boot Loader for embedded devices for stm32mp
(trusted)

On this example, the recipe name is u-boot-trusted-stm32mp

  • Start to work with u-boot
 devtool modify u-boot-trusted-stm32mp
Example:
 cd <build directory>dir>/workspace/sources/u-boot-trusted-stm32mp
  • Edit the ./board/st/stm32mp1/stm32mp1.c source file
  • Add a log information in the checkboard function
int checkboard(void)
{
	char *mode;

	[...]

	printf("Board: stm32mp1 in %s mode\n", mode);
	printf("U-Boot simple example\n");

	return 0;
}
  • Cross-compile the U-Boot: trusted boot
 devtool build u-boot-trusted-stm32mp
 bitbake u-boot-trusted-stm32mp -c deploy

  • U-Boot are put on FIP image via TF-a fip generation
 bitbake tf-a-stm32mp -c deploy -f

  • Go to the directory in which the compilation results are stored
 cd <build dir>/tmp-glibc/deploy/images/<machine name>/fip

  • Reboot the board, and hit any key to stop in the U-boot shell
 reboot
[...]
Hit any key to stop autoboot:  0 
STM32MP> 
  • Connect a USB cable between the host machine and the board via the USB OTG ports
  • In the U-Boot shell, call the USB mass storage function
STM32MP> ums 0 mmc 0
Info white.png Information
for more information about the usage of U-Boot UMS functionality, see How to use USB mass storage in U-Boot
  • On the host machine, check the partition associated with the secondary stage boot loader (ssbl): sdc3 here
 ls -l /dev/disk/by-partlabel/
total 0
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 bootfs -> ../../sdc4sdc8
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:05 02 fip-a -> ../../sdc5
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../sdc1
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 fsbl2 -> ../../sdc2
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 rootfsmetadata1 -> ../../sdc5sdc3
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 ssblmetadata2 -> ../../sdc3sdc4
lrwxrwxrwx 1 root root 11 Apr  4 10:02 Janrootfs 17 18:05 -> ../../sdc10
lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc6
sdc11
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9

  • Copy the binary (u-boot.stm32fip-<board name>-optee.bin) to the dedicated partition
 dd if=ufip-boot-<board name>-trustedoptee.stm32bin of=/dev/sdc3sdc5 bs=1M conv=fdatasync

(here ufip-bootstm32mp157f-stm32mp157cdk2-ev1-trusted.stm32 or u-boot-stm32mp157c-dk2-trusted.stm32optee.bin for stm32mp15-disco machine)

  • Reset the U-Boot shell
STM32MP> reset
  • Have a look at the new U-Boot log information when the board reboots
[...]
U-Boot <U-Boot version>

CPU: STM32MP1STM32MP157FAC rev1Rev.0Z
Model: STMicroelectronics STM32MP157C [...]STM32MP157F-DK2 Discovery Board
Board: stm32mp1 in trusted mode (st,stm32mp157f-dk2)
U-Boot simple example
[...]

6 Modifying the TF-A[edit]

This simple example adds unconditional log information when the TF-A starts. Within the scope of the trusted optee boot chain, TF-A is used as first stage boot loader (FSBL with BL2).

  • Have a look at the TF-A log information when the board reboots
 reboot
[...]
INFO:      System reset generated by MPU (MPSYSRST)
INFO:    Using SDMMC
[...]
  • Go to <build directory>the build directory
 cd <build directory>dir>

  • Search TF-A recipe
 devtool search tf-a*
babeltrace            Babeltrace - Trace Format Babel Tower
libunistring          Library for manipulating C and Unicode strings
lttng-tools           Linux Trace Toolkit Control
gettext               Utilities and libraries for producing multi-lingual messages
glibc                 GLIBC (GNU C Library)
tf-a-stm32mp          Trusted Firmware-A for STM32MP1
gnutls                GNU Transport Layer Security Library
gstreamer1.0          GStreamer 1.0 multimedia framework
harfbuzz              Text shaping library
glibc-locale          Locale data from glibc
kbd                   Keytable files and keyboard utilities

On this example, the recipe name is tf-a-stm32mp

  • Start to work with tf-a
 devtool modify tf-a-stm32mp
  • Go to the <build directory>dir>/workspace/sources/tf-a-stm32mp
 cd <build directory>dir>/workspace/sources/tf-a-stm32mp
  • Edit the ./plat/st/stm32mp1/bl2_io_storage.c source file
  • Add a log information in the stm32mp1_io_setup function
void stm32mp1_io_setup(void)
{
	int io_result;
	[...]
 
	/* Add a trace about reset reason */
	print_reset_reason();

	INFO("TF-A simple example");

	[...]
}
  • Cross-compile the TF-A
 devtool build tf-a-stm32mp
 bitbake tf-a-stm32mp -c deploy
  • Go to the directory in which the compilation results are stored
 cd <build dir>/tmp-glibc/deploy/images/<machine name>/
  • Reboot the board, and hit any key to stop in the U-boot shell
 reboot
[...]
Hit any key to stop autoboot:  0 
STM32MP> 
  • Connect a USB cable between the host machine and the board via the USB OTG ports
  • In the U-Boot shell, call the USB mass storage function
STM32MP> ums 0 mmc 0
Info white.png Information
for more information about the usage of U-boot ums functionality see How to use USB mass storage in U-Boot
  • On the host machine, check the partition associated with the first stage boot loader (fsbl1 and fsbl2 as backup): sdc1 and sdc2 (as backup) here
 ls -l /dev/disk/by-partlabel/
total 0
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 bootfs -> ../../sdc4sdc8
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 sfsbl1fip-a -> ../../sdc5
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../sdc1
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 sfsbl2fsbl2 -> ../../sdc2
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 rootfsmetadata1 -> ../../sdc5sdc3
lrwxrwxrwx 1 root root 10 JanApr 17 184 10:0502 ssblmetadata2 -> ../../sdc3sdc4
lrwxrwxrwx 1 root root 11 Apr  4 10:02 Janrootfs 17 18:05 -> ../../sdc10
lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc6
sdc11
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9

  • Copy the binary (tf-a-stm32mp157cstm32mp157f-ev1dk2-trustedsdcard.stm32) to the dedicated partition; to test the new TF-A binary, it might be useful to keep the old TF-A binary in the backup FSBL (fsbl2)
 dd if=tf-a-<board name>-trustedsdcard.stm32 of=/dev/sdc1 bs=1M conv=fdatasync

(here tf-a-stm32mp157c-ev1-trusted.stm32 or tf-a-stm32mp157c-stm32mp157f-dk2-trustedsdcard.stm32)

  • Reset the U-Boot shell
STM32MP> reset
  • Have a look at the new TF-A log information when the board reboots
[...]
INFO:      System reset generated by MPU (MPSYSRST)
INFO:    TF-A simple example
INFO:    Using SDMMC
[...]

7 Adding a "hello world" user space example[edit]

This chapter shows how to compile and execute a simple "hello world" example.

  • Create a directory for this user space example
 mkdir hello_world_example
 cd hello_world_example
  • Create the source code file for this user space example: hello_world_example.c
// SPDX-identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2018
 *
 * Authors: Jean-Christophe Trotin <jean-christophe.trotin@st.com>
 *
 */

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
	int i =11;

	printf("\
nUser
nUser space example: hello world from STMicroelectronics\n");
	setbuf(stdout,NULL);
	while (i--) {
		printf("%i ", i);
		sleep(1);
	}
	printf("\
nUser
nUser space example: goodbye from STMicroelectronics\n");

	return(0);
}

  • Create devtool environmentAdd a new recipe to the workspace
 cd <build directory>dir>
 devtool add myhelloword hello_world_example/
  • Adapt recipe
 devtool edit-recipe myhellowordmyhelloworld

Modify the recipe according the following changes (see highlighted lines)
 1 # Recipe created by recipetool
 2 # This is the basis of a recipe and may need further editing in order to be fully functional.
 3 # (Feel free to remove these comments when editing.)
 4 
 5 # Unable to find any files that looked like license statements. Check the accompanying
 6 # documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
 7 #
 8 # NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
 9 # this is not accurate with respect to the licensing of the software being built (it
10 # will not be in most cases) you must specify the correct value before using this
11 # recipe for anything other than initial testing/development!
12 LICENSE = "CLOSED"
13 LIC_FILES_CHKSUM = ""
14 
15 # No information for SRC_URI yet (only an external source tree was specified)
16 SRC_URI = ""
17 
18 # NOTE: no Makefile found, unable to determine what needs to be done
19 
20 do_configure () {
21 	# Specify any needed configure commands here
22 	:
23 }
24 
25 do_compile () {
26 	# Specify compilation commands here
27 	cd ${S}
28 	${CC} hello_world_example.c -o hello_word_example
29 }
30 
31 do_install () {
32 	# Specify install commands here
33 	install -d ${D}${bindir}
34 	install -m 755 ${S}/hello_word_example  ${D}${bindir}/
35 }

  • Compile binary
 devtool build myhelloword

  • Push this binary on board
 devtool deploy-target -s myhelloword root@<board ip address>
  • Execute this user space example
 /usr/bin/hello_world_example 

User space example: hello world from STMicroelectronics
10 9 8 7 6 5 4 3 2 1 0 
User space example: goodbye from STMicroelectronics

8 Tips[edit]

8.1 Creating a mounting point[edit]

The objective is to create a mounting point for the boot file system (bootfs partition)

  • Find the partition label associated with the boot file system
 ls -l /dev/disk/by-partlabel/
total 0
lrwxrwxrwx 1 root root 1510 DecApr 13 124 10:3102 bootfs -> ../../mmcblk0p4mmcblk0p8
lrwxrwxrwx 1 root root 1510 DecApr 13 124 10:31 02 fip-a -> ../../mmcblk0p5
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../mmcblk0p6
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 1510 DecApr 13 124 10:3102 fsbl2 -> ../../mmcblk0p2
lrwxrwxrwx 1 root root 1510 DecApr 13 124 10:31 02 metadata1 -> ../../mmcblk0p3
lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata2 -> ../../mmcblk0p4
lrwxrwxrwx 1 root root 11 Apr  4 10:02 rootfs -> ../../mmcblk0p5mmcblk0p10
lrwxrwxrwx 1 root root 1510 DecApr 13 124 10:31 ssbl02 u-boot-env -> ../../mmcblk0p3mmcblk0p7
lrwxrwxrwx 1 root root 1511 DecApr 13 124 10:3102 userfs -> ../../mmcblk0p6
mmcblk0p11
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../mmcblk0p9

  • Attach the boot file system found under /dev/mmcblk0p4mmcblk0p8 in the directory /boot
 mount /dev/mmcblk0p4mmcblk0p8 /boot



<noinclude>

{{ArticleMainWriter | ChristopheP}}
{{ ArticleApprovedVersion | ChristopheP | NathalieS (Not Done), BernardP (PASS, 28June'18), ChristopheM (Pass, 10Jul'18), SebastienG (Not Done), RomualdJ (Not Done), Jean-ChristopheT (Passed with some comments, 27Jun'18), DenisH (25Jun'18, Done with comments) | No previous approved version | AlainF - 10439 - 24Jan'19 | 25Jan'19}}

[[Category:How to build software]]
[[Category:Distribution Package]]
{{UpdateNeededForNewRelease|Please check regularly that the commands work fine}}</noinclude>


{{ReviewsComments|JCT W826: general remark:
* sometimes, you use "devtool build" to cross-compile, and sometimes, you use "bitbake <name of recipe> -C compile".
* sometimes, you use "devtool deploy-target" to deploy, and sometimes, you use "bitbake <name of kernel recipe> -c deploy"
It might be interesting to explain the reasons why different methods are used if there are such reasons. If there's no special reason (it's just that there are several methods possible, it might be interesting to indicate it}}
{{ApplicableFor
|MPUs list=STM32MP13x, STM32MP15x
|MPUs checklist=STM32MP13x,STM32MP15x
}}</noinclude>

==Article purpose==
This article provides simple examples for the Distribution Package of the OpenSTLinux distribution, that illustrate the cross-compilation with the [[OpenEmbedded - devtool|devtool]] and [[BitBake cheat sheet|BitBake]] tools:
* modification with Linux<sup>&reg;</sup> Kernel (configuration, device tree, driver, ...)
* modification of an external in-tree Linux Kernel module
* modification of U-Boot
* modification of TF-A
* addition of software
These examples also show how to deploy the results of the cross-compilation on the target, through a network connection to the host machine.
<br/>

{{info|All the examples described on this page use devtool and/or bitbake from OpenEmbededded, see [[OpenEmbedded - devtool]] for more information.}}
{{ReviewsComments|BPU W826: an article exists on bitbake in the wiki, it may be interesting to reference it here: BitBake_cheat_sheet }}
and [[BitBake cheat sheet]] for more information.}}
{{info|There are many ways to achieve the same result; this article aims to provide at least one solution per example. You have the liberty to explore other methods that are better adapted to your development constraints.}}

==Prerequisites==
The prerequisites from [[STM32MP1 Distribution Package#Installing the OpenSTLinux distribution|Installing the OpenSTLinux distribution]] must be executed.

The board and the host machine are connected through an Ethernet link, and a remote terminal program is started on the host machine: see [[How to get Terminal]].

The target is started, and its IP address (<board ip address>) is known.

==Modification with kernel ==
===Preamble===
To start modification with a module, you need to initialize your Distribution Package environment.
 {{PC$}} cd <working directory path of distribution>

 {{PC$}} DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
You are now in the build directory, identified by <build dir> in the following paragraphs.
Initialize devtool for kernel component:
 {{PC$}} devtool modify virtual/kernel
 NOTE: Starting bitbake server...
 NOTE: Creating workspace layer in /mnt/internal_storage/oetest/oe_openstlinux_rockokirkstone/build-openstlinuxweston-stm32mp1/workspace
 NOTE: Enabling workspace layer in bblayers.conf
 Parsing recipes: 100% |########################################################################################| Time: 0:00:54
 Parsing of 2401 .bb files complete (0 cached, 2401 parsed). 3282 targets, 88 skipped, 0 masked, 0 errors.
 NOTE: '''Mapping virtual/kernel to linux-stm32mp'''
 NOTE: Resolving any missing task queue dependencies
 ...

{{Info| For the case of virtual/<something> component, you need to get the name of mapping between virtual component and associated recipe. In this example, the name of kernel recipe is indicated in the trace, but you can also get it by calling '''devtool status'''
A minority of devtool command supports the virtual/<something> component, like devtool modify, it is why you need to get the recipe name associated to virtual/component. <br/>

In this example, the name of kernel recipe is indicated in the trace (''linux-stm32mp'')}}

{{Info| The source code of kernel is located on <build dir>/workspace/sources. You can change the path where the source code is extracted by customizing the devtool modify command }}

{{ReviewsComments|BPU W826: information below is very interesting but not clear at first read. Proposals to add:
* why deploy is better than a build image + flash: it saves a lot of time.
* elaborate on the diff between bitbake deploy (can scp only required but need to know what you are doing) and devtool deploy-target (probably copy unnecessary files but nothing to care about the installation directory)}}
{{Info| For all the work around the kernel, we strongly encourage some usage for deploying the binaries on board
* Kernel image, device tree: use bitbake deploy command and scp (see [[#modifying kernel configuration]] ))
* Kernel module: use devtool deploy-target by passing by a temporary directory (see [[#Modifying/adding an external Linux kernel module]])
The difference of usage comes from the number of files to deploy on board. When there is only one or two files to put on board, the easiest way to do it is to deploy only the desired files .}}

===Modifying kernel configuration===

This simple example modifies the kernel configuration via menuconfig for the CMA size.
* Get the current value of the CMA size (128 Mbytes here) through the analysis of the target boot log
 {{Board$}} dmesg | grep -i cma
 [    0.000000] cma: Reserved 128 MiB at 0xf0000000

* Start the Linux kernel configuration menu: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]

* Navigate to "Device Drivers - Generic Driver OptionsLibrary routines"
** select "Size in Megabytes"
** modify its value to 256
** exit and save the new configuration

* Check that the configuration file (''.config'') has been modified
 {{PC$}} grep -i CONFIG_CMA_SIZE_MBYTES <build dir>/workspace/sources/<name of kernel recipe>/.config.new
 CONFIG_CMA_SIZE_MBYTES=256

* Cross-compile the Linux kernel: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]

* Update the Linux kernel image on board: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]

* Reboot the board: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]

* Get the new value of the CMA size (256 Mbytes) through the analysis of the target boot log
 {{Board$}} dmesg | grep -i cma
 [    0.000000] cma: Reserved {{Highlight|256}} MiB at 0xe0000000

===Modifying the Linux kernel device tree===
{{Info| The example given below is associated with the STM32MP15 Evaluation board, but the method is independent of the board. }}
This simple example modifies the default status of a user LED.

* With the board started; check that the user LED (LD3) is disabled

* Go to the <build dir>/workspace/sources/<name of kernel recipe>/ directory
 {{PC$}} cd <build dir>/workspace/sources/<name of kernel recipe>/

* Edit the ''arch/arm/boot/dts/stm32mp157c-ed1.dtsstm32mp15xx-edx.dtsi'' Device Tree Source file for evaluation board or
Edit the ''arch/arm/boot/dts/stm32mp157c-dk2.dts''stm32mp15xx-dkx.dtsi" Device Tree Source file for discovery boardor
* Change 

* modify led node for adding green ledChange the status of the "stm32mp:green:user" led to "okay", and set its default state to "on"
 	led {
 		compatible = "gpio-leds";
status = "{{Highlight|okay}}";
 		red {
 			label = "stm32mp:red:status";
 			gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;

 			status = "disabled";
 		};
 		green {
 			label = "stm32mp:green:user";
 			gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;led-blue {
 			label = "heartbeat";
 			gpios = <......>;
 			linux,default-trigger = "heartbeat";
 			default-state = "off";
		};
 		{{Highlight|led-green}} {
 			{{Highlight|label {{=}} "stm32mp:green:user";}}
 			{{Highlight|gpios {{=}} <&gpioa 14 GPIO_ACTIVE_LOW>;}}

 			{{Highlight|default-state {{=}} "on";}}
{{Highlight|status = "{{Highlight|okay}}";
 		};
 	};

{{ReviewsComments|mcc W906:
why not create a patch on kernel configuration as described :
http://intranet.lme.st.com:8000/php-bin/ug_mcdmpu/index.php/How_to_customize_the_Linux_kernel
seems better method to compile the kernel modification
please can you refer to this wiki page and following section
3.2 Adding kernel driver or device tree modifications

)}}

* Go to the <build directory>

 {{PC$}} cd <build directory>


{{ReviewsComments|BPU W826: Why we do not do like before (build + deploy) ? It may need some explanation here (diff should be limited but interesting to learn)}}
* Generate the device tree blobs (''*.dtb'')
 {{PC$}} bitbake <name of recipe> -C compile
{{=}} "okay";}}
 		};
 	};

* Go to the build directory
 {{PC$}} cd <build dir>


* Generate the device tree blobs (''*.dtb'')
 {{PC$}} bitbake virtual/kernel -C compile
{{Info|we use here bitbake command instead of '''devtool build''' because the '''build''' makes '''compile''', '''compile_kernemodules''' and '''install''' commands whereas we only need only '''compile''' command to generate the kernel image and the device tree }}* Update the device tree blobs on the board
 {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/*.dtb root@<board ip address>:/boot
{{Info|If the ''/boot'' mounting point doesn't exist yet, please see [[#Creating a mounting point|how to create a mounting point]]}}

* Reboot the board
 {{Board$}} cd /boot; sync; systemctl reboot

* Check that the user LED (LD3) is {{Highlight|enabled}} (green)

===Modifying a built-in Linux kernel device driver===
This simple example adds unconditional log information when the display driver is probed.<br><br>


* Check that there is no log information when the display driver is probed
 {{Board$}} dmesg | grep -i stm_drm_platform_probe
 {{Board$}}

* Go to the <build dir>/workspace/sources/<name of kernel recipe>/
 {{PC$}} cd <build dir>/workspace/sources/<name of kernel recipe>/

* Edit the ''./drivers/gpu/drm/stm/drv.c'' source file
* Add a log information in the ''stm_drm_platform_probe'' function
 static int stm_drm_platform_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct drm_device *ddev;
 	int ret;
 	[...]

 	{{Highlight|DRM_INFO("Simple example - %s\n", __func__);}}

 	return 0;
 	[...]
 }

* Go to the <build directory>build  directory{{PC$}} cd <build directorydir>


* Cross-compile the Linux kernel
 {{PC$}} bitbake <name of recipe>virtual/kernel -C compile

* Update the Linux kernel image on board
 {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/kernel/uImage root@<board ip address>:/boot
{{Info|If the ''/boot'' mounting point doesn't exist yet, please see [[#Creating a mounting point|how to create a mounting point]]}}

* Reboot the board
 {{Board$}} cd /boot; sync; systemctl reboot

* Check that there is now log information when the display driver is probed
 {{Board$}} dmesg | grep -i stm_drm_platform_probe
 [    5.005833] [drm] {{Highlight|Simple example}} - stm_drm_platform_probe

===Modifying/adding an external Linux kernel module===
Most device drivers (modules) in the Linux kernel can be compiled either into the kernel itself (built-in/internal module) or as Loadable Kernel Modules (LKM/external module) that need to be placed in the root file system under the /lib/modules directory. An external module can be in-tree (in the kernel tree structure), or out-of-tree (outside the kernel tree structure).

This simple example adds an unconditional log information when the virtual video test driver (vivid) kernel module is probed or removed.<br><br>


* Go to the <build dir>/workspace/sources/<name of kernel recipe>/
 {{PC$}} cd <build dir>/workspace/sources/<name of kernel recipe>/

* Edit the ''./drivers/media/platform/vivid/vivid-core.c'' source file
* Add log information in the ''vivid_probe'' and ''vivid_remove'' functions
 static int vivid_probe(struct platform_device *pdev)
 {
 	const struct font_desc *font = find_font("VGA8x16");
 	int ret = 0, i;
 	[...]

 	/* n_devs will reflect the actual number of allocated devices */
 	n_devs = i;

 	{{Highlight|pr_info("Simple example - %s\n", __func__)}};

 	return ret;
 }

 static int vivid_remove(struct platform_device *pdev)
 {
 	struct vivid_dev *dev;
 	unsigned int i, j;
 	[...]

 	{{Highlight|pr_info("Simple example - %s\n", __func__)}};

 	return 0;
 }

* Go to the <build directory>build  directory{{PC$}} cd <build directorydir>


* Cross-compile the Linux kernel modules
 {{PC$}} bitbake <name of recipe>virtual/kernel -C compile

* Update the vivid kernel module on the board
 {{PC$}} devtool deploy-target -Ss <name of kernel recipe> root@<board ip address>:/home/root
 {{PC$}} ssh root@<board ip address> cp -afr /home/root/lib/modules/* /lib/modules/
 {{PC$}} ssh root@<board ip address> cp -f /home/root/boot/uImage /boot/
 {{PC$}} ssh root@<board ip address> cp -f /home/root/boot/*.dtb /boot/
 {{PC$}} ssh root@<board ip address> rm -rf /home/root/lib/ /home/root/etc /home/root/boot

{{ReviewsComments| BPU W826: why you don't do only this commands ?: {{PC$}} devtool deploy-target -Ss <name of kernel recipe> root@<board ip address> <br />

I read what you put below but I have no pb on an external baseline (alpha) except for the vmlinux story.}} 
{{Info| due to the multiple mount points available on board and space associated to this mount point, it's not possible to push directly the binaries on the final location on board, but we can pass by a temporary space (here /home/root/)


{{info|Take care to have enought place available on board to receive the binaries deployed via '''deploy-target''' command.<br/>

The binaries (mainly kernel modules) are not stripped on '''deploy-target''' command and take a lot of place.}}

* Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
 {{Board$}} /sbin/depmod -a
 {{Board$}} sync

* Insert the vivid kernel module into the Linux kernel
 {{Board$}} modprobe vivid                   
 [...]
 [ 3412.784638] {{Highlight|Simple example}} - vivid_probe

* Remove the vivid kernel module from the Linux kernel
 {{Board$}} rmmod vivid
 [...]
 [ 3423.708517] {{Highlight|Simple example}} - vivid_remove

==Adding an external out-of-tree Linux kernel module==
This simple example adds a "Hello World" external out-of-tree Linux kernel module to the Linux kernel.<br><br>


* Create a directory for this kernel module example
 {{PC$}} mkdir kernel_module_example
 {{PC$}} cd kernel_module_example

* Create the source code file for this kernel module example: ''kernel_module_example.c''<pre><syntaxhighlight lang="c">

// SPDX-identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2018
 *
 * Authors: Jean-Christophe Trotin <jean-christophe.trotin@st.com>

 *
 */

#include <linux/module.h>    /* for all kernel modules */
#include <linux/kernel.h>    /* for KERN_INFO */
#include <linux/init.h>      /* for __init and __exit macros */

static int __init kernel_module_example_init(void)
{
	printk(KERN_INFO "Kernel module example: hello world from STMicroelectronics\n");
	return 0;
}

static void __exit kernel_module_example_exit(void)
{
	printk(KERN_INFO "Kernel module example: goodbye from STMicroelectronics\n");
}

module_init(kernel_module_example_init);
module_exit(kernel_module_example_exit);

MODULE_DESCRIPTION("STMicroelectronics simple external out-of-tree Linux kernel module example");
MODULE_AUTHOR("Jean-Christophe Trotin <jean-christophe.trotin@st.com>");
MODULE_LICENSE("GPL v2");</pre></syntaxhighlight>


* Create the makefile for this kernel module example: ''Makefile''
{{info|All the indentations in a makefile are tabulations}}<pre>

# Makefile for simple external out-of-tree Linux kernel module example

# Object file(s) to be built
obj-m := kernel_module_example.o

# Path to the directory that contains the Linux kernel source code
# and the configuration file (.config)
KERNEL_DIR ?= <Linux kernel path>


# Path to the directory that contains the source file(s) to compile
PWD := $(shell pwd) 

default:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean</pre>


* Add a new recipe to the workspace
 {{PC$}} cd <build directorydir>

 {{PC$}} devtool add mymodule kernel_module_example/

* Adapt recipe to kernel module build
 {{PC$}} devtool edit-recipe mymodule
:Modify the recipe according the following changes (see highlighted lines)<pre class="brush:c; gutter:true; highlight: [21,22,24,25,27,40,41];">

<syntaxhighlight lang="c" line highlight="21-22,24-25,27,40-41">
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# Unable to find any files that looked like license statements. Check the accompanying
# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
#
# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
# this is not accurate with respect to the licensing of the software being built (it
# will not be in most cases) you must specify the correct value before using this
# recipe for anything other than initial testing/development!
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""

# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
# recipe automatically - you will need to examine the Makefile yourself and ensure
# that the appropriate arguments are passed in.
DEPENDS = "virtual/kernel"
inherit module

EXTRA_OEMAKE  = "ARCH=arm"
EXTRA_OEMAKE += "KERNEL_DIR=${STAGING_KERNEL_BUILDDIR}"

S = "${WORKDIR}"

do_configure () {
	# Specify any needed configure commands here
	:
}

do_compile () {
 	# You will almost certainly need to add additional arguments here
	oe_runmake
}

do_install () {
	# NOTE: unable to determine what to put here - there is a Makefile but no
	# target named "install", so you will need to define this yourself
        install -d ${D}/lib/modules/${KERNEL_VERSION}</font>

        install -m 0755 ${B}/kernel_module_example.ko ${D}/lib/modules/${KERNEL_VERSION}/</font>

}</pre>

}</syntaxhighlight>


* Go to the <build directory>build  directory{{PC$}} cd <build directorydir>


* Generated kernel module example
 {{PC$}} devtool build mymodule

* Push this kernel module example on board
 {{PC$}} devtool deploy-target -Ss mymodule root@<board ip address>


* Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
 {{Board$}} /sbin/depmod -a
 {{Board$}} sync

* Insert the kernel module example into the Linux kernel
 {{Board$}} modprobe kernel_module_example
 [18167.821725] {{Highlight|Kernel module example}}: hello world from STMicroelectronics

* Remove the kernel module example from the Linux kernel
 {{Board$}} rmmod kernel_module_example
 [18180.086722] {{Highlight|Kernel module example}}: goodbye from STMicroelectronics

==Modifying the U-Boot==

This simple example adds unconditional log information when U-Boot starts. Within the scope of the [[Boot chainschain overview|trustedoptee boot chain]], U-Boot is used as second stage boot loader (SSBL).

* Have a look at the U-Boot log information when the board reboots
 {{Board$}} reboot
 [...]
 U-Boot &#60;U-Boot version>

 CPU: STM32MP1 rev1.0STM32MP157FAC Rev.Z

 Model: STMicroelectronics STM32MP157C [...]
 Board: stm32mp1 in trusted mode
 [...]

* Go to <build directory>
STM32MP157F-DK2 Discovery Board
 Board: stm32mp1 in trusted mode (st,stm32mp157f-dk2)
 [...]
{{ReviewsComments | [[User:Romuald Jeanne|Romuald Jeanne]] ([[User talk:Romuald Jeanne|talk]]) 12:05, 27 June 2022 (CEST) - If we are in 'optee boot chain', we may need to update the console info from 'trusted' to 'optee'}}
{{ReviewsComments|-- [[User:Jean-philippe Romain|Jean-philippe Romain]] ([[User talk:Jean-philippe Romain|talk]]) 21:37, 27 June 2022 (CEST)<br />When checking a boot log as https://citools.st.com/projects/mpu/lava/scheduler/job/330045, U-Boot still display "trusted"...}}

* Go to the build directory{{PC$}} cd <build directorydir>

* Search U-boot recipe
 {{PC$}} devtool search u-boot*
 u-boot-stm32mp-extlinux  Generate 'extlinux.conf' file for U-boot
 u-boot-trusted-stm32mp          Universal Boot Loader for embedded devices for stm32mp(trusted)On this example, the recipe name is '''u-boot-trusted-stm32mp'''

* Start to work with u-boot
 {{PC$}} devtool modify u-boot-trusted-stm32mp

 Example:
 {{PC$}} cd <build directorydir>/workspace/sources/u-boot-trusted-stm32mp
* Edit the ''./board/st/stm32mp1/stm32mp1.c'' source file
* Add a log information in the ''checkboard'' function
 int checkboard(void)
 {
 	char *mode;

 	[...]

 	printf("Board: stm32mp1 in %s mode\n", mode);
 	{{Highlight|printf("U-Boot simple example\n");}}

 	return 0;
 }
{{ReviewsComments | [[User:Romuald Jeanne|Romuald Jeanne]] ([[User talk:Romuald Jeanne|talk]]) 12:05, 27 June 2022 (CEST) - U-Boot code has been updated for 'checkboard' function. Propose:<br>

 	log_info("Board: stm32mp1 in %s mode (%s)\n", mode,
 		 fdt_compat && fdt_compat_len ? fdt_compat : "");
 	log_info("U-Boot simple example\n");<br>

}}* Cross-compile the U-Boot: trusted boot
{{PC$}} devtool build u-boot-trusted-stm32mp
 {{PC$}} bitbake u-boot-trusted-stm32mp -c deploy
stm32mp -c deploy

* U-Boot are put on FIP image via TF-a fip generation
 {{PC$}} bitbake tf-a-stm32mp -c deploy -f
* Go to the directory in which the compilation results are stored
 {{PC$}} cd <build dir>/tmp-glibc/deploy/images/<machine name>/fip


* Reboot the board, and hit any key to stop in the U-boot shell
 {{Board$}} reboot
 [...]
 Hit any key to stop autoboot:  0 
 STM32MP> 

* Connect a USB cable between the host machine and the board via the USB OTG ports

* In the U-Boot shell, call the USB mass storage function
 STM32MP> ums 0 mmc 0
{{Info|for more information about the usage of U-Boot UMS functionality, see [[How to use USB mass storage in U-Boot]]}}

* On the host machine, check the partition associated with the secondary stage boot loader (''ssbl''): ''sdc3'' here
 {{PC$}} ls -l /dev/disk/by-partlabel/
 total 0
 lrwxrwxrwx 1 root root 10 Jan 17 18:05 bootfs -> ../../sdc4Apr  4 10:02 bootfs -> ../../sdc8

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 Apr  4 10:02 {{Highlight|fip-a -> ../../sdc5}}
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../sdc1
 lrwxrwxrwx 1 root root 10 Jan 17 18:05Apr  4 10:02 fsbl2 -> ../../sdc2
 lrwxrwxrwx 1 root root 10 Jan 17 18:05 rootfs -> ../../sdc5Apr  4 10:02 metadata1 -> ../../sdc3

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|ssbl -> ../../sdc3}}Apr  4 10:02 metadata2 -> ../../sdc4

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 userfs -> ../../sdc6

* Copy the binary (u-boot.stm3211 Apr  4 10:02 rootfs -> ../../sdc10
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
 lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc11
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9

* Copy the binary (fip-<board name>-optee.bin) to the dedicated partition
 {{PC$}} dd if=u-boot-fip-<board name>-trusted.stm32optee.bin of=/dev/sdc3sdc5 bs=1M conv=fdatasync
(here u-boot-stm32mp157c-ev1-trusted.stm32 or u-boot-stm32mp157c-dk2-trusted.stm32fip-stm32mp157f-dk2-optee.bin for stm32mp15-disco machine)

* Reset the U-Boot shell
 STM32MP> reset

* Have a look at the new U-Boot log information when the board reboots
 [...]
 U-Boot &#60;U-Boot version&#62;

 CPU: STM32MP1 rev1.0STM32MP157FAC Rev.Z

 Model: STMicroelectronics STM32MP157C [...]STM32MP157F-DK2 Discovery BoardBoard: stm32mp1 in trusted mode  (st,stm32mp157f-dk2){{Highlight|U-Boot simple example}}
 [...]

==Modifying the TF-A==
This simple example adds unconditional log information when the TF-A starts. Within the scope of the [[Boot chainschain overview|trustedoptee boot chain]], TF-A is used as first stage boot loader (FSBL with BL2).

* Have a look at the TF-A log information when the board reboots
 {{Board$}} reboot
 [...]
 INFO:      System reset generated by MPU (MPSYSRST)
 INFO:    Using SDMMC
 [...]

* Go to the <build directory>build  directory{{PC$}} cd <build directorydir>

* Search TF-A recipe
 {{PC$}} devtool search tf-a*
 babeltrace            Babeltrace - Trace Format Babel Tower
 libunistring          Library for manipulating C and Unicode strings
 lttng-tools           Linux Trace Toolkit Control
 gettext               Utilities and libraries for producing multi-lingual messages
 glibc                 GLIBC (GNU C Library)
 {{Highlight|tf-a-stm32mp }}         Trusted Firmware-A for STM32MP1
 gnutls                GNU Transport Layer Security Library
 gstreamer1.0          GStreamer 1.0 multimedia framework
 harfbuzz              Text shaping library
 glibc-locale          Locale data from glibc
 kbd                   Keytable files and keyboard utilities
On this example, the recipe name is '''tf-a-stm32mp'''

* Start to work with tf-a
 {{PC$}} devtool modify tf-a-stm32mp

* Go to the <build directorydir>/workspace/sources/tf-a-stm32mp
 {{PC$}} cd <build directorydir>/workspace/sources/tf-a-stm32mp

* Edit the ''./plat/st/stm32mp1/bl2_io_storage.c'' source file
* Add a log information in the ''stm32mp1_io_setup'' function
 void stm32mp1_io_setup(void)
 {
 	int io_result;
 	[...]

 	/* Add a trace about reset reason */
 	print_reset_reason();

 	INFO("TF-A simple example");

 	[...]
 }

* Cross-compile the TF-A
 {{PC$}} devtool build tf-a-stm32mp
 {{PC$}} bitbake tf-a-stm32mp -c deploy

* Go to the directory in which the compilation results are stored
 {{PC$}} cd <build dir>/tmp-glibc/deploy/images/<machine name>/

* Reboot the board, and hit any key to stop in the U-boot shell
 {{Board$}} reboot
 [...]
 Hit any key to stop autoboot:  0 
 STM32MP> 

* Connect a USB cable between the host machine and the board via the USB OTG ports

* In the U-Boot shell, call the USB mass storage function
 STM32MP> ums 0 mmc 0
{{Info|for more information about the usage of U-boot ums functionality see [[How to use USB mass storage in U-Boot]]}}

* On the host machine, check the partition associated with the first stage boot loader (''fsbl1'' and ''fsbl2'' as backup): ''sdc1'' and ''sdc2'' (as backup) here
 {{PC$}} ls -l /dev/disk/by-partlabel/
 total 0
 lrwxrwxrwx 1 root root 10 Jan 17 18:05 bootfs -> ../../sdc4Apr  4 10:02 bootfs -> ../../sdc8

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|sfsbl1Apr  4 10:02 fip-a -> ../../sdc5
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 {{Highlight|fsbl1 -> ../../sdc1}}
 lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|sfsbl2Apr  4 10:02 {{Highlight|fsbl2 -> ../../sdc2}}
 lrwxrwxrwx 1 root root 10 Jan 17 18:05 rootfs -> ../../sdc5Apr  4 10:02 metadata1 -> ../../sdc3

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 ssbl -> ../../sdc3Apr  4 10:02 metadata2 -> ../../sdc4

 lrwxrwxrwx 1 root root 10 Jan 17 18:05 userfs -> ../../sdc6
11 Apr  4 10:02 rootfs -> ../../sdc10
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
 lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc11
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9
* Copy the binary (tf-a-stm32mp157c-ev1-trustedstm32mp157f-dk2-sdcard.stm32) to the dedicated partition; to test the new TF-A binary, it might be useful to keep the old TF-A binary in the backup FSBL (''fsbl2'') 
 {{PC$}} dd if=tf-a-<board name>-trustedsdcard.stm32 of=/dev/sdc1 bs=1M conv=fdatasync
(here tf-a-stm32mp157c-ev1-trusted.stm32 or tf-a-stm32mp157c-dk2-trustedstm32mp157f-dk2-sdcard.stm32) 

* Reset the U-Boot shell
 STM32MP> reset

* Have a look at the new TF-A log information when the board reboots
 [...]
 INFO:      System reset generated by MPU (MPSYSRST)
 INFO:    {{Highlight|TF-A simple example}}
 INFO:    Using SDMMC
 [...]

==Adding a "hello world" user space example==
This chapter shows how to compile and execute a simple "hello world" example.

* Create a directory for this user space example
 {{PC$}} mkdir hello_world_example
 {{PC$}} cd hello_world_example

* Create the source code file for this user space example: ''hello_world_example.c''<pre><syntaxhighlight lang="c">

// SPDX-identifier: GPL-2.0
/*
 * Copyright (C) STMicroelectronics SA 2018
 *
 * Authors: Jean-Christophe Trotin <jean-christophe.trotin@st.com>

 *
 */

#include <stdio.h>

#include <unistd.h>


int main(int argc, char **argv)
{
	int i =11;

	printf("\nUser space example: hello world from STMicroelectronics\n");
	setbuf(stdout,NULL);
	while (i--) {
		printf("%i ", i);
		sleep(1);
	}
	printf("\nUser space example: goodbye from STMicroelectronics\n");

	return(0);
}</pre>


{{ReviewsComments|JCT W826: "</syntaxhighlight>


* Add a new recipe to the workspace" instead of "Create devtool environment"?}}
* Create devtool environment
{{PC$}} cd <build directorydir>

 {{PC$}} devtool add myhelloword hello_world_example/

* Adapt recipe
 {{PC$}} devtool edit-recipe myhellowordmyhelloworld

:Modify the recipe according the following changes (see highlighted lines)<pre class="brush:c; gutter:true; highlight: [27,28,33,34];"><syntaxhighlight lang="c" line highlight="27-28,33-34">

# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)

# Unable to find any files that looked like license statements. Check the accompanying
# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.
#
# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if
# this is not accurate with respect to the licensing of the software being built (it
# will not be in most cases) you must specify the correct value before using this
# recipe for anything other than initial testing/development!
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""

# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""

# NOTE: no Makefile found, unable to determine what needs to be done

do_configure () {
	# Specify any needed configure commands here
	:
}

do_compile () {
	# Specify compilation commands here
	cd ${S}
	${CC} hello_world_example.c -o hello_word_example
}

do_install () {
	# Specify install commands here
	install -d ${D}${bindir}
	install -m 755 ${S}/hello_word_example  ${D}${bindir}/
}</pre>


* </syntaxhighlight>


* Compile binary
 {{PC$}} devtool build myhelloword

* Push this binary on board
 {{PC$}} devtool deploy-target -s myhelloword root@<board ip address>


* Execute this user space example
 {{Board$}} /usr/bin/hello_world_example 

 {{Highlight|User space example}}: hello world from STMicroelectronics
 10 9 8 7 6 5 4 3 2 1 0 
 {{Highlight|User space example}}: goodbye from STMicroelectronics

==Tips==
===Creating a mounting point===
The objective is to create a mounting point for the boot file system (bootfs partition)
* Find the partition label associated with the boot file system
 {{Board$}} ls -l /dev/disk/by-partlabel/
 total 0
 lrwxrwxrwx 1 root root 15 Dec 13 12:3110 Apr  4 10:02 {{Highlight|bootfs -> ../../mmcblk0p4mmcblk0p8}}
 lrwxrwxrwx 1 root root 15 Dec 13 12:31 10 Apr  4 10:02 fip-a -> ../../mmcblk0p5
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../mmcblk0p6
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../mmcblk0p1
 lrwxrwxrwx 1 root root 15 Dec 13 12:3110 Apr  4 10:02 fsbl2 -> ../../mmcblk0p2
 lrwxrwxrwx 1 root root 15 Dec 13 12:31 rootfs -> ../../mmcblk0p510 Apr  4 10:02 metadata1 -> ../../mmcblk0p3
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata2 -> ../../mmcblk0p4
 lrwxrwxrwx 1 root root 11 Apr  4 10:02 rootfs -> ../../mmcblk0p10

 lrwxrwxrwx 1 root root 15 Dec 13 12:31 ssbl -> ../../mmcblk0p310 Apr  4 10:02 u-boot-env -> ../../mmcblk0p7

 lrwxrwxrwx 1 root root 15 Dec 13 12:31 userfs -> ../../mmcblk0p611 Apr  4 10:02 userfs -> ../../mmcblk0p11
 lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../mmcblk0p9
* Attach the boot file system found under ''/dev/mmcblk0p4mmcblk0p8'' in the directory ''/boot''
 {{Board$}} mount /dev/mmcblk0p4mmcblk0p8 /boot

<noinclude>

[[Category:How to build software]]
[[Category:Distribution Package]]
{{PublicationRequestId | 10439 | 2019-01-24 | AlainF}}
{{UpdateNeededForNewRelease|Please check regularly that the commands work fine}}
{{ReviewsComments|JCT W826: general remark:
* sometimes, you use "devtool build" to cross-compile, and sometimes, you use "bitbake <name of recipe> -C compile".
* sometimes, you use "devtool deploy-target" to deploy, and sometimes, you use "bitbake <name of kernel recipe> -c deploy"
It might be interesting to explain the reasons why different methods are used if there are such reasons. If there's no special reason (it's just that there are several methods possible, it might be interesting to indicate it}}</noinclude>
(81 intermediate revisions by 7 users not shown)
Line 1: Line 1:
<noinclude>
+
<noinclude>{{ApplicableFor
{{ArticleMainWriter | ChristopheP}}
+
|MPUs list=STM32MP13x, STM32MP15x
{{ ArticleApprovedVersion | ChristopheP | NathalieS (Not Done), BernardP (PASS, 28June'18), ChristopheM (Pass, 10Jul'18), SebastienG (Not Done), RomualdJ (Not Done), Jean-ChristopheT (Passed with some comments, 27Jun'18), DenisH (25Jun'18, Done with comments) | No previous approved version | AlainF - 10439 - 24Jan'19 | 25Jan'19}}
+
|MPUs checklist=STM32MP13x,STM32MP15x
 
+
}}</noinclude>
[[Category:How to build software]]
 
[[Category:Distribution Package]]
 
{{UpdateNeededForNewRelease|Please check regularly that the commands work fine}}
 
</noinclude>
 
 
 
{{ReviewsComments|JCT W826: general remark:
 
* sometimes, you use "devtool build" to cross-compile, and sometimes, you use "bitbake <name of recipe> -C compile".
 
* sometimes, you use "devtool deploy-target" to deploy, and sometimes, you use "bitbake <name of kernel recipe> -c deploy"
 
It might be interesting to explain the reasons why different methods are used if there are such reasons. If there's no special reason (it's just that there are several methods possible, it might be interesting to indicate it}}
 
   
 
==Article purpose==
 
==Article purpose==
Line 23: Line 14:
   
 
<br/>
 
<br/>
{{info|All the examples described on this page use devtool and/or bitbake from OpenEmbededded, see [[OpenEmbedded - devtool]] for more information.}}
+
{{info|All the examples described on this page use devtool and/or bitbake from OpenEmbededded, see [[OpenEmbedded - devtool]] and [[BitBake cheat sheet]] for more information.}}
{{ReviewsComments|BPU W826: an article exists on bitbake in the wiki, it may be interesting to reference it here: BitBake_cheat_sheet }}
 
   
 
{{info|There are many ways to achieve the same result; this article aims to provide at least one solution per example. You have the liberty to explore other methods that are better adapted to your development constraints.}}
 
{{info|There are many ways to achieve the same result; this article aims to provide at least one solution per example. You have the liberty to explore other methods that are better adapted to your development constraints.}}
Line 39: Line 29:
 
To start modification with a module, you need to initialize your Distribution Package environment.
 
To start modification with a module, you need to initialize your Distribution Package environment.
 
  {{PC$}} cd <working directory path of distribution>
 
  {{PC$}} cd <working directory path of distribution>
  {{PC$}} DISTRO=openstlinux-weston MACHINE=stm32mp1 source meta-st/scripts/envsetup.sh
+
  {{PC$}} DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
  +
 
  +
You are now in the build directory, identified by <build dir> in the following paragraphs.
   
 
Initialize devtool for kernel component:
 
Initialize devtool for kernel component:
 
  {{PC$}} devtool modify virtual/kernel
 
  {{PC$}} devtool modify virtual/kernel
 
  NOTE: Starting bitbake server...
 
  NOTE: Starting bitbake server...
  NOTE: Creating workspace layer in /mnt/internal_storage/oetest/oe_openstlinux_rocko/build-openstlinuxweston-stm32mp1/workspace
+
  NOTE: Creating workspace layer in /mnt/internal_storage/oetest/oe_openstlinux_kirkstone/build-openstlinuxweston-stm32mp1/workspace
 
  NOTE: Enabling workspace layer in bblayers.conf
 
  NOTE: Enabling workspace layer in bblayers.conf
 
  Parsing recipes: 100% |########################################################################################| Time: 0:00:54
 
  Parsing recipes: 100% |########################################################################################| Time: 0:00:54
Line 58: Line 50:
 
{{Info| The source code of kernel is located on <build dir>/workspace/sources. You can change the path where the source code is extracted by customizing the devtool modify command }}
 
{{Info| The source code of kernel is located on <build dir>/workspace/sources. You can change the path where the source code is extracted by customizing the devtool modify command }}
   
{{ReviewsComments|BPU W826: information below is very interesting but not clear at first read. Proposals to add:
 
* why deploy is better than a build image + flash: it saves a lot of time.
 
* elaborate on the diff between bitbake deploy (can scp only required but need to know what you are doing) and devtool deploy-target (probably copy unnecessary files but nothing to care about the installation directory)}}
 
 
{{Info| For all the work around the kernel, we strongly encourage some usage for deploying the binaries on board
 
{{Info| For all the work around the kernel, we strongly encourage some usage for deploying the binaries on board
 
* Kernel image, device tree: use bitbake deploy command and scp (see [[#modifying kernel configuration]] ))
 
* Kernel image, device tree: use bitbake deploy command and scp (see [[#modifying kernel configuration]] ))
Line 75: Line 64:
 
* Start the Linux kernel configuration menu: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]
 
* Start the Linux kernel configuration menu: see [[Menuconfig or how to configure kernel#Menuconfig and Distribution Package|Menuconfig or how to configure kernel]]
   
* Navigate to "Device Drivers - Generic Driver Options"
+
* Navigate to "Library routines"
 
** select "Size in Megabytes"
 
** select "Size in Megabytes"
 
** modify its value to 256
 
** modify its value to 256
Line 95: Line 84:
   
 
===Modifying the Linux kernel device tree===
 
===Modifying the Linux kernel device tree===
  +
  +
{{Info| The example given below is associated with the STM32MP15 Evaluation board, but the method is independent of the board. }}
   
 
This simple example modifies the default status of a user LED.
 
This simple example modifies the default status of a user LED.
Line 103: Line 94:
 
  {{PC$}} cd <build dir>/workspace/sources/<name of kernel recipe>/
 
  {{PC$}} cd <build dir>/workspace/sources/<name of kernel recipe>/
   
* Edit the ''arch/arm/boot/dts/stm32mp157c-ed1.dts'' Device Tree Source file for evaluation board or
+
* Edit the ''arch/arm/boot/dts/stm32mp15xx-edx.dtsi'' Device Tree Source file for evaluation board or
Edit the ''arch/arm/boot/dts/stm32mp157c-dk2.dts'' Device Tree Source file for discovery board or
+
Edit the ''arch/arm/boot/dts/stm32mp15xx-dkx.dtsi" Device Tree Source file for discovery board
* Change the status of the "stm32mp:green:user" led to "okay", and set its default state to "on"
+
 
  +
* modify led node for adding green ledChange the status of the "stm32mp:green:user" led to "okay", and set its default state to "on"
 
  led {
 
  led {
 
  compatible = "gpio-leds";
 
  compatible = "gpio-leds";
 
   
 
   
  status = "{{Highlight|okay}}";
+
  led-blue {
red {
+
  label = "heartbeat";
  label = "stm32mp:red:status";
+
  gpios = <......>;
  gpios = <&gpioa 13 GPIO_ACTIVE_LOW>;
+
linux,default-trigger = "heartbeat";
+
  default-state = "off";
  status = "disabled";
+
};
};
+
  {{Highlight|led-green}} {
  green {
+
  {{Highlight|label {{=}} "stm32mp:green:user";}}
  label = "stm32mp:green:user";
+
  {{Highlight|gpios {{=}} <&gpioa 14 GPIO_ACTIVE_LOW>;}}
  gpios = <&gpioa 14 GPIO_ACTIVE_LOW>;
 
 
  {{Highlight|default-state {{=}} "on";}}
 
  {{Highlight|default-state {{=}} "on";}}
 
   
 
   
  status = "{{Highlight|okay}}";
+
  {{Highlight|status {{=}} "okay";}}
 
  };
 
  };
 
  };
 
  };
   
{{ReviewsComments|mcc W906:
+
* Go to the build directory
why not create a patch on kernel configuration as described :
+
{{PC$}} cd <build dir>
http://intranet.lme.st.com:8000/php-bin/ug_mcdmpu/index.php/How_to_customize_the_Linux_kernel
 
seems better method to compile the kernel modification
 
please can you refer to this wiki page and following section
 
3.2 Adding kernel driver or device tree modifications
 
 
 
)}}
 
   
* Go to the <build directory>
 
{{PC$}} cd <build directory>
 
 
{{ReviewsComments|BPU W826: Why we do not do like before (build + deploy) ? It may need some explanation here (diff should be limited but interesting to learn)}}
 
 
* Generate the device tree blobs (''*.dtb'')
 
* Generate the device tree blobs (''*.dtb'')
  {{PC$}} bitbake <name of recipe> -C compile
+
  {{PC$}} bitbake virtual/kernel -C compile
 
+
{{Info|we use here bitbake command instead of '''devtool build''' because the '''build''' makes '''compile''', '''compile_kernemodules''' and '''install''' commands whereas we only need only '''compile''' command to generate the kernel image and the device tree }}
 
* Update the device tree blobs on the board
 
* Update the device tree blobs on the board
 
  {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/*.dtb root@<board ip address>:/boot
 
  {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/*.dtb root@<board ip address>:/boot
Line 176: Line 157:
 
  }
 
  }
   
* Go to the <build directory>
+
* Go to the build directory
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
   
 
* Cross-compile the Linux kernel
 
* Cross-compile the Linux kernel
  {{PC$}} bitbake <name of recipe> -C compile
+
  {{PC$}} bitbake virtual/kernel -C compile
   
 
* Update the Linux kernel image on board
 
* Update the Linux kernel image on board
  {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/uImage root@<board ip address>:/boot
+
  {{PC$}} scp <build dir>/tmp-glibc/deploy/images/<machine name>/kernel/uImage root@<board ip address>:/boot
 
{{Info|If the ''/boot'' mounting point doesn't exist yet, please see [[#Creating a mounting point|how to create a mounting point]]}}
 
{{Info|If the ''/boot'' mounting point doesn't exist yet, please see [[#Creating a mounting point|how to create a mounting point]]}}
  +
   
 
* Reboot the board
 
* Reboot the board
Line 229: Line 211:
 
  }
 
  }
   
* Go to the <build directory>
+
* Go to the build directory
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
 
   
 
   
 
* Cross-compile the Linux kernel modules
 
* Cross-compile the Linux kernel modules
  {{PC$}} bitbake <name of recipe> -C compile
+
  {{PC$}} bitbake virtual/kernel -C compile
   
 
* Update the vivid kernel module on the board
 
* Update the vivid kernel module on the board
  {{PC$}} devtool deploy-target -Ss <name of kernel recipe> root@<board ip address>:/home/root
+
  {{PC$}} devtool deploy-target -Ss <name of kernel recipe> root@<board ip address>:/
{{PC$}} ssh root@<board ip address> cp -afr /home/root/lib/modules/* /lib/modules/
 
{{PC$}} ssh root@<board ip address> cp -f /home/root/boot/uImage /boot/
 
{{PC$}} ssh root@<board ip address> cp -f /home/root/boot/*.dtb /boot/
 
{{PC$}} ssh root@<board ip address> rm -rf /home/root/lib/ /home/root/etc /home/root/boot
 
   
{{ReviewsComments| BPU W826: why you don't do only this commands ?: {{PC$}} devtool deploy-target -Ss <name of kernel recipe> root@<board ip address> <br />
+
{{info|Take care to have enought place available on board to receive the binaries deployed via '''deploy-target''' command.<br/>
I read what you put below but I have no pb on an external baseline (alpha) except for the vmlinux story.}}
+
The binaries (mainly kernel modules) are not stripped on '''deploy-target''' command and take a lot of place.}}
{{Info| due to the multiple mount points available on board and space associated to this mount point, it's not possible to push directly the binaries on the final location on board, but we can pass by a temporary space (here /home/root/)}}
 
   
 
* Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
 
* Update dependency descriptions for loadable kernel modules, and synchronize the data on disk with memory
Line 269: Line 246:
   
 
* Create the source code file for this kernel module example: ''kernel_module_example.c''
 
* Create the source code file for this kernel module example: ''kernel_module_example.c''
<pre>
+
<syntaxhighlight lang="c">
 
// SPDX-identifier: GPL-2.0
 
// SPDX-identifier: GPL-2.0
 
/*
 
/*
Line 299: Line 276:
 
MODULE_AUTHOR("Jean-Christophe Trotin <jean-christophe.trotin@st.com>");
 
MODULE_AUTHOR("Jean-Christophe Trotin <jean-christophe.trotin@st.com>");
 
MODULE_LICENSE("GPL v2");
 
MODULE_LICENSE("GPL v2");
</pre>
+
</syntaxhighlight >
   
 
* Create the makefile for this kernel module example: ''Makefile''
 
* Create the makefile for this kernel module example: ''Makefile''
Line 324: Line 301:
   
 
* Add a new recipe to the workspace
 
* Add a new recipe to the workspace
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
 
  {{PC$}} devtool add mymodule kernel_module_example/
 
  {{PC$}} devtool add mymodule kernel_module_example/
   
Line 330: Line 307:
 
  {{PC$}} devtool edit-recipe mymodule
 
  {{PC$}} devtool edit-recipe mymodule
 
:Modify the recipe according the following changes (see highlighted lines)
 
:Modify the recipe according the following changes (see highlighted lines)
<pre class="brush:c; gutter:true; highlight: [21,22,24,25,27,40,41];">
+
 
  +
<syntaxhighlight lang="c" line highlight="21-22,24-25,27,40-41">
 
# Recipe created by recipetool
 
# Recipe created by recipetool
 
# This is the basis of a recipe and may need further editing in order to be fully functional.
 
# This is the basis of a recipe and may need further editing in order to be fully functional.
Line 372: Line 350:
 
# NOTE: unable to determine what to put here - there is a Makefile but no
 
# NOTE: unable to determine what to put here - there is a Makefile but no
 
# target named "install", so you will need to define this yourself
 
# target named "install", so you will need to define this yourself
         install -d ${D}/lib/modules/${KERNEL_VERSION}</font>
+
         install -d ${D}/lib/modules/${KERNEL_VERSION}
         install -m 0755 ${B}/kernel_module_example.ko ${D}/lib/modules/${KERNEL_VERSION}/</font>
+
         install -m 0755 ${B}/kernel_module_example.ko ${D}/lib/modules/${KERNEL_VERSION}/
 
}
 
}
</pre>
+
</syntaxhighlight >
   
* Go to the <build directory>
+
* Go to the build directory
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
   
 
* Generated kernel module example
 
* Generated kernel module example
Line 400: Line 378:
 
==Modifying the U-Boot==
 
==Modifying the U-Boot==
   
This simple example adds unconditional log information when U-Boot starts. Within the scope of the [[Boot chains overview|trusted boot chain]], U-Boot is used as second stage boot loader (SSBL).
+
This simple example adds unconditional log information when U-Boot starts. Within the scope of the [[Boot chain overview|optee boot chain]].
   
 
* Have a look at the U-Boot log information when the board reboots
 
* Have a look at the U-Boot log information when the board reboots
Line 407: Line 385:
 
  U-Boot &#60;U-Boot version>
 
  U-Boot &#60;U-Boot version>
 
   
 
   
  CPU: STM32MP1 rev1.0
+
  CPU: STM32MP157FAC Rev.Z
  Model: STMicroelectronics STM32MP157C [...]
+
  Model: STMicroelectronics STM32MP157F-DK2 Discovery Board
  Board: stm32mp1 in trusted mode
+
  Board: stm32mp1 in trusted mode (st,stm32mp157f-dk2)
 
  [...]
 
  [...]
  +
{{ReviewsComments | [[User:Romuald Jeanne|Romuald Jeanne]] ([[User talk:Romuald Jeanne|talk]]) 12:05, 27 June 2022 (CEST) - If we are in 'optee boot chain', we may need to update the console info from 'trusted' to 'optee'}}
  +
{{ReviewsComments|-- [[User:Jean-philippe Romain|Jean-philippe Romain]] ([[User talk:Jean-philippe Romain|talk]]) 21:37, 27 June 2022 (CEST)<br />When checking a boot log as https://citools.st.com/projects/mpu/lava/scheduler/job/330045, U-Boot still display "trusted"...}}
   
* Go to <build directory>
+
* Go to the build directory
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
 
* Search U-boot recipe
 
* Search U-boot recipe
 
  {{PC$}} devtool search u-boot*
 
  {{PC$}} devtool search u-boot*
  u-boot-stm32mp-extlinux  Generate 'extlinux.conf' file for U-boot
+
  u-boot-stm32mp       Universal Boot Loader for embedded devices for stm32mp
u-boot-trusted-stm32mp  Universal Boot Loader for embedded devices for stm32mp (trusted)
+
On this example, the recipe name is '''u-boot-stm32mp'''
On this example, the recipe name is '''u-boot-trusted-stm32mp'''
 
   
 
* Start to work with u-boot
 
* Start to work with u-boot
  {{PC$}} devtool modify u-boot-trusted-stm32mp
+
  {{PC$}} devtool modify u-boot-stm32mp
   
 
  Example:
 
  Example:
  {{PC$}} cd <build directory>/workspace/sources/u-boot-trusted-stm32mp
+
  {{PC$}} cd <build dir>/workspace/sources/u-boot-stm32mp
 
* Edit the ''./board/st/stm32mp1/stm32mp1.c'' source file
 
* Edit the ''./board/st/stm32mp1/stm32mp1.c'' source file
 
* Add a log information in the ''checkboard'' function
 
* Add a log information in the ''checkboard'' function
Line 438: Line 417:
 
  return 0;
 
  return 0;
 
  }
 
  }
  +
{{ReviewsComments | [[User:Romuald Jeanne|Romuald Jeanne]] ([[User talk:Romuald Jeanne|talk]]) 12:05, 27 June 2022 (CEST) - U-Boot code has been updated for 'checkboard' function. Propose:<br>
  +
log_info("Board: stm32mp1 in %s mode (%s)\n", mode,
  +
fdt_compat && fdt_compat_len ? fdt_compat : "");
  +
log_info("U-Boot simple example\n");
  +
<br>
  +
}}
  +
* Cross-compile the U-Boot
  +
{{PC$}} devtool build u-boot-stm32mp
  +
{{PC$}} bitbake u-boot-stm32mp -c deploy
   
* Cross-compile the U-Boot: trusted boot
+
* U-Boot are put on FIP image via TF-a fip generation
{{PC$}} devtool build u-boot-trusted-stm32mp
+
  {{PC$}} bitbake tf-a-stm32mp -c deploy -f
  {{PC$}} bitbake u-boot-trusted-stm32mp -c deploy
 
   
 
* Go to the directory in which the compilation results are stored
 
* Go to the directory in which the compilation results are stored
  {{PC$}} cd <build dir>/tmp-glibc/deploy/images/<machine name>/
+
 
  +
  {{PC$}} cd <build dir>/tmp-glibc/deploy/images/<machine name>/fip
   
 
* Reboot the board, and hit any key to stop in the U-boot shell
 
* Reboot the board, and hit any key to stop in the U-boot shell
Line 461: Line 449:
 
  {{PC$}} ls -l /dev/disk/by-partlabel/
 
  {{PC$}} ls -l /dev/disk/by-partlabel/
 
  total 0
 
  total 0
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 bootfs -> ../../sdc4
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 bootfs -> ../../sdc8
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 fsbl1 -> ../../sdc1
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 {{Highlight|fip-a -> ../../sdc5}}
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 fsbl2 -> ../../sdc2
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 rootfs -> ../../sdc5
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../sdc1
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|ssbl -> ../../sdc3}}
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl2 -> ../../sdc2
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 userfs -> ../../sdc6
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata1 -> ../../sdc3
  +
lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata2 -> ../../sdc4
  +
lrwxrwxrwx 1 root root 11 Apr  4 10:02 rootfs -> ../../sdc10
  +
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
  +
  lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc11
  +
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9
   
* Copy the binary (u-boot.stm32) to the dedicated partition
+
* Copy the binary (fip-<board name>-optee.bin) to the dedicated partition
  {{PC$}} dd if=u-boot-<board name>-trusted.stm32 of=/dev/sdc3 bs=1M conv=fdatasync
+
  {{PC$}} dd if=fip-<board name>-optee.bin of=/dev/sdc5 bs=1M conv=fdatasync
(here u-boot-stm32mp157c-ev1-trusted.stm32 or u-boot-stm32mp157c-dk2-trusted.stm32)
+
(here fip-stm32mp157f-dk2-optee.bin for stm32mp15-disco machine)
   
 
* Reset the U-Boot shell
 
* Reset the U-Boot shell
Line 479: Line 472:
 
  U-Boot &#60;U-Boot version&#62;
 
  U-Boot &#60;U-Boot version&#62;
 
   
 
   
  CPU: STM32MP1 rev1.0
+
  CPU: STM32MP157FAC Rev.Z
  Model: STMicroelectronics STM32MP157C [...]
+
  Model: STMicroelectronics STM32MP157F-DK2 Discovery Board
  Board: stm32mp1 in trusted mode
+
  Board: stm32mp1 in trusted mode (st,stm32mp157f-dk2)
 
  {{Highlight|U-Boot simple example}}
 
  {{Highlight|U-Boot simple example}}
 
  [...]
 
  [...]
   
 
==Modifying the TF-A==
 
==Modifying the TF-A==
This simple example adds unconditional log information when the TF-A starts. Within the scope of the [[Boot chains overview|trusted boot chain]], TF-A is used as first stage boot loader (FSBL).
+
This simple example adds unconditional log information when the TF-A starts. Within the scope of the [[Boot chain overview|optee boot chain]], TF-A is used as first stage boot loader (FSBL with BL2).
   
 
* Have a look at the TF-A log information when the board reboots
 
* Have a look at the TF-A log information when the board reboots
Line 495: Line 488:
 
  [...]
 
  [...]
   
* Go to <build directory>
+
* Go to the build directory
  {{PC$}} cd <build directory>
+
  {{PC$}} cd <build dir>
 
* Search TF-A recipe
 
* Search TF-A recipe
 
  {{PC$}} devtool search tf-a*
 
  {{PC$}} devtool search tf-a*
Line 515: Line 508:
 
  {{PC$}} devtool modify tf-a-stm32mp
 
  {{PC$}} devtool modify tf-a-stm32mp
   
* Go to the <build directory>/workspace/sources/tf-a-stm32mp
+
* Go to <build dir>/workspace/sources/tf-a-stm32mp
  {{PC$}} cd <build directory>/workspace/sources/tf-a-stm32mp
+
  {{PC$}} cd <build dir>/workspace/sources/tf-a-stm32mp
   
 
* Edit the ''./plat/st/stm32mp1/bl2_io_storage.c'' source file
 
* Edit the ''./plat/st/stm32mp1/bl2_io_storage.c'' source file
Line 555: Line 548:
 
  {{PC$}} ls -l /dev/disk/by-partlabel/
 
  {{PC$}} ls -l /dev/disk/by-partlabel/
 
  total 0
 
  total 0
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 bootfs -> ../../sdc4
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 bootfs -> ../../sdc8
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|sfsbl1 -> ../../sdc1}}
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-a -> ../../sdc5
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 {{Highlight|sfsbl2 -> ../../sdc2}}
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../sdc6
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 rootfs -> ../../sdc5
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 {{Highlight|fsbl1 -> ../../sdc1}}
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 ssbl -> ../../sdc3
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 {{Highlight|fsbl2 -> ../../sdc2}}
  lrwxrwxrwx 1 root root 10 Jan 17 18:05 userfs -> ../../sdc6
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata1 -> ../../sdc3
  +
lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata2 -> ../../sdc4
  +
lrwxrwxrwx 1 root root 11 Apr  4 10:02 rootfs -> ../../sdc10
  +
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../sdc7
  +
  lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../sdc11
  +
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../sdc9
   
* Copy the binary (tf-a-stm32mp157c-ev1-trusted.stm32) to the dedicated partition; to test the new TF-A binary, it might be useful to keep the old TF-A binary in the backup FSBL (''fsbl2'')  
+
* Copy the binary (tf-a-stm32mp157f-dk2-sdcard.stm32) to the dedicated partition; to test the new TF-A binary, it might be useful to keep the old TF-A binary in the backup FSBL (''fsbl2'')  
  {{PC$}} dd if=tf-a-<board name>-trusted.stm32 of=/dev/sdc1 bs=1M conv=fdatasync
+
  {{PC$}} dd if=tf-a-<board name>-sdcard.stm32 of=/dev/sdc1 bs=1M conv=fdatasync
(here tf-a-stm32mp157c-ev1-trusted.stm32 or tf-a-stm32mp157c-dk2-trusted.stm32)  
+
(here tf-a-stm32mp157f-dk2-sdcard.stm32)  
   
 
* Reset the U-Boot shell
 
* Reset the U-Boot shell
Line 584: Line 582:
   
 
* Create the source code file for this user space example: ''hello_world_example.c''
 
* Create the source code file for this user space example: ''hello_world_example.c''
<pre>
+
<syntaxhighlight lang="c">
 
// SPDX-identifier: GPL-2.0
 
// SPDX-identifier: GPL-2.0
 
/*
 
/*
Line 610: Line 608:
 
return(0);
 
return(0);
 
}
 
}
</pre>
+
</syntaxhighlight>
   
{{ReviewsComments|JCT W826: "Add a new recipe to the workspace" instead of "Create devtool environment"?}}
+
* Add a new recipe to the workspace
* Create devtool environment
+
  {{PC$}} cd <build dir>
  {{PC$}} cd <build directory>
 
 
  {{PC$}} devtool add myhelloword hello_world_example/
 
  {{PC$}} devtool add myhelloword hello_world_example/
   
 
* Adapt recipe
 
* Adapt recipe
  {{PC$}} devtool edit-recipe myhelloword
+
  {{PC$}} devtool edit-recipe myhelloworld
 
:Modify the recipe according the following changes (see highlighted lines)
 
:Modify the recipe according the following changes (see highlighted lines)
<pre class="brush:c; gutter:true; highlight: [27,28,33,34];">
+
<syntaxhighlight lang="c" line highlight="27-28,33-34">
 
# Recipe created by recipetool
 
# Recipe created by recipetool
 
# This is the basis of a recipe and may need further editing in order to be fully functional.
 
# This is the basis of a recipe and may need further editing in order to be fully functional.
Line 656: Line 653:
 
install -m 755 ${S}/hello_word_example  ${D}${bindir}/
 
install -m 755 ${S}/hello_word_example  ${D}${bindir}/
 
}
 
}
</pre>
+
</syntaxhighlight>
  +
 
  +
* Compile binary
  +
{{PC$}} devtool build myhelloword
   
 
* Push this binary on board
 
* Push this binary on board
Line 674: Line 674:
 
  {{Board$}} ls -l /dev/disk/by-partlabel/
 
  {{Board$}} ls -l /dev/disk/by-partlabel/
 
  total 0
 
  total 0
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 {{Highlight|bootfs -> ../../mmcblk0p4}}
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 {{Highlight|bootfs -> ../../mmcblk0p8}}
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 fsbl1 -> ../../mmcblk0p1
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-a -> ../../mmcblk0p5
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 fsbl2 -> ../../mmcblk0p2
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fip-b -> ../../mmcblk0p6
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 rootfs -> ../../mmcblk0p5
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl1 -> ../../mmcblk0p1
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 ssbl -> ../../mmcblk0p3
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 fsbl2 -> ../../mmcblk0p2
  lrwxrwxrwx 1 root root 15 Dec 13 12:31 userfs -> ../../mmcblk0p6
+
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata1 -> ../../mmcblk0p3
* Attach the boot file system found under ''/dev/mmcblk0p4'' in the directory ''/boot''
+
lrwxrwxrwx 1 root root 10 Apr  4 10:02 metadata2 -> ../../mmcblk0p4
  {{Board$}} mount /dev/mmcblk0p4 /boot
+
lrwxrwxrwx 1 root root 11 Apr  4 10:02 rootfs -> ../../mmcblk0p10
  +
  lrwxrwxrwx 1 root root 10 Apr  4 10:02 u-boot-env -> ../../mmcblk0p7
  +
  lrwxrwxrwx 1 root root 11 Apr  4 10:02 userfs -> ../../mmcblk0p11
  +
lrwxrwxrwx 1 root root 10 Apr  4 10:02 vendorfs -> ../../mmcblk0p9
  +
 
  +
* Attach the boot file system found under ''/dev/mmcblk0p8'' in the directory ''/boot''
  +
  {{Board$}} mount /dev/mmcblk0p8 /boot
  +
 
  +
<noinclude>
  +
[[Category:How to build software]]
  +
[[Category:Distribution Package]]
  +
{{PublicationRequestId | 10439 | 2019-01-24 | AlainF}}
  +
{{UpdateNeededForNewRelease|Please check regularly that the commands work fine}}
  +
{{ReviewsComments|JCT W826: general remark:
  +
* sometimes, you use "devtool build" to cross-compile, and sometimes, you use "bitbake <name of recipe> -C compile".
  +
* sometimes, you use "devtool deploy-target" to deploy, and sometimes, you use "bitbake <name of kernel recipe> -c deploy"
  +
It might be interesting to explain the reasons why different methods are used if there are such reasons. If there's no special reason (it's just that there are several methods possible, it might be interesting to indicate it}}
  +
</noinclude>