microsoft/openvmm

Public

mirrored fromhttps://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e7ab2a78cb2ba1d35447aca97d3fc96f76e86b40

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Guide/src/dev_guide/getting_started/cross_compile.md

358lines · modecode

1# \[WSL2] Cross Compiling from WSL2 to Windows
2
3Setting up cross compilation is very useful, as it allows using the same repo
4cloned in WSL2 to both develop OpenHCL, as well as launch it via OpenVMM via the
5WHP backend.
6
7## Required Dependencies
8
9Note that this requires some additional dependencies, described below.
10
11### Windows deps
12
13Visual Studio build tools must be installed, along with the Windows SDK.
14[This is the same as what's required to build OpenVMM on windows.](./windows.md#installing-rust)
15
16### WSL deps
17
18The msvc target `x86_64-pc-windows-msvc` must be installed for the toolchain
19being used in WSL. This can be added by doing the following:
20
21```bash
22rustup target add x86_64-pc-windows-msvc
23```
24
25Additional build tools must be installed as well. If your distro has LLVM 14
26available (Ubuntu 22.04 or newer):
27
28```bash
29sudo apt install clang-tools-14 lld-14 llvm-dev
30```
31
32Otherwise, follow the steps at <https://apt.llvm.org/> to install a specific
33version, by adding the correct apt repos. Note that you must install
34`clang-tools-14` as default `clang-14` uses gcc style arguments, where
35`clang-cl-14` uses msvc style arguments. You can use their helper script as
36well:
37
38```bash
39wget https://apt.llvm.org/llvm.sh
40chmod +x llvm.sh
41sudo ./llvm.sh 14
42sudo apt install clang-tools-14
43```
44
45## Setting up the terminal environment
46
47Source the `build_support/setup_windows_cross.sh` script from your terminal
48instance. For example, the following script will do this along with setting a
49default cargo build target:
50
51```bash
52#!/bin/bash
53
54# Setup environment and windows cross tooling.
55
56export CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu
57cd path/to/openvmm || exit
58. build_support/setup_windows_cross.sh
59exec "$SHELL"
60```
61
62For developers using shells other than bash, you may need to run the
63`setup_windows_cross.sh` script in bash then launch your shell in order to get
64the correct environment variables.
65
66## Editing with vscode
67
68You can have rust-analyzer target Windows, which will allow you to use the same
69repo for OpenHCL, Linux, and Windows changes, but the vscode remote server
70must be launched from the terminal window that sourced the setup script. You can
71do this by closing all vscode windows then opening your workspace with
72`code <path to workspace>` in your terminal.
73
74Add the following to your workspace settings for a vscode workspace
75dedicated to Windows:
76
77```json
78"settings": {
79 "rust-analyzer.cargo.target": "x86_64-pc-windows-msvc"
80}
81```
82
83## Running Windows OpenVMM from within WSL
84
85You can build and run the windows version of OpenVMM by overriding the target
86field of cargo commands, via `--target x86_64-pc-windows-msvc`. For example, the
87following command will run OpenVMM with WHP:
88
89```bash
90cargo run --target x86_64-pc-windows-msvc
91```
92
93You can optionally set cargo aliases for this so that you don't have to type out
94the full target every time. Add the following to your `~/.cargo/config.toml`:
95
96```toml
97[alias]
98winbuild = "build --target x86_64-pc-windows-msvc"
99wincheck = "check --target x86_64-pc-windows-msvc"
100winclippy = "clippy --target x86_64-pc-windows-msvc"
101windoc = "doc --target x86_64-pc-windows-msvc"
102winrun = "run --target x86_64-pc-windows-msvc"
103wintest = "test --target x86_64-pc-windows-msvc"
104```
105
106You can then run the windows version of OpenVMM by running:
107
108```bash
109cargo winrun
110```
111
112OpenVMM configures some environment variables that specify the default Linux kernel,
113initrd, and UEFI firmware. To make those variables available in Windows, run the following:
114
115```bash
116export WSLENV=$WSLENV:X86_64_OPENVMM_LINUX_DIRECT_KERNEL:X86_64_OPENVMM_LINUX_DIRECT_INITRD:AARCH64_OPENVMM_LINUX_DIRECT_KERNEL:AARCH64_OPENVMM_LINUX_DIRECT_INITRD:X86_64_OPENVMM_UEFI_FIRMWARE:AARCH64_OPENVMM_UEFI_FIRMWARE:RUST_BACKTRACE
117```
118
119### Speeding up Windows OpenVMM launch
120
121Due to filesystem limitations on WSL, launching OpenVMM directly will be somewhat
122slow. Instead, you can copy the built binaries to a location on in the Windows
123filesystem and then launch them via WSL.
124
125Quite a few folks working on the OpenVMM project have hacked together personal
126helper scripts to automate this process. Here is one example: (update the
127variables at the top of the file as necessary.)
128
129```bash
130#!/bin/bash
131
132# build & run script for openhcl testing with openvmm
133
134set -e
135
136args="-m 4GB -p 4"
137copy_symbols=true
138copy_remote=false
139windows_temp="/mnt/e/cross"
140windows_temp_win="E:\\cross"
141remote_temp="\\\\<remote_computer>\\cross"
142windows_enlistment="/mnt/e/openvmm"
143
144disk_path="$windows_temp_win\\disk.vhdx"
145uefi_firmware="$windows_temp_win\\MSVM.fd"
146
147if [[ $# -lt 2 ]]; then
148 echo "Usage: $0 <build|run|ohcldiag-dev> <x64|aarch64>..."
149 exit 1
150fi
151
152if [[ $2 == "aarch64" ]]; then
153 arch="aarch64"
154 short_arch="aarch64"
155elif [[ $2 == "x64" ]]; then
156 arch="x86_64"
157 short_arch="x64"
158else
159 echo "Unknown arch: $2"
160 echo "Usage: $0 $1 <x64|aarch64>"
161 exit 2
162fi
163
164uhdiag_path="$windows_temp_win\\uhdiag"
165openvmm_path="$windows_temp/openvmm.exe"
166windows_openvmm="$windows_temp/openvmm"
167base_igvm="flowey-out/artifacts/build-igvm"
168win_target="$arch-pc-windows-msvc"
169base_win="target/$win_target/debug"
170
171if [[ $1 == "build" || $1 == "run" ]]; then
172
173 build_args="--target $arch-pc-windows-msvc"
174
175 if [[ $3 == "vmm" ]]; then
176
177
178 if [[ $4 == "uefi" ]]; then
179 args+=" --uefi --uefi-firmware $uefi_firmware --disk memdiff:$disk_path"
180 elif [[ $4 == "linux" ]]; then
181 args+=""
182 else
183 echo "Unknown load mode: $4"
184 echo "Usage: $0 $1 $2 $3 <uefi|linux>"
185 exit 2
186 fi
187
188 elif [[ $3 == "hcl" ]]; then
189
190 if [[ $4 == "uefi" ]]; then
191 recipe="$short_arch"
192 args+=" --disk memdiff:$disk_path --gfx --vmbus-com1-serial term --uefi-console-mode com1 --uefi"
193 elif [[ $4 == "linux" ]]; then
194 recipe="$short_arch-test-linux-direct"
195 args+=" --vmbus-com1-serial term --vmbus-com2-serial term"
196 else
197 echo "Unknown load mode: $4"
198 echo "Usage: $0 $1 $2 $3 <uefi|linux>"
199 exit 2
200 fi
201
202 ohcl_name="openhcl-$recipe.bin"
203 ohcl_path="$base_igvm/debug/$recipe"
204 ohcl_symbols="openvmm_hcl"
205
206 args+=" --hv --vtl2 --igvm $windows_temp_win\\$ohcl_name --vtl2-vsock-path $uhdiag_path --com3 term"
207
208 echo "Building OpenHCL..."
209 (
210 set -x
211 cargo xflowey build-igvm $recipe
212 )
213
214 else
215 echo "Unknown package: $2"
216 echo "Usage: $0 $1 <vmm|hcl>"
217 exit 2
218 fi
219
220 echo
221
222 if [[ $5 == "unstable" ]]; then
223 build_args+=" --features unstable_whp"
224 fi
225
226 echo "Building openvmm..."
227 (
228 set -x
229 cargo build $build_args
230 )
231 echo
232
233 # Copy to Windows
234 echo "Copying to windows"
235
236 if [[ $3 == "hcl" ]]; then
237 (
238 set -x
239 cp -u "$ohcl_path/$ohcl_name" "$windows_temp/$ohcl_name" -f
240 mkdir -p "$windows_enlistment/$ohcl_path"
241 cp -u "$ohcl_path/$ohcl_name" "$windows_enlistment/$ohcl_path/$ohcl_name" -f
242 )
243 if $copy_remote; then
244 (
245 set -x
246 powershell.exe Copy-Item "$windows_temp_win\\$ohcl_name" "$remote_temp\\$ohcl_name" -Force
247 )
248 fi
249 if $copy_symbols; then
250 (
251 set -x
252 cp -u "$ohcl_path/$ohcl_symbols" "$windows_temp/openvmm_hcl" -f
253 cp -u "$ohcl_path/$ohcl_symbols.dbg" "$windows_temp/openvmm_hcl.dbg" -f
254 )
255 fi
256 fi
257
258 (
259 set -x
260 cp -u "$base_win/openvmm.exe" $openvmm_path -f
261 mkdir -p "$windows_enlistment/$base_win"
262 cp -u "$base_win/openvmm.exe" "$windows_enlistment/$base_win/openvmm.exe" -f
263 )
264 if $copy_remote; then
265 (
266 set -x
267 powershell.exe Copy-Item "$windows_temp_win\\openvmm.exe" "$remote_temp\\openvmm.exe" -Force
268 )
269 fi
270 if $copy_symbols; then
271 (
272 set -x
273 cp -u "$base_win/openvmm.pdb" "$windows_temp/openvmm.pdb" -f
274 )
275 fi
276
277 echo
278
279 if [[ $1 == "run" ]]; then
280 (
281 set -x
282 $openvmm_path $args
283 )
284 else
285 echo $openvmm_path $args
286 fi
287
288elif [[ $1 == "ohcldiag-dev" ]]; then
289
290 shift 2
291 (
292 set -x
293 cargo build --target $arch-pc-windows-msvc -p ohcldiag-dev
294 cp -u $base_win/ohcldiag-dev.exe "$windows_temp/ohcldiag-dev.exe" -f
295 "$windows_temp/ohcldiag-dev.exe" "$uhdiag_path" "$@"
296 )
297
298else
299
300 echo "Unknown command: $1"
301 echo "Usage: $0 <build|run|ohcldiag-dev> <x64|aarch64>..."
302 exit 1
303
304fi
305```
306
307## Running Windows binaries from WSL2
308
309When you cross-compile to `x86_64-pc-windows-msvc` and run the resulting `.exe`
310from WSL, it runs as a **native Windows process**. This means it sees Windows
311paths (`C:\...`), not Linux paths (`/mnt/c/...`). You must translate paths at the
312command line.
313
314Use `wslpath -w` to convert a WSL path to a Windows path:
315
316```bash
317# Convert a WSL path to a Windows path
318wslpath -w /mnt/c/vhds/server25.vhdx
319# Output: C:\vhds\server25.vhdx
320```
321
322Here is a full working example that launches OpenVMM with a VHDX disk:
323
324```bash
325cargo run --target x86_64-pc-windows-msvc -- \
326 --disk "memdiff:file:$(wslpath -w /mnt/c/vhds/server25.vhdx)" \
327 --uefi \
328 --uefi-firmware "$(wslpath -w .packages/hyperv.uefi.mscoreuefi.x64.RELEASE/MsvmX64/RELEASE_VS2022/FV/MSVM.fd)" \
329 --gfx -p 6 -m 8GB
330```
331
332~~~admonish tip
333If you have the [WSLENV export](#running-windows-openvmm-from-within-wsl)
334active, you can omit `--uefi-firmware` — the `X86_64_OPENVMM_UEFI_FIRMWARE`
335env var (set in `.cargo/config.toml`) is automatically translated to a
336Windows path:
337
338```bash
339export WSLENV=$WSLENV:X86_64_OPENVMM_UEFI_FIRMWARE/p
340cargo run --target x86_64-pc-windows-msvc -- \
341 --disk "memdiff:file:$(wslpath -w /mnt/c/vhds/server25.vhdx)" \
342 --uefi --gfx -p 6 -m 8GB
343```
344~~~
345
346```admonish warning
347A common mistake is passing `/mnt/c/...` paths directly. The Windows binary
348does not understand Linux paths, so you'll get "Access is denied" or "file not
349found" errors.
350```
351
352```admonish tip
353Keep VHDX files on the Windows filesystem (e.g., `C:\vhds\`), not on the WSL
354ext4 volume. The WSL volume is slow for large I/O and has limited size. The
355same performance note from
356[Speeding up Windows OpenVMM launch](#speeding-up-windows-openvmm-launch)
357applies to disk images — large files should live on the Windows side.
358```
359