-
Notifications
You must be signed in to change notification settings - Fork 5
Description
OPTEE-OS会对secure memory进行分配,需要在ATF启动阶段就对DDR进行空间分层。因此,大致需要修改:
- ATF启动对secure ddr的划分
- Linux Kernel需要对踩在secure ddr范围的driver进行内存重新编址,需要更改设备树和kernel
- OPTEE-OS kernel需要定义HEAP_SIZE大小
- TA层级需要配置单个TA的HEAP分配能力
目标:
- 把TDA4原始的secure ddr起始地址从
0x9e800000->0xb2000000 - 原始色secure ddr size从
32M->128M
Note, 可能内存会有overlap,只是为了演示如何更改。
了解平台的memory map
每家SoC厂的内存设计不一样,因此需要先看SoC的物理内存结构和映射,check是否在物理层划分到secure ddr。
- TDA4平台的memory架构文档: https://www.ti.com/jp/lit/pdf/spradc1
- TDA4平台的memory map文档: https://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/latest/exports/docs/psdk_rtos/docs/user_guide/developer_notes_memory_map.html
- 官方手册:SPRUJ52C - J784S4-TDA4AP-TDA4VP-TDA4AH-TDA4VHAM-69A TRM.pdf
ATF
原理
ATF会启动OPTEE-OS BL32,需要指定跳转地址,因此这个首地址尽量不要去改:
ATF代码中缺省值: 0x9e800000 通过外部的make文件可以修改这个值。ATF这个位置,指定OPTEE-OS固件的位置:
最终ATF会调用到这里:
在设备上启动之后的log:
Note, opteeos开了ASLR,地址随机化之后就不是真实的地址了。
实践
编译ATF的时候:
export SECURE_DDR_START=0xb2000000
export SECURE_DDR_SIZE=0x10000000
make PLAT=k3 ARCH=aarch64 TARGET_BOARD=${TARGET_BOARD} SPD=opteed K3_USART=0x8 \
BL32_BASE=${SECURE_DDR_START} $( [ "$BUILD_DEBUG" = "Y" ] || [ "$BUILD_DEBUG" = "y" ] && echo "DEBUG=1" )
指定: BL32_BASE 环境变量即可:
https://github.com/carloscn/tda4-bsp/blob/master/bsp/build_atf.sh
OPTEE-OS 编译的时候
OPTEE-OS都可以通过编译的时候指定内存属性:
export CFG_CONSOLE_UART=0x8 && make -j16 \
CROSS_COMPILE=${ARCH32_CROSS_COMPILE} \
CROSS_COMPILE64=${ARCH64_CROSS_COMPILE} \
$( [ "$BUILD_DEBUG" = "Y" ] || [ "$BUILD_DEBUG" = "y" ] && echo "CFG_TEE_CORE_LOG_LEVEL=4 CFG_TEE_TA_LOG_LEVEL=4 CFG_TEE_CORE_DEBUG=y CFG_CORE_DUMP_OOM=y" ) \
PLATFORM=${PLATFORM} \
CFG_ARM64_core=y \
CFG_TEE_BENCHMARK=y \
CFG_TA_FLOAT_SUPPORT=y \
CFG_TZDRAM_START=${SECURE_DDR_START} \
CFG_TZDRAM_SIZE=${SECURE_DDR_SIZE} \
CFG_NUM_THREADS=64 \
CFG_TEE_RAM_VA_SIZE=0x8000000 \
CFG_SHMEM_SIZE=0x01000000 \
CFG_CORE_HEAP_SIZE=33554432这里面涉及到的比较重要的:
CFG_TZDRAM_START这是OPTEE-OS及TAs整个内存的起始位置,这里给定的是0xb2000000CFG_TZDRAM_SIZE同样OPTEE-OS及TAs整个内存的大小,这里给定的是128MB0x10000000已经非常高了。CFG_NUM_THREADS: 影响最大分页能力,大概是单个TA用heap和stack空间是64M,差不多就是64;同理,单个TA最大用32M,差不多这个数就是32;CFG_TEE_RAM_VA_SIZE:虚拟空间需要略低于CFG_TZDRAM_SIZE因为OPTEE-OS Core也需要一定的内存。这部分会影响单个TA的最大heap和stack空间的配置。如果单个TA的配置HEAP和STACK超过了这个值,TA在elf load阶段就会sys_map_zi出错。
D/TC:? 00 tee_ta_init_pseudo_ta_session:297 Lookup pseudo TA 67f7d1a5-dba8-48bc-9e79-79aa289e7d74
D/TC:? 00 ldelf_load_ldelf:110 ldelf load address 0x40007000
D/LD: ldelf:142 Loading TS 67f7d1a5-dba8-48bc-9e79-79aa289e7d74
F/TC:? 00 trace_syscall:150 syscall #3 (syscall_get_property)
F/TC:? 00 trace_syscall:150 syscall #5 (syscall_open_ta_session)
D/TC:? 00 ldelf_syscall_open_bin:163 Lookup user TA ELF 67f7d1a5-dba8-48bc-9e79-79aa289e7d74 (Secure Storage TA)
I/TC: WARNING (insecure configuration): Failed to get monotonic counter for REE FS, using 0
F/TC:? 00 plat_prng_add_jitter_entropy:72 0x81
F/TC:? 00 plat_prng_add_jitter_entropy:72 0xF2
F/TC:? 00 plat_prng_add_jitter_entropy:72 0x0B
F/TC:? 00 plat_prng_add_jitter_entropy:72 0x96
D/TC:? 00 ldelf_syscall_open_bin:167 res=0xffff0008
D/TC:? 00 ldelf_syscall_open_bin:163 Lookup user TA ELF 67f7d1a5-dba8-48bc-9e79-79aa289e7d74 (REE)
D/TC:2 00 core_mmu_xlat_table_alloc:527 xlat tables used 4 / 8
D/TC:2 00 core_mmu_xlat_table_alloc:527 xlat tables used 5 / 8
D/TC:? 00 ldelf_syscall_open_bin:167 res=0
F/TC:? 00 trace_syscall:150 syscall #7 (syscall_invoke_ta_command)
F/TC:? 00 trace_syscall:150 syscall #11 (syscall_mask_cancellation)
F/TC:? 00 trace_syscall:150 syscall #7 (syscall_invoke_ta_command)
F/TC:? 00 trace_syscall:150 syscall #3 (syscall_get_property)
E/LD: populate_segments:891 sys_map_zi
E/TC:? 00 ldelf_init_with_ldelf:152 ldelf failed with res: 0xffff000c
D/TC:? 00 tee_ta_open_session:689 init session failed 0xffff000c
tp: TEEC_Opensession failed with code 0xffff000c origin 0x3CFG_SHMEM_SIZEsharing memorpy大小CFG_CORE_HEAP_SIZE: 给OPTEE-OS Core的分配,这个数值其实有点太大了,OPTEE-OS暂时不需要这么多,如果并行运行非常多的TA,core可能需要更大的heap空间。
Uboot SPL
原理
TI设定了一个非常奇怪的启动时序,目前暂时没有体会到这样设计为什么,估计是为了TI的一些固件考虑吧。
TIFS -> ATF-> OPTEE-OS -> TIFS-> SPL ->U-Boot
这些固件制作tispl.bin还是在编译uboot的阶段。因此这里有个非常重要的点,tispl.bin的生成都是在uboot阶段生成的,tispl.bin的布局类似于一个fit image格式。因此TEE的地址需要在这里改正确,不然ATF没有办法启动optee-os:
实践
更改上述文件,load和entry都按照SECURE_DDR_START编写。
U-Boot
到了正式的U-Boot时,OPTEE-OS已经启动。此时Uboot的任务是初始化Linux Kernel,让其内存不要和secure ddr打架。如果kernel以非安全的权限访问到了secure ddr,会发生内存访问的系统异常。
U-Boot 是 bootloader,主要负责系统的初始化和加载 Linux 内核。在 U-Boot 阶段,设备树的主要作用是为 U-Boot 提供硬件描述,以便它能够正确配置硬件并完成启动流程。其中包含了OPTEE-OS对于secure ddr的预留空间,让UBOOT不要访问这部分的安全空间。
起始地址和大小对此进行保留:
secure_ddr: optee@b2000000 {
reg = <0x00 0xb2000000 0x00 0x10000000>;
no-map;
};
Linux Kernel
我暂时不确定Linux的kernel使用的设备树是uboot传递过来的还是自身的,这个可以通过配置来完成。但我倾向于TI的SDK是用Linux kernel中的设备树,因此这部分也需要改。
改成和Uboot一致即可
secure_ddr: optee@b2000000 {
reg = <0x00 0xb2000000 0x00 0x10000000>;
no-map;
};
目前通过启动可以看到OPTEE-OS的地址已经更改到0xb2000000了,但是和vision-apps-c71-dma-memory有冲突。可能需要找到一个没有被使用的空间,但现在只要vision-apps-c71-dma-memory 没有用,optee可以正常工作。
TA
我们只做了一个demo,该demo会对HEAP空间进行分配。
https://github.com/carloscn/cprojects/tree/master/test_performance
我们在TA里面分配如此大的空间,以应对TEE_Malloc。
目前可以正常的运行。










