Skip to content

Instantly share code, notes, and snippets.

@penk
Last active October 16, 2024 22:31
Show Gist options
  • Save penk/2e5e39048de473dd48541170fe017dbf to your computer and use it in GitHub Desktop.
Save penk/2e5e39048de473dd48541170fe017dbf to your computer and use it in GitHub Desktop.

How to work with x86_64 binaries in the ARM64 Linux VM on top of M1 macOS Host

Let's take Qt online installer and Qt Creator as an example.

Requirements

At the time of this writing:

  • macOS 13.0 Beta (22A5266r)
  • Xcode 14.0 beta (14A5228q)

Download sample code

Download RunningGUILinuxInAVirtualMachineOnAMac.zip

Patch sample code to enable Rosetta (on Host)

diff --git a/GUILinuxVirtualMachineSampleApp/AppDelegate.swift b/GUILinuxVirtualMachineSampleApp/AppDelegate.swift
index 332eb5d..7135702 100644
--- a/GUILinuxVirtualMachineSampleApp/AppDelegate.swift
+++ b/GUILinuxVirtualMachineSampleApp/AppDelegate.swift
@@ -177,6 +177,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, VZVirtualMachineDelegate {
         return consoleDevice
     }

+    private func createRosettaShareDeviceConfiguration() -> VZVirtioFileSystemDeviceConfiguration {
+        let rosettaDirectoryShare = try! VZLinuxRosettaDirectoryShare()
+        let directorySharingDevice = VZVirtioFileSystemDeviceConfiguration(tag: "RosettaShare")
+        directorySharingDevice.share = rosettaDirectoryShare
+
+        return directorySharingDevice
+    }
+
     // MARK: Create the virtual machine configuration and instantiate the virtual machine.

     func createVirtualMachine() {
@@ -219,6 +227,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, VZVirtualMachineDelegate {
         virtualMachineConfiguration.keyboards = [VZUSBKeyboardConfiguration()]
         virtualMachineConfiguration.pointingDevices = [VZUSBScreenCoordinatePointingDeviceConfiguration()]
         virtualMachineConfiguration.consoleDevices = [createSpiceAgentConsoleDeviceConfiguration()]
+        virtualMachineConfiguration.directorySharingDevices = [createRosettaShareDeviceConfiguration()]

         try! virtualMachineConfiguration.validate()
         virtualMachine = VZVirtualMachine(configuration: virtualMachineConfiguration)

Build and run the sample.

Install arm64 Linux

Upon running, the application will prompt for an ISO image, here ubuntu-22.04-live-server-arm64.iso is used.

Follow the installation procedure, and note that VM disk image will be placed under ~/GUI Linux VM.bundle/Disk.img.

Enable Rosetta (on Guest)

sudo apt install binfmt-support 

mkdir /tmp/mountpoint
sudo mount -t virtiofs RosettaShare /tmp/mountpoint
sudo /usr/sbin/update-binfmts --install rosetta /tmp/mountpoint/rosetta \
    --magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
    --mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
    --credentials yes --preserve no --fix-binary yes

Note the RosettaShare tag is defined in VZVirtioFileSystemDeviceConfiguration, YMMV.

Add amd64 architecture and dependencies

Edit /etc/apt/sources.list and add the following section:

deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy main universe
deb [arch=amd64] http://archive.ubuntu.com/ubuntu jammy-updates main universe

Then

sudo dpkg --add-architecture amd64
sudo apt update 
sudo apt install libgl1:amd64 libegl1:amd64 libglib2.0-0:amd64 libwayland-cursor0:amd64
sudo apt install gdm3 ubuntu-desktop-minimal x11-xserver-utils xorg

sudo service gdm start

And that's it! :-)

Bonus: using X11 Forwarding

With xquartz and socat installed on the macOS host, the old trick of running Linux GUI application directly on the macOS desktop still works. Please see the reference link for more info about this.

On the host:

HOSTIP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
DISPLAY=:0.0 /opt/X11/bin/xhost + $HOSTIP
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"

And launch application from the guest:

DISPLAY=$HOSTIP:0 ~/Qt/Tools/QtCreator/bin/qtcreator & 

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment