[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC 3/3] pvh: Boot uncompressed kernel using direct boot ABI
On Tue, Dec 11, 2018 at 7:35 PM Maran Wilson <maran.wilson@xxxxxxxxxx> wrote: > > On 12/11/2018 9:11 AM, Stefano Garzarella wrote: > > Hi Liam, > > in order to support PVH also with SeaBIOS, I'm going to work on a new > > option rom (like linuxboot/multiboot) that can be used in this case. > > That is awesome. Yes, please keep us posted when you have something working. Yes, I'll keep you updated! > > Just FYI, before switching over to using Qemu+qboot, we had been using a > Qemu only solution (but not using an option rom) internally that worked > very well using no FW at all. We had Qemu simply parse the ELF file and > jump to the PVH entry point if one is found. The only gotcha was that we > had to include a pair of patches that were originally written by folks > at Intel as part of the clear containers work. Specifically, in order to > be able to skip firmware entirely, we had to do 2 additional things: (1) > ACPI tables generated by Qemu are usually patched up by FW. Since we > were running no FW, we needed to do that patching up of the ACPI tables > in Qemu when it was detected that we were going to enter the OS via the > PVH entry point. (2) We also needed to add a patch to Qemu to enable a > few PM registers -- something typically done by FW. I had a look of qemu-lite, are you referring to this? > > But if SeaBIOS is involved in the solution you are working on, I guess > you won't really need those extra patches. Just figured I'd mention it > so you have the full picture. Thank you very much to share with me these details! Cheers, Stefano > > Thanks, > -Maran > > > I'll keep you updated on it! > > > > Cheers, > > Stefano > > On Wed, Dec 5, 2018 at 11:38 PM Liam Merwick <liam.merwick@xxxxxxxxxx> > > wrote: > >> These changes (along with corresponding qboot and Linux kernel changes) > >> enable a guest to be booted using the x86/HVM direct boot ABI. > >> > >> This commit adds a load_elfboot() routine to pass the size and > >> location of the kernel entry point to qboot (which will fill in > >> the start_info struct information needed to to boot the guest). > >> Having loaded the ELF binary, load_linux() will run qboot > >> which continues the boot. > >> > >> The address for the kernel entry point has already been read > >> from an ELF Note in the uncompressed kernel binary earlier > >> in pc_memory_init(). > >> > >> Signed-off-by: George Kennedy <George.Kennedy@xxxxxxxxxx> > >> Signed-off-by: Liam Merwick <Liam.Merwick@xxxxxxxxxx> > >> --- > >> hw/i386/pc.c | 72 > >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > >> 1 file changed, 72 insertions(+) > >> > >> diff --git a/hw/i386/pc.c b/hw/i386/pc.c > >> index 056aa46d99b9..d3012cbd8597 100644 > >> --- a/hw/i386/pc.c > >> +++ b/hw/i386/pc.c > >> @@ -54,6 +54,7 @@ > >> #include "sysemu/qtest.h" > >> #include "kvm_i386.h" > >> #include "hw/xen/xen.h" > >> +#include "hw/xen/start_info.h" > >> #include "ui/qemu-spice.h" > >> #include "exec/memory.h" > >> #include "exec/address-spaces.h" > >> @@ -1098,6 +1099,50 @@ done: > >> return pvh_start_addr != 0; > >> } > >> > >> +static bool load_elfboot(const char *kernel_filename, > >> + int kernel_file_size, > >> + uint8_t *header, > >> + size_t pvh_xen_start_addr, > >> + FWCfgState *fw_cfg) > >> +{ > >> + uint32_t flags = 0; > >> + uint32_t mh_load_addr = 0; > >> + uint32_t elf_kernel_size = 0; > >> + uint64_t elf_entry; > >> + uint64_t elf_low, elf_high; > >> + int kernel_size; > >> + > >> + if (ldl_p(header) != 0x464c457f) { > >> + return false; /* no elfboot */ > >> + } > >> + > >> + bool elf_is64 = header[EI_CLASS] == ELFCLASS64; > >> + flags = elf_is64 ? > >> + ((Elf64_Ehdr *)header)->e_flags : ((Elf32_Ehdr *)header)->e_flags; > >> + > >> + if (flags & 0x00010004) { /* LOAD_ELF_HEADER_HAS_ADDR */ > >> + error_report("elfboot unsupported flags = %x", flags); > >> + exit(1); > >> + } > >> + > >> + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, > >> + &elf_low, &elf_high, 0, I386_ELF_MACHINE, > >> + 0, 0); > >> + > >> + if (kernel_size < 0) { > >> + error_report("Error while loading elf kernel"); > >> + exit(1); > >> + } > >> + mh_load_addr = elf_low; > >> + elf_kernel_size = elf_high - elf_low; > >> + > >> + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, pvh_xen_start_addr); > >> + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_load_addr); > >> + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, elf_kernel_size); > >> + > >> + return true; > >> +} > >> + > >> static void load_linux(PCMachineState *pcms, > >> FWCfgState *fw_cfg) > >> { > >> @@ -1138,6 +1183,33 @@ static void load_linux(PCMachineState *pcms, > >> if (ldl_p(header+0x202) == 0x53726448) { > >> protocol = lduw_p(header+0x206); > >> } else { > >> + /* If the kernel address for using the x86/HVM direct boot ABI has > >> + * been saved then proceed with booting the uncompressed kernel */ > >> + if (pvh_start_addr) { > >> + if (load_elfboot(kernel_filename, kernel_size, > >> + header, pvh_start_addr, fw_cfg)) { > >> + struct hvm_modlist_entry ramdisk_mod = { 0 }; > >> + > >> + fclose(f); > >> + > >> + fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, > >> + strlen(kernel_cmdline) + 1); > >> + 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_bytes(fw_cfg, FW_CFG_SETUP_DATA, > >> + header, sizeof(header)); > >> + > >> + return; > >> + } > >> + } > >> /* This looks like a multiboot kernel. If it is, let's stop > >> treating it like a Linux kernel. */ > >> if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename, > >> -- > >> 1.8.3.1 > >> > > > -- Stefano Garzarella Red Hat _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |