grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Loading DSDT table using 'acpi' or some memory write command?


From: Nando Eva
Subject: Re: Loading DSDT table using 'acpi' or some memory write command?
Date: Mon, 27 Feb 2017 18:21:46 +0000 (UTC)

Vladimir 'phcoder' Serbinenko wrote:

I reproduced the bug. I'm investigating
>> Apparently finish_boot_services rewrites acpi tables. It's possible to workaround this, possibly by using acpi table protocol. >> But it's certainely not for 2.02 at this point.

Thank you for investigating the issue. Earlier I did a test to check to see if UEFI chainloading was altering ACPI tables. I did this by:

1. performing two grub2 "write_dword" console memory commands to enable ASPM in the ACPI FADT (FACP on my system) table as per http://smackerelofopinion.blogspot.com.au/2011/03/making-sense-of-pcie-aspm.html

2. then chainloaded from Grub2 to windows: chainloader /efi/Microsoft/Boot/bootmgfw.efi

The ASPM enabling change was there as found by using r-w everything and reported by 'powercfg /energy', indicating the UEFI chainloading isn't, at least for ACPI FADT (FACP), altering the in-memory table.

As the DSDT table is much larger, I can't really write_dword it. Hence asking for some other memory loading module.

As another lead, I found the mentioned finish_boot_services routine in mm.c, quoted below. Would you mind pointing out which code is rewriting the ACPI tables?

Thank you,
Nando

---
grub_err_t
grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
                   grub_efi_uintn_t *map_key,
                   grub_efi_uintn_t *efi_desc_size,
                   grub_efi_uint32_t *efi_desc_version)
{
  grub_efi_boot_services_t *b;
  grub_efi_status_t status;

#if defined (__i386__) || defined (__x86_64__)
  const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
  int is_apple;

  is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor,
               apple, sizeof (apple)) == 0);
#endif

  while (1)
    {
      if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
                   &finish_desc_size, &finish_desc_version) < 0)
    return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");

      if (outbuf && *outbuf_size < finish_mmap_size)
    return grub_error (GRUB_ERR_IO, "memory map buffer is too small");

      finish_mmap_buf = grub_malloc (finish_mmap_size);
      if (!finish_mmap_buf)
    return grub_errno;

      if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key,
                   &finish_desc_size, &finish_desc_version) <= 0)
    {
      grub_free (finish_mmap_buf);
      return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
    }

      b = grub_efi_system_table->boot_services;
      status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
               finish_key);
      if (status == GRUB_EFI_SUCCESS)
    break;

      if (status != GRUB_EFI_INVALID_PARAMETER)
    {
      grub_free (finish_mmap_buf);
      return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
    }

      grub_free (finish_mmap_buf);
      grub_printf ("Trying to terminate EFI services again\n");
    }
  grub_efi_is_finished = 1;
  if (outbuf_size)
    *outbuf_size = finish_mmap_size;
  if (outbuf)
    grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
  if (map_key)
    *map_key = finish_key;
  if (efi_desc_size)
    *efi_desc_size = finish_desc_size;
  if (efi_desc_version)
    *efi_desc_version = finish_desc_version;

#if defined (__i386__) || defined (__x86_64__)
  if (is_apple)
    stop_broadcom ();
#endif

  return GRUB_ERR_NONE;
}


Nando


On Tuesday, 28 February 2017, 2:13, Nando Eva <address@hidden> wrote:


Andrei Borzenkov wrote:
>> That's more or less what grub tries to do. We cannot really overwrite >> ACPI tables because they may be located in read-only memory, but it >> attempts to create EBDA and place new RSDP there and update EBDA >> address as well as update RSDP pointer in EFI system table. I would >> suggest trying to load something else (like Linux) and check whether >> it sees new or old table.

This user had 'acpi' also fail to replace the FACS ACPI table on Linux:
https://bbs.archlinux.org/viewtopic.php?id=190258

The DSDT I require is for Win10. Win10 has a registry override method to replace a DSDT but requires test signing mode to do it, along with some app restrictions/incompatibilities.

I require a pre-boot DSDT override method to overcome Win10 test signing mode AND have my required DSDT table loaded. Just need an in-memory DSDT subsitution tool to do it.

I have been able to accomplish this using MBR boot because the tools exist. For the more popular UEFI,I have yet to find a load-file-into-memory-location tool to make it possible. Only things are the multiboot file encapsulation, hexedit and write_dword. All not the right fit.

Any chance the grub-devel team can help out here with either a load-file-to-memory-location module/tool (where I need to find the address) or specifically one that does a in-memory DSDT override by overwriting the existing table? Of course, ppl with read-only memory can't use it just like I imagine would be the case with the current 'acpi' method.


Thank you,
Nando



reply via email to

[Prev in Thread] Current Thread [Next in Thread]