MCPcopy Create free account
hub / github.com/LPC4/Full-Stack / from_elf

Method from_elf

crates/virtual-machine/src/virtual_machine.rs:50–103  ·  view source on GitHub ↗

Create a VM from a complete ELF-64 image by mapping every `PT_LOAD` segment.

(bytes: &[u8])

Source from the content-addressed store, hash-verified

48 /// This snapshot with both bulk images dropped (RAM and framebuffer planes).
49 pub fn without_bulk(&self) -> Self {
50 Self {
51 cpu: self.cpu.clone(),
52 devices: self.devices.without_fb(),
53 ram: Vec::new(),
54 }
55 }
56
57 /// This snapshot with both bulk images reattached, ready for
58 /// [`VirtualMachine::restore`].
59 pub fn with_bulk(&self, ram: Vec<u8>, fb: &[u8]) -> Self {
60 let mut devices = self.devices.clone();
61 devices.load_fb_image(fb);
62 Self {
63 cpu: self.cpu.clone(),
64 devices,
65 ram,
66 }
67 }
68}
69
70// --- Constructors ---
71
72impl VirtualMachine {
73 /// Create a VM from raw assembled output by exporting it to ELF and loading that image.
74 pub fn new(assembled: &AssembledOutput) -> Self {
75 let elf = assembled.to_elf(ELF_LOAD_BASE);
76 Self::from_elf(&elf).unwrap_or_else(|e| panic!("failed to load assembled ELF: {e}"))
77 }
78
79 /// Loads the kernel ELF at `RAM_BASE` but resets the CPU to `ROM_BASE`, so the
80 /// ROM stub sets up PMP and delegation before `mret`ing into S-mode.
81 pub fn new_kernel(assembled: &AssembledOutput) -> Self {
82 let elf = assembled.to_elf_with_entry(ELF_LOAD_BASE, "_kernel_start");
83 let mut vm =
84 Self::from_elf(&elf).unwrap_or_else(|e| panic!("failed to load kernel ELF: {e}"));
85 let entry = vm.cpu.peek_pc(); // ELF entry point (_kernel_start) resolved by from_elf
86 vm.cpu.reset_pc(crate::rom::ROM_BASE);
87 vm.cpu.set_boot_entry(entry); // a0 = _kernel_start; ROM _start does `csrw mepc, a0`
88 vm
89 }
90
91 /// Create a VM from a complete ELF-64 image by mapping every `PT_LOAD` segment.
92 pub fn from_elf(bytes: &[u8]) -> Result<Self, VmError> {
93 let elf = ParsedElf::parse(bytes)?;
94
95 let rom_image = crate::rom::generate_rom_image();
96 let mut bus = SystemBus::new(rom_image);
97
98 let image_base = elf
99 .load_segments
100 .iter()
101 .map(|segment| segment.vaddr)
102 .min()
103 .unwrap_or(RAM_BASE);
104
105 let mut highest_mapped = RAM_BASE;
106 for segment in &elf.load_segments {

Callers

nothing calls this directly

Calls 7

generate_rom_imageFunction · 0.85
getMethod · 0.80
cold_cache_resetMethod · 0.80
align_upFunction · 0.70
parseFunction · 0.50
write_byteMethod · 0.45
write_doublewordMethod · 0.45

Tested by

no test coverage detected