qemu(3) -- qemu-arm使用

1. 前言

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

2. 安装

2.1 qemu-user

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

shell 复制代码
# 大概需要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命令安装。
shell 复制代码
# 大概需要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
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");
	#endif

	return 0;
}
  1. 编写一个Makefile
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

  2. 根据这边文章的描述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调试。

shell 复制代码
# 启动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(4) -- qemu-system-arm使用

目录:全部文章合集

参考

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

相关推荐
yovo12 小时前
Linux权限管理
linux·运维·github
Johny_Zhao8 小时前
Ubuntu堡垒机搭建与设备管理指南
linux·网络·人工智能·信息安全·云计算·yum源·系统运维·teleport
程序员-King.9 小时前
【网络服务器】——回声服务器(echo)
linux·运维·服务器
华纳云IDC服务商9 小时前
华纳云:centos如何实现JSP页面的动态加载
java·linux·centos
云中飞鸿10 小时前
加载ko驱动模块:显示Arm版本问题解决!
linux·arm开发
二进制coder10 小时前
ARM32静态交叉编译并使用pidstat教程
linux
郑梓妍11 小时前
(持续更新)Ubuntu搭建LNMP(Linux + Nginx + MySQL + PHP)环境
linux·ubuntu·php
xflm12 小时前
qemu(4) -- qemu-system-arm使用
linux
Tesseract_952712 小时前
【Linux】VSCode用法
linux·c语言·vscode