用QEMU虚拟机运行MacOSX笔记

基本安装及运行方式

只要在Linux上简单运行这个项目即可:macOS Simple KVM

总结下来就这么几个步骤:

  • 安装QEMU等:sudo apt-get install qemu-system qemu-utils python3 python3-pip
  • 下载OSX镜像并创建虚拟机:./jumpstart.sh,可选择--high-sierra, --mojave, --catalina安装,默认安装catalina。
  • 创建虚拟硬盘:qemu-img create -f qcow2 MyDisk.qcow2 64G
  • 修改启动脚本basic.sh,添加硬盘:
-drive id=SystemDisk,if=none,file=MyDisk.qcow2 \
-device ide-hd,bus=sata.4,drive=SystemDisk \
  • 如使用无头方式运行——如通过远程连接在云端运行——还需要添加:-nographic -vnc :0 -k en-us,然后通过5900的VNC端口连接虚拟机。
  • 另一种无头方式运行是通过环境变量:HEADLESS=1 MEM=1G CPUS=2 SYSTEM_DISK=MyDisk.qcow2 ./headless.sh
  • 运行./basic.sh或通过无头方式运行,即可启动OSX虚拟机。

增加内存和CPU

默认创建的虚拟机只有2G内存,见basic.sh中的-m 2G,可自行增加,但不能超过主机的物理内存。

默认创建的CPU是双核4线程,可自行增加,如:-smp cores=4,threads=4,sockets=1

增加网桥

默认创建的虚拟机网络是NAT方式,即虚拟机可以通过主机上网的模式,但是与主机及主机LAN不能互通,如果要让虚拟机加入主机LAN,需要创建一个网桥。

方法一

修改主机网络配置。编辑/etc/network/interfaces,加入:

auto br0
iface br0 inet dhcp
  bridge_ports DEVICENAME tap0

auto tap0
iface tap0 inet dhcp
  pre-up tunctl -u MYUSERNAME -t tap0

其中DEVICENAME是主机的网卡名,MYUSERNAME是运行basic.sh的用户名

方法二

使用NetworkManager。

# 创建网桥
nmcli connection add type bridge ifname br1 con-name mybridge
# 关联网桥到网卡
nmcli connection add type bridge-slave ifname DEVICENAME con-name mynetwork master br1
# 创建Tun/Tap
nmcli connection add type tun ifname tap0 con-name mytap mode tap owner `id -u`
# 关联Tun/Tap到网桥
nmcli connection mod mytap connection.slave-type bridge connection.master br1

关联网桥到虚拟机

以上两种方法创建网桥以后,都需要关联到虚拟机。修改basic.sh,把:

-netdev user,id=net0

替换为:

-netdev tap,id=net0,ifname=tap0,script=no,downscript=no

对于ElCapitan或更高版本的OSX,可以使用性能更好的虚拟网卡:vmxnet3

-device vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:27

硬件直通

首先需要在BIOS里打开相关选项,如:Intel VT-d或AMD Vi。

PCIe直通(显卡或声卡)

  • 先查看设备:lspci -nn | grep "VGA\|Audio",返回结果每一行的最前面一项是BDF ID,最后一项是设备ID。
  • 加载vfio-pci模块,不同的发行版不一定包含此模块,需要自行处理。
  • 启用iommu内核配置:

在GRUB中通过编辑/etc/default/grub实现,修改GRUB_CMDLINE_LINUX_DEFAULT的值,然后运行sudo update-grub,再重启。

AMD的配置值为:iommu=pt amd_iommu=on vfio-pci.ids=1002:66af,1002:ab20

Intel的配置值为:iommu=pt intel_iommu=on vfio-pci.ids=1002:66af,1002:ab20

注意其中的ID为需要直通的设备ID。

  • 关联设备到虚拟机:修改basic.sh
    -vga none \
    -device pcie-root-port,bus=pcie.0,multifunction=on,port=1,chassis=1,id=port.1 \
    -device vfio-pci,host=26:00.0,bus=port.1,multifunction=on,romfile=/path/to/card.rom \
    -device vfio-pci,host=26:00.1,bus=port.1 \

注意这里用的是BDF ID,另,romfile参数为可选。

USB直通

放狗找了一圈,找到两个参考:

一个可能有问题的配置

    -device qemu-xhci,id=xhci -device usb-host,bus=xhci.0,hostbus=1,hostaddr=11 \

一个据说可行的配置

-usb
-nodefaults
-serial none
-parallel none
-rtc clock=host,base=localtime
-device usb-host,hostbus=3,hostport=3
-device usb-host,hostbus=3,hostport=4
-device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1
-device vfio-pci,host=03:00.0,bus=root.1,addr=0x00,multifunction=on
-device vfio-pci,host=03:00.1,bus=root.1,addr=0x00.1

其配置关键是-device usb-host...,顺籐摸瓜找到Can I pass through a USB Port via qemu Command Line?

其中说到官文档有两种配置方式,但实际需要使用第三种方式(就是上面用的这种),配置中用到的hostbus, hostport参数可通过lsusb -t取得。

不过需要注意的是,对于USB3.x的口,如果插了USB2.0的设备,对应的hostbus会不同,但hostport是一样的。但对于USB2.0的口来说,插USB3.x的设备也是当2.0用,所以hostbus是一样的。

对于USB HUB的情况来说,会有下一层hostport,这时需要用点号.隔开。

推送到[go4pro.org]