|  | // Copyright 2022 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package main | 
|  |  | 
|  | import ( | 
|  | "fmt" | 
|  | "log" | 
|  | "os" | 
|  | "os/exec" | 
|  | "path/filepath" | 
|  | ) | 
|  |  | 
|  | // defaultDarwinDir returns a default path for a darwin VM. | 
|  | // | 
|  | // The directory should contain the darwin VM image, and QEMU | 
|  | // (sysroot-macos-x86_64). | 
|  | func defaultDarwinDir() string { | 
|  | home, err := os.UserHomeDir() | 
|  | if err != nil { | 
|  | log.Printf("os.UserHomeDir() = %q, %v", home, err) | 
|  | return "" | 
|  | } | 
|  | return home | 
|  | } | 
|  |  | 
|  | // darwinCmd returns a qemu command for running a darwin VM, ready | 
|  | // to be started. | 
|  | func darwinCmd(base string) *exec.Cmd { | 
|  | if *macosVersion == 0 { | 
|  | log.Fatalf("-macos-version required") | 
|  | } | 
|  | if *osk == "" { | 
|  | log.Fatalf("-osk required") | 
|  | } | 
|  |  | 
|  | sysroot := filepath.Join(base, "sysroot-macos-x86_64") | 
|  | ovmfCode := filepath.Join(sysroot, "share/qemu/edk2-x86_64-code.fd") | 
|  |  | 
|  | disk := filepath.Join(base, "macos.qcow2") | 
|  |  | 
|  | // Note that vmnet-shared requires that we run QEMU as root, so | 
|  | // runqemubuildlet must run as root. | 
|  | // | 
|  | // These arguments should be kept in sync with env/darwin/aws/qemu.sh. | 
|  | args := []string{ | 
|  | // Discard disk changes on exit. | 
|  | "-snapshot", | 
|  | "-m", "10240", | 
|  | "-cpu", "host", | 
|  | "-machine", "q35", | 
|  | "-usb", | 
|  | "-device", "usb-kbd", | 
|  | "-device", "usb-tablet", | 
|  | // macOS only likes a power-of-two number of cores, but odd socket count is | 
|  | // fine. | 
|  | "-smp", "cpus=6,sockets=3,cores=2,threads=1", | 
|  | "-device", "usb-ehci,id=ehci", | 
|  | "-device", "nec-usb-xhci,id=xhci", | 
|  | "-global", "nec-usb-xhci.msi=off", | 
|  | "-device", fmt.Sprintf("isa-applesmc,osk=%s", *osk), | 
|  | "-drive", fmt.Sprintf("if=pflash,format=raw,readonly=on,file=%s", ovmfCode), | 
|  | "-smbios", "type=2", | 
|  | "-device", "ich9-intel-hda", | 
|  | "-device", "hda-duplex", | 
|  | "-device", "ich9-ahci,id=sata", | 
|  | "-drive", fmt.Sprintf("id=MacHDD,if=none,format=qcow2,file=%s", disk), | 
|  | "-device", "ide-hd,bus=sata.2,drive=MacHDD", | 
|  | "-monitor", "stdio", | 
|  | "-device", "VGA,vgamem_mb=128", | 
|  | "-M", "accel=hvf", | 
|  | "-display", fmt.Sprintf("vnc=127.0.0.1:%d", *guestIndex), | 
|  | // DHCP range is a dummy range. The actual guest IP is assigned statically | 
|  | // based on the MAC address matching an entry in /etc/bootptab. | 
|  | "-netdev", "vmnet-shared,id=net0,start-address=192.168.64.1,end-address=192.168.64.100,subnet-mask=255.255.255.0", | 
|  | } | 
|  | if *macosVersion >= 11 { | 
|  | args = append(args, "-device", fmt.Sprintf("virtio-net-pci,netdev=net0,id=net0,mac=52:54:00:c9:18:0%d", *guestIndex)) | 
|  | } else { | 
|  | args = append(args, "-device", fmt.Sprintf("vmxnet3,netdev=net0,id=net0,mac=52:54:00:c9:18:0%d", *guestIndex)) | 
|  | } | 
|  |  | 
|  | cmd := exec.Command(filepath.Join(sysroot, "bin/qemu-system-x86_64"), args...) | 
|  | cmd.Env = append(os.Environ(), | 
|  | fmt.Sprintf("DYLD_LIBRARY_PATH=%s", filepath.Join(sysroot, "lib")), | 
|  | ) | 
|  | return cmd | 
|  | } |