文章目录
1. 环境及需求
- host主机
- 系统:ubuntu 16.04 x86_64
- CPU:双核i5
- 内存:8G
- 硬盘:1T
- guest虚拟机
- CPU::cortex-a53, arm64位 四核
- 内存:1G
- 内核:kernel-4.9.140
- 硬件:六个网口,其中一个桥接到host主机的一个物理网口
- 硬盘:文件系统,32G, 可持久化
2. 安装QEMU
1. 从仓库安装
sudo apt-get install qemu-system-aarch64
2. 从源码安装
- 源码获取:https://download.qemu.org/
- 解压:
tar -xvf qemu-5.1.0.tar.xz
- 配置:
./configure --enable-kvm --enable-virtfs --enable-vhost-net --enable-vhost-kernel --enable-vhost-user --enable-vdi --enable-parallels --enable-linux-user --enable-user --enable-system --enable-guest-agent --enable-curses --enable-vnc --enable-fdt --enable-linux-aio --enable-libnfs --enable-slirp
如果出现错误,根据提示apt安装对应的包即可
4. 编译 & 安装:
make
sudo make install
3. 配置内核
- 获取内核
https://mirrors.edge.kernel.org/pub/linux/kernel/ - 配置内核
内核需支持以下配置:
CONFIG_PCI=y
CONFIG_VIRTIO_PCI=y
CONFIG_PCI_HOST_GENERIC=y
编译内核镜像:
make zImage
- 编译出的内核位于arch/arm64/boot/zImage
4. 制作文件系统
- 下载buildroot
https://buildroot.org/download.html - 配置buildroot生成tar和ramdisk镜像
Filesystem images --->
[*] cpio the root filesystem (for use as an initial RAM filesystem)
[*] tar the root filesystem #配置默认串口 qemu默认串口名称为ttyAMA0
System configuration >
Run a getty (login prompt) after boot
(ttyAMA0) TTY port
- 编译
make
- 在output/images下生成rootfs.cpio.gz和rootfs.tar文件
5. 创建虚拟硬盘
1. 在host主机上制作
- 创建空的虚拟硬盘
qemu-img create -f vdi rootfs.vdi 32G
- -f:指定虚拟硬盘格式
- 挂载虚拟硬盘到host主机
#host主机安装nbd内核模块
sudo modprobe nbd
- 挂载虚拟硬盘
sudo qemu-nbd -c /dev/nbd0 rootfs.vdi
- 虚拟硬盘分区
sudo fdisk /dev/nbd0
- 格式化分区
sudo mkfs.ext4 /dev/nbd0p1
- 挂载虚拟硬盘
sudo mount /dev/nbd0p1 /mnt
- 解压出文件系统到虚拟硬盘
sudo tar -xvf rootfs.tar -C /mnt
- 卸载虚拟硬盘
sudo umount /mnt
- 断开VDI虚拟硬盘连接
sudo qemu-nbd -d /dev/nbd0
2. 挂载到VirtualBox虚拟机里面制作
参考VirtualBox虚拟机虚拟硬盘操作。
6. 创建host桥接网络
主机上有一个物理网口,需要将此网口和虚拟机网口桥接在一起。如果host主机为虚拟机,则需要打开网卡的混杂模式。
enp0s3 Link encap:Ethernet HWaddr 08:00:27:1f:8d:c8
inet6 addr: fe80::a00:27ff:fe1f:8dc8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:54 errors:0 dropped:0 overruns:0 frame:0
TX packets:90 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:5917 (5.9 KB) TX bytes:12560 (12.5 KB)</pre>
- 创建网桥
sudo brctl addbr br0
- qemu虚拟机默认连接到br0网桥.
- 添加端口到网桥
sudo brctl addif enp0s3
- 清除网口IP,给网桥添加IP
sudo ip addr flush enp0s3
sudo ifconfig br0 192.168.10.2
- 配置qemu网桥规则
- 如:允许br0桥接,则:
sudo mkdir -p /etc/qemu
sudo sh -c 'echo "allow br0" > /etc/qemu/bridge.conf'
2. 允许所有的网桥:
echo "allow all" | sudo tee /etc/qemu/bridge.conf
- 设置文件权限
sudo chmod 644 /etc/qemu/bridge.conf
sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper
所有操作可以添加到开机启动脚本rc.local里面,实现自动添加网桥。
#rc.local
brctl addbr br0
brctl addif br0 enp0s3
ifconfig enp0s3 up
在interfaces里面添加br0的IP信息:
auto br0
iface br0 inet static
address 192.168.10.2
netmask 255.255.255.0
打开host主机的地址转发功能,关闭防火墙:
sudo ufw disable
sudo vim /etc/sysctl.conf
#取消注释
net.ipv4.ip_forward=1
重启host主机生效
7. 启动qemu虚拟机
启动时需要切换到root用户运行,因为需要创建host虚拟网卡。
1. 正常启动
启动命令:
qemu-system-aarch64 -m 1G -cpu cortex-a53 -smp 4 -machine virt,highmem=off \
-kernel zImage \
-append "root=/dev/vda1 rw rootfstype=ext4 rootflags=data=journal console=ttyAMA0 rootwait earyprintk" \
-drive file=rootfs.vdi,cache=none,if=virtio,format=vdi \
-serial tcp::4446,server,telnet,nowait \
-monitor tcp::4447,server,telnet,nowait \
-device virtio-net-pci,netdev=net0 \
-netdev bridge,id=net0,br=br0 \
-device virtio-net-pci,netdev=net1 \
-netdev user,id=net1 \
-device virtio-net-pci,netdev=net2 \
-netdev user,id=net2 \
-device virtio-net-pci,netdev=net3 \
-netdev user,id=net3 \
-device virtio-net-pci,netdev=net4 \
-netdev user,id=net4 \
-device virtio-net-pci,netdev=net5 \
-netdev user,id=net5 \
-device virtio-net-pci,netdev=net6 \
-netdev user,id=net6 \
-nographic
- -m:指定内存大小,1G
- -cpu:指定CPU型号,cortex-a53
- -smp:指定内核数,4
- -machine:指定模拟机器型号,virt: arm通用虚拟机。可以通过
qemu-system-aarch64 -machine help
查看支持的所有虚拟机型号。 - -kernel:内核镜像文件,Image
- -append:指定内核启动参数
- /dev/vda1:挂载的虚拟硬盘在内核里面的名称默认为vda。可以通过
ramdisk
方式启动系统,查看虚拟硬盘在内核中的默认名称。 - ttyAMA0:qemu启动后,内核里面默认的串口名称
- /dev/vda1:挂载的虚拟硬盘在内核里面的名称默认为vda。可以通过
- -drive:指定虚拟硬盘,用于挂载文件系统
- -serial:指定默认串口
- -stdio: host的标准输出
- tcp::4446,server,telnet : 通过host主机的telnet端口4446输出
- nowait:不指定时,则默认当通过telnet登录时,虚拟机才启动。
- -monitor:指定监控设备,同-serial
- -device virtio-net-pci:添加虚拟设备,虚拟网卡。
qemu-system-aarch64 -device help
`可以查看所有可模拟的设备类型。 - -netdev:指定网卡设备的名称,不是内核里面显示的名称,只是一个ID,和
-netdev
配合使用,用于区分网卡类型。 - -netdev:指定网卡类型
- bridge:桥接类型
- id:绑定一个
-device
虚拟网卡设备的ID - br:桥接的host主机的网桥名称,默认为
br0
- -nographic:指明没有显示设备
2. ramdisk启动
qemu-system-aarch64 -m 1G -cpu cortex-a53 -smp 4 -machine virt,highmem=off \
-kernel zImage \
-initrd rootfs.cpio.gz
-append "root=/dev/ram0 rw rootfstype=ext4 rootflags=data=journal console=ttyAMA0 rootwait earyprintk" \
-drive file=rootfs.vdi,cache=none,if=virtio,format=vdi \
-serial tcp::4446,server,telnet,nowait \
-monitor tcp::4447,server,telnet,nowait \
-device virtio-net-pci,netdev=net0 \
-netdev bridge,id=net0,br=br0 \
-device virtio-net-pci,netdev=net1 \
-netdev user,id=net1 \
-device virtio-net-pci,netdev=net2 \
-netdev user,id=net2 \
-device virtio-net-pci,netdev=net3 \
-netdev user,id=net3 \
-device virtio-net-pci,netdev=net4 \
-netdev user,id=net4 \
-device virtio-net-pci,netdev=net5 \
-netdev user,id=net5 \
-device virtio-net-pci,netdev=net6 \
-netdev user,id=net6 \
-nographic
- -initrd:指定ramdisk镜像文件
- -append:指定内核启动参数
- /dev/ram0:内核中默认ramdisk设备名称