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