* 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
|
@ -1,3 +1,7 @@
|
||||||
|
2013-10-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/loader/multiboot_mbi2.c: Implement EFI memory map.
|
||||||
|
|
||||||
2013-10-28 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-10-28 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/loader/multiboot.c: Add support for multiboot kernels
|
* grub-core/loader/multiboot.c: Add support for multiboot kernels
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
#include <grub/net.h>
|
#include <grub/net.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
#include <grub/efi/efi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The bits in the required part of flags field we don't support. */
|
/* The bits in the required part of flags field we don't support. */
|
||||||
#define UNSUPPORTED_FLAGS 0x0000fff8
|
#define UNSUPPORTED_FLAGS 0x0000fff8
|
||||||
|
|
||||||
|
@ -587,6 +591,12 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
||||||
ptrdest += sizeof (struct grub_vbe_mode_info_block);
|
ptrdest += sizeof (struct grub_vbe_mode_info_block);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef GRUB_MACHINE_EFI
|
||||||
|
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
#endif
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,12 +131,6 @@ grub_multiboot_boot (void)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_EFI
|
|
||||||
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (__i386__) || defined (__x86_64__)
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
|
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -295,9 +295,55 @@ acpiv2_size (void)
|
||||||
#endif
|
#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
|
static grub_size_t
|
||||||
grub_multiboot_get_mbi_size (void)
|
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)
|
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||||
+ (sizeof (struct multiboot_tag_string)
|
+ (sizeof (struct multiboot_tag_string)
|
||||||
+ ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
|
+ 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)
|
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
|
||||||
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
||||||
+ acpiv2_size ()
|
+ 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_vbe) + MULTIBOOT_TAG_ALIGN - 1
|
||||||
+ sizeof (struct multiboot_tag_apm) + 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
|
#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;
|
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||||
tag->type = MULTIBOOT_TAG_TYPE_END;
|
tag->type = MULTIBOOT_TAG_TYPE_END;
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
||||||
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
||||||
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||||
|
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||||
|
|
||||||
#define MULTIBOOT_HEADER_TAG_END 0
|
#define MULTIBOOT_HEADER_TAG_END 0
|
||||||
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
||||||
|
@ -361,6 +362,15 @@ struct multiboot_tag_network
|
||||||
multiboot_uint8_t dhcpack[0];
|
multiboot_uint8_t dhcpack[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct multiboot_tag_efi_mmap
|
||||||
|
{
|
||||||
|
multiboot_uint32_t type;
|
||||||
|
multiboot_uint32_t size;
|
||||||
|
multiboot_uint32_t descr_size;
|
||||||
|
multiboot_uint32_t descr_vers;
|
||||||
|
multiboot_uint8_t efi_mmap[0];
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* ! ASM_FILE */
|
#endif /* ! ASM_FILE */
|
||||||
|
|
||||||
#endif /* ! MULTIBOOT_HEADER */
|
#endif /* ! MULTIBOOT_HEADER */
|
||||||
|
|
Loading…
Reference in a new issue