OPTEE
Per capire il motivo dell’ esistenza di
OPTEE (Open Portable Trusted Execution Environment)
dobbiamo prima parlare di Arm TrustZone,
cioè il meccanismo hardware
che permette di suddividere l’esecuzione della CPU
in 2 ambienti isolati tra loro,
il Secure World e il Normal World.
L’intera memoria indirizzabile dalla CPU
viene suddivisa in zone sicure o non sicure.
La memoria indirizzabile, chiamata address space,
è mappata fisicamente a varie periferiche,
come UART, RAM DDR, SYSRAM e così via.
Di conseguenza anche determinati applicativi
e interrupt routine possono essere marcati come
sicuri o non sicuri.
La CPU viene inizializzata in Secure World dal codice ROM
e TFA deve gestire il passaggio da questo al Normal World.
Dietro questo processo si nascondono i meccanismi di CoT (Chain Of Trust),
ma li affronteremo più avanti.
Per il momento ci basta sapere che
nella sua implementazione più semplice
il TFA si autentica come elemento sicuro,
avvia OPTEE come elemento sicuro e persistente in RAM DDR,
carica UBOOT come elemento non sicuro
e passa l’esecuzione a questo.
OPTEE viene chiamato Secure Monitor perchè
sarà poi lui a gestire eventuali richieste
dal Normal World al Secure World,
ad esempio se un applicativo non sicuro
vuole accedere a risorse sicure (come chiavi cifrate o alto).
Come visto per il TFA, cerchiamo di capire come configurare OPTEE basandoci su:
- il recipe originale
optee-os_4.10.0.bb - la documentazione di OPTEE
- i sorgenti della repository OPTEE
dal recipe originale
Notiamo subito che il progetto utilizza make e che vengono passate le seguenti variabili:
23EXTRA_OEMAKE += " \
24 PLATFORM=${OPTEEMACHINE} \
25 CFG_${OPTEE_CORE}_core=y \
26 CROSS_COMPILE_core=${HOST_PREFIX} \
27 CROSS_COMPILE_ta_${OPTEE_ARCH}=${HOST_PREFIX} \
28 AFLAGS="${CFLAGS}" \
29 ta-targets=ta_${OPTEE_ARCH} \
30 O=${B} \
31"e compilati con target all:
43do_compile() {
44 oe_runmake -C ${S} all
45}Le variabile bitbake che ci interessano sono:
OPTEEMACHINEOPTEE_COREOPTEE_ARCH
Mentre quelle make che sarebbero da indagare sono:
PLATFORMCFG_*_coreta-targets
dalla documentazione
La documentazione più recente indica il supporto
per la famiglia stm32mp1, ma non per stm32mp2,
quindi è probabile che ST abbia dovuto fare un fork
del progetto e i cambiamenti non siano ancora
stati aggiunti in upstream.
Potremmo leggere le procedure di porting,
ma visto che non saremo noi a dover scrivere
il codice c per supportare il processore
per il momento passiamo a…
dai sorgenti
Nel Makefile principale si vede l’inclusione di core/core.mk
e in questo l’utilizzo delle variabili ARCH e PLATFORM
per individuare un make specifico per la piattaforma:
43arch-dir := core/arch/$(ARCH)
44platform-dir := $(arch-dir)/plat-$(PLATFORM)
45include $(platform-dir)/conf.mk
46include mk/config.mk
47# $(ARCH).mk also sets the compiler for the core module
48include core/arch/$(ARCH)/$(ARCH).mkoptee_os
├── Makefile
├── ...
└── core
├── ...
└── arch
├── riscv
└── arm
├── ...
├── dts
│ ├── ...
│ └── stm32mp257f-dk.dts
└── plat-stm32mp2
├── ...
└── conf.mkIn questo vediamo come viene definito il devicetree da utilizzare:
16# Check if device-tree exist in OP-TEE source code, else search it in external
17# device tree repository
18ifeq ($(wildcard $(arch-dir)/dts/$(CFG_EMBED_DTB_SOURCE_FILE)),)
19# External device tree default path
20CFG_EXT_DTS ?= $(arch-dir)/dts/external-dt/opteeCome viene definito il modello di CPU:
37# CFG_STM32MP2x switches are exclusive.
38# - CFG_STM32MP25 is enabled for STM32MP25x-* targets (default)
39# - CFG_STM32MP23 is enabled for STM32MP23x-* targets
40# - CFG_STM32MP21 is enabled for STM32MP21x-* targets
41# We try to guess the variant from the embedded DT source file nameUna menzione a diverse modalità di OPTEE:
68# CFG_STM32MP_PROFILE selects the profile of the services embedded in OP-TEE
69CFG_STM32MP_PROFILE ?= secure_and_system_services
70
71ifeq ($(filter $(CFG_STM32MP_PROFILE),system_services secure_and_system_services),)
72$(error CFG_STM32MP_PROFILE shall be one of system_services or secure_and_system_services)
73endif
74
75ifeq ($(CFG_STM32MP_PROFILE),system_services)
76include $(platform-dir)/conf.disable-secure-services.mk
77endifUna sfilza di configurazioni di default:
68# Support DDR ranges up to 8GBytes (address range: 0x80000000 + DDR size)
69CFG_CORE_LARGE_PHYS_ADDR ?= y
70CFG_CORE_ARM64_PA_BITS ?= 34
71
72CFG_TEE_RAM_VA_SIZE ?= 0x400000
73CFG_CORE_HEAP_SIZE ?= 393216
74CFG_CORE_RESERVED_SHM ?= nPer evitare problemi con l’ assegnazione di argomenti a make, dobbiamo controllare quali valori il recipe originale gli passa e come li assegna. Ad esempio:
12OPTEEMACHINE ?= "${MACHINE}"
13OPTEE_ARCH:aarch64 = "arm64"
14OPTEE_CORE = "${@d.getVar('OPTEE_ARCH').upper()}"che poi vengono passate alla variabile OEMAKE:
22EXTRA_OEMAKE += " \
23 PLATFORM=${OPTEEMACHINE} \
24 CFG_${OPTEE_CORE}_core=y \
25 CROSS_COMPILE_core=${HOST_PREFIX} \
26 CROSS_COMPILE_ta_${OPTEE_ARCH}=${HOST_PREFIX} \
27 NOWERROR=1 \
28 ta-targets=ta_${OPTEE_ARCH} \
29 O=${B} \
30"che causerà nel recipe:
23EXTRA_OEMAKE += " \
24 PLATFORM=stm32mp257f-dk \
25 CFG_ARM64_core=y \
26 CROSS_COMPILE_core=${HOST_PREFIX} \
27 CROSS_COMPILE_ta_arm64=${HOST_PREFIX} \
28 AFLAGS="${CFLAGS}" \
29 ta-targets=ta_arm64 \
30 O=${B} \
31"l’unico problema è che vogliamo PLATFORM=stm32mp2 in make
quindi definiamo OPTEEMACHINE=stm32mp2 in yocto.
Poi definiamo il modello preciso passando CFG_STM32MP25=y a make.
Definiamo il devicetree passando CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-dk.dts a make.
E per il momento passiamo CFG_STM32MP_PROFILE=system_services a make
per disabilitare delle funzioni aggiuntive di cui possiamo fare a meno.
recipe finale
Otteniamo allora:
68PV = "4.0.0-stm32mp"
69SRC_URI = "git://github.com/STMicroelectronics/optee_os.git;protocol=https;branch=4.0.0-stm32mp"
70SRCREV = "4.0.0-stm32mp-r2"
71
72
73OPTEEMACHINE = "stm32mp2"
74
75EXTRA_OEMAKE:append = " \
76 CFG_STM32MP25=y \
77 CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-dk.dts \
78 CFG_STM32MP_PROFILE=system_services \
79"