首页 > 其他分享 >初探 ARM 半主机(Semihosting)及 QEMU 调试

初探 ARM 半主机(Semihosting)及 QEMU 调试

时间:2023-05-28 21:36:11浏览次数:45  
标签:newlib Semihosting com https QEMU ARM

转载:[分享] 初探 ARM 半主机(Semihosting)及 QEMU 调试-智能设备-看雪-安全社区|安全招聘|kanxue.com

 

我很想深入研究 ARM 的 TrustZone,想要搭建一个可以模拟和调试 Trusted Application 的平台环境。我了解到 Open-TEE (ATF) 项目提供有一个 QEMU 模拟调试环境。虽然是针对于 Open-TEE 的 TrustZone 实现,但是也可以作为一个参考来学习。在阅读这个项目的代码时,我留意到了一个 QEMU 的启动参数:

1 2 3 -semihosting-config enable,target=native   https://github.com/OP-TEE/build/blob/637c7863d7e428d673b18bae21ac1db52b2a9b8d/qemu.mk#L179

经过一番查找后发现这个 Semihosting 功能颇有用处:他能够让 bare-metal 的 ARM 设备通过拦截指定的 SVC 指令,在连操作系统都没有的环境中实现 POSIX 中的许多标准函数,比如 printf、scanf、open、read、write 等等。这些 IO 操作将被 Semihosting 协议转发到 Host 主机上,然后由主机代为执行,所以在 ARM 模拟器中执行一个 printf 可以直接打印到 Host 主机上的终端窗口中;在 ARM 模拟器中写一个文件可以直接写到 Host 主机的当前目录下,等等。

 

如果要写一个 TrustZone Kernel 的 QEMU 模拟环境,如果使用了 Semihosting,则不需要去模拟 FLASH 存储设备就能直接从 Host 主机上加载文件;不需要模拟串口设备就能直接打印 Log 输出,将会大大减少开发工作量。Open-TEE 项目也正是利用了 Semihosting 非常简单地就加载了 Trusted Application。

 

为了今后能够在我自己的项目中使用 Semihosting 这一方便的功能,我想要写点 Hello World 程序看看如何使用这个功能。

 

Semihosting 其实是 ARM 官方定义的功能,所有 ARM 芯片都支持这个协议,只要连上硬件调试器就能使用。当然了,QEMU 模拟 ARM 也把 Semihosting 模拟了一遍,只不过不需要什么特殊的连接就能直接使用。这个是 ARM 的官方文档:

 

https://developer.arm.com/documentation/dui0471/g/Semihosting/The-semihosting-interface

 

可以看到 SVC 0x123456 是官方给 Semihosting 预留的指定命令。当这条 SVC 被执行时,R0 寄存器的值是一个 Operation ID,R1 寄存器的值是指向附加参数结构体的指针。这个页面列举了 Semihosting 支持的 Operations:

 

https://developer.arm.com/documentation/dui0471/g/Semihosting/Semihosting-operations

 

比方说最简单的 puts 函数,对应的 Operation ID 是 SYS_WRITE0 (0x04),那我们就可以很简单地用 C 和汇编写一个 Hello World:

 

https://github.com/iNvEr7/qemu-learn/blob/master/semihosting

 

这个例子直接调用 SVC 指令把字符串打印出来。执行 make run 编译执行,需要安装 qemu, gcc, gcc-arm-none-eabi, tmux。

 

但是光有最基本 SVC 指令太弱了,如何才能使用更为强大的 POSIX/libc 功能,比如 printf 呢?答案是编译的时候使用 --specs=rdimon.specs 参数。这个会告诉编译器去链接 newlib 的 Semihosting 版本。这里解释一下,newlib 是专门给嵌入式设备实现的 libc 库,当然也包括了以 Semihosting 作为底层支持的模式。还有一个可选的参数 --specs=nano.specs 会链接 newlib 的精简版,去掉很多少用到的功能,减少编译出来的体积。

 

另外,newlib 因为要初始化 libc 环境,需要知道你的栈和堆在哪,所以需要你至少先将 SP 寄存器初始化到栈顶,newlib 会通过 Semihosting 的 HEAPINFO 指令获得内存大小,自动选择堆底地址。另外,newlib 虽然会初始化(清空).bss 内存区域,但是不会帮你初始化(拷贝).data 内存区域,所以需要你自己进行初始化。这是我用 newlib+Semihosting 实现的 Hello World:

 

https://github.com/iNvEr7/qemu-learn/blob/master/semihosting-newlib

 (已下载)

在实现这个 newlib 版本的时候,我遇到了一个让我头疼万分的 bug,在经过重重调试后发现原来是 QEMU 的一个 Regression Bug:

 

https://bugs.launchpad.net/qemu/+bug/1915925

 

已经提交给官方了,什么时候能修复还不知道,但是各位要运行这个例子的话需要给 QEMU 打一个补丁才行:

 

https://gist.github.com/iNvEr7/f99fe1219a30480ba692762c98fde829

 

如此一来你就可以使用任何 libc 的功能了,而且直接就能在 ARM bare-metal 系统上跑,完全不用理会 FLASH、UART 等硬件的实现。

 

更新一下,QEMU那個bug已經有fix了,會在6.0版推出修復,在那之前可以直接使用最新的git版本

 

标签:newlib,Semihosting,com,https,QEMU,ARM
From: https://www.cnblogs.com/zhiminyu/p/17438886.html

相关文章

  • 基于pycharm环境下opencv的搭建
    国际智能自主机器人大赛环境搭建python环境,IDE为pycharm,配置第三方库opencv。按下cmd+r,输入以下安装命令:pipinstallopencv-python--user-ihttps://pypi.tuna.tsinghua.edu.cn/simplepipinstallopencv-contrib-python--user-ihttps://pypi.tuna.tsinghua.edu.cn/simp......
  • Qemu仿真----(9)运行Debian Rootfs
    平台:ubuntu-22.04-desktop-amd64.对象:debianrootfs、qemu.文件:linux-6.1.26.tar.xz本例通过qemu运行debianrootfsforarm64。1.安装依赖$sudoaptinstallbinfmt-supportqemu-user-staticqemu-system-aarch64gcc-aarch64-linux-gnudebootstrap2.下载文件linux-......
  • PyCharm 版本2020.3 如何设置默认的python版本 以及 对应的依赖镜像源
    要在PyCharm2020.3中设置默认的Python版本以及依赖镜像源,请按照以下步骤进行操作:设置默认的Python版本:打开PyCharm,并打开您的项目。点击菜单栏上的"File"(文件)选项,然后选择"Settings"(设置)。在弹出的窗口中,展开"Project:YourProjectName"(项目:您的项目名)。点击"ProjectI......
  • PyCharm:PyCharm常用快捷命令
    为了提高编写代码的速度,以及方面程度,需要知道一些常用的快捷键。最常用的是:1.ctrl+c复制2.ctrl+d快速复制选中的内容并粘贴3.Ctrl+shift+n通过文件名快速查找工程内的文件4.ctrl+a全选5.Ctrl+alt+l调整代码格式6.Alt+enter导入模块7.Ctrl+z回退8.ctrl+x剪贴9.ctrl+/......
  • ARM Cortex-A72 CPU All In One
    ARMCortex-A72CPUAllInOneRaspberryPi4B,BCM27114核心1.5GHz64位CPU/RaspberryPi4B,BCM27114核心1.8GHz64位CPUCortex-A72https://developer.arm.com/Processors/Cortex-A72https://developer.arm.com/documentation/100095/0003/Introduction/A......
  • Qemu仿真----(7)运行Ubuntu Base
    平台:ubuntu-22.04-desktop-amd64.对象:ubuntubase、qemu.文件: ubuntu-base-22.04.2-base-arm64.tar.gz、linux-6.1.26.tar.xzUbuntuBase不是一个超小的内存运行嵌入式发行版;它是Ubuntu的最小实现,本例通过qemu运行ubuntu-base.1.安装依赖$sudoaptinstallbinfmt-suppor......
  • pycharm打开项目乱码解决方案
    常见乱码情况:控制台,左侧项目名称或程序中包含中文,展示乱码,一般产生的原因为编码格式不同导致的乱码,可以通过以下步骤设置。方法一:通过“File”->“FileEncoding”,设置“ProjectEncoding”为UTF-8方法二:如果是新增文件乱码,则可以在文件第一行设置编码格式#coding:gbk方法三:上......
  • (ADI)AD7276ARMZ高速模数转换器、A4980KLPTR汽车步进电机驱动器
    AD7276ARMZ是(ADI)的高速模数转换器、数模转换器和AFE/CODEC构成了业界知名的高速数据转换器产品组合。该器件具有出色性能、高输入带宽和集成的信号处理,使设计人员能够轻松、可靠地选择合适的方案用于各种应用,包括仪表、军用/航天、无线/有线通信和医学影像。位数:12采样率(每......
  • POJ 3069 Saruman's Army(贪心)
    传送门这个题是说给你n个点,然后让你标记其中尽可能少的点,使得n个点都处于被标记点左右不超过R的区间内我们使用的是贪心算法,也就是我们要将被标记的点尽可能的朝右边去即可,首先我们将他们从左到右进行排序,第一个我们所选取的被标记的点应该是能够包含掉左边的点的最靠右的点。。。......
  • 用pycharm创建一个django框架
    用pycharm创建一个django框架注意解释器的选择和文件路径创建完django项目1.自动创建了一个templates目录(先删除)2.把settings里的TEMPLATES=[{'BACKEND':'django.template.backends.django.DjangoTemplates','DIRS':[BASE_DIR/'templates......