Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e576eb0cbc
183 changed files with 5507 additions and 2653 deletions
|
@ -28,28 +28,6 @@
|
|||
static void *loaded_fdt;
|
||||
static void *fdt;
|
||||
|
||||
static void *
|
||||
get_firmware_fdt (void)
|
||||
{
|
||||
grub_efi_configuration_table_t *tables;
|
||||
grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
|
||||
void *firmware_fdt = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Look for FDT in UEFI config tables. */
|
||||
tables = grub_efi_system_table->configuration_table;
|
||||
|
||||
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
|
||||
if (grub_memcmp (&tables[i].vendor_guid, &fdt_guid, sizeof (fdt_guid)) == 0)
|
||||
{
|
||||
firmware_fdt = tables[i].vendor_table;
|
||||
grub_dprintf ("linux", "found registered FDT @ %p\n", firmware_fdt);
|
||||
break;
|
||||
}
|
||||
|
||||
return firmware_fdt;
|
||||
}
|
||||
|
||||
void *
|
||||
grub_fdt_load (grub_size_t additional_size)
|
||||
{
|
||||
|
@ -65,7 +43,7 @@ grub_fdt_load (grub_size_t additional_size)
|
|||
if (loaded_fdt)
|
||||
raw_fdt = loaded_fdt;
|
||||
else
|
||||
raw_fdt = get_firmware_fdt();
|
||||
raw_fdt = grub_efi_get_firmware_fdt();
|
||||
|
||||
size =
|
||||
raw_fdt ? grub_fdt_get_totalsize (raw_fdt) : GRUB_FDT_EMPTY_TREE_SZ;
|
||||
|
|
|
@ -37,16 +37,6 @@
|
|||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define XEN_HYPERVISOR_NAME "xen_hypervisor"
|
||||
|
||||
#define MODULE_DEFAULT_ALIGN (0x0)
|
||||
#define MODULE_IMAGE_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_INITRD_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_XSM_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
#define MODULE_CUSTOM_MIN_ALIGN MODULE_DEFAULT_ALIGN
|
||||
|
||||
#define MODULE_IMAGE_COMPATIBLE "multiboot,kernel\0multiboot,module"
|
||||
#define MODULE_INITRD_COMPATIBLE "multiboot,ramdisk\0multiboot,module"
|
||||
#define MODULE_XSM_COMPATIBLE "xen,xsm-policy\0multiboot,module"
|
||||
#define MODULE_CUSTOM_COMPATIBLE "multiboot,module"
|
||||
|
||||
/* This maximum size is defined in Power.org ePAPR V1.1
|
||||
|
@ -74,14 +64,6 @@ enum module_type
|
|||
};
|
||||
typedef enum module_type module_type_t;
|
||||
|
||||
struct fdt_node_info
|
||||
{
|
||||
module_type_t type;
|
||||
|
||||
const char *compat_string;
|
||||
grub_size_t compat_string_size;
|
||||
};
|
||||
|
||||
struct xen_hypervisor_header
|
||||
{
|
||||
struct grub_arm64_linux_kernel_header efi_head;
|
||||
|
@ -98,7 +80,7 @@ struct xen_boot_binary
|
|||
{
|
||||
struct xen_boot_binary *next;
|
||||
struct xen_boot_binary **prev;
|
||||
const char *name;
|
||||
int is_hypervisor;
|
||||
|
||||
grub_addr_t start;
|
||||
grub_size_t size;
|
||||
|
@ -106,8 +88,6 @@ struct xen_boot_binary
|
|||
|
||||
char *cmdline;
|
||||
int cmdline_size;
|
||||
|
||||
struct fdt_node_info node_info;
|
||||
};
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
|
@ -116,19 +96,6 @@ static int loaded;
|
|||
|
||||
static struct xen_boot_binary *xen_hypervisor;
|
||||
static struct xen_boot_binary *module_head;
|
||||
static const grub_size_t module_default_align[] = {
|
||||
MODULE_IMAGE_MIN_ALIGN,
|
||||
MODULE_INITRD_MIN_ALIGN,
|
||||
MODULE_XSM_MIN_ALIGN,
|
||||
MODULE_CUSTOM_MIN_ALIGN
|
||||
};
|
||||
|
||||
static const compat_string_struct_t default_compat_string[] = {
|
||||
FDT_COMPATIBLE (MODULE_IMAGE_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_INITRD_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_XSM_COMPATIBLE),
|
||||
FDT_COMPATIBLE (MODULE_CUSTOM_COMPATIBLE)
|
||||
};
|
||||
|
||||
static __inline grub_addr_t
|
||||
xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
|
@ -136,20 +103,6 @@ xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
|||
return (align ? (ALIGN_UP (start, align)) : start);
|
||||
}
|
||||
|
||||
/* set module type according to command name. */
|
||||
static grub_err_t
|
||||
set_module_type (grub_command_t cmd, struct xen_boot_binary *module)
|
||||
{
|
||||
if (!grub_strcmp (cmd->name, "xen_linux"))
|
||||
module->node_info.type = MODULE_IMAGE;
|
||||
else if (!grub_strcmp (cmd->name, "xen_initrd"))
|
||||
module->node_info.type = MODULE_INITRD;
|
||||
else if (!grub_strcmp (cmd->name, "xen_xsm"))
|
||||
module->node_info.type = MODULE_XSM;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
prepare_xen_hypervisor_params (void *xen_boot_fdt)
|
||||
{
|
||||
|
@ -203,15 +156,11 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
|||
grub_fdt_add_subnode (xen_boot_fdt, chosen_node, module_name);
|
||||
|
||||
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "compatible",
|
||||
module->node_info.compat_string,
|
||||
(grub_uint32_t) module->
|
||||
node_info.compat_string_size);
|
||||
MODULE_CUSTOM_COMPATIBLE, sizeof(MODULE_CUSTOM_COMPATIBLE) - 1);
|
||||
if (retval)
|
||||
return grub_error (GRUB_ERR_IO, "failed to update FDT");
|
||||
|
||||
grub_dprintf ("xen_loader", "Module %s compatible = %s size = 0x%lx\n",
|
||||
module->name, module->node_info.compat_string,
|
||||
module->node_info.compat_string_size);
|
||||
grub_dprintf ("xen_loader", "Module\n");
|
||||
|
||||
retval = grub_fdt_set_reg64 (xen_boot_fdt, module_node,
|
||||
xen_boot_address_align (module->start,
|
||||
|
@ -223,7 +172,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
|||
if (module->cmdline && module->cmdline_size > 0)
|
||||
{
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s cmdline : %s @ %p size:%d\n", module->name,
|
||||
"Module cmdline : %s @ %p size:%d\n",
|
||||
module->cmdline, module->cmdline, module->cmdline_size);
|
||||
|
||||
retval = grub_fdt_set_prop (xen_boot_fdt, module_node, "bootargs",
|
||||
|
@ -233,8 +182,7 @@ prepare_xen_module_params (struct xen_boot_binary *module, void *xen_boot_fdt)
|
|||
}
|
||||
else
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module %s has not bootargs!\n",
|
||||
module->name);
|
||||
grub_dprintf ("xen_loader", "Module has no bootargs!\n");
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
@ -251,8 +199,8 @@ finalize_params_xen_boot (void)
|
|||
additional_size += FDT_NODE_NAME_MAX_SIZE + xen_hypervisor->cmdline_size;
|
||||
FOR_LIST_ELEMENTS (module, module_head)
|
||||
{
|
||||
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + module->
|
||||
node_info.compat_string_size + module->cmdline_size;
|
||||
additional_size += 6 * FDT_NODE_NAME_MAX_SIZE + sizeof(MODULE_CUSTOM_COMPATIBLE) - 1
|
||||
+ module->cmdline_size;
|
||||
}
|
||||
|
||||
xen_boot_fdt = grub_fdt_load (additional_size);
|
||||
|
@ -275,8 +223,7 @@ finalize_params_xen_boot (void)
|
|||
{
|
||||
if (module->start && module->size > 0)
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module %s @ 0x%lx size:0x%lx\n",
|
||||
module->name,
|
||||
grub_dprintf ("xen_loader", "Module @ 0x%lx size:0x%lx\n",
|
||||
xen_boot_address_align (module->start, module->align),
|
||||
module->size);
|
||||
if (prepare_xen_module_params (module, xen_boot_fdt) != GRUB_ERR_NONE)
|
||||
|
@ -284,7 +231,7 @@ finalize_params_xen_boot (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
grub_dprintf ("xen_loader", "Module info error: %s!\n", module->name);
|
||||
grub_dprintf ("xen_loader", "Module info error!\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -327,19 +274,16 @@ single_binary_unload (struct xen_boot_binary *binary)
|
|||
{
|
||||
grub_free (binary->cmdline);
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s cmdline memory free @ %p size: %d\n",
|
||||
binary->name, binary->cmdline, binary->cmdline_size);
|
||||
"Module cmdline memory free @ %p size: %d\n",
|
||||
binary->cmdline, binary->cmdline_size);
|
||||
}
|
||||
|
||||
if (binary->node_info.type == MODULE_CUSTOM)
|
||||
grub_free ((void *) binary->node_info.compat_string);
|
||||
|
||||
if (grub_strcmp (binary->name, XEN_HYPERVISOR_NAME))
|
||||
if (!binary->is_hypervisor)
|
||||
grub_list_remove (GRUB_AS_LIST (binary));
|
||||
|
||||
grub_dprintf ("xen_loader",
|
||||
"Module %s struct memory free @ %p size: 0x%lx\n",
|
||||
binary->name, binary, sizeof (binary));
|
||||
"Module struct memory free @ %p size: 0x%lx\n",
|
||||
binary, sizeof (binary));
|
||||
grub_free (binary);
|
||||
|
||||
return;
|
||||
|
@ -377,8 +321,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
|||
int argc, char *argv[])
|
||||
{
|
||||
binary->size = grub_file_size (file);
|
||||
grub_dprintf ("xen_loader", "Xen_boot %s file size: 0x%lx\n",
|
||||
binary->name, binary->size);
|
||||
grub_dprintf ("xen_loader", "Xen_boot file size: 0x%lx\n", binary->size);
|
||||
|
||||
binary->start
|
||||
= (grub_addr_t) grub_efi_allocate_pages (0,
|
||||
|
@ -391,8 +334,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
|||
return;
|
||||
}
|
||||
|
||||
grub_dprintf ("xen_loader", "Xen_boot %s numpages: 0x%lx\n",
|
||||
binary->name, GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
|
||||
grub_dprintf ("xen_loader", "Xen_boot numpages: 0x%lx\n",
|
||||
GRUB_EFI_BYTES_TO_PAGES (binary->size + binary->align));
|
||||
|
||||
if (grub_file_read (file, (void *) xen_boot_address_align (binary->start,
|
||||
binary->align),
|
||||
|
@ -416,7 +359,7 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
|||
grub_create_loader_cmdline (argc - 1, argv + 1, binary->cmdline,
|
||||
binary->cmdline_size);
|
||||
grub_dprintf ("xen_loader",
|
||||
"Xen_boot %s cmdline @ %p %s, size: %d\n", binary->name,
|
||||
"Xen_boot cmdline @ %p %s, size: %d\n",
|
||||
binary->cmdline, binary->cmdline, binary->cmdline_size);
|
||||
}
|
||||
else
|
||||
|
@ -430,7 +373,8 @@ xen_boot_binary_load (struct xen_boot_binary *binary, grub_file_t file,
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
||||
grub_cmd_xen_module (grub_command_t cmd __attribute__((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
|
||||
struct xen_boot_binary *module = NULL;
|
||||
|
@ -454,34 +398,10 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
|||
if (!module)
|
||||
return grub_errno;
|
||||
|
||||
/* process all the options and get module type */
|
||||
if (set_module_type (cmd, module) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
switch (module->node_info.type)
|
||||
{
|
||||
case MODULE_IMAGE:
|
||||
case MODULE_INITRD:
|
||||
case MODULE_XSM:
|
||||
module->node_info.compat_string =
|
||||
default_compat_string[module->node_info.type].compat_string;
|
||||
module->node_info.compat_string_size =
|
||||
default_compat_string[module->node_info.type].size;
|
||||
break;
|
||||
module->is_hypervisor = 0;
|
||||
module->align = 4096;
|
||||
|
||||
case MODULE_CUSTOM:
|
||||
/* we have set the node_info in set_module_type */
|
||||
break;
|
||||
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid argument"));
|
||||
}
|
||||
module->name = module->node_info.compat_string;
|
||||
module->align = module_default_align[module->node_info.type];
|
||||
|
||||
grub_dprintf ("xen_loader", "Init %s module and node info:\n"
|
||||
"compatible %s\ncompat_string_size 0x%lx\n",
|
||||
module->name, module->node_info.compat_string,
|
||||
module->node_info.compat_string_size);
|
||||
grub_dprintf ("xen_loader", "Init module and node info\n");
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
if (!file)
|
||||
|
@ -491,7 +411,7 @@ grub_cmd_xen_module (grub_command_t cmd, int argc, char *argv[])
|
|||
if (grub_errno == GRUB_ERR_NONE)
|
||||
grub_list_push (GRUB_AS_LIST_P (&module_head), GRUB_AS_LIST (module));
|
||||
|
||||
fail:
|
||||
fail:
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
|
@ -535,7 +455,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
|
|||
if (!xen_hypervisor)
|
||||
return grub_errno;
|
||||
|
||||
xen_hypervisor->name = XEN_HYPERVISOR_NAME;
|
||||
xen_hypervisor->is_hypervisor = 1;
|
||||
xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
|
||||
|
||||
xen_boot_binary_load (xen_hypervisor, file, argc, argv);
|
||||
|
@ -559,29 +479,21 @@ fail:
|
|||
}
|
||||
|
||||
static grub_command_t cmd_xen_hypervisor;
|
||||
static grub_command_t cmd_xen_linux, cmd_xen_initrd, cmd_xen_xsm;
|
||||
static grub_command_t cmd_xen_module;
|
||||
|
||||
GRUB_MOD_INIT (xen_boot)
|
||||
{
|
||||
cmd_xen_hypervisor =
|
||||
grub_register_command ("xen_hypervisor", grub_cmd_xen_hypervisor, 0,
|
||||
N_("Load a xen hypervisor."));
|
||||
cmd_xen_linux =
|
||||
grub_register_command ("xen_linux", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen linux kernel for dom0."));
|
||||
cmd_xen_initrd =
|
||||
grub_register_command ("xen_initrd", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen initrd for dom0."));
|
||||
cmd_xen_xsm =
|
||||
grub_register_command ("xen_xsm", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen security module."));
|
||||
cmd_xen_module =
|
||||
grub_register_command ("xen_module", grub_cmd_xen_module, 0,
|
||||
N_("Load a xen module."));
|
||||
my_mod = mod;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (xen_boot)
|
||||
{
|
||||
grub_unregister_command (cmd_xen_hypervisor);
|
||||
grub_unregister_command (cmd_xen_linux);
|
||||
grub_unregister_command (cmd_xen_initrd);
|
||||
grub_unregister_command (cmd_xen_xsm);
|
||||
grub_unregister_command (cmd_xen_module);
|
||||
}
|
||||
|
|
|
@ -122,6 +122,8 @@ copy_file_path (grub_efi_file_path_device_path_t *fp,
|
|||
if (*p == '/')
|
||||
*p = '\\';
|
||||
|
||||
/* File Path is NULL terminated */
|
||||
fp->path_name[size++] = '\0';
|
||||
fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
|
||||
}
|
||||
|
||||
|
@ -156,8 +158,10 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
|||
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
|
||||
}
|
||||
|
||||
/* File Path is NULL terminated. Allocate space for 2 extra characters */
|
||||
/* FIXME why we split path in two components? */
|
||||
file_path = grub_malloc (size
|
||||
+ ((grub_strlen (dir_start) + 1)
|
||||
+ ((grub_strlen (dir_start) + 2)
|
||||
* GRUB_MAX_UTF16_PER_UTF8
|
||||
* sizeof (grub_efi_char16_t))
|
||||
+ sizeof (grub_efi_file_path_device_path_t) * 2);
|
||||
|
|
|
@ -1889,6 +1889,10 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_err_t err;
|
||||
void *src;
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_FREEBSD)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no FreeBSD loaded");
|
||||
|
||||
|
@ -1992,6 +1996,10 @@ grub_cmd_netbsd_module (grub_command_t cmd,
|
|||
{
|
||||
grub_uint32_t type;
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_NETBSD)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no NetBSD loaded");
|
||||
|
||||
|
@ -2070,6 +2078,10 @@ grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)),
|
|||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
if (! grub_loader_is_loaded ())
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
if (kernel_type != KERNEL_TYPE_OPENBSD)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "no kOpenBSD loaded");
|
||||
|
||||
|
|
|
@ -48,15 +48,15 @@ read_headers (grub_file_t file, const char *filename, Elf_Ehdr *e, char **shdr)
|
|||
if (e->e_ident[EI_CLASS] != SUFFIX (ELFCLASS))
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic"));
|
||||
|
||||
*shdr = grub_malloc (e->e_shnum * e->e_shentsize);
|
||||
*shdr = grub_malloc ((grub_uint32_t) e->e_shnum * e->e_shentsize);
|
||||
if (! *shdr)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_seek (file, e->e_shoff) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, *shdr, e->e_shnum * e->e_shentsize)
|
||||
!= e->e_shnum * e->e_shentsize)
|
||||
if (grub_file_read (file, *shdr, (grub_uint32_t) e->e_shnum * e->e_shentsize)
|
||||
!= (grub_ssize_t) ((grub_uint32_t) e->e_shnum * e->e_shentsize))
|
||||
{
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
|
@ -200,8 +200,8 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
|||
|
||||
if (chunk_size < sizeof (e))
|
||||
chunk_size = sizeof (e);
|
||||
chunk_size += e.e_phnum * e.e_phentsize;
|
||||
chunk_size += e.e_shnum * e.e_shentsize;
|
||||
chunk_size += (grub_uint32_t) e.e_phnum * e.e_phentsize;
|
||||
chunk_size += (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
|
@ -253,14 +253,14 @@ SUFFIX (grub_freebsd_load_elfmodule) (struct grub_relocator *relocator,
|
|||
curload = module + sizeof (e);
|
||||
|
||||
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_shoff,
|
||||
e.e_shnum * e.e_shentsize);
|
||||
(grub_uint32_t) e.e_shnum * e.e_shentsize);
|
||||
e.e_shoff = curload - module;
|
||||
curload += e.e_shnum * e.e_shentsize;
|
||||
curload += (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
load (file, argv[0], (grub_uint8_t *) chunk_src + curload - *kern_end, e.e_phoff,
|
||||
e.e_phnum * e.e_phentsize);
|
||||
(grub_uint32_t) e.e_phnum * e.e_phentsize);
|
||||
e.e_phoff = curload - module;
|
||||
curload += e.e_phnum * e.e_phentsize;
|
||||
curload += (grub_uint32_t) e.e_phnum * e.e_phentsize;
|
||||
|
||||
*kern_end = curload;
|
||||
|
||||
|
@ -462,7 +462,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
|||
|
||||
chunk_size = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||
+ ALIGN_UP (strsize, sizeof (grub_freebsd_addr_t))
|
||||
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
|
||||
symtarget = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t));
|
||||
{
|
||||
|
@ -498,10 +498,10 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
|
|||
s2 = (Elf_Shdr *) curload;
|
||||
grub_memcpy (curload, s, e.e_shentsize);
|
||||
if (s == symsh)
|
||||
s2->sh_offset = sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
s2->sh_offset = sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
else if (s == strsh)
|
||||
s2->sh_offset = ALIGN_UP (symsize, sizeof (grub_freebsd_addr_t))
|
||||
+ sizeof (e) + e.e_shnum * e.e_shentsize;
|
||||
+ sizeof (e) + (grub_uint32_t) e.e_shnum * e.e_shentsize;
|
||||
else
|
||||
s2->sh_offset = 0;
|
||||
s2->sh_addr = s2->sh_offset;
|
||||
|
|
|
@ -929,8 +929,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -939,8 +939,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_env_set ("gfxpayload", "text");
|
||||
grub_printf_ (N_("%s is deprecated. "
|
||||
"Use set gfxpayload=%s before "
|
||||
"linux command instead.\n"), "text",
|
||||
argv[i]);
|
||||
"linux command instead.\n"),
|
||||
argv[i], "text");
|
||||
break;
|
||||
default:
|
||||
/* Ignore invalid values. */
|
||||
|
|
|
@ -71,9 +71,18 @@ load_kernel (grub_file_t file, const char *filename,
|
|||
char *buffer, struct multiboot_header *header)
|
||||
{
|
||||
grub_err_t err;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.buffer = buffer;
|
||||
mld.mbi_ver = 1;
|
||||
mld.relocatable = 0;
|
||||
mld.avoid_efi_boot_services = 0;
|
||||
|
||||
if (grub_multiboot_quirks & GRUB_MULTIBOOT_QUIRK_BAD_KLUDGE)
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err == GRUB_ERR_NONE) {
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -122,7 +131,7 @@ load_kernel (grub_file_t file, const char *filename,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
return grub_multiboot_load_elf (file, filename, buffer);
|
||||
return grub_multiboot_load_elf (&mld);
|
||||
}
|
||||
|
||||
static struct multiboot_header *
|
||||
|
|
|
@ -205,7 +205,7 @@ grub_cmd_truecrypt (grub_command_t cmd __attribute__ ((unused)),
|
|||
fail:
|
||||
|
||||
if (!grub_errno)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
|
||||
grub_error (GRUB_ERR_BAD_OS, "bad truecrypt ISO");
|
||||
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -65,14 +65,14 @@ grub_xen_file_and_cmdline (grub_file_t file,
|
|||
grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n",
|
||||
(unsigned long long) (lh.setup_sects + 1) * 512
|
||||
+ lh.payload_offset,
|
||||
(unsigned long long) lh.payload_length - 4);
|
||||
(unsigned long long) lh.payload_length);
|
||||
|
||||
if (cmdline)
|
||||
grub_pass_verity_hash (&lh, cmdline, cmdline_max_len);
|
||||
|
||||
off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512
|
||||
+ lh.payload_offset,
|
||||
lh.payload_length - 4);
|
||||
lh.payload_length);
|
||||
if (!off_file)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <grub/xen_file.h>
|
||||
#include <grub/misc.h>
|
||||
#include <xen/elfnote.h>
|
||||
|
||||
static grub_err_t
|
||||
parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
||||
|
@ -26,6 +27,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
char *buf;
|
||||
char *ptr;
|
||||
int has_paddr = 0;
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (grub_file_seek (elf->file, off) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
buf = grub_malloc (sz);
|
||||
|
@ -35,7 +38,8 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
if (grub_file_read (elf->file, buf, sz) != (grub_ssize_t) sz)
|
||||
{
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
grub_free (buf);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
elf->file->name);
|
||||
}
|
||||
|
@ -123,14 +127,14 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
{
|
||||
xi->virt_base = grub_strtoull (ptr + sizeof ("VIRT_BASE=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "VIRT_ENTRY=", sizeof ("VIRT_ENTRY=") - 1) == 0)
|
||||
{
|
||||
xi->entry_point = grub_strtoull (ptr + sizeof ("VIRT_ENTRY=") - 1, &ptr, 16);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "HYPERCALL_PAGE=", sizeof ("HYPERCALL_PAGE=") - 1) == 0)
|
||||
|
@ -138,7 +142,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
xi->hypercall_page = grub_strtoull (ptr + sizeof ("HYPERCALL_PAGE=") - 1, &ptr, 16);
|
||||
xi->has_hypercall_page = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
if (grub_strncmp (ptr, "ELF_PADDR_OFFSET=", sizeof ("ELF_PADDR_OFFSET=") - 1) == 0)
|
||||
|
@ -146,7 +150,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
xi->paddr_offset = grub_strtoull (ptr + sizeof ("ELF_PADDR_OFFSET=") - 1, &ptr, 16);
|
||||
has_paddr = 1;
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +158,11 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
xi->hypercall_page = (xi->hypercall_page << 12) + xi->virt_base;
|
||||
if (!has_paddr)
|
||||
xi->paddr_offset = xi->virt_base;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
out:
|
||||
grub_free (buf);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
@ -196,35 +204,35 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
xi->has_note = 1;
|
||||
switch (nh->n_type)
|
||||
{
|
||||
case 1:
|
||||
case XEN_ELFNOTE_ENTRY:
|
||||
xi->entry_point = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 2:
|
||||
case XEN_ELFNOTE_HYPERCALL_PAGE:
|
||||
xi->hypercall_page = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_hypercall_page = 1;
|
||||
break;
|
||||
case 3:
|
||||
case XEN_ELFNOTE_VIRT_BASE:
|
||||
xi->virt_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 4:
|
||||
case XEN_ELFNOTE_PADDR_OFFSET:
|
||||
xi->paddr_offset = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
break;
|
||||
case 5:
|
||||
case XEN_ELFNOTE_XEN_VERSION:
|
||||
grub_dprintf ("xen", "xenversion = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 6:
|
||||
case XEN_ELFNOTE_GUEST_OS:
|
||||
grub_dprintf ("xen", "name = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 7:
|
||||
case XEN_ELFNOTE_GUEST_VERSION:
|
||||
grub_dprintf ("xen", "version = `%s'\n", (char *) desc);
|
||||
break;
|
||||
case 8:
|
||||
case XEN_ELFNOTE_LOADER:
|
||||
if (descsz < 7
|
||||
|| grub_memcmp (desc, "generic", descsz == 7 ? 7 : 8) != 0)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid loader");
|
||||
break;
|
||||
/* PAE */
|
||||
case 9:
|
||||
case XEN_ELFNOTE_PAE_MODE:
|
||||
grub_dprintf ("xen", "pae = `%s', %d, %d\n", (char *) desc,
|
||||
xi->arch, descsz);
|
||||
if (xi->arch != GRUB_XEN_FILE_I386
|
||||
|
@ -253,6 +261,13 @@ parse_note (grub_elf_t elf, struct grub_xen_file_info *xi,
|
|||
descsz == 2 ? 2 : 3) == 0)
|
||||
xi->arch = GRUB_XEN_FILE_I386;
|
||||
break;
|
||||
case XEN_ELFNOTE_INIT_P2M:
|
||||
xi->p2m_base = grub_le_to_cpu_addr (*(Elf_Addr *) desc);
|
||||
xi->has_p2m_base = 1;
|
||||
break;
|
||||
case XEN_ELFNOTE_MOD_START_PFN:
|
||||
xi->unmapped_initrd = !!grub_le_to_cpu32(*(grub_uint32_t *) desc);
|
||||
break;
|
||||
default:
|
||||
grub_dprintf ("xen", "unknown note type %d\n", nh->n_type);
|
||||
break;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <grub/i18n.h>
|
||||
#include <grub/bitmap_scale.h>
|
||||
#include <grub/cpu/io.h>
|
||||
#include <grub/random.h>
|
||||
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
@ -338,7 +339,7 @@ grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *
|
|||
utf8 = grub_malloc (namelen * 4 + 1);
|
||||
if (!utf8)
|
||||
{
|
||||
grub_free (utf8);
|
||||
grub_free (utf16);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
@ -577,11 +578,31 @@ static grub_err_t
|
|||
grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
|
||||
{
|
||||
struct grub_xnu_devtree_key *efikey;
|
||||
struct grub_xnu_devtree_key *chosenkey;
|
||||
struct grub_xnu_devtree_key *cfgtablekey;
|
||||
struct grub_xnu_devtree_key *curval;
|
||||
struct grub_xnu_devtree_key *runtimesrvkey;
|
||||
struct grub_xnu_devtree_key *platformkey;
|
||||
unsigned i, j;
|
||||
grub_err_t err;
|
||||
|
||||
chosenkey = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
|
||||
if (! chosenkey)
|
||||
return grub_errno;
|
||||
|
||||
/* Random seed. */
|
||||
curval = grub_xnu_create_value (&(chosenkey->first_child), "random-seed");
|
||||
if (! curval)
|
||||
return grub_errno;
|
||||
curval->datasize = 64;
|
||||
curval->data = grub_malloc (curval->datasize);
|
||||
if (! curval->data)
|
||||
return grub_errno;
|
||||
/* Our random is not peer-reviewed but xnu uses this seed only for
|
||||
ASLR in kernel. */
|
||||
err = grub_crypto_get_random (curval->data, curval->datasize);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* The value "model". */
|
||||
/* FIXME: may this value be sometimes different? */
|
||||
|
@ -897,6 +918,28 @@ grub_xnu_set_video (struct grub_xnu_boot_params_common *params)
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
total_ram_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size,
|
||||
grub_memory_type_t type,
|
||||
void *data)
|
||||
{
|
||||
grub_uint64_t *result = data;
|
||||
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
*result += size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
get_total_ram (void)
|
||||
{
|
||||
grub_uint64_t result = 0;
|
||||
|
||||
grub_mmap_iterate (total_ram_hook, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Boot xnu. */
|
||||
grub_err_t
|
||||
grub_xnu_boot (void)
|
||||
|
@ -973,6 +1016,7 @@ grub_xnu_boot (void)
|
|||
{
|
||||
bootparams_common = &bootparams->v2.common;
|
||||
bootparams->v2.fsbfreq = fsbfreq;
|
||||
bootparams->v2.ram_size = get_total_ram();
|
||||
}
|
||||
else
|
||||
bootparams_common = &bootparams->v1.common;
|
||||
|
@ -1080,7 +1124,7 @@ grub_xnu_boot (void)
|
|||
bootparams_common->efi_mmap = memory_map_target;
|
||||
bootparams_common->efi_mmap_size = memory_map_size;
|
||||
bootparams_common->heap_start = grub_xnu_heap_target_start;
|
||||
bootparams_common->heap_size = grub_xnu_heap_size;
|
||||
bootparams_common->heap_size = curruntimepage * GRUB_XNU_PAGESIZE - grub_xnu_heap_target_start;
|
||||
|
||||
/* Parameters for asm helper. */
|
||||
grub_xnu_stack = bootparams_common->heap_start
|
||||
|
|
|
@ -119,6 +119,48 @@ grub_multiboot_set_video_mode (void)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
#ifdef __x86_64__
|
||||
#define grub_relocator_efi_boot grub_relocator64_efi_boot
|
||||
#define grub_relocator_efi_state grub_relocator64_efi_state
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef grub_relocator_efi_boot
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel,
|
||||
grub_uint32_t target)
|
||||
{
|
||||
struct grub_relocator_efi_state state_efi = MULTIBOOT_EFI_INITIAL_STATE;
|
||||
|
||||
state_efi.MULTIBOOT_EFI_ENTRY_REGISTER = grub_multiboot_payload_eip;
|
||||
state_efi.MULTIBOOT_EFI_MBI_REGISTER = target;
|
||||
|
||||
grub_relocator_efi_boot (rel, state_efi);
|
||||
}
|
||||
#else
|
||||
#define grub_efi_is_finished 1
|
||||
static void
|
||||
efi_boot (struct grub_relocator *rel __attribute__ ((unused)),
|
||||
grub_uint32_t target __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state, 0);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
normal_boot (struct grub_relocator *rel, struct grub_relocator32_state state)
|
||||
{
|
||||
grub_relocator32_boot (rel, state);
|
||||
}
|
||||
#endif
|
||||
|
||||
static grub_err_t
|
||||
grub_multiboot_boot (void)
|
||||
{
|
||||
|
@ -132,11 +174,10 @@ grub_multiboot_boot (void)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state, 0);
|
||||
#else
|
||||
grub_relocator32_boot (grub_multiboot_relocator, state);
|
||||
#endif
|
||||
if (grub_efi_is_finished)
|
||||
normal_boot (grub_multiboot_relocator, state);
|
||||
else
|
||||
efi_boot (grub_multiboot_relocator, state.MULTIBOOT_MBI_REGISTER);
|
||||
|
||||
/* Not reached. */
|
||||
return GRUB_ERR_NONE;
|
||||
|
@ -167,13 +208,12 @@ static grub_uint64_t highest_load;
|
|||
|
||||
/* Load ELF32 or ELF64. */
|
||||
grub_err_t
|
||||
grub_multiboot_load_elf (grub_file_t file, const char *filename,
|
||||
void *buffer)
|
||||
grub_multiboot_load_elf (mbi_load_data_t *mld)
|
||||
{
|
||||
if (grub_multiboot_is_elf32 (buffer))
|
||||
return grub_multiboot_load_elf32 (file, filename, buffer);
|
||||
else if (grub_multiboot_is_elf64 (buffer))
|
||||
return grub_multiboot_load_elf64 (file, filename, buffer);
|
||||
if (grub_multiboot_is_elf32 (mld->buffer))
|
||||
return grub_multiboot_load_elf32 (mld);
|
||||
else if (grub_multiboot_is_elf64 (mld->buffer))
|
||||
return grub_multiboot_load_elf64 (mld);
|
||||
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("invalid arch-dependent ELF magic"));
|
||||
}
|
||||
|
|
|
@ -51,11 +51,15 @@ CONCAT(grub_multiboot_is_elf, XX) (void *buffer)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, void *buffer)
|
||||
CONCAT(grub_multiboot_load_elf, XX) (mbi_load_data_t *mld)
|
||||
{
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) buffer;
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *) mld->buffer;
|
||||
char *phdr_base;
|
||||
grub_err_t err;
|
||||
grub_relocator_chunk_t ch;
|
||||
grub_uint32_t load_offset, load_size;
|
||||
int i;
|
||||
void *source;
|
||||
|
||||
if (ehdr->e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr->e_ident[EI_MAG1] != ELFMAG1
|
||||
|
@ -72,57 +76,89 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
|||
return grub_error (GRUB_ERR_UNKNOWN_OS, N_("this ELF file is not of the right type"));
|
||||
|
||||
/* FIXME: Should we support program headers at strange locations? */
|
||||
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
|
||||
if (ehdr->e_phoff + (grub_uint32_t) ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
|
||||
|
||||
phdr_base = (char *) buffer + ehdr->e_phoff;
|
||||
phdr_base = (char *) mld->buffer + ehdr->e_phoff;
|
||||
#define phdr(i) ((Elf_Phdr *) (phdr_base + (i) * ehdr->e_phentsize))
|
||||
|
||||
mld->link_base_addr = ~0;
|
||||
|
||||
/* Calculate lowest and highest load address. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
mld->link_base_addr = grub_min (mld->link_base_addr, phdr(i)->p_paddr);
|
||||
highest_load = grub_max (highest_load, phdr(i)->p_paddr + phdr(i)->p_memsz);
|
||||
}
|
||||
|
||||
#ifdef MULTIBOOT_LOAD_ELF64
|
||||
if (highest_load >= 0x100000000)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "segment crosses 4 GiB border");
|
||||
#endif
|
||||
|
||||
load_size = highest_load - mld->link_base_addr;
|
||||
|
||||
if (mld->relocatable)
|
||||
{
|
||||
if (load_size > mld->max_addr || mld->min_addr > mld->max_addr - load_size)
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld->min_addr, mld->max_addr - load_size,
|
||||
load_size, mld->align ? mld->align : 1,
|
||||
mld->preference, mld->avoid_efi_boot_services);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator, &ch,
|
||||
mld->link_base_addr, load_size);
|
||||
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Cannot allocate memory for OS image\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
mld->load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%x, relocatable=%d\n", mld->link_base_addr,
|
||||
mld->load_base_addr, load_size, mld->relocatable);
|
||||
|
||||
if (mld->relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld->align, mld->preference, mld->avoid_efi_boot_services);
|
||||
|
||||
/* Load every loadable segment in memory. */
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
if (phdr(i)->p_type == PT_LOAD)
|
||||
{
|
||||
grub_err_t err;
|
||||
void *source;
|
||||
|
||||
if (phdr(i)->p_paddr + phdr(i)->p_memsz > highest_load)
|
||||
highest_load = phdr(i)->p_paddr + phdr(i)->p_memsz;
|
||||
|
||||
grub_dprintf ("multiboot_loader", "segment %d: paddr=0x%lx, memsz=0x%lx, vaddr=0x%lx\n",
|
||||
i, (long) phdr(i)->p_paddr, (long) phdr(i)->p_memsz, (long) phdr(i)->p_vaddr);
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, phdr(i)->p_paddr,
|
||||
phdr(i)->p_memsz);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading phdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
source = get_virtual_current_address (ch);
|
||||
}
|
||||
load_offset = phdr(i)->p_paddr - mld->link_base_addr;
|
||||
|
||||
if (phdr(i)->p_filesz != 0)
|
||||
{
|
||||
if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset)
|
||||
if (grub_file_seek (mld->file, (grub_off_t) phdr(i)->p_offset)
|
||||
== (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, source, phdr(i)->p_filesz)
|
||||
if (grub_file_read (mld->file, (grub_uint8_t *) source + load_offset, phdr(i)->p_filesz)
|
||||
!= (grub_ssize_t) phdr(i)->p_filesz)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (phdr(i)->p_filesz < phdr(i)->p_memsz)
|
||||
grub_memset ((grub_uint8_t *) source + phdr(i)->p_filesz, 0,
|
||||
grub_memset ((grub_uint8_t *) source + load_offset + phdr(i)->p_filesz, 0,
|
||||
phdr(i)->p_memsz - phdr(i)->p_filesz);
|
||||
}
|
||||
}
|
||||
|
@ -164,22 +200,22 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
|||
{
|
||||
grub_uint8_t *shdr, *shdrptr;
|
||||
|
||||
shdr = grub_malloc (ehdr->e_shnum * ehdr->e_shentsize);
|
||||
shdr = grub_malloc ((grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize);
|
||||
if (!shdr)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_seek (file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, ehdr->e_shoff) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (shdr);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_file_read (file, shdr, ehdr->e_shnum * ehdr->e_shentsize)
|
||||
if (grub_file_read (mld->file, shdr, (grub_uint32_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
!= (grub_ssize_t) ehdr->e_shnum * ehdr->e_shentsize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
@ -189,7 +225,9 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
|||
Elf_Shdr *sh = (Elf_Shdr *) shdrptr;
|
||||
void *src;
|
||||
grub_addr_t target;
|
||||
grub_err_t err;
|
||||
|
||||
if (mld->mbi_ver >= 2 && (sh->sh_type == SHT_REL || sh->sh_type == SHT_RELA))
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ELF files with relocs are not supported yet");
|
||||
|
||||
/* This section is a loaded section,
|
||||
so we don't care. */
|
||||
|
@ -200,33 +238,28 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, const char *filename, voi
|
|||
if (sh->sh_size == 0)
|
||||
continue;
|
||||
|
||||
{
|
||||
grub_relocator_chunk_t ch;
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator,
|
||||
&ch, 0,
|
||||
(0xffffffff - sh->sh_size)
|
||||
+ 1, sh->sh_size,
|
||||
sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
0);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
}
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, 0,
|
||||
(0xffffffff - sh->sh_size) + 1,
|
||||
sh->sh_size, sh->sh_addralign,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE,
|
||||
mld->avoid_efi_boot_services);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading shdr %d\n", i);
|
||||
return err;
|
||||
}
|
||||
src = get_virtual_current_address (ch);
|
||||
target = get_physical_target_address (ch);
|
||||
|
||||
if (grub_file_seek (file, sh->sh_offset) == (grub_off_t) -1)
|
||||
if (grub_file_seek (mld->file, sh->sh_offset) == (grub_off_t) -1)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_file_read (file, src, sh->sh_size)
|
||||
if (grub_file_read (mld->file, src, sh->sh_size)
|
||||
!= (grub_ssize_t) sh->sh_size)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
filename);
|
||||
mld->filename);
|
||||
return grub_errno;
|
||||
}
|
||||
sh->sh_addr = target;
|
||||
|
|
|
@ -69,6 +69,7 @@ static grub_size_t elf_sec_num, elf_sec_entsize;
|
|||
static unsigned elf_sec_shstrndx;
|
||||
static void *elf_sections;
|
||||
static int keep_bs = 0;
|
||||
static grub_uint32_t load_base_addr;
|
||||
|
||||
void
|
||||
grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
|
||||
|
@ -102,39 +103,43 @@ find_header (grub_properly_aligned_t *buffer, grub_ssize_t len)
|
|||
grub_err_t
|
||||
grub_multiboot_load (grub_file_t file, const char *filename)
|
||||
{
|
||||
grub_properly_aligned_t *buffer;
|
||||
grub_ssize_t len;
|
||||
struct multiboot_header *header;
|
||||
grub_err_t err;
|
||||
struct multiboot_header_tag *tag;
|
||||
struct multiboot_header_tag_address *addr_tag = NULL;
|
||||
int entry_specified = 0;
|
||||
grub_addr_t entry = 0;
|
||||
struct multiboot_header_tag_relocatable *rel_tag;
|
||||
int entry_specified = 0, efi_entry_specified = 0;
|
||||
grub_addr_t entry = 0, efi_entry = 0;
|
||||
grub_uint32_t console_required = 0;
|
||||
struct multiboot_header_tag_framebuffer *fbtag = NULL;
|
||||
int accepted_consoles = GRUB_MULTIBOOT_CONSOLE_EGA_TEXT;
|
||||
mbi_load_data_t mld;
|
||||
|
||||
buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!buffer)
|
||||
mld.mbi_ver = 2;
|
||||
mld.relocatable = 0;
|
||||
|
||||
mld.buffer = grub_malloc (MULTIBOOT_SEARCH);
|
||||
if (!mld.buffer)
|
||||
return grub_errno;
|
||||
|
||||
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
|
||||
len = grub_file_read (file, mld.buffer, MULTIBOOT_SEARCH);
|
||||
if (len < 32)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), filename);
|
||||
}
|
||||
|
||||
COMPILE_TIME_ASSERT (MULTIBOOT_HEADER_ALIGN % 4 == 0);
|
||||
|
||||
grub_tpm_measure ((unsigned char *)buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
|
||||
grub_tpm_measure ((unsigned char *)mld.buffer, len, GRUB_BINARY_PCR, "grub_multiboot", filename);
|
||||
grub_print_error();
|
||||
|
||||
header = find_header (buffer, len);
|
||||
header = find_header (mld.buffer, len);
|
||||
|
||||
if (header == 0)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found");
|
||||
}
|
||||
|
||||
|
@ -176,10 +181,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
case MULTIBOOT_TAG_TYPE_NETWORK:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_MMAP:
|
||||
case MULTIBOOT_TAG_TYPE_EFI_BS:
|
||||
case MULTIBOOT_TAG_TYPE_EFI32_IH:
|
||||
case MULTIBOOT_TAG_TYPE_EFI64_IH:
|
||||
case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
|
||||
break;
|
||||
|
||||
default:
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported information tag: 0x%x",
|
||||
request_tag->requests[i]);
|
||||
|
@ -196,6 +204,13 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64:
|
||||
#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
|
||||
efi_entry_specified = 1;
|
||||
efi_entry = ((struct multiboot_header_tag_entry_address *) tag)->entry_addr;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS:
|
||||
if (!(((struct multiboot_header_tag_console_flags *) tag)->console_flags
|
||||
& MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED))
|
||||
|
@ -210,27 +225,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
accepted_consoles |= GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_RELOCATABLE:
|
||||
mld.relocatable = 1;
|
||||
rel_tag = (struct multiboot_header_tag_relocatable *) tag;
|
||||
mld.min_addr = rel_tag->min_addr;
|
||||
mld.max_addr = rel_tag->max_addr;
|
||||
mld.align = rel_tag->align;
|
||||
switch (rel_tag->preference)
|
||||
{
|
||||
case MULTIBOOT_LOAD_PREFERENCE_LOW:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_LOW;
|
||||
break;
|
||||
|
||||
case MULTIBOOT_LOAD_PREFERENCE_HIGH:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_HIGH;
|
||||
break;
|
||||
|
||||
default:
|
||||
mld.preference = GRUB_RELOCATOR_PREFERENCE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* GRUB always page-aligns modules. */
|
||||
case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
|
||||
break;
|
||||
|
||||
case MULTIBOOT_HEADER_TAG_EFI_BS:
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
keep_bs = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"unsupported tag: 0x%x", tag->type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (addr_tag && !entry_specified)
|
||||
if (addr_tag && !entry_specified && !(keep_bs && efi_entry_specified))
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_UNKNOWN_OS,
|
||||
"load address tag without entry address tag");
|
||||
}
|
||||
|
@ -239,8 +277,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
{
|
||||
grub_uint64_t load_addr = (addr_tag->load_addr + 1)
|
||||
? addr_tag->load_addr : (addr_tag->header_addr
|
||||
- ((char *) header - (char *) buffer));
|
||||
int offset = ((char *) header - (char *) buffer -
|
||||
- ((char *) header - (char *) mld.buffer));
|
||||
int offset = ((char *) header - (char *) mld.buffer -
|
||||
(addr_tag->header_addr - load_addr));
|
||||
int load_size = ((addr_tag->load_end_addr == 0) ? file->size - offset :
|
||||
addr_tag->load_end_addr - addr_tag->load_addr);
|
||||
|
@ -253,27 +291,50 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
else
|
||||
code_size = load_size;
|
||||
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr,
|
||||
code_size);
|
||||
if (mld.relocatable)
|
||||
{
|
||||
if (code_size > mld.max_addr || mld.min_addr > mld.max_addr - code_size)
|
||||
{
|
||||
grub_free (mld.buffer);
|
||||
return grub_error (GRUB_ERR_BAD_OS, "invalid min/max address and/or load size");
|
||||
}
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
|
||||
mld.min_addr, mld.max_addr - code_size,
|
||||
code_size, mld.align ? mld.align : 1,
|
||||
mld.preference, keep_bs);
|
||||
}
|
||||
else
|
||||
err = grub_relocator_alloc_chunk_addr (grub_multiboot_relocator,
|
||||
&ch, load_addr, code_size);
|
||||
if (err)
|
||||
{
|
||||
grub_dprintf ("multiboot_loader", "Error loading aout kludge\n");
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
mld.link_base_addr = load_addr;
|
||||
mld.load_base_addr = get_physical_target_address (ch);
|
||||
source = get_virtual_current_address (ch);
|
||||
|
||||
grub_dprintf ("multiboot_loader", "link_base_addr=0x%x, load_base_addr=0x%x, "
|
||||
"load_size=0x%lx, relocatable=%d\n", mld.link_base_addr,
|
||||
mld.load_base_addr, (long) code_size, mld.relocatable);
|
||||
|
||||
if (mld.relocatable)
|
||||
grub_dprintf ("multiboot_loader", "align=0x%lx, preference=0x%x, avoid_efi_boot_services=%d\n",
|
||||
(long) mld.align, mld.preference, keep_bs);
|
||||
|
||||
if ((grub_file_seek (file, offset)) == (grub_off_t) -1)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_file_read (file, source, load_size);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
|
@ -283,17 +344,41 @@ grub_multiboot_load (grub_file_t file, const char *filename)
|
|||
}
|
||||
else
|
||||
{
|
||||
err = grub_multiboot_load_elf (file, filename, buffer);
|
||||
mld.file = file;
|
||||
mld.filename = filename;
|
||||
mld.avoid_efi_boot_services = keep_bs;
|
||||
err = grub_multiboot_load_elf (&mld);
|
||||
if (err)
|
||||
{
|
||||
grub_free (buffer);
|
||||
grub_free (mld.buffer);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry_specified)
|
||||
load_base_addr = mld.load_base_addr;
|
||||
|
||||
if (keep_bs && efi_entry_specified)
|
||||
grub_multiboot_payload_eip = efi_entry;
|
||||
else if (entry_specified)
|
||||
grub_multiboot_payload_eip = entry;
|
||||
|
||||
if (mld.relocatable)
|
||||
{
|
||||
/*
|
||||
* Both branches are mathematically equivalent. However, it looks
|
||||
* that real life (C?) is more complicated. I am trying to avoid
|
||||
* wrap around here if mld.load_base_addr < mld.link_base_addr.
|
||||
* If you look at C operator precedence then everything should work.
|
||||
* However, I am not 100% sure that a given compiler will not
|
||||
* optimize/break this stuff. So, maybe we should use signed
|
||||
* 64-bit int here.
|
||||
*/
|
||||
if (mld.load_base_addr >= mld.link_base_addr)
|
||||
grub_multiboot_payload_eip += mld.load_base_addr - mld.link_base_addr;
|
||||
else
|
||||
grub_multiboot_payload_eip -= mld.link_base_addr - mld.load_base_addr;
|
||||
}
|
||||
|
||||
if (fbtag)
|
||||
err = grub_multiboot_set_console (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER,
|
||||
accepted_consoles,
|
||||
|
@ -381,7 +466,7 @@ static grub_size_t
|
|||
grub_multiboot_get_mbi_size (void)
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
if (!efi_mmap_size)
|
||||
if (!keep_bs && !efi_mmap_size)
|
||||
find_efi_mmap_size ();
|
||||
#endif
|
||||
return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
|
||||
|
@ -400,13 +485,16 @@ grub_multiboot_get_mbi_size (void)
|
|||
+ grub_get_multiboot_mmap_count ()
|
||||
* sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_old_acpi)
|
||||
+ sizeof (struct grub_acpi_rsdp_v10), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_load_base_addr), MULTIBOOT_TAG_ALIGN)
|
||||
+ acpiv2_size ()
|
||||
+ net_size ()
|
||||
#ifdef GRUB_MACHINE_EFI
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi32_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi64_ih), MULTIBOOT_TAG_ALIGN)
|
||||
+ ALIGN_UP (sizeof (struct multiboot_tag_efi_mmap)
|
||||
+ efi_mmap_size, MULTIBOOT_TAG_ALIGN)
|
||||
#endif
|
||||
|
@ -424,6 +512,7 @@ grub_fill_multiboot_mmap_iter (grub_uint64_t addr, grub_uint64_t size,
|
|||
(*mmap_entry)->addr = addr;
|
||||
(*mmap_entry)->len = size;
|
||||
(*mmap_entry)->type = type;
|
||||
(*mmap_entry)->zero = 0;
|
||||
(*mmap_entry)++;
|
||||
|
||||
return 0;
|
||||
|
@ -681,6 +770,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
% sizeof (grub_properly_aligned_t) == 0);
|
||||
ptrorig += (2 * sizeof (grub_uint32_t)) / sizeof (grub_properly_aligned_t);
|
||||
|
||||
{
|
||||
struct multiboot_tag_load_base_addr *tag = (struct multiboot_tag_load_base_addr *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR;
|
||||
tag->size = sizeof (struct multiboot_tag_load_base_addr);
|
||||
tag->load_base_addr = load_base_addr;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
|
||||
|
@ -743,12 +841,13 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
|
||||
grub_fill_multiboot_mmap (tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_elf_sections *tag
|
||||
|
@ -764,18 +863,19 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
if (!keep_bs)
|
||||
{
|
||||
struct multiboot_tag_basic_meminfo *tag
|
||||
= (struct multiboot_tag_basic_meminfo *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_BASIC_MEMINFO;
|
||||
tag->size = sizeof (struct multiboot_tag_basic_meminfo);
|
||||
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
/* Convert from bytes to kilobytes. */
|
||||
tag->mem_lower = grub_mmap_get_lower () / 1024;
|
||||
tag->mem_upper = grub_mmap_get_upper () / 1024;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
{
|
||||
struct grub_net_network_level_interface *net;
|
||||
|
@ -874,36 +974,57 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
|
|||
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;
|
||||
|
||||
if (!keep_bs)
|
||||
err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
|
||||
&efi_desc_size, &efi_desc_version);
|
||||
else
|
||||
{
|
||||
if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
|
||||
NULL,
|
||||
&efi_desc_size, &efi_desc_version) <= 0)
|
||||
err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
tag->descr_size = efi_desc_size;
|
||||
tag->descr_vers = efi_desc_version;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
|
||||
tag->size = sizeof (*tag) + efi_mmap_size;
|
||||
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (keep_bs)
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
{
|
||||
struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
|
||||
tag->size = sizeof (struct multiboot_tag);
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
{
|
||||
struct multiboot_tag_efi32_ih *tag = (struct multiboot_tag_efi32_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI32_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi32_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
{
|
||||
struct multiboot_tag_efi64_ih *tag = (struct multiboot_tag_efi64_ih *) ptrorig;
|
||||
tag->type = MULTIBOOT_TAG_TYPE_EFI64_IH;
|
||||
tag->size = sizeof (struct multiboot_tag_efi64_ih);
|
||||
tag->pointer = (grub_addr_t) grub_efi_image_handle;
|
||||
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
|
||||
/ sizeof (grub_properly_aligned_t);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -140,17 +140,17 @@ grub_linux_boot (void)
|
|||
grub_dprintf ("loader", "Jumping to Linux...\n");
|
||||
|
||||
/* Boot the kernel. */
|
||||
asm volatile ("sethi %hi(grub_ieee1275_entry_fn), %o1\n"
|
||||
"ldx [%o1 + %lo(grub_ieee1275_entry_fn)], %o4\n"
|
||||
"sethi %hi(grub_ieee1275_original_stack), %o1\n"
|
||||
"ldx [%o1 + %lo(grub_ieee1275_original_stack)], %o6\n"
|
||||
"sethi %hi(linux_addr), %o1\n"
|
||||
"ldx [%o1 + %lo(linux_addr)], %o5\n"
|
||||
"mov %g0, %o0\n"
|
||||
"mov %g0, %o2\n"
|
||||
"mov %g0, %o3\n"
|
||||
"jmp %o5\n"
|
||||
"mov %g0, %o1\n");
|
||||
asm volatile ("ldx %0, %%o4\n"
|
||||
"ldx %1, %%o6\n"
|
||||
"ldx %2, %%o5\n"
|
||||
"mov %%g0, %%o0\n"
|
||||
"mov %%g0, %%o2\n"
|
||||
"mov %%g0, %%o3\n"
|
||||
"jmp %%o5\n"
|
||||
"mov %%g0, %%o1\n": :
|
||||
"m"(grub_ieee1275_entry_fn),
|
||||
"m"(grub_ieee1275_original_stack),
|
||||
"m"(linux_addr));
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -203,20 +203,20 @@ alloc_phys_choose (grub_uint64_t addr, grub_uint64_t len,
|
|||
if (addr + ctx->size >= end)
|
||||
return 0;
|
||||
|
||||
if (addr >= grub_phys_start && addr < grub_phys_end)
|
||||
{
|
||||
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
|
||||
if (addr + ctx->size >= end)
|
||||
return 0;
|
||||
}
|
||||
if ((addr + ctx->size) >= grub_phys_start
|
||||
&& (addr + ctx->size) < grub_phys_end)
|
||||
/* OBP available region contains grub. Start at grub_phys_end. */
|
||||
/* grub_phys_start does not start at the beginning of the memory region */
|
||||
if ((grub_phys_start >= addr && grub_phys_end < end) ||
|
||||
(addr > grub_phys_start && addr < grub_phys_end))
|
||||
{
|
||||
addr = ALIGN_UP (grub_phys_end, FOUR_MB);
|
||||
if (addr + ctx->size >= end)
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_dprintf("loader",
|
||||
"addr = 0x%lx grub_phys_start = 0x%lx grub_phys_end = 0x%lx\n",
|
||||
addr, grub_phys_start, grub_phys_end);
|
||||
|
||||
if (loaded)
|
||||
{
|
||||
grub_addr_t linux_end = ALIGN_UP (linux_paddr + linux_size, FOUR_MB);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue