Skip to content

Latest commit

 

History

History
610 lines (454 loc) · 24.7 KB

File metadata and controls

610 lines (454 loc) · 24.7 KB

Week 1

2025.3.23

确定将参赛选题定为proj325。

2025.3.25

用原版GPUReplay替代原仓库,简单修改了参考文档。

问题:

  1. (已解决)原版GR使用的是发布于2017年的Hikey960开发板/Mali-G71 GPU。解决办法包括(1)直接买一块Hikey960,免去编程问题;(2)针对我们自己的开发板,编写相应驱动。
  2. (已推翻)我们目前只有raspi5开发板,但raspi5不支持OP-TEE。解决办法是换到OP-TEE已经支持的开发板。

方案:

  • (已推翻)最优解是买新一点的板子(支持OP-TEE,最好有Mali-G71 GPU),然后再简单写一点驱动(目前还不清楚原版GR针对Hikey960板子而非GPU的特化代码有多少)。目前看来,ROCK 4B是比较理想的选择:既支持OP-TEE,也是Mali系列的GPU。
  • (已解决)仍需要进一步分析源代码,以查明要修改哪些驱动。

2025.3.26

简单分析GR项目结构。

问题:

  1. (已解决)ROCK 4B使用的是Midgard Mali架构GPU,而非Bifrost Mali架构。两者是不同架构,驱动无法通用。因此如果选择ROCK 4B作为开发平台,就必须重新修改驱动。
  2. (已推翻&已证伪)GR针对Bifrost驱动的改动,用cloc --diff计算出了至少3000行,远超论文所说的700行。再加上要针对Midgard架构的特点做其他改动,修改驱动会花费很大精力。
  3. (已解决)ROCK 4B并不很新(2018年),GPU比Hikey960还老一些。相较Hikey960,除去后者在市面上只有二手货之外,几乎没有选择ROCK 4B的特别理由。

方案:

  • (已推翻)再选择ROCK 4B似乎已经不是很现实了,大概率还是得买个Hikey960,快速进入OP-TEE&GR的开发。
  • 要仔细考察proj325的四个要求。前两个要求已经隐含在OP-TEE和GR自身中了,后两个要求则需要自己查资料。
  • (已废弃)此外,也许还得看看bifrost-driver的开发文档?

2025.3.27

编写structure.md,为部分文件添加注释。

方案:

  • (已解决。OP-TEE的shell输出不限于UART)和郭老师聊过后,发现raspi5有对Trusted Firmware的支持,可以尝试运行OP-TEE。只能使用UART。
  • 此外,要修改raspi5 gpu在linux的driver(v3d, vc4)。这之前要先阅读bifrost-driver的修改。
  • (已解决)阅读linux kernel的DRM drivers文档。仍然有很多东西要学。

2025.3.28

阅读driver相关文档,调试raspi5的串口通信,调试raspi的系统,构建OP-TEE。

2025.3.29

成功构建OP-TEE并运行xtest。

2025.3.30

阅读Linux Device Drivers的第一章,了解了LKM的大致机理及其在内核中的地位等。

week 2

2025.3.31

阅读Linux Device Drivers的第二、三章:了解了module的基本属性,从装载到卸载等;了解char drivers(DRM drivers included)的基本数据结构,如file, fops等,及简单的内存管理、写入与读出。

2025.4.1

完成nano_driver的分析;分析replayer。

2025.4.2

完成replayer的分析。

2025.4.3

阅读Linux Device Drivers的第四、六章:内核调试技术,以直接的输入输出(printk, /proc...)为主,以interactive debugger(gdb, kgdb...)为辅;

2025.4.5

阅读Linux Device Drivers的第六章一部分。接下来分析hacked driver,必须参考https://bakhi.github.io/mobileGPU/。

2025.4.6

了解DRM、OpenCL等零碎的gpu知识。修改v3d,暂时只是把KBASE_TRACE_ADD宏插在v3d的对应位置。

问题:

(已证伪&已解决。TRACE不是用来record的;粒度详见structure.md)应该怎样掌握KBASE_TRACE_ADD安插的粒度?

方案:

  • (已证伪,TRACE不是用来record的,详见structure.md)应该是在包装reg的函数之外安插TRACE,这似乎是原作者的做法。这么一看的话,就安心许多了。不过值得注意的是,bifrost kdriver有一些用作包装的api函数。
  • (已证伪,TRACE不是用来record的,详见structure.md)鉴于v3d和bifrost driver架构的不同,不能只是找所谓的对应位置,得一个一个去翻v3d的函数,再添加TRACE。

week 3

2025.4.7

稍微写了下文档。分析recorder。

2025.4.8

完善文档,结束对recorder的分析。

2025.4.9

修改项目结构。完成了raspi5的xtest。

2025.4.10

插桩v3d,制作gr_io_history。

2025.4.11

试验在raspi5单独构建v3d driver。

2025.4.12

构建插桩了io_hisory的v3d driver,要当心各种依赖关系。尝试插桩mem_contents。优化项目结构。编写文档。

2025.4.13

插桩mem_contents。有很多要改。既然v3d的mmu比bifrost更简单,那就不用太害怕。

week 4

2025.4.14

阅读drm相关文档:drm internal及一小部分的drm memory。memory这一部分很重要。

2025.4.15

插桩as、pgt等。需要重新构建optee on raspi5。 https://github.com/joaopeixoto13/OPTEE-RPI4

2025.4.16

重新构建optee on raspi5,问题很大。根据教程,决定从头再来。在第一步就无法boot成功。

2025.4.17

继续插桩,继续重新构建,算是做到了不修改config的情况下通过boot。

2025.4.18

成功直接在raspi5运行optee。

2025.4.19

完成recorder的大部分。

week 5

2025.4.21

了解buildroot,了解optee的底层机制,实际上不需要太了解optee的底层机制。写environments文档。 https://optee.readthedocs.io/en/latest/building/trusted_applications.html 有关optee TA的构建规范。

2025.4.22

了解busybox。试图将v3d挂载到optee v3d,但遇到了v3d设备树节点未注册为平台设备的问题。

2025.4.23

继续了解optee。成功加载改过的v3d模组了,问题出在兼容的bcm版本,以及overlays文件夹。成功运行optee_examples。 https://wiki.st.com/stm32mpu/wiki/OP-TEE_concepts_overview

2025.4.24

交流项目后续进展。

2025.4.25

获得xzlin的v3d baremetal replayer。

2025.4.26

写完了readme文档,做完了ppt。

2025.4.28

改replayer。

week 6

2025.5.2

根据replayer,做初版recorder。下载ARM Compute Library。

2025.5.3

因为sms的问题,改到了6.12,继续折腾。

2025.5.4

拿到了recorder,做适配。

week 7

2025.5.5

成功编译v3d.ko。有理由认为图形界面会影响recorder的运作,导致bug。

此外还遇到了v3d->drm.driver为NULL的bug。

2025.5.6

解决了bug,基本完成了recorder&replayer。

2025.5.7

写脚本,分析recorder源码。write_gpu_mem_from_file读取了elf文件。

week 8

week 9

2025.5.13

测试py-videocore6库的recording。 似乎ncnn只有初次record才会dump_gpu_region。错了。 https://github.com/Idein/py-videocore6 以后记得给pip加上--proxy=http://127.0.0.1:7890的后缀,如果下载了clash。 创建了一个软链接来解决py-videocore6的设备节点问题。不行。改成修改sandbox/videocore6/drm_v3d.py的设备树节点了。

2025.5.14

继续测试py-videocore6库的recording。我没找到用于外部app调用的ioctl接口。 重读heejin的mobile gpu,有很多能学习的地方。 v3d_submit_csd_ioctl以及寄存器类型等东西是不是也要记录一下? 我在想干脆给py-videocore6做个RPi 5的适配算了。 irq出错很可能是因为驱动和recording的record_data路径没对齐。错了,不是这个原因。应该查找submit_csd后修改的寄存器,看看是不是缺少了相关record。 严重怀疑是不该屏蔽idle对寄存器的读写。错了,不是这个原因。 很可能是得改成NOREPLAY,已改。还有一个RELAXED。 成功了……一定要走完init+record+init+replay的全部流程。看清楚是不是idle。 还是不行,不知道为什么偶尔能成功。 对一个最小的csd触发器,可以成功replay irq。

2025.5.16

有理由认为bcl提交可能会跳过mem_dump,如果v3d没有初始化。这话不对,irq_bcl显然是由submit触发的,不一定有mem_dump。参见tiny_csd。会不会问题出在submit_cl等函数的内部?需要读源码。 有可能是触发irq的寄存器偏移搞错了!应该直接一一映射吗。不对。 没触发中断,很可能是job dispatch的信号根本没被捕捉到。 会不会是dump信号没捕捉到? 一个major problem:cprm->to_skip = 0。不加上去dump_emit就被跳过了。

2025.5.17

bug出在csd_cfg4上,几乎找不到解决办法。换rpi4。编译4kb页大小下的文件。

2025.5.18

rpi4一样出bug。试试手动计算cfg4并赋值。make olddefconfig -> make clean -> make modules_prepare -> make https://raspberrypi.stackexchange.com/questions/119483/how-to-access-to-the-configuration-of-my-raspberry-pi-os-lite sudo modprobe configs; zcat /proc/config.gz > /tmp/kernel.config; cat /tmp/kernel.config 升级到了6.12.28,因为原来的v3d不知怎么就probe不了gpu了。 If no errors appeared, your firmware was successfully updated to d688b628e142f64cde5ceabd9259f813ccae77d2

2025.5.19

https://github.com/Tencent/ncnn/wiki/how-to-build 重点关注一下v3d_csd_job_timeout这个函数呢?原话说是在job执行过程中用来检查job liveness。 https://github.com/RPi-Distro/rpi-source 竟然一直都不需要全量编译!那我可是多花了不知道多少时间!

2025.5.20

pre-release的ko怎么又成6.12.25了? 无论如何,将ncnn的推理结果复现,可能工作量会太大……目前先搁置吧,把gpu内存导出到用户空间再说。 手上有rpi4,该进行rpi4的py-videocore6了!这个最方便。

2025.5.22

alloc_bo是不是失败了?虚惊一场,那是v3d自带的debugfs。

2025.5.23

OPTEE rpi5 6.12失败。

2025.5.24

OPTEE rpi5 6.6失败。

2025.5.25

OPTEE rpi4 6.12失败。 https://hackmd.io/@gagachang/atf-on-rpi4

2025.6.1

https://macoy.me/blog/programming/RaspberryPi5Debugging

2025.6.3

是否可以直接注释掉shdr_veriry_signature()? 这个函数也许只是用来检测完整性,在项目初步验证的阶段不是很需要?

2025.6.4

https://forums.raspberrypi.com/viewtopic.php?t=368402 断电后务必重启openocd,而不是直接在原来的openocd进程。 基本可以确定问题是uart0。很有可能是overlays文件夹要对应,试试用原版安装包呢? update: 无用。

2025.6.5

tee-supplicant

2025.6.7

以后再试试rpi4? 能完整跑完entry,稍微宽慰一点了。

2025.6.8

不想复习->清理回收站->发现旧的可用镜像->旧的可用镜像在我的机器还是过不了serial flush->换杨南的机器->成功了。 人的一生会遇见多少次硬件错误?

2025.6.15

csd批数的问题神秘消失……很可能是mem dump和record对不上才导致出错!看来不能简简单单把相同input下的mem dump混用。 不对,看来问题出在前面的csd,后面的csd反倒能dump。 但我还真没比较出来批数不同带来的bin变化。。。对于最后一个csd job,bunch=0 or bunch=fc的情况下。 究竟是不是前面的批数太多呢?

已证实批数不变的情况下,前后memdump相同。 此外,批数改为0也不影响 mem dump 的效果,原因未知 diff -rq data/record_mem data/replay_mem 告诉我所有文件的效果都一致。

2025.6.25

大部分库都有对应的tee库,写ta会比较方便。 用pta的形式,而非user ta。

2025.6.26

ta和ca都能通过编译了。

2025.6.27

要做register_phys_mem。 io_pa_or_va不行,必须走chip,为什么? 记录一下io_pa_or_va的return,以及chip的return。

2025.6.29

如何解决中断?或者说不解决了。 如何解决内存分配过大?

2025.7.10

写点文档。清理了仓库的外观。给项目取名Rasplayer?

2025.7.21

调研llama.cpp。安装vulkansdk,和代理杠上了。

2025.7.22

用squid规避代理问题。要注意squid进程是否正常开始或结束。

2025.7.24

需要更新vulkan driver版本以支持新的api?

2025.7.25

meson setup build \ --libdir lib64 \ --prefix=/home/zhenlu/mesa-local \ -Dplatforms=x11 \ -Dvulkan-drivers=broadcom \ -Dgallium-drivers=v3d,kmsro,zink,vc4,swrast \ -Dglx=disabled -Degl=enabled -Dgbm=enabled \ -Dbuildtype=release

ninja -C build install

meson compile -C build meson install -C build

cmake -B build -DGGML_VULKAN=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/home/zhenlu/mesa-local

cmake --build build --config Release --parallel

https://www.jeffgeerling.com/blog/2024/llms-accelerated-egpu-on-raspberry-pi-5?utm_source=chatgpt.com

llama-cli -hf ggml-org/gemma-3-1b-it-GGUF

ggml-org/llama.cpp#9801

not working and not possible...

https://blog.steelph0enix.dev/posts/llama-cpp-guide/

how about ollama?

https://pimylifeup.com/raspberry-pi-ollama/

no...

how about opencl?

https://forums.raspberrypi.com/viewtopic.php?t=371844

no...

2025.7.26

写文档。

2025.7.27

写文档。

2025.7.28

测试mesa vulkan。

2025.7.29

测试mesa vulkan,放弃。

2025.7.30

测试pytorch。

2025.7.31

测试pytorch。

2025.8.1

测试pytorch。

2025.8.2

写文档。

2025.8.3

https://downloads.raspberrypi.com/raspios_full_armhf/release_notes.txt executorch. https://docs.pytorch.org/executorch/0.3/native-delegates-executorch-vulkan-delegate.html https://docs.pytorch.org/executorch/stable/backends-vulkan.html

rm -rf cmake-rpi-out &&
mkdir cmake-rpi-out &&
cmake -S . -B cmake-rpi-out
-DCMAKE_INSTALL_PREFIX=cmake-rpi-out
-DEXECUTORCH_BUILD_VULKAN=ON
-DPYTHON_EXECUTABLE=python &&
cmake --build cmake-rpi-out -j16 --target install

cmake --build cmake-rpi-out --target vulkan_executor_runner -j16

2025.8.5

https://pytorch.ac.cn/executorch/stable/build-run-vulkan.html

https://docs.pytorch.org/executorch/0.4/build-run-vulkan.html

pytorch/executorch#6373

python -m examples.models.llama.export_llama \
--disable_dynamic_shape --vulkan -kv -d fp16 \
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'

python -m examples.models.llama.export_llama
--disable_dynamic_shape --vulkan -kv -d fp16
--pt2e_quantize awq_int4 \
-c ~/.llama/checkpoints/llama3.2-1b/consolidated.00.pth
-p ~/.llama/checkpoints/llama3.2-1b/params.json
--metadata '{"get_bos_id":128000,"get_eos_ids":[128009,128001]}'

2025.8.6

python -m examples.models.llama.export_llama
--disable_dynamic_shape --vulkan -kv --use_sdpa_with_kv_cache -d fp32
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'

python -m examples.models.llama.export_llama
--disable_dynamic_shape
--vulkan
-kv \
--quantize_kv_cache int8 \
-d fp32 \
--pt2e_quantize awq_int4 \
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000, "get_eos_ids":[128009,128001]}'

python -m examples.models.llama.export_llama
--disable_dynamic_shape
--vulkan
-kv
-d fp32
--pt2e_quantize vulkan_8w
--quantize_kv_cache
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000,"get_eos_ids":[128009,128001]}'

python -m examples.models.llama.export_llama
--disable_dynamic_shape
--vulkan
-kv --use_sdpa_with_kv_cache
-d fp32
--pt2e_quantize vulkan_8w
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000,"get_eos_ids":[128009,128001]}'

python -m examples.models.llama.export_llama
--disable_dynamic_shape --vulkan -d fp32
-c ~/.llama/checkpoints/Llama3.2-1B/consolidated.00.pth
-p ~/.llama/checkpoints/Llama3.2-1B/params.json
--metadata '{"get_bos_id":128000, "get_eos_ids":[128009, 128001]}'

python -m examples.models.llama.export_llama
--vulkan
-kv --use_sdpa_with_kv_cache
-d fp32
-c ~/llama3.2/consolidated.00.pth
-p ~/llama3.2/params.json
--metadata '{"get_bos_id":128000,"get_eos_ids":[128009,128001]}'

vulkan后端的精度锁死在fp32

先source vulkansdk的env

rm -rf cmake-rpi-out &&
cmake . -DCMAKE_INSTALL_PREFIX=cmake-rpi-out
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON
-DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON
-DEXECUTORCH_BUILD_VULKAN=ON
-DEXECUTORCH_BUILD_XNNPACK=ON
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON
-DPYTHON_EXECUTABLE=python
-Bcmake-rpi-out &&
cmake --build cmake-rpi-out -j4 --target install

rm -rf cmake-rpi-out &&
cmake . -DCMAKE_INSTALL_PREFIX=cmake-rpi-out
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON
-DEXECUTORCH_BUILD_EXTENSION_MODULE=ON
-DEXECUTORCH_BUILD_EXTENSION_TENSOR=ON
-DEXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR=ON
-DEXECUTORCH_BUILD_VULKAN=ON
-DEXECUTORCH_BUILD_XNNPACK=ON
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON
-DPYTHON_EXECUTABLE=python
-Bcmake-rpi-out &&
cmake --build cmake-rpi-out -j4 --target install

rm -rf cmake-rpi-out/examples/models/llama &&
cmake examples/models/llama
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON
-DCMAKE_INSTALL_PREFIX=cmake-rpi-out
-DPYTHON_EXECUTABLE=python
-Bcmake-rpi-out/examples/models/llama &&
cmake --build cmake-rpi-out/examples/models/llama -j4

rm -rf cmake-rpi-out/examples/models/llama &&
cmake examples/models/llama
-DEXECUTORCH_BUILD_KERNELS_OPTIMIZED=ON
-DEXECUTORCH_BUILD_KERNELS_CUSTOM=ON
-DCMAKE_INSTALL_PREFIX=cmake-rpi-out
-DPYTHON_EXECUTABLE=python
-DBUILD_TESTING=OFF
-Bcmake-rpi-out/examples/models/llama &&
cmake --build cmake-rpi-out/examples/models/llama -j4

https://help.ubuntu.com/community/SwapFaq

修改config.

https://huggingface.co/unsloth/Llama-3.2-1B/tree/main

2025.8.9

https://docs.pytorch.org/tutorials/unstable/vulkan_workflow.html

要改一下executorch的makefile,限制运行时长。

2025.8.11

0b05!或者说,0***的最后一个bin。

2025.8.12

optee app 的掣肘主要是内存。

2025.8.14

mobilenet 12dd内存有结果。 https://github.com/Tencent/ncnn/wiki/quantized-int8-inference 注意ppt.

2025.8.17

记录时延。

todo:

  • (已完成)挑重点阅读Linux Device Drivers。
  • (已完成)分析nano driver。
  • (已完成)分析replayer。
  • (已完成)分析hacked driver,根据论文,对比与原版bifrost driver的不同。
  • (已完成)分析v3d driver源码。
  • (已完成)部分一:编写v3d recorder,预计1K SLoC。
  • (已完成)部分二:编写(或移植bifrost?)v3d user-level replayer,预计1K SLoC。似乎(似乎!)bifrost replayer没有多少bifrost的专用代码。然而由于OPTEE对api的限制,依靠mmap进行kernel bypass的bifrost driver源代码恐怕很难直接投入使用。
  • (已完成)部分三:编写OPTEE driver,预计100 SLoC。
  • 统计代码量。
  • 优化ta。

notes:

构建与环境

构建driver

  • 试验在raspi5单独构建v3d driver(as a module)。加一句KBUILD_MODPOST_WARN=1便能解决unresolved symbol error。
  • ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- 交叉编译选项。放弃了,还是老实用vm编译吧。
  • 注意linux kernel版本:6.6.51(uname -r)。

概念与论述

在raspi5的什么driver上实现GPUReplay?

DRM Drivers & v3d

OP-TEE

ARM TrustZone 架构将系统分为两个独立的世界:
	•	Normal World(普通世界):通常运行 Linux/Android 等常规操作系统,提供常规应用服务。
	•	Secure World(安全世界):运行像 OP-TEE 这样的可信执行环境,专门负责安全敏感的任务和数据处理。

当你在开发板(例如 Hikey960)上运行 OP-TEE 时,通常会看到两个终端窗口或串口控制台输出。这是因为:
	1.	两个世界各自有自己的输出
	•	一个终端展示的是 Normal World 的输出,包括 Linux(或其他 OS)的 shell、日志和应用程序消息。
	•	另一个终端显示的是 Secure World 的输出,也就是 OP-TEE 内核及其运行的 Trusted Applications(TA)的调试或日志信息。
	2.	哪个是 OP-TEE?
	•	OP-TEE 实际上运行在 Secure World 中。因此,显示 Secure World 输出的那个终端就是 OP-TEE 的输出。
	•	你通常可以从输出内容中辨别,比如 Secure World 终端会显示 OP-TEE 的启动信息、TA 的调试日志或者与安全相关的消息,而 Normal World 终端则显示常规操作系统的启动日志和 shell 提示符。

总结来说,出现两个终端是因为系统同时运行两个平行的操作系统:Normal World(Linux/Android)和 Secure World(OP-TEE)。而 OP-TEE 正是 Secure World 中运行的可信执行环境,所以显示 OP-TEE 日志的那个终端就是 Secure World。
当你在 Normal World(例如 Linux 系统上)输入 xtest 命令后,整个流程大致如下:
	1.	启动 xtest 应用程序
	•	xtest 是一个用户态程序,它利用 OP-TEE 提供的客户端 API(通常来自 libteec 库)运行。
	•	启动后,xtest 首先调用诸如 TEEC_InitializeContext() 等 API,建立与 OP-TEE 的通信上下文。
	2.	建立与 OP-TEE 的会话
	•	接下来,xtest 会调用 TEEC_OpenSession(),这会通过 Linux 内核中的 OP-TEE 驱动来创建一个到安全世界(OP-TEE Trusted OS)的会话。
	•	Linux 内核中的 OP-TEE 驱动会利用 ARM TrustZone 的机制,通过 SMC(Secure Monitor Call)指令把请求从 Normal World 传递到 Secure World。
	3.	安全世界接收并执行测试命令
	•	OP-TEE 运行在 Secure World中,接收到来自 Normal World 的调用后,会找到对应的 Trusted Application(TA)或内部测试模块,并执行相应的测试。
	•	这些测试通常涵盖 OP-TEE 的基本功能、内存管理、设备通信等,目的是验证系统的安全功能和兼容性。
	4.	返回测试结果
	•	当 Secure World 中的测试执行完毕后,结果会通过 SMC 调用的返回路径传递回 Linux 内核中的 OP-TEE 驱动,再由客户端 API 将结果传回 xtest 应用程序。
	5.	xtest 显示结果
	•	xtest 收到 Secure World 的测试结果后,会在终端中打印出测试输出、通过率、错误信息等,供你查看系统的安全环境状态。

⸻

总的来说,当你在 Normal World 运行 xtest 时,其实发生了这样一个过程:
	•	用户空间应用(xtest) → 通过 OP-TEE 客户端 API 发送请求 →
	•	Linux 内核中的 OP-TEE 驱动 → 通过 SMC 指令 切换到 Secure World →
	•	Secure World中的 OP-TEE 执行测试,并将结果返回到 Normal World →
	•	xtest 程序输出测试结果 到终端。

这种机制利用了 ARM TrustZone 的隔离特性,实现了 Normal World 与 Secure World 之间的安全通信。整个过程保证了敏感操作在 Secure World 内部执行,而普通应用则只获得调用接口及结果,从而提高安全性。