From 7c4363018a4cfdfe7ce3ff167970ea7c49dcb14f Mon Sep 17 00:00:00 2001 From: Zhang Junyu Date: Sat, 28 Feb 2026 23:57:49 +0800 Subject: [PATCH] refine: Refine VmBuilder --- crates/vm-cli/src/main.rs | 6 +- crates/vm-machine/src/lib.rs | 1 + crates/vm-machine/src/vm.rs | 92 ++--------------------------- crates/vm-machine/src/vm_builder.rs | 90 ++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 91 deletions(-) create mode 100644 crates/vm-machine/src/vm_builder.rs diff --git a/crates/vm-cli/src/main.rs b/crates/vm-cli/src/main.rs index 927c5db..1812539 100644 --- a/crates/vm-cli/src/main.rs +++ b/crates/vm-cli/src/main.rs @@ -5,7 +5,7 @@ use tracing::debug; use tracing_subscriber::EnvFilter; use vm_bootloader::boot_loader::BootLoaderBuilder; use vm_core::virt::Virt; -use vm_machine::vm::VmBuilder; +use vm_machine::vm_builder::VmBuilder; use crate::cmd::Accel; use crate::cmd::Command; @@ -20,13 +20,13 @@ where V: Virt, Loader: BootLoaderBuilder, { - let vm_builder = VmBuilder::::new( + let vm_builder = VmBuilder::new( parse_memory(&args.memory)?, args.cpus, args.device.into_iter().map(Into::into).collect(), args.gdb, ); - let mut vm = vm_builder.build()?; + let mut vm = vm_builder.build::()?; let bootloader = Loader::new(args.kernel, args.initramfs, args.cmdline); diff --git a/crates/vm-machine/src/lib.rs b/crates/vm-machine/src/lib.rs index 70d96c1..fe18e5e 100644 --- a/crates/vm-machine/src/lib.rs +++ b/crates/vm-machine/src/lib.rs @@ -5,3 +5,4 @@ mod firmware; pub mod error; pub mod vm; +pub mod vm_builder; diff --git a/crates/vm-machine/src/vm.rs b/crates/vm-machine/src/vm.rs index de49f74..3854066 100644 --- a/crates/vm-machine/src/vm.rs +++ b/crates/vm-machine/src/vm.rs @@ -1,104 +1,20 @@ -use std::marker::PhantomData; use std::sync::Arc; use std::sync::Mutex; use vm_bootloader::boot_loader::BootLoader; -use vm_core::arch::layout::MemoryLayout; use vm_core::debug::gdbstub::GdbStub; use vm_core::device::device_manager::DeviceManager; -use vm_core::device::mmio::MmioLayout; use vm_core::virt::Virt; -use vm_device::device::Device; -use vm_mm::allocator::MemoryContainer; use vm_mm::manager::MemoryAddressSpace; -use vm_mm::region::MemoryRegion; -use crate::device::InitDevice; use crate::error::Error; use crate::error::Result; -pub struct VmBuilder { - memory_size: usize, - vcpus: usize, - devices: Vec, - gdb_port: Option, - _mark: PhantomData, -} - -impl VmBuilder { - pub fn new( - memory_size: usize, - vcpus: usize, - devices: Vec, - gdb_port: Option, - ) -> Self { - VmBuilder { - memory_size, - vcpus, - devices, - gdb_port, - _mark: PhantomData, - } - } -} - pub struct Vm { - memory: Arc>>, - virt: V, - device_manager: Arc>, - gdb_stub: Option, -} - -impl VmBuilder -where - V: Virt, -{ - fn init_mm(&self, ram_base: u64) -> Result> - where - C: MemoryContainer, - { - let memory_region = MemoryRegion::placeholder(ram_base, self.memory_size); - - let mut memory_regions = MemoryAddressSpace::default(); - memory_regions - .try_insert(memory_region) - .map_err(|_| Error::InitMemory("Failed to insert memory_region".to_string()))?; - - Ok(memory_regions) - } - - pub fn build(self) -> Result> { - let mut virt = V::new(self.vcpus)?; - - let layout = virt.get_layout().clone(); - let mmio_layout = MmioLayout::new(layout.get_mmio_start(), layout.get_mmio_len()); - - let irq_chip = if !self.devices.iter().any(Device::is_irq_chip) { - Some(virt.init_irq()?) - } else { - None - }; - - let mut memory = self.init_mm(layout.get_ram_base())?; - virt.init_memory(&mmio_layout, &mut memory, self.memory_size as u64)?; - let memory = Arc::new(Mutex::new(memory)); - - virt.post_init()?; - - let mut device_manager = DeviceManager::new(mmio_layout); - device_manager - .init_devices(memory.clone(), self.devices, irq_chip) - .map_err(|err| Error::InitDevice(err.to_string()))?; - - let vm = Vm { - memory, - virt, - device_manager: Arc::new(Mutex::new(device_manager)), - gdb_stub: self.gdb_port.map(GdbStub::new), - }; - - Ok(vm) - } + pub(crate) memory: Arc>>, + pub(crate) virt: V, + pub(crate) device_manager: Arc>, + pub(crate) gdb_stub: Option, } impl Vm diff --git a/crates/vm-machine/src/vm_builder.rs b/crates/vm-machine/src/vm_builder.rs new file mode 100644 index 0000000..8ab263a --- /dev/null +++ b/crates/vm-machine/src/vm_builder.rs @@ -0,0 +1,90 @@ +use std::sync::Arc; +use std::sync::Mutex; + +use vm_core::arch::layout::MemoryLayout; +use vm_core::debug::gdbstub::GdbStub; +use vm_core::device::device_manager::DeviceManager; +use vm_core::device::mmio::MmioLayout; +use vm_core::virt::Virt; +use vm_device::device::Device; +use vm_mm::allocator::MemoryContainer; +use vm_mm::manager::MemoryAddressSpace; +use vm_mm::region::MemoryRegion; + +use crate::device::InitDevice; +use crate::error::Error; +use crate::error::Result; +use crate::vm::Vm; + +pub struct VmBuilder { + memory_size: usize, + vcpus: usize, + devices: Vec, + gdb_port: Option, +} + +impl VmBuilder { + pub fn new( + memory_size: usize, + vcpus: usize, + devices: Vec, + gdb_port: Option, + ) -> Self { + VmBuilder { + memory_size, + vcpus, + devices, + gdb_port, + } + } + + pub fn build(self) -> Result> + where + V: Virt, + { + let mut virt = V::new(self.vcpus)?; + + let layout = virt.get_layout().clone(); + let mmio_layout = MmioLayout::new(layout.get_mmio_start(), layout.get_mmio_len()); + + let irq_chip = if !self.devices.iter().any(Device::is_irq_chip) { + Some(virt.init_irq()?) + } else { + None + }; + + let mut memory = self.init_mm(layout.get_ram_base())?; + virt.init_memory(&mmio_layout, &mut memory, self.memory_size as u64)?; + let memory = Arc::new(Mutex::new(memory)); + + virt.post_init()?; + + let mut device_manager = DeviceManager::new(mmio_layout); + device_manager + .init_devices(memory.clone(), self.devices, irq_chip) + .map_err(|err| Error::InitDevice(err.to_string()))?; + + let vm = Vm { + memory, + virt, + device_manager: Arc::new(Mutex::new(device_manager)), + gdb_stub: self.gdb_port.map(GdbStub::new), + }; + + Ok(vm) + } + + fn init_mm(&self, ram_base: u64) -> Result> + where + C: MemoryContainer, + { + let memory_region = MemoryRegion::placeholder(ram_base, self.memory_size); + + let mut memory_regions = MemoryAddressSpace::default(); + memory_regions + .try_insert(memory_region) + .map_err(|_| Error::InitMemory("Failed to insert memory_region".to_string()))?; + + Ok(memory_regions) + } +}