How to configure a 256MB DDR mapping from STM32 MPU Distribution Package

Revision as of 12:31, 16 March 2023 by Registered User (→‎Linux kernel memory usage)
Applicable for STM32MP13x lines

1. Purpose of article[edit source]

This article describes how to update the STM32 MPU embedded Software distribution to a specific 256Mo DDR mapping in a STM32MP13x based product.
Note that the 256Mo software configuration can be performed on a STM32MP13 DK board (512Mo of DDR), in order to prototype the new mapping memory, but for this exercise, further software updates are requested , there are highlight in the article with a information window and the label DDR512Mo.

2. Pre-requesites[edit source]

You are already familiar with the Yocto build process and OpenSTLinux distribution.

3. Introduction[edit source]

This article is a guideline for the user to update the STM32 MPU embedded Software in a distribution package of the OpenSTLinux distribution, according to his 256Mo hardware configuration.

The process is based on a OpenSTLinux configured for the STM32MP13 DK board (512Mo of DDR), with the following DDR mapping.


The default mapping defined for The OpenSTLinux on the STM32MP13 DK board for a st-image-weston image is :

0xe0000000  | (End of DDR 512Mo ) 
0xde200000  | (DDR_SEC_BASE/CFG_TZDRAM_START 
            | size DDR_SEC_SIZE/STM32MP_DDR_S_SIZE/CFG_TZDRAM_SIZE (30Mo) protected by TZC 400, 
            | Begin of OP-TEE mapping, 
            | Begin of DDR encrypted DDRMCE, size 30Mo
            | End of SHMEM)
0xde000000  | (DDR_SHARE_BASE/CFG_SHMEM_START
            | size DDR_SHARE_SIZE/STM32MP_DDR_SHMEM_SIZE/CFG_SHMEM_SIZE (2Mo no secure),
            | Begin of reserved memory optee size 32Mo)
0xdd000000  | (Begin of optee-framebuffer protected access by TZC 400 size 16Mo)
0xdc800000  | (End of Linux CMA reserved)
0xd4800000  | (Begin of Linux CMA reserved size CONFIG_CMA_SIZE_MBYTES 128Mo)
0xd0000000  | (End of DDR cacheable in U-Boot)
0xc0000000  | (STM32MP_DDR_BASE
            | DDR_NS_BASE size 464Mo
            | Begin of DDR cacheable in U-Boot, size CONFIG_DDR_CACHEABLE_SIZE 256Mo)

The exercise described in this article is to target the following 256Mo mapping:


0xd0000000  | (End of DDR 256Mo) 
0xcfc00000  | (DDR_SEC_BASE/CFG_TZDRAM_START 
            | size DDR_SEC_SIZE/STM32MP_DDR_S_SIZE/CFG_TZDRAM_SIZE (4Mo) protected by TZC 400, 
            | Begin of OP-TEE mapping, 
            | Begin of DDR encrypted DDRMCE, size 4Mo
            | End of SHMEM)
0xcfb00000  | (DDR_SHARE_BASE/CFG_SHMEM_START
            | size DDR_SHARE_SIZE/STM32MP_DDR_SHMEM_SIZE/CFG_SHMEM_SIZE (1Mo no secure),
            | Begin of reserved memory optee size 5Mo)
0xceb00000  | (Begin of optee-framebuffer protected access by TZC 400 size 16Mo)
0xcb000000  | (End of Linux CMA reserved)
0xc8000000  | (End of DDR cacheable in U-Boot)  
0xc3000000  | (Begin of Linux CMA reserved size CONFIG_CMA_SIZE_MBYTES 128Mo)
0xc0000000  | (STM32MP_DDR_BASE
            | DDR_NS_BASE size 235Mo
            | Begin of DDR cacheable in U-Boot, size CONFIG_DDR_CACHEABLE_SIZE 128Mo)

The software modification requested in the STM32MP1 Distribution Package, have been performed with the "devtool" and "bitbake" tools. The following components need to be modified (TF-A, U-boot, OP-TEE, Linux Kernel).

4. DDR configuration[edit source]

The DDR is configured with the STM32CubeMX DDR tool, the tool creates the device tree source include file.

5. TF-A updates[edit source]

To update the TF-A firmware in the STM32MP1 Distribution Package, use the devtool tool:

devtool modify tf-a-stm32mp


The updates requested according to new mapping:

#define DDR_SIZE 0x10000000
#define DDR_SEC_SIZE 0x400000
#define DDR_SHARE_SIZE 0x100000


#define STM32MP_DDR_S_SIZE 0x400000
#define STM32MP_DDR_SHMEM_SIZE 0x100000


Info white.png Information
DDR512Mo:

Modify the DDR_MEM_SIZE (512Mo->256Mo) in the file fdts/stm32mp13-ddr3-1x4Gb-1066-binF.dtsi

#define DDR_MEM_SIZE 0x10000000


5.1. Description of the TF-A updates[edit source]

For some further description please read the How to configure TF-A FW CONFIG.

  • Firewall configuration

The DDR firewall is configured to restrict access to specific areas.The TZC is configured at boot time to setup DDR accesses by the TF-A, completed by OP-TEE.

Three regions are defined:
Start address = 0xC000 0000: 251-Mbyte region where secure accesses are forbidden and to which all non- secure peripherals can access
Start address = 0xCFB0 0000: 1-Mbyte (SHM) region where secure accesses are forbidden and non-secure accesses are possible only from an A7 CPU
Start address = 0xCFC0 0000: 4-Mbyte (OP-TEE) region where only secure accesses are allowed 

OP-TEE is the secure OS executed in DDR protected by TZC, the size allocated to OP-TEE depend on how the OP-TEE is configured and used, it includes the firmware Optee-os size, the stack and heap size, stack and heap are almost dedicated to Trusted Applications. SHM is the SHare Memory between non secure and secure OS (?? usage buffer for TA access ??;..)

The configuration of the mem firewall is defined in the file fdts/stm32mp13-fw-config.dtsi

DDR_NS_BASE = STM32MP_DDR_BASE = 0xc0000000 (default OpenSTLinux RAM mapping))
DDR_SEC_SIZE = 0x00400000 (4 Mo allocated to OP-TEE).
DDR_SEC_BASE = {{HighlightParam|STM32MP_DDR_BASE + DDR_SIZE - DDR_SEC_SIZE = 0xc0000000 + 0x10000000 - 0x00400000 = 0xcfc00000
DDR_SHARE_SIZE = 0x00100000 (1 Mo allocated for Share memory)
DDR_SHARE_BASE = DDR_SEC_BASE - DDR_SHARE_SIZE = 0xcfc00000 - 0x00100000 = 0xcfb00000
DDR_NS_SIZE = DDR_SHARE_BASE - DDR_NS_BASE = 0xcfb00000 - 0xc0000000 = 0x0fb00000 (251Mo dedicated to no secure world, Linux kernel and user space)
  • DDR Encryption area

The memory region encrypted is defined in fdts/stm32mp13-fw-config-mem-encrypt.dtsi . The memory region defined by default in OpenSTLinux configuration is the region allocated to OP-TEE, so set with parameters DDR_SEC_BASE and DDR_SEC_SIZE.

  • Firmware configuration file

The FW_CONFIG define all binaries to be loading in internal RAM or DDR, with for each image the load address, the maximum binary size to be loaded, and the ID of the image. The FW_CONFIG and all binaries are embedded in a TF-A FIP binary. (Firmware Image Package). The TF-A FIP contains all boot binaries and optionally their certificates, installed by the TF-A. (U-Boot, U-Boot dtb, OP-TEE, FW_CONFIG)

The configuration is defined in the file fdts/stm32mp13-fw-config.dtsi The structure of the tos-fw (secure os) depend on the parameters DDR_SEC_BASE and DDR_SEC_SIZE.

6. OP-TEE updates[edit source]

To update the OP-TEE firmware in the STM32MP1 Distribution Package, use the devtool tool:

devtool modify optee-os-stm32mp

The updates requested according to new mapping:

  • Modify the CFG_DRAM_SIZE (512Mo->256Mo), CFG_TZDRAM_SIZE (30Mo->4Mo) and CFG_SHMEM_SIZE (2Mo->1Mo) in the file Unsupported domain!.
CFG_DRAM_SIZE    ?= 0x10000000 
CFG_TZDRAM_SIZE  ?= 0x00400000 
CFG_SHMEM_SIZE   ?= 0x00100000
  • Modify the RAM memory size (512Mo->256Mo), the location of the secure framebuffer memory (0xdd000000->0xceb00000), in the file Unsupported domain!
 memory@c0000000 {
           device_type = "memory";
           reg = <0xc0000000 0x10000000>;
 };
 
 reserved-memory {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
 
                optee_framebuffer: optee-framebuffer@ceb00000 {
                        /* Secure framebuffer memory */
                        reg = <0xceb00000 0x1000000>;
                        st,protreg = <TZC_REGION_S_RDWR 0>;
                };

6.1. Description of the updates[edit source]

  • memory secure and share memory

The OP-TEE memory configuration is defined in the file Unsupported domain!

CFG_TZDRAM_START ?= ($(CFG_DRAM_BASE) + $(CFG_DRAM_SIZE) - $(CFG_TZDRAM_SIZE))
= 0xc0000000 + 0x10000000 - 0x400000 = 0xcfc00000
CFG_SHMEM_START  ?= ($(CFG_TZDRAM_START) - $(CFG_SHMEM_SIZE))
= 0xcfc00000 - 0x100000 = 0xcfb00000

The memory size CFG_TZDRAM_SIZE and mapping reserved for OP-TEE depend on the task allocated to the secure OS. The memory allocated include the size of the Optee-os firmware, the stack and heap size, almost of stack and heap are reserved to the Trusted Applications.
See the FAQ in OP-TEE documentation.[1]

  • OP-TEE frame buffer

The OP-TEE frame buffer is a secure memory region dedicated to the display, used by Trusted UI in OP-TEE, protected by TZC. This region named optee-framebuffer is configured in OP-TEE device tree source Unsupported domain!.

7. U-Boot updates[edit source]

For some further description please read the U_Boot memory mapping.
To update the OP-TEE firmware in the STM32MP1 Distribution Package, use the devtool tool:

devtool modify u-boot-stm32mp

The updates requested according to new mapping:

  • Modify the RAM memory size (512Mo->256Mo), the location of the secure framebuffer memory (0xdd000000->0xceb00000), and the location (0xde000000->0xcfb00000) and size (30Mo->5Mo) of secure memory allocated to OP-TEE and SHM in the file arch/arm/dts/stm32mp135f-dk.dts
        memory@c0000000 {
               device_type = "memory";
               reg = <0xc0000000 0x10000000>;
        };
  
        reserved-memory {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
  
               optee_framebuffer@ceb00000 {
                        reg = <0xceb00000 0x1000000>;
                        no-map;
                };
  
                optee@cfb00000 {
                        reg = <0xcfb00000 0x00500000>;
                        no-map;
                };
     };
CONFIG_DDR_CACHEABLE_SIZE 0x8000000
Info white.png Information
DDR512Mo:
 It is a workaround to overwrite DDR size in the source file  arch/arm/mach-stm32mp/dram_init.c 
  int dram_init(void)
  {
       ...
      /*gd->ram_size = ram.size;*/
      gd->ram_size = SZ_256M;
 
       return 0;
  }

7.1. Description of the updates[edit source]

  • Secure memory reserved

It is the memory reserved for secure OS OP-TEE and share memory and the OP-TEE framebuffer dedicated to the display, used by Trusted UI in OP-TEE. The size of the memory reserved for secure OS OP-TEE is calculated as the way CFG_TZDRAM_SIZE + CFG_SHMEM_SIZE = 5Mo.

  • Size of the DDR marked cacheable in pre-reloc stage

CONFIG_DDR_CACHEABLE_SIZE define the size of the DDR marked as-cacheable in U-Boot pre-reloc stage. This option can be useful to avoid speculatif access to secured area of DDR used by TF-A or OP-TEE before U-boot initialization.

8. Kernel Linux updates[edit source]

To update the Kernel Linux in the STM32MP1 Distribution Package, use the devtool tool :

$PC > devtool modify linux-stm32mp

The updates requested according to new mapping:

  • Modify the RAM memory size (512Mo->256Mo), the location of the secure framebuffer memory (0xdd000000->0xceb00000), and the location (0xde000000->0xcfb00000) and size (30Mo->5Mo) of secure memory allocated to OP-TEE and SHM in the file arch/arm/dts/stm32mp135f-dk.dts
       memory@c0000000 {
               device_type = "memory";
               reg = <0xc0000000 0x10000000>;
        };

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		optee_framebuffer@ceb00000 {
			reg = <0xceb00000 0x1000000>;
			no-map;
		};
		
		optee@cfb00000 {
			reg = <0xcfb00000 0x00500000>;
			no-map;
		};		
	};

8.1. Description of the updates[edit source]

  • secure memory reserved

see U-boot updates description.

8.2. Linux kernel memory usage[edit source]

The resulting DDR Non Secure memory allocated to the Linux Kernel and userspace according to the mapping chosen for this exercise is: 0xceb00000 - 0xc0000000 = 0xeb00000 (235 Mo).

Purpose of this paragraph is to highlight you about some components size you can modify to share the Non secure RAM according to your need, the Linux kernel, the RAM File system, the Contiguous Memory Area (CMA).

We can estimate minimal amount of required RAM at system startup of the kernel image, we talk here about the static RAM used par Kernel image and the RAM file system. The kernel image execute the command :

$PC > size vmlinux

Example of result with OpenSTLinux default image : 16,5Mo

The initramfs/initrd is the temporary Root File system installed in RAM and used at the kernel init step, before mounting the final root file system. The contain of the RAM FS can be adjust according to the new mapping, you need space for copy the .cpio compressed file and the space for the file system unpacked. The default OpenSTLinux st-image-resize-initrd-openstlinux-weston-stm32mp13-disco.cpio.gz file is about 29.3Mo. The decompressed File system size is 50.4 Mo


Contiguous Memory Area (CMA), The size is defined in the kernel configuration file CONFIG_CMA_SIZE_MBYTES. CONFIG_CMA_SIZE_MBYTES is set to 128 in the OpenSTLinux distribution package.

9. traces/debug[edit source]

To verify your 256Mo config, some traces can be checked. The following traces have been obtained with a ST_OPTEE_DEBUG_LOG_LEVEL = "3" for the OP-TEE and a ST_TF_A_LOG_LEVEL_RELEASE = "40" for the TF-A.

Loading and boot of BL32 OP-TEE image.

INFO:    Loading image id=4 at address 0xcfc00000
INFO:    Image id=4 loaded: 0xcfc00000 - 0xcfc0001c
INFO:    OPTEE ep=0xcfc00000
INFO:    OPTEE header info:
INFO:          magic=0x4554504f
INFO:          version=0x2
INFO:          arch=0x0
INFO:          flags=0x0
INFO:          nb_images=0x1
INFO:    BL2: Loading image id 21
INFO:    Loading image id=21 at address 0xcfc00000

NOTICE:  BL2: Booting BL32
INFO:    Entry point address = 0xcfc00000

Firewall configuration D/TC:0 0 tzc_dump_state:473 region 0 D/TC:0 0 tzc_dump_state:476 region_base: 0x0000000000000000 D/TC:0 0 tzc_dump_state:479 region_top: 0x00000000ffffffff D/TC:0 0 tzc_dump_state:481 secure rw: TZC_REGION_S_NONE D/TC:0 0 tzc_dump_state:486 filter 0 enable

Secure region (4Mo) : OP-TEE D/TC:0 0 tzc_dump_state:473 region 1 D/TC:0 0 tzc_dump_state:476 region_base: 0x00000000cfc00000 D/TC:0 0 tzc_dump_state:479 region_top: 0x00000000cfffffff D/TC:0 0 tzc_dump_state:481 secure rw: TZC_REGION_S_RDWR D/TC:0 0 tzc_dump_state:486 filter 0 enable

Non secure region(1Mo) : Share memory D/TC:0 0 tzc_dump_state:473 region 2 D/TC:0 0 tzc_dump_state:476 region_base: 0x00000000cfb00000 D/TC:0 0 tzc_dump_state:479 region_top: 0x00000000cfbfffff D/TC:0 0 tzc_dump_state:481 secure rw: TZC_REGION_S_NONE D/TC:0 0 tzc_dump_state:486 filter 0 enable

Secure region (16Mo) : OP-TEE frame buffer D/TC:0 0 tzc_dump_state:473 region 3 D/TC:0 0 tzc_dump_state:476 region_base: 0x00000000ceb00000 D/TC:0 0 tzc_dump_state:479 region_top: 0x00000000cfafffff D/TC:0 0 tzc_dump_state:481 secure rw: TZC_REGION_S_RDWR D/TC:0 0 tzc_dump_state:486 filter 0 enable

Non secure region (235 Mo) : linux D/TC:0 0 tzc_dump_state:473 region 4 D/TC:0 0 tzc_dump_state:476 region_base: 0x00000000c0000000 D/TC:0 0 tzc_dump_state:479 region_top: 0x00000000ceafffff D/TC:0 0 tzc_dump_state:481 secure rw: TZC_REGION_S_NONE


U-Boot U-Boot 2021.10-stm32mp-r1 (Jan 27 2023 - 09:03:57 +0000)

CPU: STM32MP135F Rev.Z Model: STMicroelectronics STM32MP135F-DK Discovery Board Board: stm32mp1 in trusted mode (st,stm32mp135f-dk) Board: MB1635 Var1.0 Rev.C-01 DRAM: 256 MiB

Select the boot mode 1: OpenSTLinux 2: stm32mp135f-dk-a7-examples Enter choice: 1: OpenSTLinux

Temporary file system and linux kernel compressed file loaded in RAM Retrieving file: /st-image-resize-initrd 21498257 bytes read in 909 ms (22.6 MiB/s) Retrieving file: /uImage 7701112 bytes read in 335 ms (21.9 MiB/s) append: root=PARTUUID=e91c4e10-16e6-4c0e-bd0e-77becf4a3582 rootwait rw console=ttySTM0,115200 Retrieving file: /stm32mp135f-dk.dtb 59732 bytes read in 16 ms (3.6 MiB/s)

in Kernel boot traces The memory trace show the kernel part (16Mo) and the cma reserved (128Mo) CONFIG_CMA_SIZE_MBYTE

[ 0.000000] Memory: 65704K/262144K available (12288K kernel code, 1242K rwdata, 3436K rodata, 1024K init, 186K bss, 65368K reserved, 131072K cma-reserved, 0K highmem)