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

qemu(3) -- qemu-user使用

1. 前言

qemu中有很多的特技,此处记录下qemu-arm的使用方式,简单来说qemu-system-xx用于虚拟整个设备,包括操作系统的运行环境,而qemu-xx仅虚拟Linux应用程序的环境,不涉及操作系统,应用程序的系统调用有宿主系统提供。

2. 安装

2.1 qemu-user

此处直接通过apt进行qemu-user的安装,该操作会一次性安装许多平台的仿真器。

# 大概需要65MB空间
$ sudo apt install qemu-user
0 upgraded, 2 newly installed, 0 to remove and 37 not upgraded.
Need to get 9621 kB of archives.
After this operation, 65.4 MB of additional disk space will be used.

2.2 arm-linux工具链

  1. arm的工具链可以通过apt命令安装。
# 大概需要140MB空间
$ sudo apt install gcc-arm-linux-gnueabi
0 upgraded, 18 newly installed, 1 to remove and 47 not upgraded.
Need to get 43.1 MB of archives.
After this operation, 140 MB of additional disk space will be used.
  1. 也可以去arm developer网上下载,我下载的是arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz,大概123MB。

3. 测试程序

  1. 编写一个测试程序main.c
#include <stdio.h>int main(int argc, char *argv[])
{printf("hello word!!!\n");#ifdef __x86_64__printf(">>>>>> I'm x86_64 arch <<<<<<\n");#elif defined(__ARMEL__)printf(">>>>>> I'm arm arch <<<<<<\n");#endifreturn 0;
}
  1. 编写一个Makefile
# 此处定义了arm-linux工具链中包含的arm的动态库,Makefile中$有特俗作用,传递给shell处理时需要使用$$表示$
ARM_LIBC = $(shell echo $$(dirname $$(which arm-none-linux-gnueabihf-gcc))/../arm-none-linux-gnueabihf/libc)all:# 使用主机的gcc编译并运行gcc main.c -g -o hello_x86_64./hello_x86_64# 使用arm-linux工具链编译,并设置静态链接arm-none-linux-gnueabihf-gcc main.c -g -static -o hello_arm_static# 对于静态链接的程序,可以使用qemu-arm直接运行qemu-arm hello_arm_static# 使用arm-linux工具链编译,缺省为动态链接arm-none-linux-gnueabihf-gcc main.c -g -o hello_arm_dyn# 动态链接的程序需要使用-L参数指定hello_arm_dyn的动态库搜索路径qemu-arm -L $(ARM_LIBC) hello_arm_dyn# hello_arm_dyn的动态库搜索路径也可以使用环境变量QEMU_LD_PREFIX来设置QEMU_LD_PREFIX=$(ARM_LIBC) qemu-arm hello_arm_dyn
  1. 执行make,观察输出。
# 执行make命令,以下内容为makefile和可执行程序所打印,可以看到arm的程序正常运行了
$ make
gcc main.c -o hello_x86_64
./hello_x86_64
hello word!!!
>>>>>> I'm x86_64 arch <<<<<<
arm-none-linux-gnueabihf-gcc main.c -o hello_arm_static -static
qemu-arm hello_arm_static
hello word!!!
>>>>>> I'm arm arch <<<<<<
arm-none-linux-gnueabihf-gcc main.c -o hello_arm_dyn
qemu-arm -L /home/xflm/tools/exe/arm-none-linux-gnueabihf/bin/../arm-none-linux-gnueabihf/libc hello_arm_dyn
hello word!!!
>>>>>> I'm arm arch <<<<<<
QEMU_LD_PREFIX=/home/xflm/tools/exe/arm-none-linux-gnueabihf/bin/../arm-none-linux-gnueabihf/libc qemu-arm hello_arm_dyn
hello word!!!
>>>>>> I'm arm arch <<<<<<

4. binfmt_misc

  1. Linux有一种binfmt_misc机制,简单说就是我们执行程序时,系统会根据该机制的配置信息选择使用不同的加载器,wsl种默认就有注册了一个解释器WSLInterop,内容如下。
# binfmt_misc机制以文件系统的方式存在
$ mount | grep bin
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,relatime)
# 查看WSLInterop解释器配置
$ sudo cat /proc/sys/fs/binfmt_misc/WSLInterop
enabled
# interpreter -- 启动文件的程序,需要是绝对路径,长度不能超过127
interpreter /init
# flags -- 可选字段,控制interpreter打开文件的行为。
# P -- 表示preserve-argv[0]保留原始的argv[0]参数。
# F -- 表示fix binary,binfmt-misc默认的行为在spwan进程时会延迟,这种方式可能会受到mount namespace和chroot的影响,设置F时会立刻打开二进制文件。
# O -- 表示open-binary,binfmt-misc默认会传递文件的路径,而启用这个参数时,binfmt-misc会打开文件,传递文件描述符。
# C -- 表示credentials,即会传递文件的setuid等权限,这个选项也隐含了O 。
flags: PF
# 文件的偏移
offset 0
# 文件的魔幻数
magic 4d5a
# 查看window上的ping.exe文件的开头,-g表示每列1个字节,-l表示显示4个字节,-R表示不要显示颜色
$ xxd -g 1 -l 4 -R never $(which ping.exe)
00000000: 4d 5a 90 00       MZ..
# 查看一下wsl中编译的hello_x86_64
xxd -g 1 -l 4 -R never hello_x86_64
00000000: 7f 45 4c 46       .ELF
  1. 根据这边文章的描述Support for miscellaneous binary formats (binfmt_misc) with Ubuntu on WSL,wsl中貌似暂时不支持该特性,所以执行sudo apt install qemu-user-binfmt sudo modprobe binfmt_misc sudo systemctl restart systemd-binfmt均不生效。

5. 调试

qemu-arm还支持gdb调试。

# 启动qemu-arm并等待gdb连接,gdbserver的端口为tcp 1234
$ qemu-arm -g 1234 hello_arm_static
# 此时qemu-arm不会直接运行程序,而是等待gdb连接
# 另外开一个窗口运行arm-none-linux-gnueabihf-gdb
$ arm-none-linux-gnueabihf-gdb
# 连接到qemu-arm开始调试
(gdb) target remote localhost:1234
# 在main()函数入口设置断点
(gdb) b main
# 全速运行,程序运行到main()函数时会停下来
(gdb) c

上一篇:qemu(2) – 定制开发板
下一篇:qemu(3) – qemu-user使用
目录:全部文章合集

参考

QEMU的基本使用方法(MIPS)
基于QEMU和binfmt-misc透明运行不同架构程序

相关文章:

  • 【Machine Learning Q and AI 读书笔记】- 01 嵌入、潜空间和表征
  • 4.环境变量
  • 对Electron打包的exe文件进行反解析
  • 中级社会工作者工作内容有哪些
  • 【go】go语言slice/map的产生背景,及原理理解
  • 【解决方案】Linux解决CUDA安装过程中GCC版本不兼容
  • LLaMA-Factory部署以及大模型的训练(细节+新手向)
  • C语言高频面试题——局部变量和全局变量可以重名吗?
  • 02《小地图实时》Unity
  • 区块链随学随记
  • 第二章 信息技术发展(2.2 新一代信息技术及应用)
  • PostgreSQL无法查看表中数据问题排查
  • linux 文本三剑客(grep sed awk)
  • 【计算机视觉】三种图像质量评价指标详解:PSNR、SSIM与SAM
  • 升级xcode15 报错Error (Xcode): Cycle inside Runner
  • 赋能航天教育:高校卫星仿真教学实验平台解决方案
  • 说说stack reconciler 和fiber reconciler
  • 安卓基础(强制转换)
  • ArkTS基础实验 (二)
  • 20250428-AI Agent:智能体的演进与未来
  • 海南儋州市委副书记任延新已赴市人大常委会履新
  • 事关稳就业稳经济,10张海报看懂这场发布会的政策信号
  • 年客流超2500万,九岁的上海国际旅游度假区有哪些文旅商体实践?
  • 国家市监总局:民生无小事,严打民生领域侵权假冒违法行为
  • 一夜跌去200美元,黄金巨震冲上热搜!涨势已近尾声?
  • 科普|结石疼痛背后的危机信号:疼痛消失≠警报解除