Closed luodeb closed 1 week ago
Device Tree Support Currently, there is a need to boot arceos-hypervisor on hardware. However, adding a new configuration file for each new piece of hardware (in TOML format) is not ideal. Therefore, it is hoped to port over https://github.com/Starry-OS/of, which may require some effort.
It's the problem brought by ArceOS, of couse it's a important capability.
Due to the lack of a disk driver, the OS bin file can only be loaded from memory at present. The current solution involves specifying the file to be written into boot.img in arceos-vmm/build.rs, and loading it into memory when the Hypervisor starts. This approach lacks flexibility. Is there a better solution?
We can use TFTP to load image file into different memory locations seperately
But I do not think it's a problem, a good design is to pass-through mmc to the first Linux, we just need to prepare kernel image file for this Linux
Loading the Operating System
...
image_location = "memory" kernel_path = "linux-rk3588-aarch64.bin" kernel_size = 0x400_0000 dtb_path = "linux-rk3588.dtb" dtb_size = 0x8_0000
platform = "aarch64-rk3588j" arch = "aarch64" ...
``` rust
// axvm
pub struct AxVMCrateConfig {
/// The location of the image, default is 'fs'.
pub image_location: Option<String>,
/// The size of kernel.
pub kernel_size: Option<usize>,
/// The size of dtb.
pub dtb_size: Option<usize>,
}
// image.rs
match vm_create_config.image_location.as_deref() {
Some("memory") => {
load_vm_memory(vm_create_config, vm.clone())
.expect("Failed to load VM images");
}
_ => {
load_vm_images(vm_create_config, vm.clone())
.expect("Failed to load VM images");
}
}
Since load_vm_memory will be compiled, it is also necessary to explicitly provide guestkernel_start and guestdtb_start.
// image.rs
extern "C" {
fn guestdtb_start();
// fn guestdtb_end();
fn guestkernel_start();
// fn guestkernel_end();
}
// build.rs
fn new_guest_img() -> io::Result<()> {
let mut f = File::create("./guest.S").unwrap();
// let guest = std::env::var("GUEST").unwrap();
let mut img_path = String::new();
let mut dtb_path = String::new();
img_path = "../linux-aarch64.bin".to_string(); // how can i read this from configs/*.toml?
dtb_path = "../rk3588.dtb".to_string();
writeln!(
f,
r#"
.section .data
.global guestkernel_start
.global guestkernel_end
.align 16
guestkernel_start:
.incbin "{}"
guestkernel_end:
.section .data
.global guestdtb_start
.global guestdtb_end
.align 16
guestdtb_start:
.incbin "{}"
guestdtb_end:"#,
img_path, dtb_path
)?;
Ok(())
}
#[cfg(any(platform_family = "aarch64-rk3588j"))]
// build.rs
let platform = env::var("AX_PLATFORM").unwrap_or("".to_string());
let platform_family = env::var("AX_PLATFORM").unwrap_or("".to_string());
println!("cargo:rustc-cfg=platform=\"{}\"", platform);
println!("cargo:rustc-cfg=platform_family=\"{}\"", platform_family);
in this way,we should add #[cfg(any(platform_family = "aarch64-rk3588j"))]
or #[cfg(not(any(platform_family = "aarch64-rk3588j")))]
in every function of image.rs. And not easy to expand.
eg:
// image.rs
/// Loads the VM image files from the filesystem
/// into the guest VM's memory space based on the VM configuration.
pub fn load_vm_images(config: AxVMCrateConfig, vm: VMRef) -> AxResult {
#[cfg(any(platform_family = "aarch64-rk3588j"))]
{
let dtb_start_addr = guestdtb_start as usize;
let kernel_start_addr = guestkernel_start as usize;
// Load kernel image.
load_vm_image_memory(
kernel_start_addr as *mut u8,
config.kernel_load_addr,
0x400_0000,
vm.clone(),
)
...
}
#[cfg(not(any(platform_family = "aarch64-rk3588j")))]
{
// Load kernel image.
load_vm_image(
config.kernel_path,
VirtAddr::from(config.kernel_load_addr),
vm.clone(),
)?;
....
}
Ok(())
}
It's also bad.
Since load_vm_memory will be compiled, it is also necessary to explicitly provide guestkernel_start and guestdtb_start.
Try include_bytes!
create platform directory arceos-umhv/arceos-vmm/src/vmm platform ├── aarch64_bsta1000b ├── aarch64_common ├── aarch64_qemu_virt ├── aarch64_raspi ├── aarch64_rk3588j ├── dummy ├── mod.rs ├── riscv64_qemu_virt └── x86_pc
I do not get it, since we use image_location = "memory"
in toml config, why do we still need these platform config files?
Since load_vm_memory will be compiled, it is also necessary to explicitly provide guestkernel_start and guestdtb_start.
Try
include_bytes!
include_bytes!
must be provide a string literal. Do we add a env in Makefile?
Device Tree Support
Currently, there is a need to boot arceos-hypervisor on hardware. However, adding a new configuration file for each new piece of hardware (in TOML format) is not ideal. Therefore, it is hoped to port over https://github.com/Starry-OS/of, which may require some effort.
Loading the Operating System
Due to the lack of a disk driver, the OS bin file can only be loaded from memory at present. The current solution involves specifying the file to be written into boot.img in arceos-vmm/build.rs, and loading it into memory when the Hypervisor starts. This approach lacks flexibility. Is there a better solution?