在 QEMU 中建立 ARM Linux

环境

原生环境:Windows 10 64-bit
原生虚拟环境:VMware station 12.5, Ubuntu 18.04 LTS Desktop
套娃虚拟环境:QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.23),Ubuntu 16.04 LTS for aarch64 Server

使用方法:

  1. 启动 Win 10
  2. 启动 VMware
  3. 启动 VMware 里的 Ubuntu 18.04 LTS
  4. 在以上 Ubuntu 内启动 qemu-system-aarch64 的一大堆脚本
  5. qemu 会通过 UEFI-grub-kernel 的方式,启动 Ubuntu 16.04 LTS for aarch64

运行方法

安装 qemu

sudo apt install qemu-system-arm qemu-efi

建立硬盘镜像

qemu-img create -f qcow2 ubuntu16.04-arm64.qcow2 40G

下载安装镜像

http://cdimage.ubuntu.com/releases/16.04/release/

建立虚拟机并安装 Ubuntu

注意 iso 文件和 QEMU_EFI.fd 文件路径。后者在 /usr/share/qemu-efi/QEMU_EFI.fd

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic -drive if=none,file=ubuntu-16.04.6-server-arm64.iso,id=cdrom,media=cdrom -device virtio-scsi-device -device scsi-cd,drive=cdrom -drive if=none,file=ubuntu16.04-arm64.qcow2,id=hd0 -device virtio-blk-device,drive=hd0

完成后关机。

建立网络

宿主机

#!/bin/sh

ifconfig ens33 down # 首先关闭宿主机网卡接口
brctl addbr br0 # 添加一座名为 br0 的网桥
brctl addif br0 ens33 # 在 br0 中添加一个接口
brctl stp br0 off # 如果只有一个网桥,则关闭生成树协议
brctl setfd br0 1 # 设置 br0 的转发延迟
brctl sethello br0 1 # 设置 br0 的 hello 时间
ifconfig br0 0.0.0.0 promisc up # 启用 br0 接口
ifconfig ens33 0.0.0.0 promisc up # 启用网卡接口
dhclient br0 # 从 dhcp 服务器获得 br0 的 IP 地址
brctl show br0 # 查看虚拟网桥列表
brctl showstp br0 # 查看 br0 的各接口信息

tunctl -t tap0 -u root # 创建一个 tap0 接口,只允许 root 用户访问
brctl addif br0 tap0 # 在虚拟网桥中增加一个 tap0 接口
ifconfig tap0 0.0.0.0 promisc up # 启用 tap0 接口
brctl showstp br0 # 显示 br0 的各个接口

虚拟机启动

qemu-system-aarch64 -m 2048 -cpu cortex-a57 -smp 2 -M virt -bios QEMU_EFI.fd -nographic -device virtio-scsi-device -drive if=none,file=ubuntu16.04-arm64.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 -net nic -net tap,ifname=tap0,script=no,downscript=no

arm ubuntu 进去后,

ifconfig -a # 查看网卡名
sudo ifconfig <ethx> up # 启用网卡
sudo dhclient <ethx> # DHCP 获取IP

效率

测试采用 sysbench 软件,从 apt 可以直接下载。
测试指令:sysbench --test=cpu run。即使用单线程寻找前 10000 个素数。

VMware Ubuntu:每秒 941 次

CPU speed:
events per second: 940.83

General statistics:
total time: 10.0011s
total number of events: 9412

Latency (ms):
min: 0.83
avg: 1.06
max: 6.45
95th percentile: 1.42
sum: 9989.10

Threads fairness:
events (avg/stddev): 9412.0000/0.00
execution time (avg/stddev): 9.9891/0.00

QEMU Ubuntu for aarch64:37 秒完成 10000 次,每秒 270 次

Maximum prime number checked in CPU test: 10000


Test execution summary:
total time: 36.9989s
total number of events: 10000
total time taken by event execution: 36.9503
per-request statistics:
min: 2.03ms
avg: 3.70ms
max: 20.24ms
approx. 95 percentile: 7.63ms

Threads fairness:
events (avg/stddev): 10000.0000/0.00
execution time (avg/stddev): 36.9503/0.00

参考配置1
机架服务器虚拟机 Ubuntu 18.04 LTS:每秒 849 次

CPU speed:
events per second: 848.75

General statistics:
total time: 10.0009s
total number of events: 8490

Latency (ms):
min: 1.17
avg: 1.18
max: 2.05
95th percentile: 1.18
sum: 9998.11

Threads fairness:
events (avg/stddev): 8490.0000/0.00
execution time (avg/stddev): 9.9981/0.00

参考配置2
Raspberry Pi 3B:每秒约 570 次

结论:
x86 架构上性能损失约 70%,原因是 QEMU 使用软件翻译 arm 指令。在 3.3GHz 睿频的至强工作站上,效率还不到 800MHz 树莓派3 性能的一半。可见跨架构模拟效率极差,怪不得 Android Studio 的 ARM 架构模拟一塌糊涂(大部分开发者都会用 x86 架构调试)。


参考资料:

建立 vm 和安装 ubuntu
https://blog.csdn.net/chenxiangneu/article/details/78955462
但是设置网络会出现问题,因为宿主机的网卡不对

参考 https://wzt.ac.cn/2019/09/10/QEMU-networking/
建立网桥、tap0

建立快照
http://m.udpwork.com/item/12674.html
qemu-img create -f qcow2 -b centos.qcow2 snapshot.qcow2 再修改 vm 得启动代码,使得硬盘指向 snapshot.qcow2

其他坑

在 x86 上交叉编译时,由于 Makefile 中给出了 ARCH=arm64,所以在 linux-headers-xx.xx-xxxx/scripts/subarch.include 中会自动寻找 arch/arm64 的目录编译。而在 aarch64 上「交叉编译」(编译另一个内核的头文件)时,不给出 ARCH 使得编译器默认 ARCH=aarch64,因此会出现 arch/aarch64 目录不存在 的错误。
解决方法:在 arch/ 中复制 arm64/ 为 aarch64/

x86 交叉编译 aarch64 内核文件时,会出现报错:

/lib/ld_linux.so.2 不存在
或
/lib64/libc.so.6 不存在

解决方法:将 aarch64 平台上的相同文件拷贝到 x86 对应目录即可

Comments
Write a Comment
'