- Published on
在 QEMU 中建立 ARM Linux
- Authors
- Name
- wellsleep (Liu Zheng)
环境
原生环境: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
使用方法:
- 启动 Win 10
- 启动 VMware
- 启动 VMware 里的 Ubuntu 18.04 LTS
- 在以上 Ubuntu 内启动 qemu-system-aarch64 的一大堆脚本
- 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 对应目录即可