<!--
{
  "documentType" : "article",
  "framework" : "Virtualization",
  "identifier" : "/documentation/Virtualization/running-intel-binaries-in-linux-vms",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Running Intel Binaries in Linux VMs"
}
-->

# Running Intel Binaries in Linux VMs

Run x86_64 Linux binaries under ARM Linux on Apple silicon.

## Discussion

In macOS 13 and later on Mac computers with Apple silicon chips, the Virtualization framework supports apps using Intel binary translation in ARM Linux virtual machines (VMs). Until macOS 26, this capability was part of Rosetta, which allows apps built for Intel-based Mac computers to run seamlessly on Apple silicon. macOS 27 directly integrates support for Intel binary translation, without needing to install Rosetta. If your app has a minimum deployment target of macOS 27, continue with [Create the Directory Share](/documentation/Virtualization/running-intel-binaries-in-linux-vms#Create-the-Directory-Share).

> Note:
> The Virtualization framework doesn’t support the bootstrapping or installation of Intel Linux distributions on Mac computers with Apple silicon. Instead, it provides support for Intel apps that run in an ARM Linux distribution.

### Test for Rosetta on macOS 26 and earlier

> Note:
> Starting in macOS 27, support for Intel binary translation for Linux apps is included in macOS. Testing for <doc://com.apple.documentation/documentation/Virtualization/VZLinuxRosettaDirectoryShare/availability> starting in macOS 27 always returns <doc://com.apple.documentation/documentation/Virtualization/VZLinuxRosettaAvailability/installed>  and <doc://com.apple.documentation/documentation/Virtualization/VZLinuxRosettaDirectoryShare/installRosetta(completionHandler:)> always returns immediately.

Before trying to install, run, or activate Rosetta, your app should check to ensure that the capability is available in the version of macOS running on the host computer. The [`availability`](/documentation/Virtualization/VZLinuxRosettaDirectoryShare/availability) class method returns a value from the [`VZLinuxRosettaAvailability`](/documentation/Virtualization/VZLinuxRosettaAvailability) enumeration that describes whether the current host supports Rosetta or if the capability is already installed on the host Mac. The example below shows the process for checking for Rosetta availability:

```swift
import Virtualization

let supportForIntelApps = VZLinuxRosettaDirectoryShare.availability

switch supportForIntelApps {
case notSupported:
    // Alert the user the capability isn't available; offer 
    // continuation options according to your app's requirements.

case notInstalled:
    // Ask the user for permission to install Rosetta, and 
    // start the installation process if they grant permission.

case installed:
    break // Ready to go.
}
```

### Install Rosetta on macOS 26 and earlier

In macOS 26 and earlier, you need to install Rosetta to allow apps built for Intel-based Mac computers to run on Apple silicon. Installing Rosetta is a one-time process per computer that requires someone to grant permission for the system to install Rosetta. If someone has already installed Rosetta, the system activates it for use under the Virtualization framework; if Rosetta isn’t installed, the framework downloads the installer from the network and performs the installation. The installer interactively prompts a person for authorization, and your app needs to handle any of the possible error conditions that could occur during the authorization, download, and installation process. The example below shows how to start the installation:

```swift
do {
    try await VZLinuxRosettaDirectoryShare.installRosetta()
    // Success: The system installs Rosetta on the host system.
} catch let error {
    switch error.code {
    case networkError:
        // A network error prevented the download from completing successfully.
    case outOfDiskSpace:
        // Not enough disk space on the system volume to complete the installation.
    case userCancelled:
        // The user cancelled the installation.
    case notSupported:
        // Rosetta isn't supported on the host Mac or macOS version.

    default:
        break // A non installer-related error occurred.
    }
}
```

### Create the Directory Share

With Intel binary translation support enabled, your app needs to configure an appropriate directory share in the Linux guest to enable translation capabilities. The shared directory must have a tag that uniquely identifies the share and that you validate using [`validateTag(_:)`](/documentation/Virtualization/VZVirtioFileSystemDeviceConfiguration/validateTag(_:)) to ensure it conforms to the length and format for file system tags:

```swift
let tag = "EXAMPLE_TAG"  
let configuration = VZVirtualMachineConfiguration()
do {
    try let validationError = VZVirtioFileSystemDeviceConfiguration.validateTag(tag)
    let rosettaDirectoryShare = try VZLinuxRosettaDirectoryShare()
    let fileSystemDevice = VZVirtioFileSystemDeviceConfiguration(tag: tag)
    fileSystemDevice.share = rosettaDirectoryShare

    configuration.directorySharingDevices = [ fileSystemDevice ]
} catch VZError.invalidVirtualMachineConfiguration {
    // Intel binary support is not present on this device.
}
```

### Mount the shared directory and register Rosetta

In order to use Intel binary translation in the Linux guest, a person must mount the Rosetta share in the guest VM and install Rosetta as the application the system uses to run x86_64 binaries using the following process:

> Important:
> The remaining steps required to activate Intel binary translation in a Linux guest aren’t commands that your app can execute or that you can script from inside your application to a Linux VM; someone must perform them either interactively or as part of a script while logged in to the Linux guest. You must communicate these requirements to someone using your app.

1. Install the `update-binfmts` command, if necessary. The command is part of the binfmt-support package in most Linux distributions; installation methods vary by distribution. Additionally, in order to run this command, someone must be able to use the `sudo` command, which requires adding their username to the system’s `/etc/sudoers` file.
2. Create a directory as a mount point.
3. Mount the VirtioFS file system tag to the mount point. This is the file system tag the app uses to identify the share and must be the same as the tag someone specifies on the command line demonstrated here.
4. Check if the mounted directory has the Rosetta runtime. You should see `rosetta` in the mounted directory.
5. Register the Rosetta runtime binary as the handler for x86_64 ELF format executable files using the `update-binfmts` command. The `magic` parameter describes the first 20 bytes of the ELF header for x86_64 binaries. The Linux kernel performs a bitwise logical `AND` with the first 20 bytes of a binary a user attempts to run with the `mask` value. If it matches the `magic` value, the kernel uses the registered handler as the interpreter for that binary. If the system can’t find a handler for the specified binary, it reports an error.

The example below lists the commands, with the exception of the `update-binfmts` command installation, required to enable Intel binary translation in the Linux guest:

> Important:
> When using Rosetta in macOS 13, set the `preserve` option to `no.`

```bash
% mkdir /tmp/mountpoint
% sudo mount -t virtiofs EXAMPLE_TAG /tmp/mountpoint
% ls /tmp/mountpoint rosetta
% 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 yes --fix-binary yes
```

### Ensure Shared Libraries are Available for Dynamically Linked Apps

Rosetta can run statically linked x86_64 binaries without additional configuration. Binaries that are dynamically linked and that depend on shared libraries require the installation of the shared libraries, or library hierarchies, in the Linux guest in paths that are accessible to both the user account and to Rosetta.

### Configure Rosetta’s ahead of time (AOT) caching options

In macOS 14 and later, Rosetta supports options that allow you control the ahead of time (AOT) cache characteristics; this can improve the performance of some X86 workloads.

There are two modes of operation for AOT caching: The first is communication using a Unix Domain Socket where the Virtualization framework shares a file that represents the socket between the Rosetta daemon and Rosetta runtime through a symlink or bind-mount. The second is communication through an abstract socket where the framework defines a shared name rather than a shared file. 

You enable these options after you create the Rosetta directory share by setting one of the [`VZLinuxRosettaDirectoryShare.CachingOptions`](/documentation/Virtualization/VZLinuxRosettaDirectoryShare/CachingOptions-swift.enum) using [`setCachingOptions(_:)`](/documentation/Virtualization/VZLinuxRosettaDirectoryShare/setCachingOptions(_:)). This example shows how to configure Rosetta’s caching options in a new virtual machine configuration using a Unix Domain Socket though a shared, named file:

```swift
    let configuration = VZVirtualMachineConfiguration()
    do {
        let rosettaDirectoryShare = try VZLinuxRosettaDirectoryShare()
        try rosettaDirectoryShare.setCachingOptions(cachingOptions: .unixSocket("/valid/path/rosetta.sock"))

        let fileSystemDevice = VZVirtioFileSystemDeviceConfiguration(tag: "example-tag")
        fileSystemDevice.share = rosettaDirectoryShare

        configuration.directorySharingDevices = [ fileSystemDevice ]
    } catch VZError.invalidVirtualMachineConfiguration {
        // Rosetta for Linux is unavailable or failed to initialize Rosetta caching options.
        // If Rosetta for Linux is unavailable, clients may install the resources or proceed without them.
        // If Rosetta caching options failed to initialize, clients may gracefully fail or proceed without caching.
    }
```

The following example shows how to configure Rosetta’s caching options in a new virtual machine configuration using an abstract socket:

```swift
    let configuration = VZVirtualMachineConfiguration()
    do {
        let rosettaDirectoryShare = try VZLinuxRosettaDirectoryShare()
        try rosettaDirectoryShare.setCachingOptions(.abstractSocket("abstractSocketName"))

        let fileSystemDevice = VZVirtioFileSystemDeviceConfiguration(tag: "example-tag")
        fileSystemDevice.share = rosettaDirectoryShare

        configuration.directorySharingDevices = [ fileSystemDevice ]
    } catch VZError.invalidVirtualMachineConfiguration {
        // Rosetta for Linux is unavailable or failed to initialize Rosetta caching options.
        // If Rosetta for Linux is unavailable, clients may install the resources or proceed without them.
        // If Rosetta caching options failed to initialize, clients may gracefully fail or proceed without caching.
    }    
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)