* grub-core/loader/multiboot_mbi2.c: Implement EFI memory map.
This commit is contained in:
parent
00bfa988fc
commit
329550c4a9
5 changed files with 96 additions and 6 deletions
|
@ -295,9 +295,55 @@ acpiv2_size (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
|
||||
static grub_efi_uintn_t efi_mmap_size = 0;
|
||||
|
||||
/* Find the optimal number of pages for the memory map. Is it better to
|
||||
move this code to efi/mm.c? */
|
||||
static void
|
||||
find_efi_mmap_size (void)
|
||||
{
|
||||
efi_mmap_size = (1 << 12);
|
||||
while (1)
|
||||
{
|
||||
int ret;
|
||||
grub_efi_memory_descriptor_t *mmap;
|
||||
grub_efi_uintn_t desc_size;
|
||||
grub_efi_uintn_t cur_mmap_size = efi_mmap_size;
|
||||
|
||||
mmap = grub_malloc (cur_mmap_size);
|
||||
if (! mmap)
|
||||
return;
|
||||
|
||||
ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0);
|
||||
grub_free (mmap);
|
||||
|
||||
if (ret < 0)
|
||||
return;
|
||||
else if (ret > 0)
|
||||
break;
|
||||
|
||||
if (efi_mmap_size < cur_mmap_size)
|
||||
efi_mmap_size = cur_mmap_size;
|
||||
efi_mmap_size += (1 << 12);
|
||||
}
|
||||
|
||||
/* Increase the size a bit for safety, because GRUB allocates more on
|
||||
later, and EFI itself may allocate more. */
|
||||
efi_mmap_size += (3 << 12);
|
||||
|
||||
efi_mmap_size = ALIGN_UP (efi_mmap_size, 4096);
|
||||
}
|
||||
#endif
|
||||
|
||||
static grub_size_t
|
||||
grub_multiboot_get_mbi_size (void)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
if (!efi_mmap_size)
|
||||
find_efi_mmap_size ();
|
||||
#endif
|
||||
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||
+ (sizeof (struct multiboot_tag_string)
|
||||
+ ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
|
||||
|
@ -318,6 +364,10 @@ grub_multiboot_get_mbi_size (void)
|
|||
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
|
||||
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
||||
+ acpiv2_size ()
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
|
||||
+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
|
||||
#endif
|
||||
+ sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1
|
||||
+ sizeof (struct multiboot_tag_apm) + MULTIBOOT_TAG_ALIGN - 1;
|
||||
}
|
||||
|
@ -760,6 +810,28 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
{
|
||||
struct multiboot_tag_efi_mmap *tag = (struct multiboot_tag_efi_mmap *) ptrorig;
|
||||
grub_efi_uintn_t efi_desc_size;
|
||||
grub_efi_uint32_t efi_desc_version;
|
||||
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
if (err)
|
||||
return err;
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_END;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue