From 41d6b314334c3129d27713618271d9b85e6a374d Mon Sep 17 00:00:00 2001 From: James Date: Wed, 23 Oct 2013 10:49:44 +0100 Subject: first cut at xen --- master/jmm/xen-multiboot | 482 +++++++++++++++++++++++++++++++++++++++++++++++ master/series | 1 + master/status | 53 ++++++ 3 files changed, 536 insertions(+) create mode 100644 master/jmm/xen-multiboot diff --git a/master/jmm/xen-multiboot b/master/jmm/xen-multiboot new file mode 100644 index 0000000..c2769ec --- /dev/null +++ b/master/jmm/xen-multiboot @@ -0,0 +1,482 @@ +Index: grub2/conf/i386-efi.rmk +=================================================================== +diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c +index d9e74b3..9277b0a 100644 +--- a/grub-core/loader/multiboot.c ++++ b/grub-core/loader/multiboot.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -51,6 +52,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + + struct grub_relocator *grub_multiboot_relocator = NULL; + grub_uint32_t grub_multiboot_payload_eip; ++void *xen_base = NULL; ++ + #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) + #define DEFAULT_VIDEO_MODE "text" + #else +@@ -63,6 +66,8 @@ static int console_required; + static grub_dl_t my_mod; + + ++#include "xen.c" ++ + /* Return the length of the Multiboot mmap that will be needed to allocate + our platform's map. */ + grub_uint32_t +@@ -112,6 +117,36 @@ grub_multiboot_set_video_mode (void) + } + + static grub_err_t ++grub_xen_boot (void) ++{ ++ grub_err_t err; ++ struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE; ++ ++ state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip; ++ ++ err = grub_multiboot_make_mbi (&state.MULTIBOOT_MBI_REGISTER); ++ ++ if (err) ++ return err; ++ ++ xen_setup(xen_base); ++ ++ grub_sleep(5); ++ ++#ifdef GRUB_MACHINE_EFI ++ err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); ++ if (err) ++ return err; ++#endif ++ ++ grub_relocator32_boot (grub_multiboot_relocator, state); ++ ++ /* Not reached. */ ++ return GRUB_ERR_NONE; ++} ++ ++ ++static grub_err_t + grub_multiboot_boot (void) + { + grub_err_t err; +@@ -213,6 +248,71 @@ grub_multiboot_set_console (int console_type, int accepted_consoles, + } + + static grub_err_t ++grub_cmd_xen (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t file = 0; ++ grub_err_t err; ++ ++ grub_loader_unset (); ++ ++ if (argc == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); ++ ++ file = grub_file_open (argv[0]); ++ if (! file) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); ++ ++ grub_dl_ref (my_mod); ++ ++ /* Skip filename. */ ++ grub_multiboot_init_mbi (argc - 1, argv + 1); ++ ++ grub_relocator_unload (grub_multiboot_relocator); ++ grub_multiboot_relocator = grub_relocator_new (); ++ ++ if (!grub_multiboot_relocator) ++ goto fail; ++ ++ err = grub_multiboot_load (file); ++ if (err) ++ goto fail; ++ ++ /* God awful hack to find the xen binary in memory */ ++ { ++ struct grub_relocator ++ { ++ struct grub_relocator_chunk *chunks; ++ grub_phys_addr_t postchunks; ++ grub_phys_addr_t highestaddr; ++ grub_phys_addr_t highestnonpostaddr; ++ grub_size_t relocators_size; ++ } *gr = (struct grub_relocator *) grub_multiboot_relocator; ++ ++ ++ xen_base=get_virtual_current_address (gr->chunks); ++ } ++ ++ grub_multiboot_set_bootdev (); ++ ++ grub_loader_set (grub_xen_boot, grub_multiboot_unload, 0); ++ ++ fail: ++ if (file) ++ grub_file_close (file); ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_relocator_unload (grub_multiboot_relocator); ++ grub_multiboot_relocator = NULL; ++ grub_dl_unref (my_mod); ++ } ++ ++ return grub_errno; ++} ++ ++ ++static grub_err_t + grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +@@ -329,23 +429,32 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + return GRUB_ERR_NONE;; + } + +-static grub_command_t cmd_multiboot, cmd_module; ++static grub_command_t cmd_multiboot, cmd_module, cmd_xen; + + GRUB_MOD_INIT(multiboot) + { + cmd_multiboot = + #ifdef GRUB_USE_MULTIBOOT2 ++ + grub_register_command ("multiboot2", grub_cmd_multiboot, + 0, N_("Load a multiboot 2 kernel.")); + cmd_module = + grub_register_command ("module2", grub_cmd_module, + 0, N_("Load a multiboot 2 module.")); ++ ++ cmd_xen = ++ grub_register_command ("xen2", grub_cmd_xen, ++ 0, N_("Load a multiboot 2 xen kernel.")); + #else + grub_register_command ("multiboot", grub_cmd_multiboot, + 0, N_("Load a multiboot kernel.")); + cmd_module = + grub_register_command ("module", grub_cmd_module, + 0, N_("Load a multiboot module.")); ++ ++ cmd_xen = ++ grub_register_command ("xen", grub_cmd_xen, ++ 0, N_("Load a multiboot xen kernel.")); + #endif + + my_mod = mod; +diff --git a/grub-core/loader/xen.c b/grub-core/loader/xen.c +new file mode 100644 +index 0000000..0e3deee +--- /dev/null ++++ b/grub-core/loader/xen.c +@@ -0,0 +1,301 @@ ++ ++#define XEN_EFI_MAGIC 0xdeadbeefef104eadULL ++#define XEN_LOADER_GRUB_64 0x0034365f36387847ULL ++#define XEN_LOADER_GRUB_32 0x0000003233616947ULL ++ ++struct xen_efi_hdr ++{ ++ grub_uint64_t magic; ++ grub_uint64_t efi_loader_signature; ++ grub_uint64_t efi_system_table_addr; ++ grub_uint64_t realmode_available; ++ grub_uint64_t boot_vid_mode; ++ grub_uint64_t boot_vid_info; ++} __attribute__((packed)); ++ ++struct xen_boot_video_info { ++ grub_uint8_t orig_x; /* 0x00 */ ++ grub_uint8_t orig_y; /* 0x01 */ ++ grub_uint8_t orig_video_mode; /* 0x02 */ ++ grub_uint8_t orig_video_cols; /* 0x03 */ ++ grub_uint8_t orig_video_lines; /* 0x04 */ ++ grub_uint8_t orig_video_isVGA; /* 0x05 */ ++ grub_uint16_t orig_video_points; /* 0x06 */ ++ ++ /* VESA graphic mode -- linear frame buffer */ ++ grub_uint32_t capabilities; /* 0x08 */ ++ grub_uint16_t lfb_linelength; /* 0x0c */ ++ grub_uint16_t lfb_width; /* 0x0e */ ++ grub_uint16_t lfb_height; /* 0x10 */ ++ grub_uint16_t lfb_depth; /* 0x12 */ ++ grub_uint32_t lfb_base; /* 0x14 */ ++ grub_uint32_t lfb_size; /* 0x18 */ ++ grub_uint8_t red_size; /* 0x1c */ ++ grub_uint8_t red_pos; /* 0x1d */ ++ grub_uint8_t green_size; /* 0x1e */ ++ grub_uint8_t green_pos; /* 0x1f */ ++ grub_uint8_t blue_size; /* 0x20 */ ++ grub_uint8_t blue_pos; /* 0x21 */ ++ grub_uint8_t rsvd_size; /* 0x22 */ ++ grub_uint8_t rsvd_pos; /* 0x23 */ ++ grub_uint16_t vesapm_seg; /* 0x24 */ ++ grub_uint16_t vesapm_off; /* 0x26 */ ++ grub_uint16_t vesa_attrib; /* 0x28 */ ++} __attribute__((packed)); ++ ++#ifdef GRUB_MACHINE_EFI ++ ++static grub_efi_guid_t acpi_guid = GRUB_EFI_ACPI_TABLE_GUID; ++static grub_efi_guid_t acpi2_guid = GRUB_EFI_ACPI_20_TABLE_GUID; ++static grub_efi_guid_t smbios_guid = GRUB_EFI_SMBIOS_TABLE_GUID; ++ ++#define EBDA_SEG_ADDR 0x40e ++#define LOW_MEM_ADDR 0x413 ++#define FAKE_EBDA_SEG 0x7000 ++#define FAKE_SMBIOS_SEG 0x7f00 ++ ++static void ++inject_bios_acpi (void) ++{ ++ unsigned i; ++ void *acpi; ++ grub_uint16_t *ebda_seg_ptr, *low_mem_ptr; ++ ++ acpi = 0; ++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) ++ { ++ grub_efi_guid_t *guid = ++ &grub_efi_system_table->configuration_table[i].vendor_guid; ++ ++ if (!grub_memcmp (guid, &acpi2_guid, sizeof (grub_efi_guid_t))) ++ { ++ acpi = grub_efi_system_table->configuration_table[i].vendor_table; ++ grub_printf ("ACPI2: %p\n", acpi); ++ } ++ else if (!grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t))) ++ { ++ void *t; ++ ++ t = grub_efi_system_table->configuration_table[i].vendor_table; ++ if (!acpi) ++ acpi = t; ++ grub_printf ("ACPI: %p\n", t); ++ } ++ } ++ ++ if (acpi == 0) ++ return; ++ ++ ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR; ++ low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR; ++ ++ *ebda_seg_ptr = FAKE_EBDA_SEG; ++ *low_mem_ptr = FAKE_EBDA_SEG >> 6; ++ ++ grub_printf("Copying acpi %p to %x\n",acpi,(int) (FAKE_EBDA_SEG << 4)); ++ grub_memcpy ((char *) (FAKE_EBDA_SEG << 4), acpi, 0xf000); ++ ++} ++ ++static void ++inject_bios_smbios(void) ++{ ++ unsigned i; ++ void *smbios; ++ ++ smbios = 0; ++ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) ++ { ++ grub_efi_guid_t *guid = ++ &grub_efi_system_table->configuration_table[i].vendor_guid; ++ ++ if (!grub_memcmp (guid, &smbios_guid, sizeof (grub_efi_guid_t))) ++ { ++ smbios = grub_efi_system_table->configuration_table[i].vendor_table; ++ grub_printf ("SMBIOS: %p\n", smbios); ++ } ++ } ++ ++ if (smbios == 0) ++ return; ++ ++ grub_printf("Copying smbios %p to %x\n",smbios,(int) (FAKE_SMBIOS_SEG << 4)); ++ grub_memcpy ((char *) (FAKE_SMBIOS_SEG << 4), smbios, 0x1000); ++} ++ ++ ++static void fake_bios_data(void) ++{ ++ inject_bios_smbios(); ++ inject_bios_acpi(); ++} ++ ++#endif ++ ++static void stop_dma(void) ++{ ++ ++ auto int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev, ++ grub_pci_id_t pciid); ++ ++ int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev, ++ grub_pci_id_t pciid) ++ { ++ grub_pci_address_t addr; ++ grub_uint16_t old_cmd,new_cmd; ++ ++ (void) pciid; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ ++ switch (grub_pci_read (addr) >> 24) { ++ case 0x00: /*unknown*/ ++ case 0x03: /*GPU*/ ++ case 0x05: /*memory*/ ++ case 0x06: /*bridge*/ ++ case 0x07: /*firewire*/ ++ case 0x0b: /*cpu*/ ++ break; ++ default: /*everything else gets dma turned off*/ ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND); ++ old_cmd = grub_pci_read_word(addr); ++ new_cmd = old_cmd & ~GRUB_PCI_COMMAND_BUS_MASTER; ++ grub_pci_write_word(addr,new_cmd); ++ ++#if 0 ++ if (old_cmd!=new_cmd) { ++ grub_printf ("Disabled DMA on: %02x:%02x.%x %04x -> %04x\n", ++ grub_pci_get_bus (dev), grub_pci_get_device (dev), ++ grub_pci_get_function (dev), (int) old_cmd,(int) new_cmd); ++ } ++#endif ++ } ++ ++ return 0; ++ } ++ ++ grub_pci_iterate (stop_card_dma); ++} ++ ++ ++static int ++xen_setup_video (struct xen_boot_video_info *bvi) ++{ ++ struct grub_video_mode_info mode_info; ++ void *framebuffer; ++ grub_err_t err; ++ grub_video_driver_id_t driver_id; ++ ++ driver_id = grub_video_get_driver_id (); ++ ++ if (driver_id == GRUB_VIDEO_DRIVER_NONE) ++ return 1; ++ ++ err = grub_video_get_info_and_fini (&mode_info, &framebuffer); ++ ++ if (err) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 1; ++ } ++ ++ bvi->orig_video_isVGA=0x23; /*XXX: what is 0x23? */ ++ ++ bvi->lfb_linelength=mode_info.pitch; ++ bvi->lfb_width=mode_info.width; ++ bvi->lfb_height=mode_info.height; ++ bvi->lfb_depth=mode_info.bpp; ++ ++ bvi->lfb_base=(grub_size_t) framebuffer; ++ bvi->lfb_size=ALIGN_UP ((unsigned int) mode_info.pitch * (unsigned int) mode_info.height, 65536); ++ ++ bvi->red_size=mode_info.red_mask_size; ++ bvi->red_pos=mode_info.red_field_pos; ++ ++ bvi->green_size=mode_info.green_mask_size; ++ bvi->green_pos=mode_info.green_field_pos; ++ ++ bvi->blue_size=mode_info.blue_mask_size; ++ bvi->blue_pos=mode_info.blue_field_pos; ++ ++ bvi->rsvd_size=mode_info.reserved_mask_size; ++ bvi->rsvd_pos=mode_info.reserved_field_pos; ++ ++ bvi->vesa_attrib=0x3; /*Possible(0x1) and has extended data(0x2)*/ ++ ++ ++ /* No protected mode*/ ++ bvi->vesapm_seg=0x0; ++ bvi->vesapm_off=0x0; ++ ++ bvi->vesa_attrib=0x1; /*Dac is 8 bit capable*/ ++ ++ ++ return GRUB_ERR_NONE; ++} ++ ++ ++ ++ ++static grub_err_t ++xen_setup (grub_uint8_t * base) ++{ ++ struct xen_efi_hdr *hdr; ++ grub_uint8_t *realmode_available; ++ grub_uint16_t *boot_vid_mode; ++ grub_uint64_t *efi_system_table_addr; ++ grub_uint64_t *efi_loader_signature; ++ struct xen_boot_video_info *bvi; ++ ++ int i; ++ ++ for (i = 0; i <0x200; i++) ++ { ++ hdr = (struct xen_efi_hdr *) (base + i); ++ if (hdr->magic == XEN_EFI_MAGIC) ++ break; ++ } ++ ++ if (hdr->magic != XEN_EFI_MAGIC) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "No EFI support in hypervisor"); ++ ++ grub_printf("base addr is %p\n",base); ++ ++ realmode_available=(grub_uint8_t *)hdr->realmode_available; ++ grub_printf("realmode_available was %x@%p\n",(int) *realmode_available,realmode_available); ++ *realmode_available=0; ++ ++ efi_loader_signature=(grub_uint64_t*)hdr->efi_loader_signature; ++ ++#if defined(__x86_64__) ++ *efi_loader_signature=XEN_LOADER_GRUB_64; ++#elif defined (__i386__) ++ *efi_loader_signature=XEN_LOADER_GRUB_32; ++#else ++ *efi_loader_signature=0; ++#endif ++ ++ efi_system_table_addr=(grub_uint64_t*)hdr->efi_system_table_addr; ++ ++ grub_printf("efi_system_table_addr was %llx@%p\n",(long long unsigned) *efi_system_table_addr, efi_system_table_addr); ++ ++ *efi_system_table_addr= (grub_uint64_t) grub_efi_system_table; ++ ++ boot_vid_mode=(grub_uint16_t *)hdr->boot_vid_mode; ++ grub_printf("boot_vid_mode was 0x%x@%p\n",(int) *boot_vid_mode,boot_vid_mode); ++ *boot_vid_mode=0xf00; ++ ++ bvi=(struct xen_boot_video_info *)hdr->boot_vid_info; ++ grub_printf("boot_vid_info @%p\n",bvi); ++ ++ xen_setup_video (bvi); ++ ++ fake_bios_data(); ++ stop_dma(); ++ ++ return GRUB_ERR_NONE; ++} ++ ++ ++ diff --git a/master/series b/master/series index 92264d8..c356a8c 100644 --- a/master/series +++ b/master/series @@ -51,6 +51,7 @@ jmm/networking-bis jmm/efi-sni-bis jmm/copy-acpi-and-dmi-for-mb-kernels jmm/disable-all-pci-dma-on-boot +jmm/xen-multiboot endstop # # diff --git a/master/status b/master/status index e69de29..3b3541d 100644 --- a/master/status +++ b/master/status @@ -0,0 +1,53 @@ +debian/olpc_prefix_hack.patch +debian/core_in_fs.patch +debian/dpkg_version_comparison.patch +debian/grub_legacy_0_based_partitions.patch +debian/disable_floppies.patch +debian/grub.cfg_400.patch +debian/gfxpayload_keep_default.patch +debian/mkrescue_diet.patch +debian/mkconfig_skip_dmcrypt.patch +debian/install_stage2_confusion.patch +debian/qemu_img_exists.patch +debian/branch_devmapper.patch +debian/branch_squash.patch +debian/branch_longlinuxcmd.patch +debian/branch_parse-color.patch +debian/branch_embed-sectors.patch +debian/branch_fuse.patch +debian/mkrescue_efi_modules.patch +debian/mkconfig_loopback.patch +debian/lazy_stat.patch +debian/btrfs_stat.patch +debian/partition_performance.patch +debian/kfreebsd-9_ada_devices.patch +debian/gfxterm_background.patch +debian/zfs_packed_la_array.patch +debian/xen_replace.patch +debian/kfreebsd_mfi_devices.patch +debian/probe_canonicalise.patch +debian/mkconfig_skip_readme.patch +debian/kfreebsd_lvm.patch +debian/zfs_update.patch +debian/no_libzfs.patch +debian/xfs_invalid_bmap.patch +debian/handle_new_autotools.patch +debian/bash-completion_identifiers.patch +debian/mkconfig_gnumach.patch +debian/gcc_4_6_space.patch +debian/lzo.patch +debian/fat_uuid.patch +debian/efiemu_fix.patch +debian/4k_sectors.patch +debian/efi_disk_cache.patch +debian/dirlen.patch +debian/hurd.patch +debian/userland-part.patch +jmm/efi_call_7-bis +jmm/efi-load-drivers-bis +jmm/networking-bis +jmm/efi-sni-bis +jmm/copy-acpi-and-dmi-for-mb-kernels +jmm/disable-all-pci-dma-on-boot +jmm/xen-multiboot +endstop -- cgit v1.2.3