Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ass:labs-2024:03:tasks:01 [2025/08/03 10:12] (current)
florin.stancu created
Line 1: Line 1:
 +==== 01. [Re]Configuring & building OP-TEE + ATF ====
 +
 +The initial step would be to embed OP-TEE OS into our firmware boot package and re-configure (and recompile) ARM Trusted Firmware-A to load it.
 +
 +But first, we need to understand the memory organization of our board.
 +This is required since BL31 (TF-A) has to configure the TZASC peripheral to reserve a trusted region inside the main memory (DRAM) for use by our Secure OS & TAs.
 +
 +== Step 1. Memory / address calculations ==
 +
 +{{ :​ass:​labs-2024:​03:​tz-memory.png?​300}}
 +
 +In the figure to the right, we use the upper end of the DDR1 memory (**36 MB**) for the TrustZone OS (BL32).
 +We will need to calculate the addresses and supply them as configuration parameters when compiling the software.
 +
 +In order to get the actual physical addresses, one needs to check out the official [[https://​www.nxp.com/​webapp/​Download?​colCode=IMX8MDQLQRM|NXP iMX8MQ Reference Manual]], Chapter 2.1.2 (Cortex-A53 Memory Map, pg. 20).
 +We note that the first DRAM (DDR1) is mapped at ''​0x40000000''​ (exactly **1GB** from the beginning the address space) and ends at ''​0xFFFFFFFF''​ (the difference of the two addresses totals to ''​3072MB == 3 * 1024MB == 3GB''​).
 +
 +But, since our boards only come with **2GB** of LPDDR chips installed, we need to recalculate the end of our DRAM memory region:
 +''​DRAM_END = 0x40000000 + 2*1024^3 == 0xC0000000 (in hex)''​).
 +
 +Next, you must do the math to find out the beginning of the TrustZone space: subtract ''​32 + 4 = 36 MB = 36 * 1024^2''​ from the end of the RAM!
 +
 +Finally, we split the TEE space in two: first ''​32MB''​ are reserved as secure memory (OP-TEE uses the term //TZDRAM// to describe this region), the last ''​4MB''​ are used as shared memory between the TEE and the Secure Monitor (thus, it is called //SHMEM//).
 +
 +Write those values out as Makefile variables (use the hexadecimal format for the calculation results, no spaces inside the number since space is the shell argument separator!),​ e.g.:
 +
 +<code bash>
 +TEE_TZDRAM_START = 0xbdc00000
 +TEE_TZDRAM_SIZE = <32MB as number of bytes, hex is accepted!>​
 +TEE_SHMEM_START = <calc TEE_TZDRAM_START + 32MB, resulting value as hex please>
 +TEE_SHMEM_SIZE = <4MB in bytes please>
 +TEE_RAM_TOTAL_SIZE = <36MB as number of bytes>
 +</​code>​
 +
 +These will be passed as compilation flags to the OP-TEE + TF-A build scripts (also makefile-based!) and will get inserted as C expressions into their code (thus, you can use valid mathematical expressions,​ but we recommend against it due to arcane makefile <-> shell argument passing issues).
 +
 +//(oh, the angular brackets, ''<​...>'',​ are NOT PART OF THE Makefile syntax, they are used as commentary placeholder and should be removed, too!)//
 +
 +== Step 2. Download & compile OP-TEE OS ==
 +
 +Now we're ready to run some compilation commands!
 +
 +Clone the official [[https://​github.com/​OP-TEE/​optee_os/​|OP-TEE OS repository]] inside your working directory'​s root (where you have all other projects like U-Boot, ATF/TF-A, Linux kernel etc.). Suggested directory name: ''​optee_os''​ (well... git automatically implies it, since it's also the name of the project).
 +
 +Now ''​cd''​ into OP-TEE'​s freshly downloaded source dir and compile it using GNU Make!
 +Here's the official build documentation:​ https://​optee.readthedocs.io/​en/​latest/​building/​gits/​optee_os.html.
 +
 +Well, not really... since the official instructions lack many of the required configuration flags (especially for our platform) and figuring them out requires some time-consuming source code studying, here are some pointers:
 +  * set the ''​CROSS_COMPILE''​ as in the labs before!
 +  * use the ''​DEBUG'',​ ''​CFG_TEE_BENCHMARK''​ and ''​CFG_TEE_CORE_LOG_LEVEL''​ values from the official example; set the ''​O=...''​ (output directory) to wherever you like;
 +  * the ''​PLATFORM''​ is ''​imx-mx8mqevk'';​ well, not really, but it's the closest one available, we start from here and override some of its configuration defaults, see next vars ;) 
 +  * set the ''​CFG_TZDRAM_START'',​ ''​CFG_TZDRAM_SIZE'',​ ''​CFG_TEE_SHMEM_START'',​ ''​CFG_TEE_SHMEM_SIZE''​ configuration flags to the values calculated above (reminder: you can reference another Makefile variable using ''​$(VARIABLE_NAME)''​ syntax);
 +  * finally, you will also need to pass ''​CFG_DDR_SIZE=0x80000000''​ (yep, that's 2GB, our board'​s actual installed memory).
 +
 +After a successful build, check the output (''​O''​) directory'​s ''​core''​ subdirectory for the ''​tee.bin'',​ ''​tee-raw.bin''​ and many other files!
 +We will keep the raw one for later inclusion into the firmware package using ''​mkimage''​ ;)
 +
 +<​note>​
 +Don't forget to save the build commands inside your Makefile script!
 +You should have seen its usefulness by now ;)
 +</​note>​
 +
 +== Step 3. Recompile ARM Trusted Firmware-A with added flags ==
 +
 +Remember the TF-A component (BL31) from [[:​ass:​labs-2024:​01|Lab 1]]?
 +We need to re-configure + rebuild it (hopefully, you still got the Makefile script)!
 +
 +This should be straightforward,​ since you've done it before ;) 
 +You need to set the following additional configuration variables to its make invocation:
 +  * ''​SPD=opteed''​ -- this is the [[https://​trustedfirmware-a.readthedocs.io/​en/​latest/​components/​spd/​index.html|Secure Payload Dispatcher]] module, aka: who does ATF's Secure Monitor need to talk with? Our OP-TEE, of course!
 +  * ATF also has to know the memory region where we've put OP-TEE (set the ''​BL32_BASE''​ variable to lower limit, in hexadecimal);​ we also need to specify its total size: ''​BL32_SIZE''​ (remember: we allocated ''​36MB'',​ but give it in bytes, either in base 10 or 16 using C integer notation);
 +  * We want ATF to print some debug messages over the first serial peripheral so, finally, set the ''​LOG_LEVEL=40''​ and ''​IMX_BOOT_UART_BASE=0x30860000''​ (if you look in iMX8MQ'​s Memory Map (the Reference Manual), this is the physical address of our Universal Asynchronous Transmitter/​Receiver - i.e. our serial communication module!).
 +
 +== Step 4. Rebuild the firmware image package ==
 +
 +Before we can take a look at the fruits of our effort so far, we need to re-build the firmware package with these last two components.
 +
 +This is easy if you saved your mkimage script (in your Makefile). You will need JUST one additional file copied: ''​tee-raw.bin''​ from ''​optee_os''​ build output directory, ''​core''​ subdirectory (as mentioned in the subtask above!) inside ''​mkimage'''​s build directory, but rename it as ''​tee.bin''​.
 +The bundled scripts will [[https://​github.com/​nxp-imx/​imx-mkimage/​blob/​lf-5.15.32_2.0.0/​iMX8M/​mkimage_fit_atf.sh#​L32|see that this file exists]] and add it to the image automatically!
 +
 +<note warning>
 +One more thing: when calling the imx-mkimage'​s script, set ''​TEE_LOAD_ADDR=<​TrustZone DRAM start address>''​.
 +
 +The default value is wrong for our SoC.
 +</​note>​
 +
 +Also make sure to replace ''​bl31.bin''​ with the newly recompiled one from ARM Trusted Firmware-A!
 +
 +Proceed to load this image over the serial boot protocol using the IMX ''​uuu''​ utility.
 +Check the serial console (the one provided by the board'​s Micro USB port) for confirmation!
 +
 +<spoiler Example UART output>
 +<​code>​
 +Found header at 0x404089a0
 +# Now, this is some output from ATF / BL31; never mind the warnings :D
 +D/​TC:​0 ​  ​plat_get_aslr_seed:​118 Warning: no ASLR seed
 +D/​TC:​0 ​  ​add_phys_mem:​665 VCORE_UNPG_RX_PA type TEE_RAM_RX 0xbdc00000 size 0x000cb000
 +D/​TC:​0 ​  ​add_phys_mem:​665 VCORE_UNPG_RW_PA type TEE_RAM_RW 0xbdccb000 size 0x00135000
 +D/​TC:​0 ​  ​add_phys_mem:​665 ta_base type TA_RAM 0xbde00000 size 0x01e00000
 +D/​TC:​0 ​  ​add_phys_mem:​665 CONSOLE_UART_BASE type IO_NSEC 0x30800000 size 0x00400000
 +...
 +# aaaaanddd our main dish, OP-TEE (BL32):
 +I/TC: OP-TEE version: 3.22.0-12-ga012b9923 (gcc version 13.1.0 (GCC)) #1 Fri Jul 14 19:24:34 UTC 2023 aarch64
 +I/TC: WARNING: This OP-TEE configuration might be insecure!
 +I/TC: WARNING: Please check https://​optee.readthedocs.io/​en/​latest/​architecture/​porting_guidelines.html
 +I/TC: Primary CPU initializing
 +D/TC:0 0 boot_init_primary_late:​1478 Executing at offset 0 with virtual load address 0xbdc00000
 +...
 +I/TC: Primary CPU switching to normal world boot
 +...
 +# BL33 (Normal U-Boot loads afterwards, as expected)
 +U-Boot 2022.04-g1f940d6213 (Jul 14 2023 - 22:22:25 +0300)
 +
 +CPU:   ​i.MX8MQ rev2.1 1300 MHz (running at 800 MHz)
 +CPU:   ​Industrial temperature grade (-40C to 105C) at 52C
 +...
 +</​code>​
 +</​spoiler>​
 +
  
ass/labs-2024/03/tasks/01.txt ยท Last modified: 2025/08/03 10:12 by florin.stancu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0