mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 02:03:56 -06:00
pvh: load initrd and expose it through fw_cfg
When initrd is specified, load and expose it to the guest firmware through fw_cfg. The firmware will fill the hvm_start_info for the kernel. Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Based-on: <1545422632-24444-5-git-send-email-liam.merwick@oracle.com> Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
ab969087da
commit
c5bf7847b7
1 changed files with 29 additions and 9 deletions
38
hw/i386/pc.c
38
hw/i386/pc.c
|
@ -1222,25 +1222,45 @@ static void load_linux(PCMachineState *pcms,
|
||||||
*/
|
*/
|
||||||
if (load_elfboot(kernel_filename, kernel_size,
|
if (load_elfboot(kernel_filename, kernel_size,
|
||||||
header, pvh_start_addr, fw_cfg)) {
|
header, pvh_start_addr, fw_cfg)) {
|
||||||
struct hvm_modlist_entry ramdisk_mod = { 0 };
|
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
|
fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
|
||||||
strlen(kernel_cmdline) + 1);
|
strlen(kernel_cmdline) + 1);
|
||||||
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
|
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
|
||||||
|
|
||||||
assert(machine->device_memory != NULL);
|
|
||||||
ramdisk_mod.paddr = machine->device_memory->base;
|
|
||||||
ramdisk_mod.size =
|
|
||||||
memory_region_size(&machine->device_memory->mr);
|
|
||||||
|
|
||||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, &ramdisk_mod,
|
|
||||||
sizeof(ramdisk_mod));
|
|
||||||
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header));
|
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header));
|
||||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA,
|
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA,
|
||||||
header, sizeof(header));
|
header, sizeof(header));
|
||||||
|
|
||||||
|
/* load initrd */
|
||||||
|
if (initrd_filename) {
|
||||||
|
gsize initrd_size;
|
||||||
|
gchar *initrd_data;
|
||||||
|
GError *gerr = NULL;
|
||||||
|
|
||||||
|
if (!g_file_get_contents(initrd_filename, &initrd_data,
|
||||||
|
&initrd_size, &gerr)) {
|
||||||
|
fprintf(stderr, "qemu: error reading initrd %s: %s\n",
|
||||||
|
initrd_filename, gerr->message);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1;
|
||||||
|
if (initrd_size >= initrd_max) {
|
||||||
|
fprintf(stderr, "qemu: initrd is too large, cannot support."
|
||||||
|
"(max: %"PRIu32", need %"PRId64")\n",
|
||||||
|
initrd_max, (uint64_t)initrd_size);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
initrd_addr = (initrd_max - initrd_size) & ~4095;
|
||||||
|
|
||||||
|
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
|
||||||
|
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
|
||||||
|
fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data,
|
||||||
|
initrd_size);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* This looks like a multiboot kernel. If it is, let's stop
|
/* This looks like a multiboot kernel. If it is, let's stop
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue