diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c index 85ae791..07bfdda 100644 --- a/grub-core/loader/i386/linux.c +++ b/grub-core/loader/i386/linux.c @@ -407,6 +407,94 @@ grub_linux_setup_video (struct linux_kernel_params *params) return GRUB_ERR_NONE; } +#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 grub_err_t grub_linux_boot (void) { @@ -471,6 +559,10 @@ grub_linux_boot (void) e820_num = 0; grub_mmap_iterate (hook); +#ifdef GRUB_MACHINE_EFI + grub_e820_add_region (params->e820_map, &e820_num, + 0x70000, 0x10000, GRUB_E820_RESERVED); +#endif params->mmap_size = e820_num; modevar = grub_env_get ("gfxpayload"); @@ -547,6 +639,10 @@ grub_linux_boot (void) #endif #ifdef GRUB_MACHINE_EFI + fake_bios_data(); +#endif + +#ifdef GRUB_MACHINE_EFI { grub_efi_uintn_t efi_desc_size; grub_size_t efi_mmap_target;