QEMU: Difference between revisions

From NixOS Wiki
imported>Mkg20001
m Fix formatting
Onny (talk | contribs)
Register binfmt emulate different architectures
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
A generic and open source machine emulator and virtualizer
[https://www.qemu.org/ QEMU] is a generic and open source machine emulator and virtualizer.


== Install ==
== Setup ==
<syntaxhighlight lang=nix>
Install the QEMU program system wide<syntaxhighlight lang=nix>
   environment = {
   environment = {
     systemPackages = [ pkgs.qemu ];
     systemPackages = [ pkgs.qemu ];
Line 8: Line 8:
</syntaxhighlight>
</syntaxhighlight>


== Booting UEFI ==
=== Quick EMU ===
 
Quickly create and run highly optimised desktop virtual machines for Linux, macOS and Windows; with just two commands.
 
https://github.com/quickemu-project/quickemu
 
<syntaxhighlight lang=bash>
quickget windows 11
quickemu --vm windows-11.conf
</syntaxhighlight>
 
== Configuration ==
 
=== Booting UEFI ===
To boot UEFI systems using QEMU, the UEFI firmware replacing the BIOS implementation needs to be provided while starting QEMU.
To boot UEFI systems using QEMU, the UEFI firmware replacing the BIOS implementation needs to be provided while starting QEMU.


Line 15: Line 28:
<syntaxhighlight lang=nix>
<syntaxhighlight lang=nix>
  environment = {
  environment = {
   (pkgs.writeShellScriptBin "qemu-system-x86_64-uefi" ''
   systemPackages = [
    qemu-system-x86_64 \
    (pkgs.writeShellScriptBin "qemu-system-x86_64-uefi" ''
      -bios ${pkgs.OVMF.fd}/FV/OVMF.fd \
      qemu-system-x86_64 \
      "$@"
        -bios ${pkgs.OVMF.fd}/FV/OVMF.fd \
  '')
        "$@"
    '')
  ];
  };
  };
</syntaxhighlight>
</syntaxhighlight>
qcow-efi images generated from [https://github.com/nix-community/nixos-generators nixos-generators] require more RAM than the default 128MB.  Failing to provide enough RAM results in grub reporting "error: start_image() returned 0x800000000000009." or systemd-boot reporting "Failed to execute NixOS: Out of resources".
=== Run binaries of different architecture ===
Following configuration will enable the emulation of different architectures. For example to run aarch64 and riscv64 binaries on an native x86_64 host, add following part to your system configuration, apply it and reboot your system.<syntaxhighlight lang="nix">
boot.binfmt.emulatedSystems = [
  "aarch64-linux"
  "riscv64-linux"
];
</syntaxhighlight>
== Tips and tricks ==
=== Emulate different architecture ===
The following [[Flake]] file constructs and executes a NixOS virtual machine with an architecture distinct from that of the host system; in this example, it utilizes aarch64.
Save the snippet as <code>flake.nix</code> and run <code>nix run</code> in the same directory to bootup the VM.<syntaxhighlight lang="nix">
{
  description = "Nix flake to build and run a NixOS VM for aarch64";
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-24.05";
  };
  outputs = { self, nixpkgs }:
  let
    pkgs = import nixpkgs { system = "x86_64-linux"; };
    pkgsAarch64 = import nixpkgs { system = "aarch64-linux"; };
    iso = (pkgsAarch64.nixos {
      imports = [ "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-base.nix" ];
    }).config.system.build.isoImage;
    vmScript = pkgs.writeScriptBin "run-nixos-vm" ''
      #!${pkgs.runtimeShell}
      ${pkgs.qemu}/bin/qemu-system-aarch64 \
        -machine virt,gic-version=max \
        -cpu max \
        -m 2G \
        -smp 4 \
        -drive file=$(echo ${iso}/iso/*.iso),format=raw,readonly=on \
        -nographic \
        -bios ${pkgsAarch64.OVMF.fd}/FV/QEMU_EFI.fd
    '';
  in {
    defaultPackage.x86_64-linux = vmScript;
  };
}
</syntaxhighlight>Alternatively a different iso file can be specified in the drive-parameter, for example for Ubuntu Server ARM64.
[[Category:Virtualization]]

Latest revision as of 10:32, 13 August 2024

QEMU is a generic and open source machine emulator and virtualizer.

Setup

Install the QEMU program system wide

  environment = {
    systemPackages = [ pkgs.qemu ];
  };

Quick EMU

Quickly create and run highly optimised desktop virtual machines for Linux, macOS and Windows; with just two commands.

https://github.com/quickemu-project/quickemu

quickget windows 11
quickemu --vm windows-11.conf

Configuration

Booting UEFI

To boot UEFI systems using QEMU, the UEFI firmware replacing the BIOS implementation needs to be provided while starting QEMU.

The following installs a script, that always starts QEMU with OVMF firmware implementing UEFI support.

 environment = {
   systemPackages = [
     (pkgs.writeShellScriptBin "qemu-system-x86_64-uefi" ''
       qemu-system-x86_64 \
         -bios ${pkgs.OVMF.fd}/FV/OVMF.fd \
         "$@"
     '')
   ];
 };

qcow-efi images generated from nixos-generators require more RAM than the default 128MB. Failing to provide enough RAM results in grub reporting "error: start_image() returned 0x800000000000009." or systemd-boot reporting "Failed to execute NixOS: Out of resources".

Run binaries of different architecture

Following configuration will enable the emulation of different architectures. For example to run aarch64 and riscv64 binaries on an native x86_64 host, add following part to your system configuration, apply it and reboot your system.

boot.binfmt.emulatedSystems = [
  "aarch64-linux"
  "riscv64-linux"
];

Tips and tricks

Emulate different architecture

The following Flake file constructs and executes a NixOS virtual machine with an architecture distinct from that of the host system; in this example, it utilizes aarch64.

Save the snippet as flake.nix and run nix run in the same directory to bootup the VM.

{
  description = "Nix flake to build and run a NixOS VM for aarch64";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-24.05";
  };

  outputs = { self, nixpkgs }:
  let
    pkgs = import nixpkgs { system = "x86_64-linux"; };
    pkgsAarch64 = import nixpkgs { system = "aarch64-linux"; };

    iso = (pkgsAarch64.nixos {
      imports = [ "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-base.nix" ];
    }).config.system.build.isoImage;

    vmScript = pkgs.writeScriptBin "run-nixos-vm" ''
      #!${pkgs.runtimeShell}
      ${pkgs.qemu}/bin/qemu-system-aarch64 \
        -machine virt,gic-version=max \
        -cpu max \
        -m 2G \
        -smp 4 \
        -drive file=$(echo ${iso}/iso/*.iso),format=raw,readonly=on \
        -nographic \
        -bios ${pkgsAarch64.OVMF.fd}/FV/QEMU_EFI.fd
    '';

  in {
    defaultPackage.x86_64-linux = vmScript;
  };
}

Alternatively a different iso file can be specified in the drive-parameter, for example for Ubuntu Server ARM64.