microsoft/openvmm

Public

mirrored from https://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
073bb687630dc42b0c8b4ffbce1c20b5e3a1b2fa

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

356lines · 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 --vmbus-scsi id=scsi0 --disk memdiff:$disk_path,on=scsi0"
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+=" --vmbus-scsi id=scsi0 --disk memdiff:$disk_path,on=scsi0 --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 --vmbus-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 echo "Building openvmm..."
223 (
224 set -x
225 cargo build $build_args
226 )
227 echo
228
229 # Copy to Windows
230 echo "Copying to windows"
231
232 if [[ $3 == "hcl" ]]; then
233 (
234 set -x
235 cp -u "$ohcl_path/$ohcl_name" "$windows_temp/$ohcl_name" -f
236 mkdir -p "$windows_enlistment/$ohcl_path"
237 cp -u "$ohcl_path/$ohcl_name" "$windows_enlistment/$ohcl_path/$ohcl_name" -f
238 )
239 if $copy_remote; then
240 (
241 set -x
242 powershell.exe Copy-Item "$windows_temp_win\\$ohcl_name" "$remote_temp\\$ohcl_name" -Force
243 )
244 fi
245 if $copy_symbols; then
246 (
247 set -x
248 cp -u "$ohcl_path/$ohcl_symbols" "$windows_temp/openvmm_hcl" -f
249 cp -u "$ohcl_path/$ohcl_symbols.dbg" "$windows_temp/openvmm_hcl.dbg" -f
250 )
251 fi
252 fi
253
254 (
255 set -x
256 cp -u "$base_win/openvmm.exe" $openvmm_path -f
257 mkdir -p "$windows_enlistment/$base_win"
258 cp -u "$base_win/openvmm.exe" "$windows_enlistment/$base_win/openvmm.exe" -f
259 )
260 if $copy_remote; then
261 (
262 set -x
263 powershell.exe Copy-Item "$windows_temp_win\\openvmm.exe" "$remote_temp\\openvmm.exe" -Force
264 )
265 fi
266 if $copy_symbols; then
267 (
268 set -x
269 cp -u "$base_win/openvmm.pdb" "$windows_temp/openvmm.pdb" -f
270 )
271 fi
272
273 echo
274
275 if [[ $1 == "run" ]]; then
276 (
277 set -x
278 $openvmm_path $args
279 )
280 else
281 echo $openvmm_path $args
282 fi
283
284elif [[ $1 == "ohcldiag-dev" ]]; then
285
286 shift 2
287 (
288 set -x
289 cargo build --target $arch-pc-windows-msvc -p ohcldiag-dev
290 cp -u $base_win/ohcldiag-dev.exe "$windows_temp/ohcldiag-dev.exe" -f
291 "$windows_temp/ohcldiag-dev.exe" "$uhdiag_path" "$@"
292 )
293
294else
295
296 echo "Unknown command: $1"
297 echo "Usage: $0 <build|run|ohcldiag-dev> <x64|aarch64>..."
298 exit 1
299
300fi
301```
302
303## Running Windows binaries from WSL2
304
305When you cross-compile to `x86_64-pc-windows-msvc` and run the resulting `.exe`
306from WSL, it runs as a **native Windows process**. This means it sees Windows
307paths (`C:\...`), not Linux paths (`/mnt/c/...`). You must translate paths at the
308command line.
309
310Use `wslpath -w` to convert a WSL path to a Windows path:
311
312```bash
313# Convert a WSL path to a Windows path
314wslpath -w /mnt/c/vhds/server25.vhdx
315# Output: C:\vhds\server25.vhdx
316```
317
318Here is a full working example that launches OpenVMM with a VHDX disk:
319
320```bash
321cargo run --target x86_64-pc-windows-msvc -- \
322 --vmbus-scsi id=scsi0 \
323 --disk "memdiff:file:$(wslpath -w /mnt/c/vhds/server25.vhdx),on=scsi0" \
324 --uefi \
325 --uefi-firmware "$(wslpath -w .packages/hyperv.uefi.mscoreuefi.x64.RELEASE/MsvmX64/RELEASE_VS2022/FV/MSVM.fd)" \
326 --gfx -p 6 -m 8GB
327```
328
329~~~admonish tip
330If you have the [WSLENV export](#running-windows-openvmm-from-within-wsl)
331active, you can omit `--uefi-firmware` — the `X86_64_OPENVMM_UEFI_FIRMWARE`
332env var (set in `.cargo/config.toml`) is automatically translated to a
333Windows path:
334
335```bash
336export WSLENV=$WSLENV:X86_64_OPENVMM_UEFI_FIRMWARE/p
337cargo run --target x86_64-pc-windows-msvc -- \
338 --vmbus-scsi id=scsi0 \
339 --disk "memdiff:file:$(wslpath -w /mnt/c/vhds/server25.vhdx),on=scsi0" \
340 --uefi --gfx -p 6 -m 8GB
341```
342~~~
343
344```admonish warning
345A common mistake is passing `/mnt/c/...` paths directly. The Windows binary
346does not understand Linux paths, so you'll get "Access is denied" or "file not
347found" errors.
348```
349
350```admonish tip
351Keep VHDX files on the Windows filesystem (e.g., `C:\vhds\`), not on the WSL
352ext4 volume. The WSL volume is slow for large I/O and has limited size. The
353same performance note from
354[Speeding up Windows OpenVMM launch](#speeding-up-windows-openvmm-launch)
355applies to disk images — large files should live on the Windows side.
356```
357