QEMU用户模式测试AARCH64程序
QEMU的两种模式
QEMU(快速模拟器)是一个开源的机器模拟器和虚拟化器,它能够模拟多种处理器架构,并且可以在不同平台上运行。QEMU 支持两种模式:用户模式和系统模式。
- 用户模式(User Mode):
- 用户模式下的 QEMU 仅模拟用户空间的二进制执行环境,不模拟底层硬件。
- 这种模式下,QEMU 可以运行不同架构编译的二进制程序,而不需要这些程序与宿主机的架构相匹配。
- 用户模式通常用于测试和运行不同架构的应用程序,或者在不支持特定硬件架构的系统上运行程序。
- 用户模式不需要硬件虚拟化支持,因为它不模拟硬件。
- 系统模式(System Mode):
- 系统模式下的 QEMU 模拟整个计算机系统,包括 CPU、内存、硬盘、网络接口等硬件设备。
- 这种模式下,QEMU 可以运行完整的操作系统镜像,允许用户安装和运行完整的操作系统。
- 系统模式需要更多的资源,并且可能需要硬件虚拟化支持,以提高性能和安全性。
- 系统模式允许用户进行更全面的测试,包括操作系统级别的测试和硬件兼容性测试。
- 在系统模式下,QEMU 还可以使用不同的后端来提高性能,例如使用 KVM(Kernel-based Virtual Machine)在 Linux 系统上进行硬件辅助虚拟化。KVM 可以将 QEMU 转换为一个全功能的虚拟机监控器,提供接近原生硬件的性能。
要启动 QEMU 并使用用户模式或系统模式,你需要使用不同的命令行参数。例如:
用户模式:qemu-<arch> -cpu <cpu-type> -L <path-to-libraries> <program-to-run>
系统模式:qemu-system-<arch> -m <memory-size> -hda <disk-image>
其中 <arch> 是你想要模拟的架构,比如aarch64,<cpu-type> 是特定的 CPU 类型,<path-to-libraries> 是库文件的路径,<program-to-run> 是你想要运行的程序,<memory-size> 是分配给虚拟机的内存大小,<disk-image> 是虚拟硬盘镜像的路径。
QEMU 是一个非常灵活的工具,可以根据需要进行配置和扩展,以满足不同的模拟和虚拟化需求。
用户模式的安装
简单的执行如下命令就可以安装用户模式:
sudo apt-get update
sudo apt-get install qemu-user qemu-user-static gdb-multiarch build-essential gcc-aarch64-linux-gnu
用户模式C程序的测试
编写一个简单的C程序:
#include <stdio.h>int main(void) { return printf("Hello AARCH64!\n");
}
使用aarch64的编译器进行静态的交叉编译:
aarch64-linux-gnu-gcc -static -o hello64 hello.c
编译后使用file命令确认一下编译产生的事aarch64架构文件。
developer@ecs-cloud-host-ubuntu-img-make:~$ file hello64
hello64: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=c6209c6d4f0f2ec56fc1e9fe2443c34009ad60d5, for GNU/Linux 3.7.0, not stripped
如果没有安装QEMU用户模式程序,直接运行该程序会报告错误:
bash: ./hello64: cannot execute binary file: Exec format error
安装了QEMU用户模式之后,直接运行程序就可以得到正确的输出了。这是因为系统内有qemu-user-static,它支持了其他架构程序的直接运行。
developer@ecs-cloud-host-ubuntu-img-make:~$ ./hello64
Hello AARCH64!
也可以不使用static编译,比如:
aarch64-linux-gnu-gcc -o hello64dyn hello.c
不过不能直接运行hello64dyn这个程序,会报告错误:
developer@ecs-cloud-host-ubuntu-img-make:~$ ./hello64dyn
aarch64-binfmt-P: Could not open '/lib/ld-linux-aarch64.so.1': No such file or directory
这是需要使用qemu-user了:
developer@ecs-cloud-host-ubuntu-img-make:~$ qemu-aarch64 -L /usr/aarch64-linux-gnu ./hello64dyn
Hello AARCH64!
用户模式汇编程序的测试(调用C库)
准备一个简单的汇编程序hello.S
.section .text.global mainmain:
// Call puts and return stp fp, lr, [sp, #0x10]!mov fp, spadr x0, msgbl putsmov w0, wzrldp fp, lr, [sp], #0x10retmsg:.asciz "Hello Again!".align 2
这个程序里面调用了C语言的puts函数。
前两条指令是所谓的序言,SP 寄存器被调整,以便在可能的中断情况下保存数据,以便使用 puts 函数。
adr 指令将 x0 设置为字符串所在位置的内存地址。
'bl puts' 调用 puts 函数。它是一个 C 库函数,它将文本输出到控制台/终端。或者,可以使用 printf 代替。之所以使用 puts,是因为它对 CPU 来说更快,因为它不能接受所谓的字符串中的格式描述符。此外,puts 函数在控制台上自动加入换行。注意我们没有在 Hello Again 字符串中包含 "\n"。
'mov w0, wzr' 指令是给 CPU 一个零值,它将在退出程序时使用。稍后,CPU 将调用 C/C++ 退出函数来退出程序。每当你编写任何 .S(main:)类型的源文件时,最终的 ret 指令将使 CPU 结束程序并调用 C/C++ 退出函数。在 ret 指令之前,w0 应该总是设置为 0。
最后两条指令是所谓的尾声。基本上是序言的相反。
直接使用下面的语句去编译,C语言的编译器会自动处理汇编代码并进行库链接。
aarch64-linux-gnu-gcc -o hello hello.S
运行程序的方法和前面类似:
developer@ecs-cloud-host-ubuntu-img-make:~$ qemu-aarch64 -L /usr/aarch64-linux-gnu ./hello
Hello Again!
用户模式汇编程序的测试(调用系统调用)
我们也可以不使用C语言函数,直接使用QEMU模拟的系统调用。这和系统模式所模拟的裸机编程有所不同,系统模式是不提供任何系统调用的,你必须自己写串口输出代码或者使用编译好的BIOS文件。
下面是汇编代码:
.section .text.global _start_start:
// syscall write(int fd, const void *buf, size_t count)mov x0, #1 adr x1, msgmov x2, lenmov w8, #64 /*Syscall number for write for ARM64*/svc #0// syscall exit(int status)mov x0, #0mov w8, #93 /*Syscall number for exit for ARM64*/svc #0msg:.asciz "Hello World!\n"len = . - msg
QEMU 模拟所谓的系统调用。这些系统调用旨在模拟具有内置基本任务功能的计算机 BIOS。可以在程序中使用 svc 指令调用。在真正的硬件中,svc 指令将进入一个异常处理程序。在这个程序中,有代码(已经由程序早期编写)来处理 svc 的使用。
在 QEMU 中,这是完全不同的。你的程序在异常处理程序中写了什么并不重要。QEMU 将执行 svc 来模拟一个已经编写了某些指令的计算机 BIOS。简而言之,那里的例程在计算机 BIOS 中是通用的。因此,该例程接受某些参数以产生结果。你可以看出这是情况,因为在上述文件中,我们没有编写任何指令到任何异常处理程序。模拟系统调用的不好之处在于我们不能实际看到和调试 svc 异常。好的是,我们可以使用这些模拟器系统调用来执行基本任务。比如打印文本到控制台(终端),修改文件等。
系统调用 Write 会在控制台(终端)上打印消息。系统调用 Exit 退出程序。
有许多系统调用,每个系统调用都需要参数。在系统调用被“调用”(通过 svc 指令)之前,必须将正确的值放在正确的寄存器中。这种将正确的参数放在正确的寄存器中的概念被称为 ARM64 的调用约定。
代码中一些变量的解释:
- adr 设置 msg 标签所在位置的内存地址。
- msg: 是源文件中 Hello World 字符串所在的标签。字符串中的 "\n" 部分是你在控制台/终端输入新行时需要输入的。
- len = . - msg 这是用于计算字符串大小的汇编器指令。点(.)在这里代表这里。所以 '这里' 减去 msg 将设置字符串的字节量。
要运行程序,需要将其汇编成一个目标文件。然后使用链接器制作一个可执行文件。这可以通过以下两个终端命令完成..
aarch64-linux-gnu-as hello_world.s -o hello_world.o
aarch64-linux-gnu-ld hello_world.o -o hello_world
所以我们现在有一个可执行文件。我们可以用 QEMU 启动它:
qemu-aarch64 ./hello_world
得到如下输出:
developer@ecs-cloud-host-ubuntu-img-make:~$ qemu-aarch64 ./hello_world
Hello World!
因为安装了qemu-user-static,直接运行程序也是可以的。
参考文献
- Assembler, QEMU, GDB
- Running Arm Binaries on x86 with QEMU-User | Azeria Labs
相关文章:
QEMU用户模式测试AARCH64程序
QEMU的两种模式 QEMU(快速模拟器)是一个开源的机器模拟器和虚拟化器,它能够模拟多种处理器架构,并且可以在不同平台上运行。QEMU 支持两种模式:用户模式和系统模式。 用户模式(User Mode)&…...
机器学习(五) -- 监督学习(8) --神经网络2
机器学习系列文章目录及序言深度学习系列文章目录及序言 上篇:机器学习(五) -- 监督学习(8) --神经网络1 下篇: 前言 tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看…...
物联网之PWM呼吸灯、脉冲、LEDC
MENU 前言原理硬件电路设计软件程序设计analogWrite()函数实现呼吸灯效果LEDC输出PWM信号 前言 学习制作呼吸灯,通过LED灯的亮度变化来验证PWM不同电压的输出。呼吸灯是指灯光在单片机的控制之下完成由亮到暗的逐渐变化,感觉好像是人在呼吸。 原理 脉冲宽…...
Python利用pyecharts实现数据可视化
小编会持续更新知识笔记,如果感兴趣可以三连支持。闲来无事,水文一篇,不过上手实践一下倒还是挺好玩的,这一块知识说不定以后真可以尝试拿来做数据库的报表显示。 有梦别怕苦,想赢别喊累。 目录 前言 JSON数据格式的…...
网恋照妖镜源码搭建教程
文章目录 前言创建网站1.打开网站设置 配置ssl2.要打开强制HTTPS,用宝塔免费的ssl证书即可,也可以使用其他证书,必须是与域名匹配的3.上传文件至根目录进行解压4.解压后,修改文件 sc.php 里面的内容5.其余探索 前言 前俩年很火的…...
STM32
(以下操作环境为Keil5和proteus8.9) 八种输入输出模式及他们的工作模式 分析如下 总线:总线提供了数据在不同组件(如处理器、内存、输入输出设备等)之间传输的路径,使数据能够快速、准确地在系统内流动。 …...
用手机做抢答器 低预算知识竞赛活动的选择
使用手机作为抢答器是低预算竞赛活动的一个理想选择。随着智能手机的普及,传统抢答器已经被手机抢答器所替代,这种转变不仅降低了成本,而且提供了更大的灵活性和便利性。通过手机扫码登录竞赛软件,参赛者可以直接在手机上进行抢答…...
ELK学习笔记(二)——使用K8S部署Kibana8.15.0
上篇文章我们完成了,ES的集群部署,如果还没有看过上篇文章的兄弟,可以去看看。 ELK学习笔记(一)——使用K8S部署ElasticSearch8.15.0集群 话不多说,接下来直接进入kibana的搭建 一、下载镜像 #1、下载官方…...
报错:CPU指令集的问题
bug描述 我在运行CMAQ中的icon时,遇到bug: Please verify that both the operating system and the processor support Intel(R) X87, CMOV, MMX, FXSAVE, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT and AVX instructions.解决办法 经过查询&a…...
Type-C接口诱骗取电快充方案
Type-C XSP08Q 快充协议芯片是一种新型电源管理芯片,主要负责控制充电电流和电压等相关参数,从而实现快速充电功能。Type-C XSP08Q快充协议是在Type-C接口基础上,加入了XSP08Q协议芯片的支持,很大程度上提升了充电速度。 正常情况…...
图像白平衡
目录 效果 背景 什么是白平衡? 实现原理 将指定图色调调整为参考图色调主要流程 示例代码 效果 将图一效果转换为图二效果色调: 调整后,可实现色调对换 背景 现有两张图像,色调不一致,对于模型重建会有影响。因…...
SAP Business One 与无锡哲讯:携手共创企业数字化未来
在当今快速发展的商业世界中,企业的数字化转型已成为提升竞争力的关键。在众多的数字化解决方案中,SAP Business One 以其强大的功能和灵活性脱颖而出。与此同时,无锡哲讯智能科技有限公司作为专业的 SAP 系统服务提供商,为企业带…...
Unity Adressables 使用说明(五)在运行时使用 Addressables(Use Addressables at Runtime)
一旦你将 Addressable assets 组织到 groups 并构建到 AssetBundles 中,就需要在运行时加载、实例化和释放它们。 Addressables 使用引用计数系统来确保 assets 只在需要时保留在内存中。 Addressables 初始化 Addressables 系统在运行时第一次加载 Addressable …...
什么是死锁,如何解决?
什么是死锁? 在并发编程中,死锁是指两个或多个进程在竞争资源时,互相等待无法继续执行的状态。这种情况发生时,每个进程都在等待其他进程释放它们所需要的资源,但同时又不释放自己占有的资源,导致所有进程…...
借助ChatGPT三步,完成课题申报书中研究价值部分写作全攻略指南
大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 撰写申请书中的“本课题的学术价值…...
IDEA取消自动选择光标所在行
今天出现了一个怪事: 当我使用IDEA编写代码的时候,单击下一行或者上一行的时候,莫名其妙它会自己选中一行,导致我要么是回车代码直接没了,要么是代码直接给我搞错位了,还得按ctrlz返回,十分的恶…...
VUE2.0 elementUI el-input-number 数据更新,视图不更新——基础积累
今天遇到一个问题,是关于el-input-number组件的,发现数据明明已经更改了,但是页面上组件输入框中还是之前的值。 比如上方输入框中,我输入120.5,就会出现下面的诡异现象 回显此值是120.779,但是页面上输入…...
JS中this指向问题
首先,this的绑定和定义的位置无关,它的指向只和调用方式有关,this只有在运行时才知道指向谁。 一,默认绑定 默认绑定,也可以说是独立函数调用,这时this指向window。 function foo() {console.log(this) …...
大厂面试:小米嵌入式面试题大全及参考答案(130+道 12万长文)
Flink 架构介绍 Flink 是一个分布式流处理和批处理框架,具有高吞吐、低延迟、高可靠等特点。其架构主要由以下几个部分组成: 客户端(Client):负责将作业提交到集群,并与作业管理器进行交互,获取作业的状态信息。客户端可以是命令行工具、IDE 插件或者自定义的应用程序。…...
React 更新界面
文章目录 发现宝藏引入 useState声明和使用状态多个组件的状态管理解析代码 状态的局部性和性能优化结论 发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 在 React 中ÿ…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...
