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透明运行不同架构程序

相关推荐
2035去旅行6 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
陈希1237 小时前
Linux 防火墙配置实战:firewalld、iptables 与云安全组
linux·运维·服务器
女神下凡8 小时前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
且从容.11 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道12 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.15 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落16 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨16 小时前
WSL2的安装与使用
linux·wsl
微小的鱼16 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng17 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器