1use crate::build_openhcl_initrd::OpenhclInitrdExtraParams;
13use crate::build_openvmm_hcl::OpenvmmHclBuildProfile;
14use crate::build_openvmm_hcl::OpenvmmHclFeature;
15use crate::download_openhcl_kernel_package::OpenhclKernelPackageArch;
16use crate::download_openhcl_kernel_package::OpenhclKernelPackageKind;
17use crate::download_openvmm_deps::OpenvmmDepsArch;
18use crate::download_uefi_mu_msvm::MuMsvmArch;
19use crate::run_cargo_build::BuildProfile;
20use crate::run_cargo_build::common::CommonArch;
21use crate::run_cargo_build::common::CommonPlatform;
22use crate::run_cargo_build::common::CommonTriple;
23use flowey::node::prelude::*;
24use igvmfilegen_config::ResourceType;
25use std::collections::BTreeMap;
26use std::collections::BTreeSet;
27
28#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
29pub enum OpenhclKernelPackage {
30 Main,
32 Cvm,
34 Dev,
36 CvmDev,
38 CustomLocal(PathBuf),
40}
41
42#[derive(Serialize, Deserialize, Debug, Clone)]
44pub enum Vtl0KernelType {
45 Example,
46 LocalOnlyCustom(PathBuf),
47}
48
49#[derive(Serialize, Deserialize, Clone, Debug)]
50pub enum IgvmManifestPath {
51 InTree(String),
53 LocalOnlyCustom(PathBuf),
55}
56
57#[derive(Serialize, Deserialize, Clone, Debug)]
58pub struct OpenhclIgvmRecipeDetails {
59 pub local_only: Option<OpenhclIgvmRecipeDetailsLocalOnly>,
60
61 pub igvm_manifest: IgvmManifestPath,
62 pub openhcl_kernel_package: OpenhclKernelPackage,
63 pub openvmm_hcl_features: BTreeSet<OpenvmmHclFeature>,
64 pub target: CommonTriple,
65 pub vtl0_kernel_type: Option<Vtl0KernelType>,
66 pub with_uefi: bool,
67 pub with_interactive: bool,
68 pub with_sidecar: bool,
69}
70
71#[derive(Serialize, Deserialize, Clone, Debug)]
72pub struct OpenhclIgvmRecipeDetailsLocalOnly {
73 pub openvmm_hcl_no_strip: bool,
74 pub openhcl_initrd_extra_params: Option<OpenhclInitrdExtraParams>,
75 pub custom_openvmm_hcl: Option<PathBuf>,
76 pub custom_openhcl_boot: Option<PathBuf>,
77 pub custom_uefi: Option<PathBuf>,
78 pub custom_kernel: Option<PathBuf>,
79 pub custom_sidecar: Option<PathBuf>,
80 pub custom_extra_rootfs: Vec<PathBuf>,
81}
82
83#[expect(clippy::large_enum_variant)]
84#[derive(Debug, Serialize, Deserialize, Clone)]
85pub enum OpenhclIgvmRecipe {
86 LocalOnlyCustom(OpenhclIgvmRecipeDetails),
87 X64,
88 X64Devkern,
89 X64TestLinuxDirect,
90 X64TestLinuxDirectDevkern,
91 X64Cvm,
92 X64CvmDevkern,
93 Aarch64,
94 Aarch64Devkern,
95}
96
97impl OpenhclIgvmRecipe {
98 pub fn recipe_details(&self, release_cfg: bool) -> OpenhclIgvmRecipeDetails {
99 let base_openvmm_hcl_features = || {
100 let mut m = BTreeSet::new();
101
102 m.insert(OpenvmmHclFeature::Tpm);
103
104 if !release_cfg {
105 m.insert(OpenvmmHclFeature::Gdb);
106 }
107
108 m
109 };
110
111 let in_repo_template = |debug_manifest: &'static str, release_manifest: &'static str| {
112 IgvmManifestPath::InTree(if release_cfg {
113 release_manifest.into()
114 } else {
115 debug_manifest.into()
116 })
117 };
118
119 let with_interactive = !release_cfg;
121
122 match self {
123 Self::LocalOnlyCustom(details) => details.clone(),
124 Self::X64 => OpenhclIgvmRecipeDetails {
125 local_only: None,
126 igvm_manifest: in_repo_template("openhcl-x64-dev.json", "openhcl-x64-release.json"),
127 openhcl_kernel_package: OpenhclKernelPackage::Main,
128 openvmm_hcl_features: base_openvmm_hcl_features(),
129 target: CommonTriple::X86_64_LINUX_MUSL,
130 vtl0_kernel_type: None,
131 with_uefi: true,
132 with_interactive,
133 with_sidecar: true,
134 },
135 Self::X64Devkern => OpenhclIgvmRecipeDetails {
136 local_only: None,
137 igvm_manifest: in_repo_template("openhcl-x64-dev.json", "openhcl-x64-release.json"),
138 openhcl_kernel_package: OpenhclKernelPackage::Dev,
139 openvmm_hcl_features: base_openvmm_hcl_features(),
140 target: CommonTriple::X86_64_LINUX_MUSL,
141 vtl0_kernel_type: None,
142 with_uefi: true,
143 with_interactive,
144 with_sidecar: true,
145 },
146 Self::X64CvmDevkern => OpenhclIgvmRecipeDetails {
147 local_only: None,
148 igvm_manifest: in_repo_template(
149 "openhcl-x64-cvm-dev.json",
150 "openhcl-x64-cvm-release.json",
151 ),
152 openhcl_kernel_package: OpenhclKernelPackage::CvmDev,
153 openvmm_hcl_features: base_openvmm_hcl_features(),
154 target: CommonTriple::X86_64_LINUX_MUSL,
155 vtl0_kernel_type: None,
156 with_uefi: true,
157 with_interactive,
158 with_sidecar: false,
159 },
160 Self::X64TestLinuxDirect => OpenhclIgvmRecipeDetails {
161 local_only: None,
162 igvm_manifest: in_repo_template(
163 "openhcl-x64-direct-dev.json",
164 "openhcl-x64-direct-release.json",
165 ),
166 openhcl_kernel_package: OpenhclKernelPackage::Main,
167 openvmm_hcl_features: base_openvmm_hcl_features(),
168 target: CommonTriple::X86_64_LINUX_MUSL,
169 vtl0_kernel_type: Some(Vtl0KernelType::Example),
170 with_uefi: false,
171 with_interactive,
172 with_sidecar: true,
173 },
174 Self::X64TestLinuxDirectDevkern => OpenhclIgvmRecipeDetails {
175 local_only: None,
176 igvm_manifest: in_repo_template(
177 "openhcl-x64-direct-dev.json",
178 "openhcl-x64-direct-release.json",
179 ),
180 openhcl_kernel_package: OpenhclKernelPackage::Dev,
181 openvmm_hcl_features: base_openvmm_hcl_features(),
182 target: CommonTriple::X86_64_LINUX_MUSL,
183 vtl0_kernel_type: Some(Vtl0KernelType::Example),
184 with_uefi: false,
185 with_interactive,
186 with_sidecar: true,
187 },
188 Self::X64Cvm => OpenhclIgvmRecipeDetails {
189 local_only: None,
190 igvm_manifest: in_repo_template(
191 "openhcl-x64-cvm-dev.json",
192 "openhcl-x64-cvm-release.json",
193 ),
194 openhcl_kernel_package: OpenhclKernelPackage::Cvm,
195 openvmm_hcl_features: base_openvmm_hcl_features(),
196 target: CommonTriple::X86_64_LINUX_MUSL,
197 vtl0_kernel_type: None,
198 with_uefi: true,
199 with_interactive,
200 with_sidecar: false,
201 },
202 Self::Aarch64 => OpenhclIgvmRecipeDetails {
203 local_only: None,
204 igvm_manifest: in_repo_template(
205 "openhcl-aarch64-dev.json",
206 "openhcl-aarch64-release.json",
207 ),
208 openhcl_kernel_package: OpenhclKernelPackage::Main,
209 openvmm_hcl_features: base_openvmm_hcl_features(),
210 target: CommonTriple::AARCH64_LINUX_MUSL,
211 vtl0_kernel_type: None,
212 with_uefi: true,
213 with_interactive: false, with_sidecar: false,
215 },
216 Self::Aarch64Devkern => OpenhclIgvmRecipeDetails {
217 local_only: None,
218 igvm_manifest: in_repo_template(
219 "openhcl-aarch64-dev.json",
220 "openhcl-aarch64-release.json",
221 ),
222 openhcl_kernel_package: OpenhclKernelPackage::Dev,
223 openvmm_hcl_features: base_openvmm_hcl_features(),
224 target: CommonTriple::AARCH64_LINUX_MUSL,
225 vtl0_kernel_type: None,
226 with_uefi: true,
227 with_interactive: false, with_sidecar: false,
229 },
230 }
231 }
232}
233
234flowey_request! {
235 pub struct Request {
236 pub build_profile: OpenvmmHclBuildProfile,
237 pub release_cfg: bool,
238 pub recipe: OpenhclIgvmRecipe,
239 pub custom_target: Option<CommonTriple>,
240
241 pub built_openvmm_hcl: WriteVar<crate::build_openvmm_hcl::OpenvmmHclOutput>,
242 pub built_openhcl_boot: WriteVar<crate::build_openhcl_boot::OpenhclBootOutput>,
243 pub built_openhcl_igvm: WriteVar<crate::run_igvmfilegen::IgvmOutput>,
244 pub built_sidecar: WriteVar<Option<crate::build_sidecar::SidecarOutput>>,
245 }
246}
247
248new_simple_flow_node!(struct Node);
249
250impl SimpleFlowNode for Node {
251 type Request = Request;
252
253 fn imports(ctx: &mut ImportCtx<'_>) {
254 ctx.import::<crate::build_igvmfilegen::Node>();
255 ctx.import::<crate::build_openhcl_boot::Node>();
256 ctx.import::<crate::build_openhcl_initrd::Node>();
257 ctx.import::<crate::build_openvmm_hcl::Node>();
258 ctx.import::<crate::build_sidecar::Node>();
259 ctx.import::<crate::download_openhcl_kernel_package::Node>();
260 ctx.import::<crate::download_openvmm_deps::Node>();
261 ctx.import::<crate::download_uefi_mu_msvm::Node>();
262 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
263 ctx.import::<crate::run_igvmfilegen::Node>();
264 ctx.import::<crate::run_split_debug_info::Node>();
265 }
266
267 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
268 let Request {
269 build_profile,
270 release_cfg,
271 recipe,
272 custom_target,
273 built_openvmm_hcl,
274 built_openhcl_boot,
275 built_openhcl_igvm,
276 built_sidecar,
277 } = request;
278
279 let OpenhclIgvmRecipeDetails {
280 local_only,
281 igvm_manifest,
282 openhcl_kernel_package,
283 openvmm_hcl_features,
284 target,
285 vtl0_kernel_type,
286 with_uefi,
287 with_interactive,
288 with_sidecar,
289 } = recipe.recipe_details(release_cfg);
290
291 let OpenhclIgvmRecipeDetailsLocalOnly {
292 openvmm_hcl_no_strip,
293 openhcl_initrd_extra_params,
294 custom_openvmm_hcl,
295 custom_openhcl_boot,
296 custom_uefi,
297 custom_kernel,
298 custom_sidecar,
299 custom_extra_rootfs,
300 } = local_only.unwrap_or(OpenhclIgvmRecipeDetailsLocalOnly {
301 openvmm_hcl_no_strip: false,
302 openhcl_initrd_extra_params: None,
303 custom_openvmm_hcl: None,
304 custom_openhcl_boot: None,
305 custom_uefi: None,
306 custom_kernel: None,
307 custom_sidecar: None,
308 custom_extra_rootfs: Vec::new(),
309 });
310
311 let target = custom_target.unwrap_or(target);
312 let arch = CommonArch::from_triple(&target.as_triple())
313 .ok_or_else(|| anyhow::anyhow!("cannot build openHCL from recipe on {target}"))?;
314
315 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
316
317 let vtl2_kernel_package_root = {
318 let arch = match arch {
319 CommonArch::X86_64 => OpenhclKernelPackageArch::X86_64,
320 CommonArch::Aarch64 => OpenhclKernelPackageArch::Aarch64,
321 };
322
323 enum DownloadOrLocal {
324 Local(PathBuf),
325 Download(OpenhclKernelPackageKind),
326 }
327
328 let download_kind = match openhcl_kernel_package {
329 OpenhclKernelPackage::Main => {
330 DownloadOrLocal::Download(OpenhclKernelPackageKind::Main)
331 }
332 OpenhclKernelPackage::Cvm => {
333 DownloadOrLocal::Download(OpenhclKernelPackageKind::Cvm)
334 }
335 OpenhclKernelPackage::Dev => {
336 DownloadOrLocal::Download(OpenhclKernelPackageKind::Dev)
337 }
338 OpenhclKernelPackage::CvmDev => {
339 DownloadOrLocal::Download(OpenhclKernelPackageKind::CvmDev)
340 }
341 OpenhclKernelPackage::CustomLocal(path) => DownloadOrLocal::Local(path),
342 };
343
344 match download_kind {
345 DownloadOrLocal::Local(path) => ReadVar::from_static(path),
346 DownloadOrLocal::Download(kind) => {
347 ctx.reqv(
348 |v| crate::download_openhcl_kernel_package::Request::GetPackage {
349 kind,
350 arch,
351 pkg: v,
352 },
353 )
354 }
355 }
356 };
357
358 let uefi_resource = with_uefi.then(|| UefiResource {
359 msvm_fd: if let Some(path) = custom_uefi {
360 ReadVar::from_static(path)
361 } else {
362 ctx.reqv(|v| crate::download_uefi_mu_msvm::Request::GetMsvmFd {
363 arch: match arch {
364 CommonArch::X86_64 => MuMsvmArch::X86_64,
365 CommonArch::Aarch64 => MuMsvmArch::Aarch64,
366 },
367 msvm_fd: v,
368 })
369 },
370 });
371
372 let vtl0_kernel_resource = vtl0_kernel_type.map(|typ| {
373 let kernel = if let Vtl0KernelType::LocalOnlyCustom(path) = typ {
374 ReadVar::from_static(path)
375 } else {
376 match typ {
377 Vtl0KernelType::Example => ctx.reqv(|v| {
378 crate::download_openvmm_deps::Request::GetLinuxTestKernel(
379 match arch {
380 CommonArch::X86_64 => OpenvmmDepsArch::X86_64,
381 CommonArch::Aarch64 => OpenvmmDepsArch::Aarch64,
382 },
383 v,
384 )
385 }),
386 Vtl0KernelType::LocalOnlyCustom(_) => unreachable!("special cased above"),
387 }
388 };
389
390 let initrd = ctx.reqv(|v| {
391 crate::download_openvmm_deps::Request::GetLinuxTestInitrd(
392 match arch {
393 CommonArch::X86_64 => OpenvmmDepsArch::X86_64,
394 CommonArch::Aarch64 => OpenvmmDepsArch::Aarch64,
395 },
396 v,
397 )
398 });
399
400 Vtl0KernelResource { kernel, initrd }
401 });
402
403 let sidecar_bin = if with_sidecar {
405 let sidecar_bin = if let Some(path) = custom_sidecar {
406 ctx.emit_rust_stepv("set custom_sidecar", |_ctx| {
407 |_rt| {
408 let fake_dbg_path = std::env::current_dir()?
409 .join("fake_sidecar.dbg")
410 .absolute()?;
411 fs_err::write(&fake_dbg_path, "")?;
412
413 Ok(crate::build_sidecar::SidecarOutput {
414 bin: path,
415 dbg: fake_dbg_path,
416 })
417 }
418 })
419 } else {
420 ctx.reqv(|v| crate::build_sidecar::Request {
421 build_params: crate::build_sidecar::SidecarBuildParams {
422 arch,
423 profile: match build_profile {
424 OpenvmmHclBuildProfile::Debug => {
425 crate::build_sidecar::SidecarBuildProfile::Debug
426 }
427 OpenvmmHclBuildProfile::Release
428 | OpenvmmHclBuildProfile::OpenvmmHclShip => {
429 crate::build_sidecar::SidecarBuildProfile::Release
430 }
431 },
432 },
433 sidecar: v,
434 })
435 };
436 sidecar_bin.write_into(ctx, built_sidecar, Some);
437 Some(sidecar_bin)
438 } else {
439 built_sidecar.write_static(ctx, None);
440 None
441 };
442
443 let openvmm_hcl_bin = ctx.reqv(|v| {
445 crate::build_openvmm_hcl::Request {
446 build_params: crate::build_openvmm_hcl::OpenvmmHclBuildParams {
447 target: target.clone(),
448 profile: build_profile,
449 features: openvmm_hcl_features,
450 no_split_dbg_info: true,
452 },
453 openvmm_hcl_output: v,
454 }
455 });
456
457 let igvmfilegen_arch = match ctx.arch() {
459 FlowArch::X86_64 => CommonArch::X86_64,
460 FlowArch::Aarch64 => CommonArch::Aarch64,
461 arch => anyhow::bail!("unsupported arch {arch}"),
462 };
463
464 let igvmfilegen = ctx.reqv(|v| crate::build_igvmfilegen::Request {
465 build_params: crate::build_igvmfilegen::IgvmfilegenBuildParams {
466 target: CommonTriple::Common {
467 arch: igvmfilegen_arch,
468 platform: CommonPlatform::LinuxGnu,
469 },
470 profile: BuildProfile::Light,
471 },
472 igvmfilegen: v,
473 });
474
475 let openhcl_boot_bin = if let Some(path) = custom_openhcl_boot {
477 ctx.emit_rust_stepv("set custom_openhcl_boot", |_ctx| {
478 |_rt| {
479 let fake_dbg_path = std::env::current_dir()?.join("fake.dbg").absolute()?;
480 fs_err::write(&fake_dbg_path, "")?;
481
482 Ok(crate::build_openhcl_boot::OpenhclBootOutput {
483 bin: path,
484 dbg: fake_dbg_path,
485 })
486 }
487 })
488 } else {
489 ctx.reqv(|v| crate::build_openhcl_boot::Request {
490 build_params: crate::build_openhcl_boot::OpenhclBootBuildParams {
491 arch,
492 profile: match build_profile {
493 OpenvmmHclBuildProfile::Debug => {
494 crate::build_openhcl_boot::OpenhclBootBuildProfile::Debug
495 }
496 OpenvmmHclBuildProfile::Release
497 | OpenvmmHclBuildProfile::OpenvmmHclShip => {
498 crate::build_openhcl_boot::OpenhclBootBuildProfile::Release
499 }
500 },
501 },
502 openhcl_boot: v,
503 })
504 };
505 openhcl_boot_bin.write_into(ctx, built_openhcl_boot, |x| x);
506
507 let use_stripped_openvmm_hcl = {
508 if custom_openvmm_hcl.is_some() {
509 false
512 } else {
513 !openvmm_hcl_no_strip
514 }
515 };
516
517 let openvmm_hcl_bin = if use_stripped_openvmm_hcl {
519 let (read, write) = ctx.new_var();
520 let (read_dbg, write_dbg) = ctx.new_var();
521
522 let in_bin = openvmm_hcl_bin.map(ctx, |o| o.bin);
523 ctx.req(crate::run_split_debug_info::Request {
524 arch,
525 in_bin,
526 out_bin: write,
527 out_dbg_info: write_dbg,
528 });
529
530 read.zip(ctx, read_dbg).map(ctx, |(bin, dbg)| {
531 crate::build_openvmm_hcl::OpenvmmHclOutput {
532 bin,
533 dbg: Some(dbg),
534 }
535 })
536 } else {
537 openvmm_hcl_bin
538 };
539
540 openvmm_hcl_bin.write_into(ctx, built_openvmm_hcl, |x| x);
542
543 let initrd = {
544 let rootfs_config = [openvmm_repo_path.map(ctx, |p| p.join("openhcl/rootfs.config"))]
545 .into_iter()
546 .chain(
547 custom_extra_rootfs
548 .into_iter()
549 .map(|p| ReadVar::from_static(p)),
550 )
551 .collect();
552 let openvmm_hcl_bin = openvmm_hcl_bin.map(ctx, |o| o.bin);
553
554 ctx.reqv(|v| crate::build_openhcl_initrd::Request {
555 interactive: with_interactive,
556 arch,
557 extra_params: openhcl_initrd_extra_params,
558 rootfs_config,
559 extra_env: None,
560 kernel_package_root: vtl2_kernel_package_root.clone(),
561 bin_openhcl: openvmm_hcl_bin,
562 initrd: v,
563 })
564 };
565
566 let kernel =
567 if let Some(path) = custom_kernel {
568 ReadVar::from_static(path)
569 } else {
570 match arch {
571 CommonArch::X86_64 => vtl2_kernel_package_root
572 .map(ctx, |p| p.join("build/native/bin/x64/vmlinux")),
573 CommonArch::Aarch64 => vtl2_kernel_package_root
574 .map(ctx, |p| p.join("build/native/bin/arm64/Image")),
575 }
576 };
577
578 let resources = ctx.emit_minor_rust_stepv("enumerate igvm resources", |ctx| {
579 let initrd = initrd.claim(ctx);
580 let kernel = kernel.claim(ctx);
581 let openhcl_boot_bin = openhcl_boot_bin.claim(ctx);
582 let sidecar_bin = sidecar_bin.claim(ctx);
583 let uefi_resource = uefi_resource.claim(ctx);
584 let vtl0_kernel_resource = vtl0_kernel_resource.claim(ctx);
585 |rt| {
586 let mut resources = BTreeMap::<ResourceType, PathBuf>::new();
587 resources.insert(ResourceType::UnderhillKernel, rt.read(kernel));
588 resources.insert(ResourceType::UnderhillInitrd, rt.read(initrd).initrd);
589 resources.insert(ResourceType::OpenhclBoot, rt.read(openhcl_boot_bin).bin);
590 if let Some(sidecar_bin) = sidecar_bin {
591 resources.insert(ResourceType::UnderhillSidecar, rt.read(sidecar_bin).bin);
592 }
593 if let Some(uefi_resource) = uefi_resource {
594 uefi_resource.add_to_resources(&mut resources, rt);
595 }
596 if let Some(vtl0_kernel_resource) = vtl0_kernel_resource {
597 vtl0_kernel_resource.add_to_resources(&mut resources, rt);
598 }
599 resources
600 }
601 });
602
603 let igvmfilegen = igvmfilegen.map(ctx, |o| match o {
604 crate::build_igvmfilegen::IgvmfilegenOutput::LinuxBin { bin, dbg: _ } => bin,
605 crate::build_igvmfilegen::IgvmfilegenOutput::WindowsBin { exe, pdb: _ } => exe,
606 });
607
608 let manifest = match igvm_manifest {
609 IgvmManifestPath::InTree(path) => {
610 openvmm_repo_path.map(ctx, |p| p.join("vm/loader/manifests").join(path))
611 }
612 IgvmManifestPath::LocalOnlyCustom(p) => ReadVar::from_static(p),
613 };
614
615 ctx.req(crate::run_igvmfilegen::Request {
616 igvmfilegen,
617 manifest,
618 resources,
619 igvm: built_openhcl_igvm,
620 });
621
622 Ok(())
623 }
624}
625
626#[derive(Debug)]
627pub struct UefiResource<C = VarNotClaimed> {
628 pub msvm_fd: ReadVar<PathBuf, C>,
629}
630
631impl ClaimVar for UefiResource {
632 type Claimed = UefiResource<VarClaimed>;
633
634 fn claim(self, ctx: &mut StepCtx<'_>) -> UefiResource<VarClaimed> {
635 UefiResource {
636 msvm_fd: self.msvm_fd.claim(ctx),
637 }
638 }
639}
640
641impl UefiResource<VarClaimed> {
642 pub fn add_to_resources(
643 self,
644 resources: &mut BTreeMap<ResourceType, PathBuf>,
645 rt: &mut RustRuntimeServices<'_>,
646 ) {
647 let path = rt.read(self.msvm_fd);
648 resources.insert(ResourceType::Uefi, path);
649 }
650}
651
652pub struct Vtl0KernelResource<C = VarNotClaimed> {
653 pub kernel: ReadVar<PathBuf, C>,
654 pub initrd: ReadVar<PathBuf, C>,
655}
656
657impl ClaimVar for Vtl0KernelResource {
658 type Claimed = Vtl0KernelResource<VarClaimed>;
659
660 fn claim(self, ctx: &mut StepCtx<'_>) -> Vtl0KernelResource<VarClaimed> {
661 Vtl0KernelResource {
662 kernel: self.kernel.claim(ctx),
663 initrd: self.initrd.claim(ctx),
664 }
665 }
666}
667
668impl Vtl0KernelResource<VarClaimed> {
669 pub fn add_to_resources(
670 self,
671 resources: &mut BTreeMap<ResourceType, PathBuf>,
672 rt: &mut RustRuntimeServices<'_>,
673 ) {
674 let kernel = rt.read(self.kernel);
675 let initrd = rt.read(self.initrd);
676 resources.insert(ResourceType::LinuxKernel, kernel);
677 resources.insert(ResourceType::LinuxInitrd, initrd);
678 }
679}