10个版本 (重大变更)
0.11.0 | 2024年1月22日 |
---|---|
0.10.0 | 2023年10月16日 |
0.9.1 | 2023年9月1日 |
0.9.0 | 2023年5月3日 |
0.1.0 | 2019年2月19日 |
#25 in Unix API
每月38,061次下载
300KB
7K SLoC
包含 (ELF可执行文件/库, 1KB) src/loader/x86_64/elf/test_bad_align.bin、(ELF可执行文件/库, 1KB) test_dummy_note.bin、(ELF可执行文件/库, 1KB) src/loader/x86_64/elf/test_elf.bin、(ELF可执行文件/库, 1KB) src/loader/x86_64/elf/test_elfnote.bin、(ELF可执行文件/库, 1KB) test_elfnote_8byte_align.bin、(ELF可执行文件/库, 1KB) test_invalid_pvh_note.bin
Linux-loader
linux-loader
crate提供了在x86_64
和PE(Image
)内核图像上加载原始ELF(vmlinux
)和压缩大zImage(bzImage
)格式内核图像的支持。ELF支持包括Linux和PVH引导协议。
linux-loader
crate目前还不完全独立和自给自足,大部分引导过程仍然是VMM的责任。有关详细信息,请参阅[用法]。
支持的功能
- 解析并加载内核图像到虚拟机内存中。
x86_64
:vmlinux
(原始ELF图像),bzImage
aarch64
:Image
- 解析和构建内核命令行。
- 加载设备树blob (
aarch64
)。 - 使用导出的原语配置引导参数。
x86_64
Linux引导x86_64
PVH引导aarch64
引导
用法
使用 linux-loader
框架启动虚拟机涉及多个步骤,具体取决于所使用的启动协议。以下是简化的概述。
考虑一个与 x86_64
VMM 接口的虚拟机管理程序;
- 与
linux-loader
进行接口通信; - 使用
GuestMemoryMmap
作为其虚拟机内存后端; - 从
File
加载 ELF 内核映像。
加载内核
启动虚拟机的第一步之一是从 Read
er 将内核加载到虚拟机内存中。为此步骤,VMM 需要配置其虚拟机内存。
在本例中,VMM 指定了内核的起始地址和高内存的起始地址。
use linux_loader::loader::elf::Elf as Loader;
use vm_memory::GuestMemoryMmap;
use std::fs::File;
use std::result::Result;
impl MyVMM {
fn start_vm(&mut self) {
let guest_memory = self.create_guest_memory();
let kernel_file = self.open_kernel_file();
let load_result = Loader::load::<File, GuestMemoryMmap>(
&guest_memory,
Some(self.kernel_start_addr()),
&mut kernel_file,
Some(self.himem_start_addr()),
)
.expect("Failed to load kernel");
}
}
配置设备和内核命令行
在创建虚拟机内存、解析和加载内核之后,VMM 可以选择配置设备和内核命令行。然后可以将后者加载到虚拟机内存中。
impl MyVMM {
fn start_vm(&mut self) {
...
let cmdline_size = self.kernel_cmdline().as_str().len() + 1;
linux_loader::loader::load_cmdline::<GuestMemoryMmap>(
&guest_memory,
self.cmdline_start_addr(),
&CString::new(kernel_cmdline).expect("Failed to parse cmdline")
).expect("Failed to load cmdline");
}
配置启动参数
在这个阶段,VMM 设置了初始的注册表值,不使用 linux-loader
。它还可以使用由 linux-loader
导出的结构体配置额外的启动参数。
use linux_loader::configurator::linux::LinuxBootConfigurator;
use linux_loader::configurator::{BootConfigurator, BootParams};
impl MyVMM {
fn start_vm(&mut self) {
...
let mut bootparams = boot_params::default();
self.configure_bootparams(&mut bootparams);
LinuxBootConfigurator::write_bootparams(
BootParams::new(¶ms, self.zeropage_addr()),
&guest_memory,
).expect("Failed to write boot params in guest memory");
}
完成!
测试
请参阅 docs/TESTING.md
。
许可证
此项目受以下任一许可证的许可:
依赖项
~0.7–1.3MB
~26K SLoC