hermit_entry/boot_info/
kernel.rs

1use time::OffsetDateTime;
2
3use super::{
4    BootInfo, HardwareInfo, LoadInfo, PlatformInfo, RawBootInfo, RawHardwareInfo, RawLoadInfo,
5    RawPlatformInfo, TlsInfo,
6};
7
8impl From<RawHardwareInfo> for HardwareInfo {
9    fn from(raw_hardware_info: RawHardwareInfo) -> Self {
10        Self {
11            phys_addr_range: raw_hardware_info.phys_addr_start..raw_hardware_info.phys_addr_end,
12            serial_port_base: raw_hardware_info.serial_port_base,
13            device_tree: raw_hardware_info.device_tree,
14        }
15    }
16}
17
18impl From<RawLoadInfo> for LoadInfo {
19    fn from(raw_load_info: RawLoadInfo) -> Self {
20        let TlsInfo {
21            start,
22            filesz,
23            memsz,
24            align,
25        } = raw_load_info.tls_info;
26
27        Self {
28            kernel_image_addr_range: raw_load_info.kernel_image_addr_start
29                ..raw_load_info.kernel_image_addr_end,
30            tls_info: (start != 0 || filesz != 0 || memsz != 0 || align != 0)
31                .then_some(raw_load_info.tls_info),
32        }
33    }
34}
35
36impl From<RawPlatformInfo> for PlatformInfo {
37    fn from(raw_platform_info: RawPlatformInfo) -> Self {
38        match raw_platform_info {
39            #[cfg(target_arch = "x86_64")]
40            RawPlatformInfo::Multiboot {
41                command_line_data,
42                command_line_len,
43                multiboot_info_addr,
44            } => {
45                let command_line = (!command_line_data.is_null()).then(|| {
46                    // SAFETY: cmdline and cmdsize are valid forever.
47                    let slice = unsafe {
48                        core::slice::from_raw_parts(command_line_data, command_line_len as usize)
49                    };
50                    core::str::from_utf8(slice).unwrap()
51                });
52
53                Self::Multiboot {
54                    command_line,
55                    multiboot_info_addr,
56                }
57            }
58            #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
59            RawPlatformInfo::LinuxBoot => Self::LinuxBoot,
60            RawPlatformInfo::Uhyve {
61                has_pci,
62                num_cpus,
63                cpu_freq,
64                boot_time,
65            } => Self::Uhyve {
66                has_pci,
67                num_cpus,
68                cpu_freq,
69                boot_time: OffsetDateTime::from_unix_timestamp_nanos(i128::from_ne_bytes(
70                    boot_time.0,
71                ))
72                .unwrap(),
73            },
74            RawPlatformInfo::LinuxBootParams {
75                command_line_data,
76                command_line_len,
77                boot_params_addr,
78            } => {
79                let command_line = (!command_line_data.is_null()).then(|| {
80                    // SAFETY: cmdline and cmdsize are valid forever.
81                    let slice = unsafe {
82                        core::slice::from_raw_parts(command_line_data, command_line_len as usize)
83                    };
84                    core::str::from_utf8(slice).unwrap()
85                });
86
87                Self::LinuxBootParams {
88                    command_line,
89                    boot_params_addr,
90                }
91            }
92            RawPlatformInfo::Fdt => Self::Fdt,
93        }
94    }
95}
96
97impl From<RawBootInfo> for BootInfo {
98    fn from(raw_boot_info: RawBootInfo) -> Self {
99        Self {
100            hardware_info: raw_boot_info.hardware_info.into(),
101            load_info: raw_boot_info.load_info.into(),
102            platform_info: raw_boot_info.platform_info.into(),
103        }
104    }
105}