2006-04-20 Yoshinori K. Okuji <okuji@enbug.org>

Add support for pre-loaded modules into the EFI port.

        * util/i386/efi/grub-mkimage.c (make_mods_section): Rewritten
        completely. Accept one more argument DIR. The caller has changed.

        * kern/i386/efi/init.c (grub_arch_modules_addr): Removed.

        * kern/efi/efi.c: Include grub/efi/pe32.h and grub/kernel.h.
        (grub_efi_loaded_image_guid): New variable.
        (grub_efi_get_loaded_image): New function.
        (grub_arch_modules_addr): Likewise.

        * include/grub/efi/efi.h (grub_efi_get_loaded_image): New
        prototype.

        * include/grub/efi/api.h (GRUB_EFI_LOADED_IMAGE_GUID): New macro.
        (struct grub_efi_loaded_image): New structure.
        (grub_efi_loaded_image_t): New type.
This commit is contained in:
okuji 2006-04-20 04:29:17 +00:00
parent c352d8dd0b
commit 2eab1c0dad
6 changed files with 180 additions and 14 deletions

View file

@ -22,8 +22,10 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/console_control.h>
#include <grub/efi/pe32.h>
#include <grub/machine/time.h>
#include <grub/term.h>
#include <grub/kernel.h>
/* The handle of GRUB itself. Filled in by the startup code. */
grub_efi_handle_t grub_efi_image_handle;
@ -32,6 +34,7 @@ grub_efi_handle_t grub_efi_image_handle;
grub_efi_system_table_t *grub_efi_system_table;
static grub_efi_guid_t grub_efi_console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
static grub_efi_guid_t grub_efi_loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
void *
grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
@ -83,6 +86,26 @@ grub_efi_stall (grub_efi_uintn_t microseconds)
grub_efi_system_table->boot_services->stall (microseconds);
}
grub_efi_loaded_image_t *
grub_efi_get_loaded_image (void)
{
grub_efi_boot_services_t *b;
void *interface;
grub_efi_status_t status;
b = grub_efi_system_table->boot_services;
status = b->open_protocol (grub_efi_image_handle,
&grub_efi_loaded_image_guid,
&interface,
grub_efi_image_handle,
0,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (status != GRUB_EFI_SUCCESS)
return 0;
return interface;
}
void
grub_stop (void)
{
@ -108,3 +131,46 @@ grub_get_rtc (void)
+ time.nanosecond / 1000000)
* GRUB_TICKS_PER_SECOND / 1000);
}
/* Search the mods section from the PE32/PE32+ image. This code uses
a PE32 header, but should work with PE32+ as well. */
grub_addr_t
grub_arch_modules_addr (void)
{
grub_efi_loaded_image_t *image;
struct grub_pe32_header *header;
struct grub_pe32_coff_header *coff_header;
struct grub_pe32_section_table *sections;
struct grub_pe32_section_table *section;
struct grub_module_info *info;
grub_uint16_t i;
image = grub_efi_get_loaded_image ();
if (! image)
return 0;
header = image->image_base;
coff_header = &(header->coff_header);
sections
= (struct grub_pe32_section_table *) ((char *) coff_header
+ sizeof (*coff_header)
+ coff_header->optional_header_size);
for (i = 0, section = sections;
i < coff_header->num_sections;
i++, section++)
{
if (grub_strcmp (section->name, "mods") == 0)
break;
}
if (i == coff_header->num_sections)
return 0;
info = (struct grub_module_info *) ((char *) image->image_base
+ section->virtual_address);
if (info->magic != GRUB_MODULE_MAGIC)
return 0;
return (grub_addr_t) info;
}