Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take care of writing boot parameters into memory #15

Closed
bonzini opened this issue Mar 5, 2020 · 5 comments
Closed

Take care of writing boot parameters into memory #15

bonzini opened this issue Mar 5, 2020 · 5 comments
Assignees

Comments

@bonzini
Copy link
Member

bonzini commented Mar 5, 2020

The linux-loader crate does not handle writing in memory the setup header that it prepares, and there could also be extra parameters (e.g. kernel command line or, for PVH, the e820 map) that need to be written into memory. I am therefore proposing to add a "configurator" object that encapsulates all the logic needed to boot a kernel (later on this could include the CPU registers too). The basic structure would be:

pub struct E820MapEntry { ... |}
pub struct BootParameters {
    e820: Vec<E820MapEntry>, ...
};
...
pub trait BootConfigurator<M: GuestMemory> {
    pub fn write_boot_parameters(&self, result: &KernelLoaderResult, params: &BootParameters, dest: T);
}
pub struct PVHConfigurator; // implements BootConfigurator<T>
pub struct LinuxElfConfigurator; // implements BootConfigurator<T>
pub struct BzImageConfigurator; // implements BootConfigurator<T>

and probably an associated type on KernelLoader like

pub trait KernelLoader<M: GuestMemory> {
    type Configurator: Box<dyn BootConfigurator<M>>;
}

pub struct KernelLoaderResult<M: GuestMemory> {
    ...
    configurator: Box<dyn BootConfigurator<M>>
}

that can be used like

    let result = KernelLoaderType.load(guest_mem, ...)?;
    result.configurator.write_boot_parameters(result, guest_mem);
@andreeaflorescu
Copy link
Member

Yap, it makes a lot of sense. For example, in Firecracker we have this logic in the arch crate and I think it shouldn't be there. This proposal looks good to me.

@sameo
Copy link
Collaborator

sameo commented Mar 11, 2020

@bonzini I guess you meant:

let result = KernelLoaderType.load(guest_mem, ...)?;
let boot_params = arch::build_boot_params()?;
result.configurator.write_boot_parameters(result, boot_params, guest_mem);

where the linux_loader boot parameters would be built from the VMM?

@bonzini
Copy link
Member Author

bonzini commented Mar 11, 2020

Yes, precisely.

@alxiord
Copy link
Member

alxiord commented Mar 26, 2020

After looking more closely at the code for building bootparams (at least for elf), there's a lot of it in common. I think that can be packaged too in a builder of sorts, extended in the vmm if needed, then passed on to the Configurator.

pub trait BootConfigurator {
    type Error;

    fn write_bootparams<B: ByteValued, M: GuestMemory>(
        params: B,
        guest_memory: &M,
        addr: GuestAddress,
    ) -> Result<(), Self::Error>;
}

Elf boot params:

pub struct ElfBootParams {
    bootparams: boot_params,
    // TODO: cmdline, others?
}

impl ElfBootParams {
    pub fn new(
        cmdline_addr: GuestAddress,
        cmdline_size: usize,
        himem_start: GuestAddress,
        ...
    ) -> Result<Self>;

    pub fn with_ebda(
        &mut self, 
        ebda_start: GuestAddress
    ) -> Result<&mut Self>;
    
    pub fn with_pci(
        &mut self,
        pci_mmconfig_start: GuestAddress,
        pci_mmconfig_size: usize,
    ) -> Result<&mut Self>;

impl ByteValued for ElfBootParams {}

Elf boot configurator:

pub struct ElfBootConfigurator {}

pub enum ElfBootConfiguratorError {...}

impl BootConfigurator for ElfBootConfigurator {
    type Error = ElfBootConfiguratorError;

    fn write_bootparams<B: ByteValued, M: GuestMemory>(
        params: B,
        guest_memory: &M,
        addr: GuestAddress,
    ) -> Result<(), Self::Error>;
}

VMM:

let loader_result = Elf::load(
    &guest_mem,
    Some(kernel_addr),
    &mut Cursor::new(&image),
    Some(himem_start),
)?;

let elf_boot_params = ElfBootParams::new(
    cmdline_addr,
    cmdline_size,
    himem_start
)?.with_ebda(ebda_start)?.with_pci(pci_start, pci_size)?;

ElfBootConfigurator::write_bootparams(*elf_boot_params, &guest_mem, zeropage_addr);

(I'm fighting dynamic dispatch issues for embedding a BootConfigurator in the KernelLoaderResult.)

@bonzini @sameo WDYT?

alxiord pushed a commit to alxiord/linux-loader that referenced this issue Mar 27, 2020
This commit introduces a new configurator module that takes
boot parameters created in the VMM (boot_params / start_info
+ e820 map) and writes them into guest memory. The module is
meant to be extended in order to include *building* the boot
parameters as well.

Fixes rust-vmm#15

Signed-off-by: Alexandra Iordache <[email protected]>
alxiord pushed a commit to alxiord/linux-loader that referenced this issue Mar 27, 2020
This commit introduces a new configurator module that takes
boot parameters created in the VMM (boot_params / start_info
+ e820 map) and writes them into guest memory. The module is
meant to be extended in order to include *building* the boot
parameters as well.

Fixes rust-vmm#15

Signed-off-by: Alexandra Iordache <[email protected]>
alxiord pushed a commit to alxiord/linux-loader that referenced this issue Apr 1, 2020
This commit introduces a new configurator module that takes
boot parameters created in the VMM (boot_params / start_info
+ e820 map) and writes them into guest memory. The module is
meant to be extended in order to include *building* the boot
parameters as well.

Fixes rust-vmm#15

Signed-off-by: Alexandra Iordache <[email protected]>
@bonzini
Copy link
Member Author

bonzini commented Apr 3, 2020

The embedding part can be done later. #31 is certainly a step in the right direction!

alxiord pushed a commit to alxiord/linux-loader that referenced this issue Apr 9, 2020
This commit introduces a new configurator module that takes
boot parameters created in the VMM (boot_params / start_info
+ e820 map) and writes them into guest memory. The module is
meant to be extended in order to include *building* the boot
parameters as well.

Fixes rust-vmm#15

Signed-off-by: Alexandra Iordache <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants