起因
使用了RK3588的板子,想在Ubuntu18.04的主机上使用QEMU安装Ubuntu20.04的arm64镜像进行交叉编译测试,调试程序更方便。之前尝试了用docker的方式,使用qemu-user-static的方式,但是遇到了一个很难解决的问题————使用catkin_make最多只能占用物理机器1个核CPU,运行nproc命令能看到和物理机器一样的核数,但是编译时只能使用1个核,导致编译速度极慢,最后放弃了docker方式,改用QEMU虚拟机方式。
~~docker版本的我测试了就算是自己编译的qemu-aarch64也不行,虽然版本是7.0,执行catkin_make的时候还是只能用1个核。~~实测使用catkin tool编译而不是catkin_make可以使用多核!!
暂时不清楚是不是因为重新编译了qemu-aarch64的原因。
解决方法
1 构建QEMU 7.0版本
由于Ubuntu18.04自带的QEMU版本过低,不支持多核arm64虚拟机,所以需要从源码编译QEMU 7.0版本。
执行编译之前需要保证目前配置的默认编译器是自带的gcc-7.5版本
# 和宿主机器做文件共享需要用到的库
sudo apt install libcap-ng-dev libattr1-dev
sudo apt install cloud-image-utils
# 克隆代码
git clone --depth 1 --branch v7.0.0 https://gitlab.com/qemu-project/qemu.git
cd qemu
# 配置编译选项
./configure --target-list=aarch64-softmmu --enable-tcg --enable-system --enable-user --enable-virtfs --python=/usr/bin/python3
# 如果提示少什么库,自己看情况安装缺失的库,然后重新执行上面configure命令
# 编译安装
make -j10
# 等待安装完成后,安装到/usr/local/bin目录下
sudo make install
2 创建工作目录
mkdir -p ~/qemu
cd ~/qemu
3 下载Ubuntu20.04的arm64云镜像
使用云镜像的好处是体积小,启动快,而且不需要安装过程,直接启动即可使用。
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-arm64.img
# 镜像站点下载
wget https://mirrors.tuna.tsinghua.edu.cn/ubuntu-cloud-images/focal/current/focal-server-cloudimg-arm64.img
4 创建QEMU虚拟机磁盘
cp focal-server-cloudimg-arm64.img ubuntu-arm64.qcow2
# 为了避免云镜像空间不够用,扩展磁盘大小到20G
qemu-img resize ubuntu-arm64.qcow2 20G
5 创建cloud-init配置文件
创建user-data文件:
cat > user-data <<EOF
#cloud-config
password: ubuntu
chpasswd: { expire: False }
ssh_pwauth: True
bootcmd:
- sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="console=ttyAMA0"/' /etc/default/grub
- update-grub
EOF
执行命令生成seed.img文件:
cloud-localds seed.img user-data
6 启动QEMU虚拟机
执行以下命令启动虚拟机:
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-smp 8 \
-m 4096 \
-bios /usr/local/share/qemu/edk2-aarch64-code.fd \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-drive if=virtio,format=qcow2,file=ubuntu-arm64.qcow2 \
-drive if=virtio,format=raw,file=seed.img \
-nographic \
-serial mon:stdio \
-accel tcg,thread=multi
如果需要挂载自己的宿主机目录,可以添加以下参数:
-virtfs local,path=/home/yourusername/shared,security_model=mapped-xattr,mount_tag=workspace \
最终可以在虚拟机内通过以下命令挂载:
sudo mount -t 9p workspace /mnt
或者修改cloud-init文件,添加挂载命令:
runcmd:
- [ sh, -lc, "mkdir -p /mnt" ]
- [ sh, -lc, "modprobe 9pnet_virtio 9p 2>/dev/null || true" ]
- [ sh, -lc, "mount -t 9p -o trans=virtio,version=9p2000.L,rw workspace /mnt || true" ]