main: Add kernel command line support

In order to let the user choose which kernel parameters to append, the
kernel boot parameters can be now specified from the command line.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-05-06 13:24:57 -07:00 committed by Samuel Ortiz
parent 1270d09301
commit 112418d928
2 changed files with 21 additions and 24 deletions

View File

@ -25,6 +25,12 @@ fn main() {
.help("Path to kernel image (vmlinux)") .help("Path to kernel image (vmlinux)")
.takes_value(true), .takes_value(true),
) )
.arg(
Arg::with_name("cmdline")
.long("cmdline")
.help("Kernel command line")
.takes_value(true),
)
.arg( .arg(
Arg::with_name("disk") Arg::with_name("disk")
.long("disk") .long("disk")
@ -51,6 +57,11 @@ fn main() {
.expect("Missing argument: kernel"); .expect("Missing argument: kernel");
let kernel_path = kernel_arg.as_path(); let kernel_path = kernel_arg.as_path();
let cmdline = cmd_arguments
.value_of("cmdline")
.map(std::string::ToString::to_string)
.expect("Missing argument: cmdline");
let disk_arg = cmd_arguments let disk_arg = cmd_arguments
.value_of("disk") .value_of("disk")
.map(PathBuf::from) .map(PathBuf::from)
@ -70,7 +81,7 @@ fn main() {
println!("VM [{} vCPUS {} MB of memory]", vcpus, memory); println!("VM [{} vCPUS {} MB of memory]", vcpus, memory);
println!("Booting {:?}...", kernel_path); println!("Booting {:?}...", kernel_path);
let vm_config = VmConfig::new(kernel_path, disk_path, vcpus, memory).unwrap(); let vm_config = VmConfig::new(kernel_path, disk_path, cmdline, vcpus, memory).unwrap();
vmm::boot_kernel(vm_config).unwrap(); vmm::boot_kernel(vm_config).unwrap();
} }

View File

@ -40,8 +40,6 @@ use vmm_sys_util::EventFd;
const VCPU_RTSIG_OFFSET: i32 = 0; const VCPU_RTSIG_OFFSET: i32 = 0;
pub const DEFAULT_VCPUS: u8 = 1; pub const DEFAULT_VCPUS: u8 = 1;
pub const DEFAULT_MEMORY: GuestUsize = 512; pub const DEFAULT_MEMORY: GuestUsize = 512;
const DEFAULT_CMDLINE: &str = "console=ttyS0 reboot=k panic=1 nomodules \
i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd";
const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000); const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000);
const X86_64_IRQ_BASE: u32 = 5; const X86_64_IRQ_BASE: u32 = 5;
@ -207,7 +205,7 @@ impl Vcpu {
pub struct VmConfig<'a> { pub struct VmConfig<'a> {
kernel_path: &'a Path, kernel_path: &'a Path,
disk_path: &'a Path, disk_path: &'a Path,
cmdline: Option<cmdline::Cmdline>, cmdline: cmdline::Cmdline,
cmdline_addr: GuestAddress, cmdline_addr: GuestAddress,
memory_size: GuestUsize, memory_size: GuestUsize,
@ -218,36 +216,24 @@ impl<'a> VmConfig<'a> {
pub fn new( pub fn new(
kernel_path: &'a Path, kernel_path: &'a Path,
disk_path: &'a Path, disk_path: &'a Path,
cmdline_str: String,
vcpus: u8, vcpus: u8,
memory_size: GuestUsize, memory_size: GuestUsize,
) -> Result<Self> { ) -> Result<Self> {
let mut cmdline = cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
cmdline.insert_str(cmdline_str).unwrap();
Ok(VmConfig { Ok(VmConfig {
kernel_path, kernel_path,
disk_path, disk_path,
cmdline,
cmdline_addr: CMDLINE_OFFSET,
memory_size, memory_size,
vcpu_count: vcpus, vcpu_count: vcpus,
..Default::default()
}) })
} }
} }
impl<'a> Default for VmConfig<'a> {
fn default() -> Self {
let line = String::from(DEFAULT_CMDLINE);
let mut cmdline = cmdline::Cmdline::new(arch::CMDLINE_MAX_SIZE);
cmdline.insert_str(line).unwrap();
VmConfig {
kernel_path: Path::new(""),
disk_path: Path::new(""),
cmdline: Some(cmdline),
cmdline_addr: CMDLINE_OFFSET,
memory_size: DEFAULT_MEMORY,
vcpu_count: DEFAULT_VCPUS,
}
}
}
struct DeviceManager { struct DeviceManager {
io_bus: devices::Bus, io_bus: devices::Bus,
mmio_bus: devices::Bus, mmio_bus: devices::Bus,
@ -518,8 +504,8 @@ impl<'a> Vm<'a> {
} }
pub fn load_kernel(&mut self) -> Result<GuestAddress> { pub fn load_kernel(&mut self) -> Result<GuestAddress> {
let cmdline = self.config.cmdline.clone().ok_or(Error::CmdLine)?; let cmdline_cstring =
let cmdline_cstring = CString::new(cmdline).map_err(|_| Error::CmdLine)?; CString::new(self.config.cmdline.clone()).map_err(|_| Error::CmdLine)?;
let entry_addr = linux_loader::loader::Elf::load( let entry_addr = linux_loader::loader::Elf::load(
&self.memory, &self.memory,
None, None,