当前位置: 首页 > news >正文

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&#xff08;快速模拟器&#xff09;是一个开源的机器模拟器和虚拟化器&#xff0c;它能够模拟多种处理器架构&#xff0c;并且可以在不同平台上运行。QEMU 支持两种模式&#xff1a;用户模式和系统模式。 用户模式&#xff08;User Mode&#xff09;&…...

机器学习(五) -- 监督学习(8) --神经网络2

机器学习系列文章目录及序言深度学习系列文章目录及序言 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 监督学习&#xff08;8&#xff09; --神经网络1 下篇&#xff1a; 前言 tips&#xff1a;标题前有“***”的内容为补充内容&#xff0c;是给好奇心重的宝宝看…...

物联网之PWM呼吸灯、脉冲、LEDC

MENU 前言原理硬件电路设计软件程序设计analogWrite()函数实现呼吸灯效果LEDC输出PWM信号 前言 学习制作呼吸灯&#xff0c;通过LED灯的亮度变化来验证PWM不同电压的输出。呼吸灯是指灯光在单片机的控制之下完成由亮到暗的逐渐变化&#xff0c;感觉好像是人在呼吸。 原理 脉冲宽…...

Python利用pyecharts实现数据可视化

小编会持续更新知识笔记&#xff0c;如果感兴趣可以三连支持。闲来无事&#xff0c;水文一篇&#xff0c;不过上手实践一下倒还是挺好玩的&#xff0c;这一块知识说不定以后真可以尝试拿来做数据库的报表显示。 有梦别怕苦&#xff0c;想赢别喊累。 目录 前言 JSON数据格式的…...

网恋照妖镜源码搭建教程

文章目录 前言创建网站1.打开网站设置 配置ssl2.要打开强制HTTPS&#xff0c;用宝塔免费的ssl证书即可&#xff0c;也可以使用其他证书&#xff0c;必须是与域名匹配的3.上传文件至根目录进行解压4.解压后&#xff0c;修改文件 sc.php 里面的内容5.其余探索 前言 前俩年很火的…...

STM32

&#xff08;以下操作环境为Keil5和proteus8.9&#xff09; 八种输入输出模式及他们的工作模式 分析如下 总线&#xff1a;总线提供了数据在不同组件&#xff08;如处理器、内存、输入输出设备等&#xff09;之间传输的路径&#xff0c;使数据能够快速、准确地在系统内流动。 …...

用手机做抢答器 低预算知识竞赛活动的选择

使用手机作为抢答器是低预算竞赛活动的一个理想选择。随着智能手机的普及&#xff0c;传统抢答器已经被手机抢答器所替代&#xff0c;这种转变不仅降低了成本&#xff0c;而且提供了更大的灵活性和便利性。通过手机扫码登录竞赛软件&#xff0c;参赛者可以直接在手机上进行抢答…...

ELK学习笔记(二)——使用K8S部署Kibana8.15.0

上篇文章我们完成了&#xff0c;ES的集群部署&#xff0c;如果还没有看过上篇文章的兄弟&#xff0c;可以去看看。 ELK学习笔记&#xff08;一&#xff09;——使用K8S部署ElasticSearch8.15.0集群 话不多说&#xff0c;接下来直接进入kibana的搭建 一、下载镜像 #1、下载官方…...

报错:CPU指令集的问题

bug描述 我在运行CMAQ中的icon时&#xff0c;遇到bug&#xff1a; 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 快充协议芯片是一种新型电源管理芯片&#xff0c;主要负责控制充电电流和电压等相关参数&#xff0c;从而实现快速充电功能。Type-C XSP08Q快充协议是在Type-C接口基础上&#xff0c;加入了XSP08Q协议芯片的支持&#xff0c;很大程度上提升了充电速度。 正常情况…...

图像白平衡

目录 效果 背景 什么是白平衡&#xff1f; 实现原理 将指定图色调调整为参考图色调主要流程 示例代码 效果 将图一效果转换为图二效果色调&#xff1a; 调整后&#xff0c;可实现色调对换 背景 现有两张图像&#xff0c;色调不一致&#xff0c;对于模型重建会有影响。因…...

SAP Business One 与无锡哲讯:携手共创企业数字化未来

在当今快速发展的商业世界中&#xff0c;企业的数字化转型已成为提升竞争力的关键。在众多的数字化解决方案中&#xff0c;SAP Business One 以其强大的功能和灵活性脱颖而出。与此同时&#xff0c;无锡哲讯智能科技有限公司作为专业的 SAP 系统服务提供商&#xff0c;为企业带…...

Unity Adressables 使用说明(五)在运行时使用 Addressables(Use Addressables at Runtime)

一旦你将 Addressable assets 组织到 groups 并构建到 AssetBundles 中&#xff0c;就需要在运行时加载、实例化和释放它们。 Addressables 使用引用计数系统来确保 assets 只在需要时保留在内存中。 Addressables 初始化 Addressables 系统在运行时第一次加载 Addressable …...

什么是死锁,如何解决?

什么是死锁&#xff1f; 在并发编程中&#xff0c;死锁是指两个或多个进程在竞争资源时&#xff0c;互相等待无法继续执行的状态。这种情况发生时&#xff0c;每个进程都在等待其他进程释放它们所需要的资源&#xff0c;但同时又不释放自己占有的资源&#xff0c;导致所有进程…...

借助ChatGPT三步,完成课题申报书中研究价值部分写作全攻略指南

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 撰写申请书中的“本课题的学术价值…...

IDEA取消自动选择光标所在行

今天出现了一个怪事&#xff1a; 当我使用IDEA编写代码的时候&#xff0c;单击下一行或者上一行的时候&#xff0c;莫名其妙它会自己选中一行&#xff0c;导致我要么是回车代码直接没了&#xff0c;要么是代码直接给我搞错位了&#xff0c;还得按ctrlz返回&#xff0c;十分的恶…...

VUE2.0 elementUI el-input-number 数据更新,视图不更新——基础积累

今天遇到一个问题&#xff0c;是关于el-input-number组件的&#xff0c;发现数据明明已经更改了&#xff0c;但是页面上组件输入框中还是之前的值。 比如上方输入框中&#xff0c;我输入120.5&#xff0c;就会出现下面的诡异现象 回显此值是120.779&#xff0c;但是页面上输入…...

JS中this指向问题

首先&#xff0c;this的绑定和定义的位置无关&#xff0c;它的指向只和调用方式有关&#xff0c;this只有在运行时才知道指向谁。 一&#xff0c;默认绑定 默认绑定&#xff0c;也可以说是独立函数调用&#xff0c;这时this指向window。 function foo() {console.log(this) …...

大厂面试:小米嵌入式面试题大全及参考答案(130+道 12万长文)

Flink 架构介绍 Flink 是一个分布式流处理和批处理框架,具有高吞吐、低延迟、高可靠等特点。其架构主要由以下几个部分组成: 客户端(Client):负责将作业提交到集群,并与作业管理器进行交互,获取作业的状态信息。客户端可以是命令行工具、IDE 插件或者自定义的应用程序。…...

React 更新界面

文章目录 发现宝藏引入 useState声明和使用状态多个组件的状态管理解析代码 状态的局部性和性能优化结论 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 在 React 中&#xff…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...