2006-04-30 Yoshinori K. Okuji <okuji@enbug.org>
Extend the loader so that GRUB can accept a loader which comes back to GRUB when a loaded image exits. Also, this change adds support for a chainloader on EFI. * term/efi/console.c: Include grub/misc.h. (grub_console_checkkey): Display a scan code on the top for debugging. This will be removed once the EFI port gets stable. Correct the scan code mapping. * kern/efi/mm.c (sort_memory_map): Sort in a descending order to allocate memory from larger regions, in order to reduce the number of allocated regions. Otherwise, the MacOSX loader panics. (filter_memory_map): Avoid less than 1MB for compatibility with other loaders. (add_memory_regions): Allocate from the tail of a region, if possible, to avoid allocating a region near to 1MB, for the MacOSX loader. * kern/efi/init.c (grub_efi_set_prefix): Specify GRUB_EFI_IMAGE_HANDLE to grub_efi_get_loaded_image. * kern/efi/efi.c (grub_efi_get_loaded_image): Accept a new argument IMAGE_HANDLE and specify it to get a loaded image. (grub_arch_modules_addr): Specify GRUB_EFI_IMAGE_HANDLE to grub_efi_get_loaded_image. (grub_efi_get_filename): Divide the legnth by the size of grub_efi_char16_t. (grub_efi_get_device_path): New function. (grub_efi_print_device_path): Print End Device Path nodes. Divide the length by the size of grub_efi_char16_t for a file path device path node. * kern/loader.c (grub_loader_noreturn): New variable. (grub_loader_set): Accept a new argument NORETURN. Set GRUB_LOADER_NORETURN to NORETURN. All callers changed. (grub_loader_boot): If GRUB_LOADER_NORETURN is false, do not call grub_machine_fini. * include/grub/efi/efi.h (grub_efi_get_device_path): New prototype. (grub_efi_get_loaded_image): Take an argument to specify an image handle. * include/grub/loader.h (grub_loader_set): Added one more argument NORETURN. * disk/efi/efidisk.c (make_devices): Use grub_efi_get_device_path instead of grub_efi_open_protocol. (grub_efidisk_get_device_name): Likewise. (grub_efidisk_close): Print a newline. (grub_efidisk_get_device_handle): Fixed to use GRUB_EFI_DEVICE_PATH_SUBTYPE instead of GRUB_EFI_DEVICE_PATH_TYPE. * disk/efi/efidisk.c (device_path_guid): Moved to ... * kern/efi/efi.c (device_path_guid): ... here. * conf/i386-efi.rmk (pkgdata_MODULES): Added _chain.mod and chain.mod. (kernel_mod_HEADERS): Added efi/disk.h. (_chain_mod_SOURCES): New variable. (_chain_mod_CFLAGS): Likewise. (_chain_mod_LDFLAGS): Likewise. (chain_mod_SOURCES): Likewise. (chain_mod_CFLAGS): Likewise. (chain_mod_LDFLAGS): Likewise. * DISTLIST: Added include/grub/efi/chainloader.h, loader/efi/chainloader.c and loader/efi/chainloader_normal.c. * include/grub/efi/chainloader.h: New file. * loader/efi/chainloader.c: Likewise. * loader/efi/chainloader_normal.c: Likewise.
This commit is contained in:
parent
c0111d6e92
commit
7f362539b7
19 changed files with 743 additions and 64 deletions
|
@ -36,6 +36,7 @@ grub_efi_system_table_t *grub_efi_system_table;
|
|||
|
||||
static grub_efi_guid_t console_control_guid = GRUB_EFI_CONSOLE_CONTROL_GUID;
|
||||
static grub_efi_guid_t loaded_image_guid = GRUB_EFI_LOADED_IMAGE_GUID;
|
||||
static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
|
||||
|
||||
void *
|
||||
grub_efi_locate_protocol (grub_efi_guid_t *protocol, void *registration)
|
||||
|
@ -144,9 +145,9 @@ grub_efi_stall (grub_efi_uintn_t microseconds)
|
|||
}
|
||||
|
||||
grub_efi_loaded_image_t *
|
||||
grub_efi_get_loaded_image (void)
|
||||
grub_efi_get_loaded_image (grub_efi_handle_t image_handle)
|
||||
{
|
||||
return grub_efi_open_protocol (grub_efi_image_handle,
|
||||
return grub_efi_open_protocol (image_handle,
|
||||
&loaded_image_guid,
|
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ grub_arch_modules_addr (void)
|
|||
struct grub_module_info *info;
|
||||
grub_uint16_t i;
|
||||
|
||||
image = grub_efi_get_loaded_image ();
|
||||
image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
if (! image)
|
||||
return 0;
|
||||
|
||||
|
@ -248,7 +249,8 @@ grub_efi_get_filename (grub_efi_device_path_t *dp)
|
|||
else
|
||||
size = 0;
|
||||
|
||||
len = GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4;
|
||||
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
|
||||
/ sizeof (grub_efi_char16_t));
|
||||
p = grub_realloc (name, size + len * 4 + 1);
|
||||
if (! p)
|
||||
{
|
||||
|
@ -278,6 +280,13 @@ grub_efi_get_filename (grub_efi_device_path_t *dp)
|
|||
return name;
|
||||
}
|
||||
|
||||
grub_efi_device_path_t *
|
||||
grub_efi_get_device_path (grub_efi_handle_t handle)
|
||||
{
|
||||
return grub_efi_open_protocol (handle, &device_path_guid,
|
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
}
|
||||
|
||||
/* Print the chain of Device Path nodes. This is mainly for debugging. */
|
||||
void
|
||||
grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||
|
@ -294,12 +303,12 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
|||
switch (subtype)
|
||||
{
|
||||
case GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE:
|
||||
/* grub_printf ("/EndEntire\n"); */
|
||||
grub_putchar ('\n');
|
||||
grub_printf ("/EndEntire\n");
|
||||
//grub_putchar ('\n');
|
||||
break;
|
||||
case GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE:
|
||||
/* grub_printf ("/EndThis\n"); */
|
||||
grub_putchar ('\n');
|
||||
grub_printf ("/EndThis\n");
|
||||
//grub_putchar ('\n');
|
||||
break;
|
||||
default:
|
||||
grub_printf ("/EndUnknown(%x)\n", (unsigned) subtype);
|
||||
|
@ -633,9 +642,11 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
|||
case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE:
|
||||
{
|
||||
grub_efi_file_path_device_path_t *fp;
|
||||
grub_uint8_t buf[(len - 4) * 4 + 1];
|
||||
grub_uint8_t buf[(len - 4) * 2 + 1];
|
||||
fp = (grub_efi_file_path_device_path_t *) dp;
|
||||
*grub_utf16_to_utf8 (buf, fp->path_name, len - 4) = '\0';
|
||||
*grub_utf16_to_utf8 (buf, fp->path_name,
|
||||
(len - 4) / sizeof (grub_efi_char16_t))
|
||||
= '\0';
|
||||
grub_printf ("/File(%s)", buf);
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue