Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Windows on Arm virtual machine creation using Arm Linux, QEMU, and KVM

draft: true
cascade:
draft: true

minutes_to_complete: 90

who_is_this_for: This is for developers and system administrators who want to automate Windows on Arm virtual machine (VM) creation on Arm Linux systems using QEMU and KVM.

learning_objectives:
- Understand the process of creating Windows on Arm virtual machine using Bash scripts.
- Run scripts for VM creation and management.
- Troubleshoot common VM setup and runtime issues.
- Use Windows on Arm virtual machines for software development and testing.

prerequisites:
- An Arm Linux system with KVM support and a minimum of 8GB RAM and 50GB free disk space.

author: Jason Andrews

### Tags
skilllevels: Introductory
subjects: Migration to Arm
armips:
- Neoverse
- Cortex-A
operatingsystems:
- Linux
- Windows
tools_software_languages:
- QEMU
- KVM
- Bash
- RDP

further_reading:
- resource:
title: Linaro Wiki - Windows on Arm
link: https://wiki.linaro.org/LEG/Engineering/Kernel/WindowsOnArm
type: documentation
- resource:
title: Botspot Virtual Machine (BVM) Project
link: https://github.com/Botspot/bvm
type: website

### FIXED, DO NOT MODIFY
# ================================================================================
weight: 1 # _index.md always has weight of 1 to order correctly
layout: "learningpathall" # All files under learning paths have this same wrapper
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# ================================================================================
# FIXED, DO NOT MODIFY THIS FILE
# ================================================================================
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
title: "Next Steps" # Always the same, html page title.
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
---
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: System requirements
weight: 2

### FIXED, DO NOT MODIFY
layout: learningpathall
---

If you are building and testing Windows on Arm software you have a variety of options to run Windows on Arm. You can use local laptops, cloud virtual machines, and CI/CD platforms like GitHub Actions for development tasks.

You can also use a local Arm Linux server to create virtual machines for Windows on Arm software development tasks. This Learning Path explains how to install and use Windows on Arm virtual machines on an Arm Linux system. Two scripts are provided to create and run Windows on Arm virtual machines to make the process easy.

Before creating a Windows on Arm virtual machine, ensure your Arm Linux system meets the hardware and software requirements. This section covers everything you need to prepare to create a Windows on Arm virtual machine using QEMU and KVM.

## Hardware requirements

You need an Arm Linux system with enough performance, memory, and storage to run a Windows on Arm virtual machine.

The provided scripts have been tested on a [Thelio Astra](https://system76.com/desktops/thelio-astra-a1.1-n1/configure?srsltid=AfmBOoplXbwXifyxppxFe_oyahYMJHUT0bp2BnIBSH5ADjqgZxB7wW75) running Ubuntu 24.04.

Thelio Astra is an Arm-based desktop computer designed by System76 for autonomous vehicle development and other general-purpose Arm software development. It uses the Ampere Altra processor, which is based on the Arm Neoverse N1 CPU, and ships with the Ubuntu operating system.

Other Arm Linux systems and other Linux distributions are possible, but have not been tested. General hardware requirements are listed below.

The minimum hardware requirements for the Arm Linux system are:

- 8 cores with hardware virtualization support
- 8 GB RAM
- 50 GB free disk space

The scripts automatically allocate resources as listed below, but the details can be customized for your system.

- CPU: half of available cores (minimum 4 cores)
- Memory: half of available RAM (minimum 4 GB)
- Disk: 40 GB VM disk

## KVM support

Kernel-based Virtual Machine (KVM) support is required for hardware-accelerated virtualization and good VM performance.

KVM is a virtualization infrastructure built into the Linux kernel that allows you to run virtual machines with near-native performance. It leverages Arm's hardware virtualization extensions to provide efficient CPU virtualization, while QEMU handles device emulation and management. Without KVM, virtual machines run much slower using software emulation.

Verify your system supports KVM by running:

```console
sudo apt install cpu-checker -y
sudo kvm-ok
```

If KVM is available, you will see the messages:

```output
INFO: /dev/kvm exists
KVM acceleration can be used
```

This confirms that:
- Your CPU supports hardware virtualization
- The KVM kernel module is loaded
- The `/dev/kvm` device exists

## Required software

The scripts require several software packages.

Install the packages using the Linux package manager.

```console
sudo apt update
sudo apt install qemu-system-arm qemu-utils genisoimage wget curl jq uuid-runtime -y
```

If needed, the [Remmina](https://remmina.org/) remote desktop (RDP) client is automatically installed by the run script so you don't need to install it now, but you can install it using the command below.

```console
sudo apt install remmina remmina-plugin-rdp -y
```

Proceed to the next section to learn about the scripts.

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: Understanding the virtual machine scripts

weight: 3

layout: "learningpathall"
---

A GitHub project provides two Bash scripts. Understanding their architecture and design will help you use them effectively and enable you to customize the options for your specific needs.

Start by cloning the project repository from GitHub to your Arm Linux system.

```bash
git clone https://github.com/jasonrandrews/win11arm.git
cd win11arm
```

The remainder of this section explains the structure of the scripts, and the next section provides details to run the scripts to create a Windows virtual machine.

## Project overview

The project includes two Bash scripts.

- VM create script: `create-win11-vm.sh` handles all VM creation tasks
- VM run script: `run-win11-vm.sh` manages VM execution and connectivity

All configuration is available using command-line options.

The VM create script also allows you to perform the entire VM creation with a single command or run each individual step to learn and monitor the process.

This modular approach allows you to understand each component while maintaining the simplicity of automated execution.

## Virtual machine creation

The creation script, `create-win11-vm.sh` is responsible for building a complete Windows 11 on Arm VM from scratch. It handles everything from directory setup to Windows installation, with each step clearly defined and independently executable.

The script handles resource detection and allocation, provides unattended Windows installation, and has a flexible command line to change default values.

Virtual machine creation includes the following steps:

- Download the Windows 11 for Arm ISO from Microsoft
- Configure VirtIO drivers for optimal performance
- Set up automated installation with custom credentials
- Create optimized disk images

### Virtual machine creation details

The `create-win11-vm.sh` script implements a four-step process that builds a Windows VM incrementally:

### Step 1: Create VM directory

Step 1 initializes the VM directory structure and configuration. It creates the VM directory, copies initial configuration files, and sets up the basic environment. As a result, the VM directory, configuration files, and connection profiles are created.

### Step 2: Download Windows

Step 2 downloads the Windows 11 ISO and VirtIO drivers. It downloads the Windows 11 Arm ISO from Microsoft, fetches VirtIO drivers, and prepares unattended installation files. The files created during this step include `installer.iso`, `virtio-win.iso`, and the unattended installation directory. This step takes some time as the Windows ISO download is large, but if you already have the file the script will save time and not repeat the download.

### Step 3: Prepare VM disk image

Step 3 creates the VM disk image and finalizes the installation setup. It builds the unattended installation ISO, creates the main VM disk image, and configures all installation media. The files created during this step include `disk.qcow2` and `unattended.iso`.

{{% notice Note %}}
The product key used in the scripts is a generic key provided by Microsoft, which allows installation. This key is for testing purposes only and does not activate Windows. If you plan to continue using Windows beyond installation, you should replace it with a genuine product key.
{{% /notice %}}

### Step 4: First Windows boot

Step 4 executes the Windows installation. It boots the VM with installation media, runs the automated Windows setup, and completes the initial configuration. The result is a fully installed and configured Windows on Arm VM.

Each step builds on the previous one, and you can run them individually for debugging or customization purposes.

## Virtual machine execution

The `run-win11-vm.sh` script runs virtual machines by managing their execution and connectivity.

The script begins by checking if the VM is already active by validating QEMU processes and PID files. If the VM is running, it skips to establishing an RDP connection; otherwise, it proceeds to start the VM.

Next, the script launches the VM in headless mode, optimized for RDP access, by configuring QEMU with a headless display, setting up port forwarding, and starting the VM as a background daemon process.

Once the VM is running, the script waits for the RDP service to become available, configures the Remmina client, and establishes a desktop connection.

This process ensures seamless access to the VM with proper display scaling and input handling.

## Automatic resource detection and allocation

The scripts try to manage resources based on your system.

For CPU allocation, `/proc/cpuinfo` is used to determine the total number of CPU cores and use half of the available cores for the VM. A minimum of 2 cores for creation and 4 cores for runtime are required.

For memory allocation, `/proc/meminfo` is used to determine total system RAM and allocate half of the available memory for the VM. A minimum of 2GB is required and memory usage is based on system capacity, with an option to override using a command line parameter.

For storage, the default VM disk size is 40GB in QCOW2 format. The available disk space is validated before creation.

All settings are customizable using command line arguments.

## Script Integration and Workflow

The create and run scripts share the same configuration files. Separating creation from execution enables you to create a VM once and then use the run script repeatedly.

The next section explains how to create and run a Windows on Arm virtual machine.
Loading