From: phcoder <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: Efiemu
Date: Sun, 01 Mar 2009 11:49:17 +0100 [thread overview]
Message-ID: <49AA682D.4040602@gmail.com> (raw)
In-Reply-To: <49A96398.1070609@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 177 bytes --]
Naming problem fixed
> Usage:
> First compile grub2 with this patch and efiemu runtime (in archive)
Now it's compiled by normal make
--
Regards
Vladimir 'phcoder' Serbinenko
[-- Attachment #2: efiemu.patch --]
[-- Type: text/x-patch, Size: 92515 bytes --]
Index: conf/i386-pc.rmk
===================================================================
--- conf/i386-pc.rmk (revision 1998)
+++ conf/i386-pc.rmk (working copy)
@@ -146,7 +147,8 @@
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
- grub_emu_init.c
+ grub_emu_init.c efiemu/main.c efiemu/loadcore.c efiemu/mm.c \
+ efiemu/modules/pnvram.c efiemu/i386/loadcore.c lib/crc.c \
grub_emu_LDFLAGS = $(LIBCURSES)
@@ -172,3 +177,3 @@
vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod \
ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod
+ efiemu.mod efiemu_acpi.mod efiemu_pnvram.mod _linux_efi.mod linux_efi.mod
+# For efiemu.mod.
+efiemu_mod_SOURCES = efiemu/main.c efiemu/i386/loadcore.c efiemu/i386/pc/cfgtables.c efiemu/mm.c efiemu/loadcore.c
+efiemu_mod_CFLAGS = $(COMMON_CFLAGS) -Werror -Wall
+efiemu_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+efiemu_acpi_mod_SOURCES = efiemu/modules/acpi.c efiemu/modules/i386/pc/acpi.c
+efiemu_acpi_mod_CFLAGS = $(COMMON_CFLAGS) -Werror -Wall
+efiemu_acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+efiemu_pnvram_mod_SOURCES = efiemu/modules/pnvram.c
+efiemu_pnvram_mod_CFLAGS = $(COMMON_CFLAGS) -Werror -Wall
+efiemu_pnvram_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For biosdisk.mod.
biosdisk_mod_SOURCES = disk/i386/pc/biosdisk.c
biosdisk_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -200,6 +225,16 @@
linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For _linux_efi.mod.
+_linux_efi_mod_SOURCES = loader/i386/efi/linux.c
+_linux_efi_mod_CFLAGS = $(COMMON_CFLAGS)
+_linux_efi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For linux_efi.mod.
+linux_efi_mod_SOURCES = loader/linux_normal_efiemu.c
+linux_efi_mod_CFLAGS = $(COMMON_CFLAGS)
+linux_efi_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
#
# Only arch dependant part of normal.mod will be here. Common part for
# all architecures of normal.mod is at start and should be kept at sync
Index: kern/i386/pc/init.c
===================================================================
--- kern/i386/pc/init.c (revision 1998)
+++ kern/i386/pc/init.c (working copy)
@@ -149,9 +149,9 @@
#endif
/* Add the lower memory into free memory. */
- if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
+ /* if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
- grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
+ grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);*/
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
Index: efiemu/main.c
===================================================================
--- efiemu/main.c (revision 0)
+++ efiemu/main.c (revision 0)
@@ -0,0 +1,363 @@
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/lib/crc.h>
+
+/* These are function for loading and configuring EFI emulator*/
+
+grub_efi_system_table32_t *grub_efiemu_system_table32 = 0;
+grub_efi_system_table64_t *grub_efiemu_system_table64 = 0;
+
+struct grub_efiemu_configuration_table
+{
+ struct grub_efiemu_configuration_table *next;
+ grub_efi_guid_t guid;
+ void * (*get_table) (void *data);
+ void (*unload) (void *data);
+ void *data;
+};
+
+struct grub_efiemu_prepare_hook
+{
+ struct grub_efiemu_prepare_hook *next;
+ grub_err_t (*hook) (void *data);
+ void (*unload) (void *data);
+ void *data;
+};
+
+static struct grub_efiemu_prepare_hook *efiemu_prepare_hooks = 0;
+static struct grub_efiemu_configuration_table *efiemu_config_tables = 0;
+
+grub_err_t
+grub_efiemu_unload (void)
+{
+ struct grub_efiemu_configuration_table *cur, *d;
+ struct grub_efiemu_prepare_hook *curhook, *d2;
+ grub_efiemu_loadcore_unload ();
+
+ grub_efiemu_mm_unload ();
+
+ for (cur = efiemu_config_tables; cur;)
+ {
+ d = cur->next;
+ if (cur->unload)
+ cur->unload (cur->data);
+ grub_free (cur);
+ cur = d;
+ }
+ efiemu_config_tables = 0;
+
+ for (curhook = efiemu_prepare_hooks; curhook;)
+ {
+ d2 = curhook->next;
+ if (curhook->unload)
+ curhook->unload (curhook->data);
+ grub_free (curhook);
+ curhook = d2;
+ }
+ efiemu_prepare_hooks = 0;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_prepare (void)
+{
+ grub_err_t err;
+ int conftable_handle;
+ struct grub_efiemu_configuration_table *cur;
+ struct grub_efiemu_prepare_hook *curhook;
+
+ int cntconftables = 0;
+ grub_efiemu_configuration_table32_t *conftables32 = 0;
+
+ grub_dprintf ("efiemu", "Preparing EfiEmu\n");
+
+ for (cur = efiemu_config_tables; cur; cur = cur->next)
+ cntconftables++;
+
+ if (grub_arch_efiemu_sizeof_uintn_t () == 4)
+ {
+ conftable_handle
+ = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
+ cntconftables * sizeof (*conftables32),
+ GRUB_EFI_RUNTIME_SERVICES_DATA);
+
+ }
+ else
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "loading 64-bit efiemu isn't implemented yet");
+
+ grub_efiemu_alloc_syms ();
+
+ grub_efiemu_mm_do_alloc ();
+
+ grub_efiemu_system_table32 = 0;
+ grub_efiemu_system_table64 = 0;
+ grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
+ 8*grub_arch_efiemu_sizeof_uintn_t ());
+ if (grub_arch_efiemu_sizeof_uintn_t () == 4)
+ {
+ grub_efiemu_runtime_services32_t *runtime_services;
+ int i;
+ int handle;
+ grub_off_t off;
+
+ for (curhook = efiemu_prepare_hooks; curhook; curhook = curhook->next)
+ curhook->hook (curhook->data);
+
+ if ((err = grub_efiemu_loadcore_load ()))
+ {
+ grub_efiemu_unload ();
+ return err;
+ }
+
+ if ((err = grub_efiemu_resolve_symbol ("efiemu_system_table",
+ &handle, &off)))
+ return err;
+
+ grub_efiemu_system_table32 = (grub_efi_system_table32_t *)
+ ((grub_uint8_t *)grub_efiemu_mm_obtain_request (handle) + off);
+ grub_dprintf ("efiemu", "system_table = %p\n",
+ grub_efiemu_system_table32);
+
+
+ if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
+ &handle, &off)))
+ return err;
+ runtime_services = (grub_efiemu_runtime_services32_t *)
+ ((grub_uint8_t *)grub_efiemu_mm_obtain_request (handle) + off);
+ runtime_services->hdr.crc32 = 0;
+ runtime_services->hdr.crc32 = grub_getcrc32 (0, runtime_services,
+ sizeof (*runtime_services));
+
+
+ grub_efiemu_write_uint32
+ (&(grub_efiemu_system_table32->configuration_table), 0,
+ conftable_handle, 0, 1);
+ grub_efiemu_system_table32->num_table_entries = cntconftables;
+
+ conftables32 = (grub_efiemu_configuration_table32_t *)
+ grub_efiemu_mm_obtain_request (conftable_handle);
+ i = 0;
+ for (cur = efiemu_config_tables; cur; cur = cur->next, i++)
+ {
+ grub_memcpy (&(conftables32[i].vendor_guid), &(cur->guid),
+ sizeof (cur->guid));
+ if (cur->get_table)
+ conftables32[i].vendor_table
+ = PTR_TO_UINT32 (cur->get_table (cur->data));
+ else
+ conftables32[i].vendor_table = PTR_TO_UINT32 (cur->data);
+ }
+
+ grub_efiemu_system_table32->hdr.crc32 = 0;
+ grub_efiemu_system_table32->hdr.crc32
+ = grub_getcrc32 (0, grub_efiemu_system_table32,
+ sizeof (*grub_efiemu_system_table32));
+ grub_dprintf ("efiemu","system_table = %p, runtime_services = %p,"
+ " conftables = %p (%d entries)\n",
+ grub_efiemu_system_table32, runtime_services,
+ conftables32, cntconftables);
+ }
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid)
+{
+ struct grub_efiemu_configuration_table *cur, *prev;
+ while (efiemu_config_tables
+ && !grub_memcmp (&(efiemu_config_tables->guid), &guid, sizeof (guid)))
+ {
+ if (efiemu_config_tables->unload)
+ efiemu_config_tables->unload (efiemu_config_tables->data);
+ cur = efiemu_config_tables->next;
+ grub_free (efiemu_config_tables);
+ efiemu_config_tables = cur;
+ }
+ if (!efiemu_config_tables)
+ return GRUB_ERR_NONE;
+ for (prev = efiemu_config_tables, cur=prev->next;cur;)
+ if (!grub_memcmp (&(cur->guid),&guid, sizeof (guid)))
+ {
+ if (cur->unload)
+ cur->unload (cur->data);
+ prev->next = cur->next;
+ grub_free (cur);
+ cur = prev->next;
+ }
+ else
+ {
+ prev = cur;
+ cur = cur->next;
+ }
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+ void (*unload) (void *data),
+ void *data)
+{
+ struct grub_efiemu_prepare_hook *nhook;
+ if (!hook)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "you must set at least get_table or data");
+ nhook = (struct grub_efiemu_prepare_hook *) grub_malloc (sizeof (*nhook));
+ if (!nhook)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't prepare hook");
+ nhook->hook = hook;
+ nhook->unload = unload;
+ nhook->data = data;
+ nhook->next = efiemu_prepare_hooks;
+ efiemu_prepare_hooks = nhook;
+ return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+ void * (*get_table) (void *data),
+ void (*unload) (void *data),
+ void *data)
+{
+ struct grub_efiemu_configuration_table *tbl;
+ grub_err_t err;
+ grub_dprintf ("efiemu", "registering table %x\n",guid.data1);
+ if (!get_table && !data)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "you must set at least get_table or data");
+ if ((err = grub_efiemu_unregister_configuration_table (guid)))
+ return err;
+ tbl = (struct grub_efiemu_configuration_table *) grub_malloc (sizeof (*tbl));
+ if (!tbl)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register table");
+ tbl->guid = guid;
+ tbl->get_table = get_table;
+ tbl->unload = unload;
+ tbl->data = data;
+ tbl->next = efiemu_config_tables;
+ efiemu_config_tables = tbl;
+ return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_cmd_efiemu_unload (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ return grub_efiemu_unload ();
+}
+
+static grub_err_t
+grub_cmd_efiemu_prepare (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ return grub_efiemu_prepare ();
+}
+
+\f
+
+
+int
+grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
+ __attribute__ ((unused)))
+{
+ /* Nothing to do here yet */
+ return 1;
+}
+
+
+/* Load a module from the file FILENAME. */
+static grub_err_t
+grub_efiemu_load_file (const char *filename)
+{
+ grub_file_t file;
+ grub_err_t err;
+
+ file = grub_file_open (filename);
+ if (! file)
+ return 0;
+
+ grub_dprintf ("efiemu", "file opened\n");
+
+ err = grub_efiemu_mm_init ();
+ if (err)
+ {
+ grub_file_close (file);
+ grub_efiemu_unload ();
+ return grub_error (grub_errno, "Couldn't init memory management");
+ }
+
+ grub_dprintf ("efiemu", "mm inited\n");
+
+ if ((err = grub_efiemu_loadcore_init (file)))
+ {
+ grub_file_close (file);
+ grub_efiemu_unload ();
+ return err;
+ }
+
+ grub_file_close (file);
+
+ /* for configuration tables entry in system table*/
+ grub_efiemu_request_symbols (1);
+
+ return GRUB_ERR_NONE;
+}
+
+
+static grub_err_t
+grub_cmd_efiemu_load (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_err_t err;
+
+ grub_efiemu_unload ();
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
+
+ if ((err = grub_efiemu_load_file (args[0])))
+ return err;
+#ifndef GRUB_UTIL
+ if ((err = grub_machine_efiemu_init_tables ()))
+ return err;
+#endif
+ return GRUB_ERR_NONE;
+}
+
+
+GRUB_MOD_INIT(efiemu)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command ("efiemu_loadcore", grub_cmd_efiemu_load,
+ GRUB_COMMAND_FLAG_BOTH,
+ "efiemu_loadcore FILE",
+ "Load and initialize EFI emulator", 0);
+ grub_register_command ("efiemu_prepare", grub_cmd_efiemu_prepare,
+ GRUB_COMMAND_FLAG_BOTH,
+ "efiemu_prepare",
+ "Finalize loading of EFI emulator", 0);
+ grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
+ GRUB_COMMAND_FLAG_BOTH,
+ "efiemu_unload",
+ "Unload EFI emulator", 0);
+}
+
+GRUB_MOD_FINI(efiemu)
+{
+ grub_unregister_command ("efiemu_loadcore");
+ grub_unregister_command ("efiemu_prepare");
+ grub_unregister_command ("efiemu_unload");
+}
Property changes on: efiemu/main.c
___________________________________________________________________
Added: svn:mergeinfo
Index: efiemu/modules/pnvram.c
===================================================================
--- efiemu/modules/pnvram.c (revision 0)
+++ efiemu/modules/pnvram.c (revision 0)
@@ -0,0 +1,282 @@
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/lib/crc.h>
+
+struct efi_variable
+{
+ grub_efi_guid_t guid;
+ grub_uint32_t namelen;
+ grub_uint32_t size;
+ grub_efi_uint32_t attributes;
+} __attribute__ ((packed));
+
+static int nvram_handle = 0;
+static int nvramsize_handle = 0;
+static int high_monotonic_count_handle = 0;
+static grub_uint8_t *nvram;
+static grub_size_t nvramsize;
+static grub_dl_t my_mod;
+static grub_uint32_t high_monotonic_count;
+static const struct grub_arg_option options[] = {
+ {"size", 's', 0, "number of bytes to reserve for pseudo NVRAM", 0,
+ ARG_TYPE_INT},
+ {"high-monotonic-count", 'm', 0,
+ "Initial value of high monotonic count", 0, ARG_TYPE_INT},
+ {0, 0, 0, 0, 0, 0}
+};
+
+static grub_err_t
+nvram_set (void * data __attribute__ ((unused)))
+{
+
+ grub_uint8_t *nvram_def = grub_efiemu_mm_obtain_request (nvram_handle);
+ grub_uint32_t *nvramsize_def
+ = grub_efiemu_mm_obtain_request (nvramsize_handle);
+ grub_uint32_t *high_monotonic_count_def
+ = grub_efiemu_mm_obtain_request (high_monotonic_count_handle);
+ grub_dprintf ("efiemu", "preparing pnvram\n");
+ grub_memcpy (nvram_def, nvram, nvramsize);
+ *nvramsize_def = nvramsize;
+ *high_monotonic_count_def = high_monotonic_count;
+ grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0);
+ grub_efiemu_register_symbol ("efiemu_varsize", nvramsize_handle, 0);
+ grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
+ high_monotonic_count_handle, 0);
+ return GRUB_ERR_NONE;
+}
+
+static void
+nvram_unload (void * data __attribute__ ((unused)))
+{
+ grub_efiemu_mm_return_request (nvram_handle);
+ grub_efiemu_mm_return_request (nvramsize_handle);
+ grub_free (nvram);
+ nvram = 0;
+}
+
+/* guid:attr:name:data;*/
+static grub_err_t
+read_pnvram (char *filename)
+{
+ char *buf, *end, *ptr, *ptr2;
+ grub_file_t file;
+ grub_size_t size;
+ grub_uint8_t *nvramptr = nvram;
+ struct efi_variable *efivar;
+ grub_size_t guidlen, datalen;
+ unsigned i, j;
+
+ file = grub_file_open (filename);
+ if (!file)
+ return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram");
+ size = grub_file_size (file);
+ buf = grub_malloc (size + 1);
+ if (!buf)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read pnvram");
+ if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
+ return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram");
+ buf[size] = 0;
+ grub_file_close (file);
+ end = buf + size;
+ for (ptr = buf; *ptr; )
+ {
+ if (grub_isspace (*ptr))
+ {
+ ptr++;
+ continue;
+ }
+
+ efivar = (struct efi_variable *) nvramptr;
+ if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "file is too large for reserved variable space");
+
+ nvramptr += sizeof (struct efi_variable);
+
+ guidlen = 0;
+
+ for (ptr2 = ptr; (grub_isspace (*ptr2)
+ || (*ptr2 >= '0' && *ptr2 <= '9')
+ || (*ptr2 >= 'a' && *ptr2 <= 'f')
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ ptr2++)
+ if (!grub_isspace (*ptr2))
+ guidlen++;
+ guidlen /= 2;
+ if (guidlen != sizeof (efivar->guid))
+ {
+ grub_free (buf);
+ return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+ }
+ for (i = 0; i < 2 * sizeof (efivar->guid); i++)
+ {
+ int hex = 0;
+ while (grub_isspace (*ptr))
+ ptr++;
+ if (*ptr >= '0' && *ptr <= '9')
+ hex = *ptr - '0';
+ if (*ptr >= 'a' && *ptr <= 'f')
+ hex = *ptr - 'a' + 10;
+ if (*ptr >= 'A' && *ptr <= 'F')
+ hex = *ptr - 'A' + 10;
+
+ if (i%2 == 0)
+ ((grub_uint8_t *)&(efivar->guid))[i/2] = hex << 4;
+ else
+ ((grub_uint8_t *)&(efivar->guid))[i/2] |= hex;
+ ptr++;
+ }
+
+ while (grub_isspace (*ptr))
+ ptr++;
+ if (*ptr != ':')
+ {
+ grub_dprintf ("efiemu", "Not colon\n");
+ grub_free (buf);
+ return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+ }
+ ptr++;
+ while (grub_isspace (*ptr))
+ ptr++;
+ efivar->attributes = grub_strtoul (ptr, &ptr, 16);
+
+ while (grub_isspace (*ptr))
+ ptr++;
+ if (*ptr != ':')
+ {
+ grub_dprintf ("efiemu", "Not colon\n");
+ grub_free (buf);
+ return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+ }
+ ptr++;
+ while (grub_isspace (*ptr))
+ ptr++;
+
+ for (j = 0; j < 2; j++)
+ {
+ datalen = 0;
+ for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
+ || (*ptr2 >= '0' && *ptr2 <= '9')
+ || (*ptr2 >= 'a' && *ptr2 <= 'f')
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ ptr2++)
+ if (!grub_isspace (*ptr2))
+ datalen++;
+ datalen /= 2;
+ if (nvramptr - nvram + datalen > nvramsize)
+ {
+ grub_free (buf);
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "file is too large for reserved "
+ " variable space");
+ }
+
+ for (i = 0; i < 2*datalen; i++)
+ {
+ int hex = 0;
+ while (grub_isspace (*ptr))
+ ptr++;
+ if (*ptr >= '0' && *ptr <= '9')
+ hex = *ptr - '0';
+ if (*ptr >= 'a' && *ptr <= 'f')
+ hex = *ptr - 'a' + 10;
+ if (*ptr >= 'A' && *ptr <= 'F')
+ hex = *ptr - 'A' + 10;
+
+ if (i%2 == 0)
+ nvramptr[i/2] = hex << 4;
+ else
+ nvramptr[i/2] |= hex;
+ ptr++;
+ }
+ nvramptr += datalen;
+ while (grub_isspace (*ptr))
+ ptr++;
+ if (*ptr != (j ? ';' : ':'))
+ {
+ grub_free (buf);
+ grub_dprintf ("efiemu", j?"Not semicolon\n":"Not colon\n");
+ return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
+ }
+ if (j)
+ efivar->size = datalen;
+ else
+ efivar->namelen = datalen;
+
+ ptr++;
+ }
+ }
+ grub_free (buf);
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_efiemu_pnvram (struct grub_arg_list *state,
+ int argc, char **args)
+{
+ grub_err_t err;
+
+ if (argc > 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one argument expected");
+
+ nvramsize = state[0].set ? grub_strtoul (state[0].arg, 0, 0) : 2048;
+ high_monotonic_count = state[1].set ? grub_strtoul (state[1].arg, 0, 0) : 1;
+
+ nvram = grub_malloc (nvramsize);
+ if (!nvram)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Couldn't allocate space for temporary pnvram storage");
+ grub_memset (nvram, 0, nvramsize);
+
+ if (argc == 1 && (err = read_pnvram (args[0])))
+ {
+ grub_free (nvram);
+ return err;
+ }
+
+ if ((err = grub_efiemu_register_prepare_hook (nvram_set, nvram_unload, 0)))
+ {
+ grub_free (nvram);
+ return err;
+ }
+ nvram_handle
+ = grub_efiemu_request_memalign (1, nvramsize,
+ GRUB_EFI_RUNTIME_SERVICES_DATA);
+ nvramsize_handle
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+ GRUB_EFI_RUNTIME_SERVICES_DATA);
+ high_monotonic_count_handle
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+ GRUB_EFI_RUNTIME_SERVICES_DATA);
+ grub_efiemu_request_symbols (3);
+#ifndef GRUB_UTIL
+ grub_dl_ref (my_mod);
+#endif
+ return GRUB_ERR_NONE;
+}
+
+
+
+GRUB_MOD_INIT(efiemu_pnvram)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command ("efiemu_pnvram", grub_cmd_efiemu_pnvram,
+ GRUB_COMMAND_FLAG_BOTH,
+ "efiemu_pnvram [FILENAME]",
+ "Initialise pseudo-NVRAM and load variables from FILE",
+ options);
+ my_mod=mod;
+}
+
+GRUB_MOD_FINI(efiemu_pnvram)
+{
+ grub_unregister_command ("efiemu_pnvram");
+}
Property changes on: efiemu/modules/pnvram.c
___________________________________________________________________
Added: svn:mergeinfo
Index: efiemu/modules/i386/pc/acpi.c
===================================================================
--- efiemu/modules/i386/pc/acpi.c (revision 0)
+++ efiemu/modules/i386/pc/acpi.c (revision 0)
@@ -0,0 +1,35 @@
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/acpi.h>
+
+struct grub_acpi_rsdp_v10 *
+grub_machine_efiemu_get_rsdp (void)
+{
+ int ebda_len;
+ grub_uint8_t *ptr;
+
+ grub_dprintf ("efiemu", "Looking for RSDP. Scanning EBDA\n");
+
+ ebda_len = 1024 * (*((grub_uint8_t *)0x40e));
+ for (ptr = (grub_uint8_t *)0x410; ptr < (grub_uint8_t *)(0x410 + ebda_len);
+ ptr += 16)
+ if (!grub_memcmp (ptr, "RSD PTR ", 8)
+ && grub_efiemu_acpi_checksum (ptr,
+ sizeof (struct grub_acpi_rsdp_v10)) == 0)
+ return (struct grub_acpi_rsdp_v10 *) ptr;
+
+ grub_dprintf ("efiemu", "Looking for RSDP. Scanning BIOS\n");
+ for (ptr=(grub_uint8_t *)0xe0000;ptr<(grub_uint8_t *)0x100000;ptr+=16)
+ if (!grub_memcmp (ptr, "RSD PTR ", 8)
+ && grub_efiemu_acpi_checksum (ptr,
+ sizeof (struct grub_acpi_rsdp_v10)) == 0)
+ return (struct grub_acpi_rsdp_v10 *) ptr;
+ return 0;
+}
Index: efiemu/modules/acpi.c
===================================================================
--- efiemu/modules/acpi.c (revision 0)
+++ efiemu/modules/acpi.c (revision 0)
@@ -0,0 +1,514 @@
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/arg.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/gzio.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/efiemu/acpi.h>
+#include <grub/mm.h>
+
+
+static const struct grub_arg_option options[] = {
+ {"exclude", 'x', 0,
+ "Don't load host tables specified by comma-separated list",
+ 0, ARG_TYPE_STRING},
+ {"load-only", 'n', 0,
+ "Load only tables specified by comma-separated list", 0, ARG_TYPE_STRING},
+ {"v1", '1', 0, "Expose v1 tables", 0, ARG_TYPE_NONE},
+ {"v2", '2', 0, "Expose v2 and v3 tables", 0, ARG_TYPE_NONE},
+ {"oemid", 'o', 0, "Set OEMID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+ {"oemtable", 't', 0,
+ "Set OEMTABLE ID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+ {"oemtablerev", 'r', 0,
+ "Set OEMTABLE revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+ {"oemtablecreator", 'c', 0,
+ "Set creator field of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+ {"oemtablecreatorrev", 'd', 0,
+ "Set creator revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+ {0, 0, 0, 0, 0, 0}
+};
+
+static int rev1, rev2;
+static grub_dl_t my_mod;
+static char root_oemid[6];
+static char root_oemtable[8];
+static grub_uint32_t root_oemrev;
+static char root_creator_id[4];
+static grub_uint32_t root_creator_rev;
+
+struct efiemu_acpi_table
+{
+ void *data;
+ void *addr;
+ grub_size_t size;
+ int alloc_handle;
+ struct efiemu_acpi_table *next;
+};
+
+static struct efiemu_acpi_table *acpi_tables = 0;
+/* DSDT isn't in RSDT. So treat it specially */
+static void *table_dsdt = 0;
+static void *rsdt_addr = 0;
+static int dsdt_alloc_handle = 0;
+static grub_size_t dsdt_size = 0;
+static grub_uint32_t facs_addr = 0;
+static int rsdpv1_alloc_handle = 0;
+static int rsdpv2_alloc_handle = 0;
+static int rsdt_alloc_handle = 0;
+static int xsdt_alloc_handle = 0;
+static int tables_set = 0;
+static int locked = 0;
+
+grub_uint8_t
+grub_efiemu_acpi_checksum (void *base, grub_size_t size)
+{
+ grub_uint8_t *ptr;
+ grub_uint8_t ret = 0;
+ for (ptr = (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size;
+ ptr++)
+ ret += *ptr;
+ return ret;
+}
+
+static void
+grub_efiemu_acpi_clear (void)
+{
+ static struct efiemu_acpi_table *cur, *d;
+ for (cur = acpi_tables; cur; )
+ {
+ grub_free (cur->data);
+ d = cur->next;
+ grub_free (cur);
+ cur = d;
+ }
+
+ acpi_tables = 0;
+ grub_free (table_dsdt);
+ table_dsdt = 0;
+ dsdt_size = 0;
+ dsdt_alloc_handle = 0;
+ rev1 = rev2 = 0;
+
+ grub_efiemu_mm_return_request (dsdt_alloc_handle);
+ grub_efiemu_mm_return_request (rsdpv1_alloc_handle);
+ grub_efiemu_mm_return_request (rsdpv2_alloc_handle);
+ grub_efiemu_mm_return_request (rsdt_alloc_handle);
+ grub_efiemu_mm_return_request (xsdt_alloc_handle);
+
+ dsdt_alloc_handle = 0;
+ rsdpv1_alloc_handle = 0;
+ rsdpv2_alloc_handle = 0;
+ rsdt_alloc_handle = 0;
+ xsdt_alloc_handle = 0;
+
+ tables_set = 0;
+ rsdt_addr = 0;
+
+ if (locked)
+ grub_dl_unref (my_mod);
+
+}
+
+static void
+unloadv1table (void *data __attribute__ ((unused)))
+{
+ rev1 = 0;
+ grub_efiemu_mm_return_request (rsdpv1_alloc_handle);
+ rsdpv1_alloc_handle = 0;
+ if (!rev2)
+ grub_efiemu_acpi_clear ();
+}
+
+static void
+unloadv2table (void *data __attribute__ ((unused)))
+{
+ rev2 = 0;
+ grub_efiemu_mm_return_request (rsdpv2_alloc_handle);
+ grub_efiemu_mm_return_request (xsdt_alloc_handle);
+ rsdpv2_alloc_handle = 0;
+ xsdt_alloc_handle = 0;
+
+ if (!rev1)
+ grub_efiemu_acpi_clear ();
+}
+
+static void
+setup_common_tables (void)
+{
+ struct efiemu_acpi_table *cur;
+ void *dest;
+ void *dsdt_addr = 0;
+ struct grub_acpi_table_header *rsdt;
+ grub_uint32_t *rsdt_entry;
+ int numoftables;
+
+ if (tables_set)
+ return;
+ if (table_dsdt)
+ {
+ dsdt_addr = grub_efiemu_mm_obtain_request (dsdt_alloc_handle);
+ grub_memcpy (dsdt_addr, table_dsdt, dsdt_size);
+ }
+ for (cur = acpi_tables; cur; cur = cur->next)
+ {
+ struct grub_acpi_fadt *fadt;
+ cur->addr = dest = grub_efiemu_mm_obtain_request (cur->alloc_handle);
+ grub_memcpy (dest, cur->data, cur->size);
+ fadt = (struct grub_acpi_fadt *) dest;
+ if (!grub_memcmp (fadt->hdr.signature, "FACP", 4))
+ {
+ fadt->dsdt_addr = PTR_TO_UINT32 (dsdt_addr);
+ /* Does a revision 2 exist at all? */
+ if (fadt->hdr.revision >= 3)
+ fadt->dsdt_xaddr = PTR_TO_UINT64 (dsdt_addr);
+ fadt->hdr.checksum = 0;
+ fadt->hdr.checksum = 1 + ~grub_efiemu_acpi_checksum
+ (fadt, fadt->hdr.length);
+ }
+ }
+ rsdt_addr = rsdt = (struct grub_acpi_table_header *)
+ grub_efiemu_mm_obtain_request (rsdt_alloc_handle);
+ rsdt_entry = (grub_uint32_t *)(rsdt + 1);
+ numoftables = 0;
+ for (cur = acpi_tables; cur; cur = cur->next)
+ {
+ *(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
+ numoftables++;
+ }
+ grub_memcpy (&(rsdt->signature), "RSDT", 4);
+ rsdt->length = sizeof (struct grub_acpi_table_header) + 4 * numoftables;
+ rsdt->revision = 1;
+ grub_memcpy (&(rsdt->oemid), root_oemid, 6);
+ grub_memcpy (&(rsdt->oemtable), root_oemtable, 4);
+ rsdt->oemrev = root_oemrev;
+ grub_memcpy (&(rsdt->creator_id), root_creator_id, 6);
+ rsdt->creator_rev = root_creator_rev;
+
+ rsdt->checksum = 0;
+ rsdt->checksum = 1 + ~grub_efiemu_acpi_checksum (rsdt, rsdt->length);
+}
+
+static void *
+getv1table (void *data __attribute__ ((unused)))
+{
+ struct grub_acpi_rsdp_v10 *rsdp;
+ grub_dprintf ("efiemu", "Generating common tables\n");
+ setup_common_tables ();
+ grub_dprintf ("efiemu", "Generating ACPIv1 tables\n");
+ rsdp = (struct grub_acpi_rsdp_v10 *)
+ grub_efiemu_mm_obtain_request (rsdpv1_alloc_handle);
+ grub_memcpy (&(rsdp->signature), "RSD PTR ", 8);
+ grub_memcpy (&(rsdp->oemid), root_oemid, sizeof (rsdp->oemid));
+ rsdp->revision = 0;
+ rsdp->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+ rsdp->checksum = 0;
+ rsdp->checksum = 1 + ~grub_efiemu_acpi_checksum (rsdp,
+ sizeof (*rsdp));
+ grub_dprintf ("efiemu", "Generated ACPIv1 tables\n");
+
+ return rsdp;
+}
+
+static void *
+getv2table (void *data __attribute__ ((unused)))
+{
+ struct grub_acpi_rsdp_v20 *rsdp;
+ struct grub_acpi_table_header *xsdt;
+ struct efiemu_acpi_table *cur;
+ grub_uint64_t *xsdt_entry;
+ int numoftables;
+ grub_dprintf ("efiemu", "Generating common tables\n");
+ setup_common_tables ();
+ grub_dprintf ("efiemu", "Generating ACPIv2 tables\n");
+ xsdt = (struct grub_acpi_table_header *)
+ grub_efiemu_mm_obtain_request (xsdt_alloc_handle);
+ xsdt_entry = (grub_uint64_t *)(xsdt + 1);
+ numoftables = 0;
+ for (cur = acpi_tables; cur; cur = cur->next)
+ {
+ *(xsdt_entry++) = PTR_TO_UINT64 (cur->addr);
+ numoftables++;
+ }
+ grub_memcpy (&(xsdt->signature), "XSDT", 4);
+ xsdt->length = sizeof (struct grub_acpi_table_header) + 8 * numoftables;
+ xsdt->revision = 1;
+ grub_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid));
+ grub_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable));
+ xsdt->oemrev = root_oemrev;
+ grub_memcpy (&(xsdt->creator_id), root_creator_id, sizeof (xsdt->creator_id));
+ xsdt->creator_rev = root_creator_rev;
+ xsdt->checksum = 0;
+ xsdt->checksum = 1 + ~grub_efiemu_acpi_checksum (xsdt, xsdt->length);
+
+ rsdp = (struct grub_acpi_rsdp_v20 *)
+ grub_efiemu_mm_obtain_request (rsdpv2_alloc_handle);
+ grub_memcpy (&(rsdp->rsdpv1.signature), "RSD PTR ",
+ sizeof (rsdp->rsdpv1.signature));
+ grub_memcpy (&(rsdp->rsdpv1.oemid), root_oemid, sizeof (rsdp->rsdpv1.oemid));
+ rsdp->rsdpv1.revision = rev2;
+ rsdp->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
+ rsdp->rsdpv1.checksum = 0;
+ rsdp->rsdpv1.checksum = 1 + ~grub_efiemu_acpi_checksum
+ (&(rsdp->rsdpv1), sizeof (rsdp->rsdpv1));
+ rsdp->length = sizeof (*rsdp);
+ rsdp->xsdt_addr = PTR_TO_UINT64 (xsdt);
+ rsdp->checksum = 0;
+ rsdp->checksum = 1 + ~grub_efiemu_acpi_checksum (rsdp, rsdp->length);
+ grub_dprintf ("efiemu", "Generated ACPIv2 tables\n");
+
+ return rsdp;
+}
+
+static grub_err_t
+grub_cmd_efiemu_acpi (struct grub_arg_list *state,
+ int argc, char **args)
+{
+ grub_efi_guid_t acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
+ grub_efi_guid_t acpi = GRUB_EFI_ACPI_TABLE_GUID;
+ struct grub_acpi_rsdp_v10 *rsdp;
+ int i;
+ int numtables;
+
+ grub_efiemu_unregister_configuration_table (acpi);
+
+ grub_efiemu_acpi_clear ();
+
+ rev1 = 1;
+ rev2 = 3;
+
+ rsdp = grub_machine_efiemu_get_rsdp ();
+
+ if (rsdp)
+ {
+ grub_uint32_t *entry_ptr;
+ char *exclude = 0;
+ char *load_only = 0;
+ char *ptr;
+ /* RSDT consists of header and an array of 32-bit pointers */
+ struct grub_acpi_table_header *rsdt;
+
+ exclude = state[0].set ? grub_strdup (state[0].arg) : 0;
+
+ if (exclude)
+ {
+ for (ptr = exclude; ptr; ptr++)
+ *ptr = grub_tolower (*ptr);
+ }
+
+ load_only = state[1].set ? grub_strdup (state[1].arg) : 0;
+ if (load_only)
+ {
+ for (ptr = load_only; ptr; ptr++)
+ *ptr = grub_tolower (*ptr);
+ }
+
+ rev1 = !rsdp->revision;
+ rev2 = rsdp->revision;
+ rsdt = (struct grub_acpi_table_header *)(rsdp->rsdt_addr);
+ for (entry_ptr = (grub_uint32_t *)(rsdt + 1);
+ entry_ptr < (grub_uint32_t *)(((grub_uint8_t *) rsdt)+rsdt->length);
+ entry_ptr++)
+ {
+ char signature[5];
+ struct efiemu_acpi_table *table;
+ struct grub_acpi_table_header *curtable
+ = (struct grub_acpi_table_header *)*entry_ptr;
+ signature[4] = 0;
+ for (i = 0; i < 4;i++)
+ signature[i] = grub_tolower (curtable->signature[i]);
+
+ if (!grub_strcmp (signature, "facp"))
+ {
+ struct grub_acpi_table_header *dsdt;
+ struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
+
+ dsdt = (struct grub_acpi_table_header *) fadt->dsdt_addr;
+ grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
+ sizeof (root_oemid));
+ grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
+ sizeof (root_oemtable));
+ root_oemrev = fadt->hdr.oemrev;
+ grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
+ sizeof (root_creator_id));
+ root_creator_rev = fadt->hdr.creator_rev;
+
+ if (dsdt && (!exclude || !grub_strword (exclude, "dsdt"))
+ && (!load_only || grub_strword (load_only, "dsdt"))
+ && dsdt->length >= sizeof (*dsdt))
+ {
+ dsdt_size = dsdt->length;
+ table_dsdt = grub_malloc (dsdt->length);
+ if (!table_dsdt)
+ {
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Could allocate table");
+ }
+ grub_memcpy (table_dsdt, dsdt, dsdt->length);
+ }
+ facs_addr = ((struct grub_acpi_fadt *) entry_ptr)->facs_addr;
+ }
+
+ if (exclude && grub_strword (exclude, signature))
+ continue;
+ if (load_only && !grub_strword (load_only, signature))
+ continue;
+
+ if (curtable->length < sizeof (*curtable))
+ continue;
+
+ table = (struct efiemu_acpi_table *) grub_malloc
+ (sizeof (struct efiemu_acpi_table));
+ if (!table)
+ {
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Could allocate table structure");
+ }
+ table->size = curtable->length;
+ table->data = grub_malloc (table->size);
+ if (!table->data)
+ {
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Could allocate table");
+ }
+ table->alloc_handle = 0;
+ table->next = acpi_tables;
+ acpi_tables = table;
+ grub_memcpy (table->data, curtable, table->size);
+ }
+ grub_free (exclude);
+ grub_free (load_only);
+ }
+ if (state[2].set || state[3].set)
+ {
+ rev1 = state[2].set;
+ if (state[3].set)
+ rev2 = rev2 ? : 2;
+ else
+ rev2 = 0;
+ }
+
+ if (state[4].set)
+ grub_strncpy (root_oemid, state[4].arg, sizeof (root_oemid));
+ if (state[5].set)
+ grub_strncpy (root_oemtable, state[5].arg, sizeof (root_oemtable));
+ if (state[6].set)
+ root_oemrev = grub_strtoul (state[6].arg, 0, 0);
+ if (state[7].set)
+ grub_strncpy (root_creator_id, state[7].arg, sizeof (root_creator_id));
+ if (state[8].set)
+ root_creator_rev = grub_strtoul (state[8].arg, 0, 0);
+
+ for (i = 0; i < argc; i++)
+ {
+ grub_file_t file;
+ grub_size_t size;
+ char *buf;
+ file = grub_gzfile_open (args[i], 1);
+ if (!file)
+ {
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_BAD_OS, "couldn't open file %s", args[i]);
+ }
+ size = grub_file_size (file);
+ if (size < sizeof (struct grub_acpi_table_header))
+ {
+ grub_file_close (file);
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_BAD_OS, "file %s is too small", args[i]);
+ }
+ buf = (char *) grub_malloc (size);
+ if (grub_file_read (file, buf, size) != (int) size)
+ {
+ grub_file_close (file);
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]);
+ }
+ grub_file_close (file);
+ if (!grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
+ "DSDT", 4))
+ {
+ grub_free (table_dsdt);
+ table_dsdt = buf;
+ dsdt_size = size;
+ }
+ else
+ {
+ struct efiemu_acpi_table *table;
+ table = (struct efiemu_acpi_table *) grub_malloc
+ (sizeof (struct efiemu_acpi_table));
+ if (!table)
+ {
+ grub_efiemu_acpi_clear ();
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Could allocate table structure");
+ }
+ table->alloc_handle = 0;
+ table->size = size;
+ table->data = buf;
+ }
+ }
+
+ numtables = 0;
+ {
+ struct efiemu_acpi_table *cur;
+ for (cur = acpi_tables; cur; cur = cur->next)
+ {
+ cur->alloc_handle = grub_efiemu_request_memalign
+ (1, cur->size, GRUB_EFI_ACPI_RECLAIM_MEMORY);
+ numtables++;
+ }
+ }
+
+
+ rsdt_alloc_handle = grub_efiemu_request_memalign
+ (1, sizeof (struct grub_acpi_table_header)+4*numtables,
+ GRUB_EFI_ACPI_RECLAIM_MEMORY);
+
+ if (rev1)
+ {
+ rsdpv1_alloc_handle = grub_efiemu_request_memalign
+ (1, sizeof (struct grub_acpi_rsdp_v10),
+ GRUB_EFI_ACPI_RECLAIM_MEMORY);
+ grub_efiemu_register_configuration_table (acpi, getv1table,
+ unloadv1table, 0);
+ }
+
+ if (rev2)
+ {
+ rsdpv2_alloc_handle = grub_efiemu_request_memalign
+ (1, sizeof (struct grub_acpi_rsdp_v20),
+ GRUB_EFI_ACPI_RECLAIM_MEMORY);
+ xsdt_alloc_handle = grub_efiemu_request_memalign
+ (1, sizeof (struct grub_acpi_table_header)+8*numtables,
+ GRUB_EFI_ACPI_RECLAIM_MEMORY);
+ grub_efiemu_register_configuration_table (acpi20, getv2table,
+ unloadv2table, 0);
+ }
+ if (dsdt_size)
+ dsdt_alloc_handle = grub_efiemu_request_memalign
+ (1, dsdt_size, GRUB_EFI_ACPI_RECLAIM_MEMORY);
+ grub_dl_ref (my_mod);
+ return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT(efiemu_acpi)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command ("efiemu_acpi", grub_cmd_efiemu_acpi,
+ GRUB_COMMAND_FLAG_BOTH,
+ "efiemu_acpi [-1|-2] [--exclude=table1,table2|--load-only=table1,table2] filename1 [filename2] [...]",
+ "Load host acpi tables and tables specified by arguments",
+ options);
+ my_mod=mod;
+}
+
+GRUB_MOD_FINI(efiemu_acpi)
+{
+ grub_unregister_command ("efiemu_acpi");
+}
Index: efiemu/loadcore.c
===================================================================
--- efiemu/loadcore.c (revision 0)
+++ efiemu/loadcore.c (revision 0)
@@ -0,0 +1,544 @@
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/elf.h>
+
+struct grub_efiemu_ptv_rel
+{
+ grub_uint64_t addr;
+ grub_efi_memory_type_t plustype;
+ grub_efi_memory_type_t minustype;
+ grub_uint32_t size;
+} __attribute__ ((packed));
+
+struct grub_efiemu_sym
+{
+ struct grub_efiemu_sym *next;
+ char *name;
+ int handle;
+ grub_off_t off;
+};
+struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0;
+int grub_efiemu_nelfsyms = 0;
+static struct grub_efiemu_sym *efiemu_syms = 0;
+static grub_efiemu_segment_t efiemu_segments = 0;
+static grub_ssize_t efiemu_core_size;
+static void *efiemu_core = 0;
+grub_efiemu_mode_t grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+static int ptv_written = 0;
+static int ptv_alloc = 0;
+static int ptv_handle = 0;
+static int ptv_requested = 0;
+static int grub_efiemu_unload_segs (grub_efiemu_segment_t seg);
+static void grub_efiemu_free_syms (void);
+
+static void
+grub_efiemu_free_syms (void)
+{
+ struct grub_efiemu_sym *cur, *d;
+ for (cur = efiemu_syms; cur;)
+ {
+ d = cur->next;
+ grub_free (cur->name);
+ grub_free (cur);
+ cur = d;
+ }
+ efiemu_syms = 0;
+}
+
+grub_err_t
+grub_efiemu_request_symbols (int num)
+{
+ if (ptv_alloc)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "symbols have already been allocated");
+ if (num < 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't request negative symbols");
+ ptv_requested += num;
+ return GRUB_ERR_NONE;
+}
+
+/* Resolve the symbol name NAME and return the address.
+ Return NULL, if not found. */
+grub_err_t
+grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off)
+{
+ struct grub_efiemu_sym *cur;
+ grub_dprintf ("efiemu", "looking for %s\n", name);
+ for (cur = efiemu_syms; cur; cur = cur->next)
+ if (!grub_strcmp (name, cur->name))
+ {
+ *handle = cur->handle;
+ *off = cur->off;
+ return GRUB_ERR_NONE;
+ }
+ grub_dprintf ("efiemu", "%s not found\n", name);
+ return grub_error (GRUB_ERR_BAD_OS, "symbol %s isn't found", name);
+}
+
+grub_err_t
+grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off)
+{
+ struct grub_efiemu_sym *cur;
+ cur = (struct grub_efiemu_sym *) grub_malloc (sizeof (*cur));
+ grub_dprintf ("efiemu", "registering %s\n", name);
+ if (!cur)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't register symbol");
+ cur->name = grub_strdup (name);
+ cur->next = efiemu_syms;
+ cur->handle = handle;
+ cur->off = off;
+ efiemu_syms = cur;
+
+ return 0;
+}
+
+grub_err_t
+grub_efiemu_write_uint32 (void * addr, grub_uint32_t value, int plus_handle,
+ int minus_handle, int ptv_needed)
+{
+ struct grub_efiemu_ptv_rel *ptv_rels
+ = grub_efiemu_mm_obtain_request (ptv_handle);
+ if (ptv_needed && ptv_written >= ptv_alloc)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "your module didn't declare efiemu symbols correctly");
+ if (ptv_needed)
+ {
+ if (minus_handle)
+ ptv_rels[ptv_written].minustype
+ = grub_efiemu_mm_get_type (minus_handle);
+ else
+ ptv_rels[ptv_written].minustype = 0;
+
+ if (plus_handle)
+ ptv_rels[ptv_written].plustype
+ = grub_efiemu_mm_get_type (plus_handle);
+ else
+ ptv_rels[ptv_written].plustype = 0;
+
+ ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
+ ptv_rels[ptv_written].size = sizeof (grub_uint32_t);
+ ptv_written++;
+ grub_memset (&ptv_rels[ptv_written], 0, sizeof (ptv_rels[ptv_written]));
+ }
+
+ if (minus_handle)
+ value -= PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (minus_handle));
+ else
+ ptv_rels[ptv_written].minustype = 0;
+
+ if (plus_handle)
+ value += PTR_TO_UINT32 (grub_efiemu_mm_obtain_request (plus_handle));
+ else
+ ptv_rels[ptv_written].plustype = 0;
+
+ *((grub_uint32_t *) addr) = value;
+
+ return GRUB_ERR_NONE;
+}
+
+/* Return the address of a section whose index is N. */
+static grub_err_t
+grub_efiemu_get_section_addr (grub_efiemu_segment_t segs, unsigned n,
+ int *handle, grub_off_t *off)
+{
+ grub_efiemu_segment_t seg;
+
+ for (seg = segs; seg; seg = seg->next)
+ if (seg->section == n)
+ {
+ *handle = seg->handle;
+ *off = seg->off;
+ return GRUB_ERR_NONE;
+ }
+
+ return grub_error (GRUB_ERR_BAD_OS, "section %d not found", n);
+}
+
+/* Check if EHDR is a valid ELF header. */
+static grub_err_t
+grub_efiemu_check_header (void *ehdr, grub_size_t size)
+{
+ Elf32_Ehdr *e = ehdr;
+
+ /* Check the header size. */
+ if (size < sizeof (Elf32_Ehdr))
+ return grub_error (GRUB_ERR_BAD_OS, "ELF header smaller than expected");
+
+ /* Check the magic numbers. */
+ if (grub_arch_efiemu_check_header (ehdr, &grub_efiemu_mode)
+ || e->e_ident[EI_MAG0] != ELFMAG0
+ || e->e_ident[EI_MAG1] != ELFMAG1
+ || e->e_ident[EI_MAG2] != ELFMAG2
+ || e->e_ident[EI_MAG3] != ELFMAG3
+ || e->e_ident[EI_VERSION] != EV_CURRENT
+ || e->e_version != EV_CURRENT)
+ return grub_error (GRUB_ERR_BAD_OS, "invalid arch independent ELF magic");
+
+ return GRUB_ERR_NONE;
+}
+
+/* Load all segments from memory specified by E. */
+static grub_err_t
+grub_efiemu_load_segments32 (grub_efiemu_segment_t segs, const Elf32_Ehdr *e)
+{
+ Elf32_Shdr *s;
+ grub_efiemu_segment_t cur;
+
+ grub_dprintf ("efiemu", "loading segments\n");
+
+ for (cur=segs; cur; cur = cur->next)
+ {
+ s = (Elf32_Shdr *)cur->srcptr;
+
+ if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
+ {
+ void *addr;
+
+ addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
+ + cur->off;
+
+ switch (s->sh_type)
+ {
+ case SHT_PROGBITS:
+ grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+ break;
+ case SHT_NOBITS:
+ grub_memset (addr, 0, s->sh_size);
+ break;
+ }
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static char *
+grub_efiemu_get_string32 (unsigned offset, const Elf32_Ehdr *e)
+{
+ unsigned i;
+ Elf32_Shdr *s;
+
+ for (i = 0, s = (Elf32_Shdr *)((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *)((char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
+ {
+ grub_dprintf ("efiemu", "string:%s\n", (char *) e + s->sh_offset + offset);
+ return (char *) e + s->sh_offset + offset;
+ }
+ return 0;
+}
+
+static grub_err_t
+grub_efiemu_init_segments32 (grub_efiemu_segment_t *segs, const Elf32_Ehdr *e)
+{
+ unsigned i;
+ Elf32_Shdr *s;
+
+ grub_dprintf ("efiemu", "allocating segments\n");
+
+ for (i = 0, s = (Elf32_Shdr *)((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *)((char *) s + e->e_shentsize))
+ {
+ if (s->sh_flags & SHF_ALLOC)
+ {
+ grub_efiemu_segment_t seg;
+ grub_dprintf ("efiemu", "section %d, %d\n", i, s->sh_size);
+ seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
+ if (! seg)
+ return grub_errno;
+
+ if (s->sh_size)
+ {
+ seg->handle
+ = grub_efiemu_request_memalign
+ (s->sh_addralign, s->sh_size,
+ s->sh_flags & SHF_EXECINSTR?GRUB_EFI_RUNTIME_SERVICES_CODE
+ :GRUB_EFI_RUNTIME_SERVICES_DATA);
+ if (seg->handle < 0)
+ return grub_errno;
+ seg->off = 0;
+ }
+
+ if (!grub_strcmp (grub_efiemu_get_string32 (s->sh_name, e),
+ ".text-physical"))
+ seg->ptv_rel_needed = 0;
+ else
+ seg->ptv_rel_needed = 1;
+ seg->size = s->sh_size;
+ seg->section = i;
+ seg->next = *segs;
+ seg->srcptr = s;
+ *segs = seg;
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efiemu_count_symbols32 (const Elf32_Ehdr *e)
+{
+ unsigned i;
+ Elf32_Shdr *s;
+ int num = 0;
+
+ grub_dprintf ("efiemu", "counting symbols\n");
+
+ for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_SYMTAB)
+ break;
+
+ if (i == e->e_shnum)
+ return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+ grub_efiemu_nelfsyms = s->sh_size / s->sh_entsize;
+ grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
+ grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
+
+ for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_REL)
+ num += s->sh_size / s->sh_entsize;
+ grub_efiemu_request_symbols (num);
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efiemu_resolve_symbols32 (grub_efiemu_segment_t segs, Elf32_Ehdr *e)
+{
+ unsigned i;
+ Elf32_Shdr *s;
+ Elf32_Sym *sym;
+ const char *str;
+ Elf32_Word size, entsize;
+
+ grub_dprintf ("efiemu", "resolving symbols\n");
+
+ for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_SYMTAB)
+ break;
+
+ if (i == e->e_shnum)
+ return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
+
+ sym = (Elf32_Sym *) ((char *) e + s->sh_offset);
+ size = s->sh_size;
+ entsize = s->sh_entsize;
+
+ grub_efiemu_nelfsyms = size / entsize;
+ grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
+ grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
+
+
+ s = (Elf32_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
+ str = (char *) e + s->sh_offset;
+
+ for (i = 0;
+ i < size / entsize;
+ i++, sym = (Elf32_Sym *) ((char *) sym + entsize))
+ {
+ unsigned char type = ELF32_ST_TYPE (sym->st_info);
+ unsigned char bind = ELF32_ST_BIND (sym->st_info);
+ int handle;
+ grub_off_t off;
+ grub_err_t err;
+ const char *name = str + sym->st_name;
+ grub_efiemu_elfsyms[i].section = sym->st_shndx;
+ switch (type)
+ {
+ case STT_NOTYPE:
+ /* Resolve a global symbol. */
+ if (sym->st_name != 0 && sym->st_shndx == 0)
+ {
+ if ((err = grub_efiemu_resolve_symbol (name, &handle, &off)))
+ return err;
+ grub_efiemu_elfsyms[i].handle = handle;
+ grub_efiemu_elfsyms[i].off = off;
+ }
+ else
+ sym->st_value = 0;
+ break;
+
+ case STT_OBJECT:
+ if ((err = grub_efiemu_get_section_addr
+ (segs, sym->st_shndx, &handle, &off)))
+ return err;
+
+ off += sym->st_value;
+ if (bind != STB_LOCAL)
+ if ((err = grub_efiemu_register_symbol (name, handle, off)))
+ return err;
+ grub_efiemu_elfsyms[i].handle = handle;
+ grub_efiemu_elfsyms[i].off = off;
+ break;
+
+ case STT_FUNC:
+ if ((err = grub_efiemu_get_section_addr
+ (segs, sym->st_shndx, &handle, &off)))
+ return err;
+
+ off += sym->st_value;
+ if (bind != STB_LOCAL)
+ if ((err = grub_efiemu_register_symbol (name, handle, off)))
+ return err;
+ grub_efiemu_elfsyms[i].handle = handle;
+ grub_efiemu_elfsyms[i].off = off;
+ break;
+
+ case STT_SECTION:
+ if ((err = grub_efiemu_get_section_addr
+ (segs, sym->st_shndx, &handle, &off)))
+ {
+ grub_efiemu_elfsyms[i].handle = 0;
+ grub_efiemu_elfsyms[i].off = 0;
+ grub_errno = GRUB_ERR_NONE;
+ break;
+ }
+
+ grub_efiemu_elfsyms[i].handle = handle;
+ grub_efiemu_elfsyms[i].off = off;
+ break;
+
+ case STT_FILE:
+ grub_efiemu_elfsyms[i].handle = 0;
+ grub_efiemu_elfsyms[i].off = 0;
+ break;
+
+ default:
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "unknown symbol type `%d'", (int) type);
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/* Unload segments */
+static int
+grub_efiemu_unload_segs (grub_efiemu_segment_t seg)
+{
+ grub_efiemu_segment_t segn;
+ for (; seg; seg = segn)
+ {
+ segn = seg->next;
+ grub_efiemu_mm_return_request (seg->handle);
+ grub_free (seg);
+ }
+ return 1;
+}
+
+grub_err_t
+grub_efiemu_loadcore_unload(void)
+{
+ grub_efiemu_mode = GRUB_EFIEMU_NOTLOADED;
+
+ grub_free (efiemu_core);
+ efiemu_core = 0;
+
+ grub_efiemu_unload_segs (efiemu_segments);
+ efiemu_segments = 0;
+
+ grub_efiemu_free_syms ();
+
+ grub_free (grub_efiemu_elfsyms);
+ grub_efiemu_elfsyms = 0;
+
+ ptv_written = 0;
+ ptv_alloc = 0;
+ ptv_requested = 0;
+ grub_efiemu_mm_return_request (ptv_handle);
+ ptv_handle = 0;
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_loadcore_init (grub_file_t file)
+{
+ Elf32_Ehdr *e;
+ grub_err_t err;
+
+ efiemu_core_size = grub_file_size (file);
+ efiemu_core = 0;
+ efiemu_core = grub_malloc (efiemu_core_size);
+ if (! efiemu_core)
+ return grub_errno;
+
+
+ if (grub_file_read (file, efiemu_core, efiemu_core_size)
+ != (int) efiemu_core_size)
+ {
+ grub_free (efiemu_core);
+ return grub_errno;
+ }
+
+ e = efiemu_core;
+ if (grub_efiemu_check_header (e, efiemu_core_size))
+ {
+ grub_free (efiemu_core);
+ return GRUB_ERR_BAD_MODULE;
+ }
+
+ if (e->e_type != ET_REL)
+ {
+ grub_free (efiemu_core);
+ return grub_error (GRUB_ERR_BAD_MODULE, "invalid ELF file type");
+ }
+
+ /* Make sure that every section is within the core. */
+ if ((grub_size_t)efiemu_core_size < e->e_shoff + e->e_shentsize * e->e_shnum)
+ {
+ grub_free (efiemu_core);
+ return grub_error (GRUB_ERR_BAD_OS, "ELF sections outside core");
+ }
+
+ if ((err = grub_efiemu_init_segments32 (&efiemu_segments, efiemu_core)))
+ {
+ grub_free (efiemu_core);
+ return err;
+ }
+ if ((err = grub_efiemu_count_symbols32 (efiemu_core)))
+ {
+ grub_free (efiemu_core);
+ return err;
+ }
+ grub_efiemu_request_symbols (1);
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_alloc_syms (void)
+{
+ ptv_alloc = ptv_requested;
+ ptv_handle = grub_efiemu_request_memalign
+ (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
+ GRUB_EFI_RUNTIME_SERVICES_DATA);
+ grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0);
+ return grub_errno;
+}
+
+grub_err_t
+grub_efiemu_loadcore_load (void)
+{
+ if (grub_efiemu_load_segments32 (efiemu_segments, efiemu_core)
+ || grub_efiemu_resolve_symbols32 (efiemu_segments, efiemu_core)
+ || grub_arch_efiemu_relocate_symbols (efiemu_segments, efiemu_core,
+ grub_efiemu_mode))
+ grub_efiemu_loadcore_unload ();
+
+ return grub_errno;
+}
Index: efiemu/i386/pc/cfgtables.c
===================================================================
--- efiemu/i386/pc/cfgtables.c (revision 0)
+++ efiemu/i386/pc/cfgtables.c (revision 0)
@@ -0,0 +1,22 @@
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
+grub_err_t
+grub_machine_efiemu_init_tables ()
+{
+ grub_uint8_t *ptr;
+ grub_efi_guid_t smbios = GRUB_EFI_SMBIOS_TABLE_GUID;
+ grub_dprintf ("efiemu", "Registering SMBIOS\n");
+ for (ptr=(grub_uint8_t *)0xf0000;ptr<(grub_uint8_t *)0x100000;ptr+=16)
+ if (!grub_memcmp (ptr, "_SM_", 4))
+ break;
+ /* FIXME: checksum ! */
+ if (ptr < (grub_uint8_t *)0x100000)
+ grub_efiemu_register_configuration_table (smbios, 0, 0, ptr);
+
+ return GRUB_ERR_NONE;
+}
Property changes on: efiemu/i386/pc/cfgtables.c
___________________________________________________________________
Added: svn:mergeinfo
Index: efiemu/i386/loadcore.c
===================================================================
--- efiemu/i386/loadcore.c (revision 0)
+++ efiemu/i386/loadcore.c (revision 0)
@@ -0,0 +1,129 @@
+
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/elf.h>
+
+int
+grub_arch_efiemu_sizeof_uintn_t (void)
+{
+ if (grub_efiemu_mode == GRUB_EFIEMU32)
+ return 4;
+ if (grub_efiemu_mode == GRUB_EFIEMU64)
+ return 8;
+ return 0;
+}
+
+/* Check if EHDR is a valid ELF header. */
+grub_err_t
+grub_arch_efiemu_check_header (void *ehdr, grub_efiemu_mode_t *mode)
+{
+ Elf32_Ehdr *e32 = ehdr;
+ Elf64_Ehdr *e64 = ehdr;
+
+ /* Check the magic numbers. */
+ if (e32->e_ident[EI_CLASS] == ELFCLASS32
+ && e32->e_ident[EI_DATA] == ELFDATA2LSB
+ && e32->e_machine == EM_386
+ && (*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU32))
+ {
+ *mode = GRUB_EFIEMU32;
+ return GRUB_ERR_NONE;
+ }
+ if (e64->e_ident[EI_CLASS] == ELFCLASS64
+ && e64->e_ident[EI_DATA] == ELFDATA2LSB
+ && e64->e_machine == EM_X86_64
+ && (*mode == GRUB_EFIEMU_NOTLOADED || *mode == GRUB_EFIEMU64))
+ {
+ *mode = GRUB_EFIEMU64;
+ return GRUB_ERR_NONE;
+ }
+ return grub_error (GRUB_ERR_BAD_OS, "invalid arch specific ELF magic");
+}
+
+/* Relocate symbols. */
+static grub_err_t
+grub_arch_efiemu32_relocate_symbols (grub_efiemu_segment_t segs, void *ehdr)
+{
+ unsigned i;
+ Elf32_Ehdr *e = ehdr;
+ Elf32_Shdr *s;
+ grub_err_t err;
+
+ grub_dprintf ("efiemu", "relocating symbols %d %d\n",
+ e->e_shoff, e->e_shnum);
+
+ for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_REL)
+ {
+ grub_efiemu_segment_t seg;
+ grub_dprintf ("efiemu", "shtrel\n");
+
+ /* Find the target segment. */
+ for (seg = segs; seg; seg = seg->next)
+ if (seg->section == s->sh_info)
+ break;
+
+ if (seg)
+ {
+ Elf32_Rel *rel, *max;
+
+ for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
+ max = rel + s->sh_size / s->sh_entsize;
+ rel < max;
+ rel++)
+ {
+ Elf32_Word *addr;
+ struct grub_efiemu_elf_sym sym;
+ if (seg->size < rel->r_offset)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "reloc offset is out of the segment");
+
+ addr = (Elf32_Word *)
+ ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+ + seg->off + rel->r_offset);
+ sym = grub_efiemu_elfsyms[ELF32_R_SYM (rel->r_info)];
+
+ switch (ELF32_R_TYPE (rel->r_info))
+ {
+ case R_386_32:
+ if ((err = grub_efiemu_write_uint32 (addr,
+ sym.off + *addr,
+ sym.handle,
+ 0,
+ seg->ptv_rel_needed)))
+ return err;
+
+ break;
+
+ case R_386_PC32:
+ if ((err = grub_efiemu_write_uint32
+ (addr, sym.off + *addr - rel->r_offset
+ - seg->off, sym.handle,
+ seg->handle,
+ seg->ptv_rel_needed)))
+ return err;
+ break;
+ }
+ }
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_arch_efiemu_relocate_symbols (grub_efiemu_segment_t segs, void *ehdr,
+ grub_efiemu_mode_t mode)
+{
+ if (mode == GRUB_EFIEMU32)
+ return grub_arch_efiemu32_relocate_symbols (segs, ehdr);
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "64-bit EFI emulation isn't implemented yet");
+}
Property changes on: efiemu/i386/loadcore.c
___________________________________________________________________
Added: svn:mergeinfo
Index: efiemu/mm.c
===================================================================
--- efiemu/mm.c (revision 0)
+++ efiemu/mm.c (revision 0)
@@ -0,0 +1,463 @@
+#include <grub/file.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#include <grub/machine/efiemu.h>
+#include <grub/elf.h>
+#include <grub/lib/crc.h>
+
+struct grub_efiemu_memrequest
+{
+ struct grub_efiemu_memrequest *next;
+ grub_efi_memory_type_t type;
+ grub_size_t size;
+ grub_size_t align_overhead;
+ int handle;
+ void *val;
+};
+static struct grub_efiemu_memrequest *memrequests = 0;
+//static int mmap_handle;
+//static grub_uint8_t *efiemu_mmap = 0;
+static grub_efi_memory_descriptor_t *efiemu_mmap = 0;
+static void *resident_memory = 0;
+static grub_size_t total_alloc = 0;
+static grub_size_t requested_memory[GRUB_EFI_MAX_MEMORY_TYPE];
+static grub_uint64_t type_start[GRUB_EFI_MAX_MEMORY_TYPE];
+static grub_uint64_t type_end[GRUB_EFI_MAX_MEMORY_TYPE];
+
+//static grub_uint64_t mmap_startaddr, mmap_endaddr, mmap_size;
+static int mmap_reserved_size = 0, mmap_num = 0;
+
+static grub_err_t
+grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
+ grub_efi_memory_type_t type)
+{
+ grub_uint64_t page_start, npages;
+ if (mmap_num >= mmap_reserved_size)
+ {
+ efiemu_mmap = (grub_efi_memory_descriptor_t *)
+ grub_realloc (efiemu_mmap, (++mmap_reserved_size)
+ * sizeof (grub_efi_memory_descriptor_t));
+ if (!efiemu_mmap)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "Not enough space for memory map");
+ }
+ grub_dprintf ("efiemu", "grub_efiemu_add_to_mmap: %d, 0x%llx, 0x%llx\n",
+ type, start, size);
+ page_start = start - (start % GRUB_EFIEMU_PAGESIZE);
+ npages = (size + (start % GRUB_EFIEMU_PAGESIZE) + GRUB_EFIEMU_PAGESIZE - 1)
+ / GRUB_EFIEMU_PAGESIZE;
+ efiemu_mmap[mmap_num].physical_start = start;
+ efiemu_mmap[mmap_num].virtual_start = start;
+ efiemu_mmap[mmap_num].num_pages = npages;
+ efiemu_mmap[mmap_num].type = type;
+ mmap_num++;
+ return GRUB_ERR_NONE;
+}
+
+int
+grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+ grub_efi_memory_type_t type)
+{
+ grub_size_t align_overhead;
+ struct grub_efiemu_memrequest *ret, *cur, *prev;
+ align_overhead = align - (requested_memory[type]%align);
+ if (align_overhead == align)
+ align_overhead = 0;
+ requested_memory[type] += align_overhead + size;
+ if (type >= GRUB_EFI_MAX_MEMORY_TYPE || type <= GRUB_EFI_LOADER_CODE)
+ return -2;
+ ret = grub_malloc (sizeof (*ret));
+ if (!ret)
+ return -1;
+ ret->type = type;
+ ret->size = size;
+ ret->align_overhead = align_overhead;
+ ret->val = 0;
+ ret->next = 0;
+ prev = 0;
+ for (cur = memrequests; cur; prev = cur, cur = cur->next);
+ if (prev)
+ {
+ ret->handle = prev->handle + 1;
+ prev->next = ret;
+ }
+ else
+ {
+ ret->handle = 1; /* Avoid 0 handle*/
+ memrequests = ret;
+ }
+ return ret->handle;
+}
+
+static grub_err_t
+efiemu_alloc_requests (void)
+{
+ grub_size_t align_overhead = 0;
+ grub_uint8_t *curptr, *typestart;
+ struct grub_efiemu_memrequest *cur;
+ unsigned i;
+ grub_efi_memory_type_t reqorder[] =
+ {
+ /* First come regions usable by OS*/
+ GRUB_EFI_LOADER_CODE,
+ GRUB_EFI_LOADER_DATA,
+ GRUB_EFI_BOOT_SERVICES_CODE,
+ GRUB_EFI_BOOT_SERVICES_DATA,
+ GRUB_EFI_CONVENTIONAL_MEMORY,
+ GRUB_EFI_ACPI_RECLAIM_MEMORY,
+
+ GRUB_EFI_RUNTIME_SERVICES_CODE,
+ GRUB_EFI_RUNTIME_SERVICES_DATA,
+ GRUB_EFI_ACPI_MEMORY_NVS,
+ GRUB_EFI_UNUSABLE_MEMORY,
+ GRUB_EFI_MEMORY_MAPPED_IO,
+ GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+ GRUB_EFI_PAL_CODE
+ };
+ total_alloc = 0;
+ for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+ {
+ align_overhead = GRUB_EFIEMU_PAGESIZE
+ - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+ if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+ align_overhead = 0;
+ total_alloc += requested_memory[reqorder[i]] + align_overhead;
+ }
+ resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc);
+ if (!resident_memory)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "couldn't allocate resident memory");
+ curptr = resident_memory;
+ for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
+ {
+ if (!requested_memory[reqorder[i]])
+ {
+ type_start[reqorder[i]] = type_end[reqorder[i]] = 0;
+ continue;
+ }
+ typestart = curptr;
+ for (cur = memrequests; cur; cur = cur->next)
+ if (cur->type == reqorder[i])
+ {
+ curptr = ((grub_uint8_t *)curptr) + cur->align_overhead;
+ cur->val = curptr;
+ curptr = ((grub_uint8_t *)curptr) + cur->size;
+ }
+ align_overhead = GRUB_EFIEMU_PAGESIZE
+ - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
+ if (align_overhead == GRUB_EFIEMU_PAGESIZE)
+ align_overhead = 0;
+ curptr = ((grub_uint8_t *)curptr) + align_overhead;
+ grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
+ curptr - typestart, reqorder[i]);
+ }
+ return GRUB_ERR_NONE;
+}
+
+void *
+grub_efiemu_mm_obtain_request (int handle)
+{
+ struct grub_efiemu_memrequest *cur;
+ for (cur = memrequests; cur; cur = cur->next)
+ if (cur->handle == handle)
+ return cur->val;
+ return 0;
+}
+
+grub_efi_memory_type_t
+grub_efiemu_mm_get_type (int handle)
+{
+ struct grub_efiemu_memrequest *cur;
+ for (cur = memrequests; cur; cur = cur->next)
+ if (cur->handle == handle)
+ return cur->type;
+ return 0;
+}
+
+void
+grub_efiemu_mm_return_request (int handle)
+{
+ struct grub_efiemu_memrequest *cur, *prev;
+ while (memrequests && memrequests->handle == handle)
+ {
+ cur = memrequests->next;
+ grub_free (memrequests);
+ memrequests = cur;
+ }
+ if (!memrequests)
+ return;
+
+ for (prev = memrequests, cur = prev->next; cur;)
+ if (cur->handle == handle)
+ {
+ prev->next = cur->next;
+ grub_free (cur);
+ cur = prev->next;
+ }
+ else
+ {
+ prev = cur;
+ cur = prev->next;
+ }
+
+}
+
+
+static grub_err_t
+grub_efiemu_mmap_init (void)
+{
+ auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
+ grub_uint32_t);
+ int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ grub_uint32_t type __attribute__ ((unused)))
+ {
+ mmap_reserved_size++;
+ return 0;
+ }
+
+ // the place for memory used by efiemu itself
+ mmap_reserved_size = GRUB_EFI_MAX_MEMORY_TYPE + 1;
+
+#ifndef GRUB_UTIL
+ grub_machine_mmap_iterate (bounds_hook);
+#endif
+
+ return GRUB_ERR_NONE;
+}
+/* Get the memory map as defined in the EFI spec. Return 1 if successful,
+ return 0 if partial, or return -1 if an error occurs. */
+int
+grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version)
+{
+ if (!efiemu_mmap)
+ return grub_error (GRUB_ERR_INVALID_COMMAND,
+ "you need to first launch efiemu_prepare");
+ if (*memory_map_size < mmap_num * sizeof (grub_efi_memory_descriptor_t))
+ {
+ *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+ return 0;
+ }
+ *memory_map_size = mmap_num * sizeof (grub_efi_memory_descriptor_t);
+ grub_memcpy (memory_map, efiemu_mmap, *memory_map_size);
+ if (descriptor_size)
+ *descriptor_size = sizeof (grub_efi_memory_descriptor_t);
+ if (descriptor_version)
+ *descriptor_version = 1;
+ if (map_key)
+ *map_key = 0;
+ return 1;
+}
+
+grub_err_t
+grub_efiemu_mm_unload (void)
+{
+ struct grub_efiemu_memrequest *cur, *d;
+ for (cur = memrequests; cur;)
+ {
+ d = cur->next;
+ grub_free (cur);
+ cur = d;
+ }
+ memrequests = 0;
+ grub_memset (&requested_memory, 0, sizeof (requested_memory));
+ grub_free (resident_memory);
+ resident_memory = 0;
+ grub_free (efiemu_mmap);
+ efiemu_mmap = 0;
+ mmap_reserved_size = mmap_num = 0;
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efiemu_mm_init (void)
+{
+ grub_err_t err;
+
+ err = grub_efiemu_mm_unload ();
+ if (err)
+ return err;
+
+ grub_efiemu_mmap_init ();
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efiemu_mmap_fill (void)
+{
+ auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+ int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
+ grub_uint64_t size,
+ grub_uint32_t type)
+ {
+ switch (type)
+ {
+ case GRUB_MACHINE_MEMORY_AVAILABLE:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_CONVENTIONAL_MEMORY);
+ default:
+ grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
+ case GRUB_MACHINE_MEMORY_RESERVED:
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_UNUSABLE_MEMORY);
+ }
+ }
+
+#ifndef GRUB_UTIL
+ grub_machine_mmap_iterate (fill_hook);
+#endif
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_efiemu_mmap_sort_and_uniq (void)
+{
+ int priority[GRUB_EFI_MAX_MEMORY_TYPE] =
+ {
+ [GRUB_EFI_RESERVED_MEMORY_TYPE] = 4,
+ [GRUB_EFI_LOADER_CODE] = 2,
+ [GRUB_EFI_LOADER_DATA] = 2,
+ [GRUB_EFI_BOOT_SERVICES_CODE] = 2,
+ [GRUB_EFI_BOOT_SERVICES_DATA] = 2,
+ [GRUB_EFI_RUNTIME_SERVICES_CODE] = 3,
+ [GRUB_EFI_RUNTIME_SERVICES_DATA] = 3,
+ [GRUB_EFI_CONVENTIONAL_MEMORY] = 0,
+ [GRUB_EFI_UNUSABLE_MEMORY] = 4,
+ [GRUB_EFI_ACPI_RECLAIM_MEMORY] = 1,
+ [GRUB_EFI_ACPI_MEMORY_NVS] = 3,
+ [GRUB_EFI_MEMORY_MAPPED_IO] = 4,
+ [GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE] = 4,
+ [GRUB_EFI_PAL_CODE] = 4
+ };
+ int i, j, k, done;
+ struct grub_efiemu_mmap_scan
+ {
+ grub_uint64_t pos;
+ int type;
+ grub_efi_memory_type_t memtype;
+ };
+
+ struct grub_efiemu_mmap_scan *scanline_events;
+ struct grub_efiemu_mmap_scan t;
+ grub_uint64_t lastaddr;
+ int lasttype;
+ int curtype;
+ int present[GRUB_EFI_MAX_MEMORY_TYPE];
+ grub_efi_memory_descriptor_t *result;
+
+ grub_dprintf ("efiemu", "mmap %d entries originally\n", mmap_num);
+ for (j = 0; j < mmap_num; j++)
+ {
+ grub_dprintf ("efiemu",
+ "mmap entry: type %d start 0x%llx 0x%llx pages\n",
+ efiemu_mmap[j].type,
+ efiemu_mmap[j].physical_start, efiemu_mmap[j].num_pages)
+
+ }
+
+ grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
+ scanline_events = (struct grub_efiemu_mmap_scan *)
+ grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
+ /* Number of chunks can't increase more than by factor of 2 */
+ result = (grub_efi_memory_descriptor_t *)
+ grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
+ if (!result || !scanline_events)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate space for");
+
+ for (i = 0; i < mmap_num; i++)
+ {
+ scanline_events[2 * i].pos = efiemu_mmap[i].physical_start;
+ scanline_events[2 * i].type = 0;
+ scanline_events[2 * i].memtype = efiemu_mmap[i].type;
+ scanline_events[2 * i + 1].pos = efiemu_mmap[i].physical_start
+ + efiemu_mmap[i].num_pages * GRUB_EFIEMU_PAGESIZE;
+ scanline_events[2 * i + 1].type = 1;
+ scanline_events[2 * i + 1].memtype = efiemu_mmap[i].type;
+ }
+
+ done = 1;
+ while (done)
+ {
+ done = 0;
+ for (i = 0; i < 2 * mmap_num - 1; i++)
+ if (scanline_events[i + 1].pos < scanline_events[i].pos)
+ {
+ t = scanline_events[i + 1];
+ scanline_events[i + 1] = scanline_events[i];
+ scanline_events[i] = t;
+ done = 1;
+ }
+ }
+ j = 0;
+ lastaddr = scanline_events[0].pos;
+ lasttype = scanline_events[0].memtype;
+ for (i = 0; i < 2 * mmap_num; i++)
+ {
+ if (scanline_events[i].type)
+ present[scanline_events[i].memtype]--;
+ else
+ present[scanline_events[i].memtype]++;
+ curtype = -1;
+ for (k = 0; k < GRUB_EFI_MAX_MEMORY_TYPE; k++)
+ if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
+ curtype = k;
+ if ((curtype == -1 || curtype != lasttype)
+ && lastaddr != scanline_events[i].pos
+ && lasttype != -1 && (scanline_events[i].pos - lastaddr)
+ / GRUB_EFIEMU_PAGESIZE != 0)
+ {
+ result[j].virtual_start = result[j].physical_start = lastaddr;
+ result[j].num_pages = (scanline_events[i].pos - lastaddr)
+ / GRUB_EFIEMU_PAGESIZE;
+ result[j].type = lasttype;
+ result[j].attribute
+ = (lasttype == GRUB_EFI_RUNTIME_SERVICES_CODE
+ || lasttype == GRUB_EFI_RUNTIME_SERVICES_DATA)
+ ? GRUB_EFI_MEMORY_RUNTIME : 0;
+ grub_dprintf ("efiemu",
+ "mmap entry: type %d start 0x%llx 0x%llx pages\n",
+ result[j].type,
+ result[j].physical_start, result[j].num_pages);
+ j++;
+ }
+ if (curtype == -1 || curtype != lasttype)
+ {
+ lasttype = curtype;
+ lastaddr = scanline_events[i].pos;
+ }
+ }
+ grub_free (efiemu_mmap);
+ grub_free (scanline_events);
+ efiemu_mmap = grub_realloc (result, j * sizeof (*result));
+ return GRUB_ERR_NONE;
+}
+
+
+grub_err_t
+grub_efiemu_mm_do_alloc (void)
+{
+ /* Preallocate mmap */
+ efiemu_mmap = (grub_efi_memory_descriptor_t *)
+ grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
+ if (!efiemu_mmap)
+ {
+ grub_efiemu_unload ();
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't initilaize mmap");
+ }
+ efiemu_alloc_requests ();
+ grub_efiemu_mmap_fill ();
+ grub_efiemu_mmap_sort_and_uniq ();
+ return GRUB_ERR_NONE;
+}
Index: include/grub/autoefi.h
===================================================================
--- include/grub/autoefi.h (revision 0)
+++ include/grub/autoefi.h (revision 0)
@@ -0,0 +1,22 @@
+#include <grub/machine/machine.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#define GRUB_EFI(x) grub_efi_ ## x
+#define SYSTEM_TABLE_SIZEOF GRUB_EFI_SYSTEM_TABLE_SIZEOF
+#define SYSTEM_TABLE_VAR GRUB_EFI_SYSTEM_TABLE_VAR
+#define SYSTEM_TABLE_PTR GRUB_EFI_SYSTEM_TABLE_PTR
+#define SIZEOF_OF_UINTN GRUB_EFI_SIZEOF_OF_UINTN
+#define SYSTEM_TABLE GRUB_EFI_SYSTEM_TABLE
+#else
+#include <grub/efiemu/efiemu.h>
+#include <grub/cpu/efiemu.h>
+#define GRUB_EFI(x) grub_efiemu_ ## x
+#define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF
+#define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR
+#define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR
+#define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
+#define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
+#define grub_efi_allocate_pages(x,y) (x)
+#define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS
+#endif
Index: include/grub/i386/efiemu.h
===================================================================
--- include/grub/i386/efiemu.h (revision 0)
+++ include/grub/i386/efiemu.h (revision 0)
@@ -0,0 +1,15 @@
+#ifndef GRUB_ARCH_EFI_EMU_HEADER
+#define GRUB_ARCH_EFI_EMU_HEADER 1
+
+typedef enum {GRUB_EFIEMU_NOTLOADED,
+ GRUB_EFIEMU32, GRUB_EFIEMU64} grub_efiemu_mode_t;
+
+grub_err_t
+grub_arch_efiemu_relocate_symbols (grub_efiemu_segment_t segs, void *ehdr,
+ grub_efiemu_mode_t mode);
+grub_err_t
+grub_arch_efiemu_check_header (void *ehdr, grub_efiemu_mode_t *mode);
+
+extern grub_efiemu_mode_t grub_efiemu_mode;
+
+#endif
Index: include/grub/i386/pc/efiemu.h
===================================================================
--- include/grub/i386/pc/efiemu.h (revision 0)
+++ include/grub/i386/pc/efiemu.h (revision 0)
@@ -0,0 +1,6 @@
+#ifndef GRUB_MACHINE_EFI_EMU_HEADER
+#define GRUB_MACHINE_EFI_EMU_HEADER 1
+
+grub_err_t grub_machine_efiemu_init_tables (void);
+
+#endif
Index: include/grub/efi/api.h
===================================================================
--- include/grub/efi/api.h (revision 1998)
+++ include/grub/efi/api.h (working copy)
@@ -40,15 +40,15 @@
#define GRUB_EFI_TPL_NOTIFY 16
#define GRUB_EFI_TPL_HIGH_LEVEL 31
-#define GRUB_EFI_MEMORY_UC 0x0000000000000001
-#define GRUB_EFI_MEMORY_WC 0x0000000000000002
-#define GRUB_EFI_MEMORY_WT 0x0000000000000004
-#define GRUB_EFI_MEMORY_WB 0x0000000000000008
-#define GRUB_EFI_MEMORY_UCE 0x0000000000000010
-#define GRUB_EFI_MEMORY_WP 0x0000000000001000
-#define GRUB_EFI_MEMORY_RP 0x0000000000002000
-#define GRUB_EFI_MEMORY_XP 0x0000000000004000
-#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000
+#define GRUB_EFI_MEMORY_UC 0x0000000000000001LL
+#define GRUB_EFI_MEMORY_WC 0x0000000000000002LL
+#define GRUB_EFI_MEMORY_WT 0x0000000000000004LL
+#define GRUB_EFI_MEMORY_WB 0x0000000000000008LL
+#define GRUB_EFI_MEMORY_UCE 0x0000000000000010LL
+#define GRUB_EFI_MEMORY_WP 0x0000000000001000LL
+#define GRUB_EFI_MEMORY_RP 0x0000000000002000LL
+#define GRUB_EFI_MEMORY_XP 0x0000000000004000LL
+#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL
#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
@@ -916,6 +916,20 @@
};
typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
+#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
+
+#define GRUB_EFI_ACPI_20_TABLE_GUID \
+ {0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x0,0x80,0xc7,0x3c,0x88,0x81}}
+#define GRUB_EFI_ACPI_TABLE_GUID \
+ {0xeb9d2d30,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define GRUB_EFI_SAL_SYSTEM_TABLE_GUID \
+ {0xeb9d2d32,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define GRUB_EFI_SMBIOS_TABLE_GUID \
+ {0xeb9d2d31,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+#define GRUB_EFI_MPS_TABLE_GUID \
+ {0xeb9d2d2f,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d}}
+
struct grub_efi_simple_input_interface
{
grub_efi_status_t
Index: include/grub/efi/efi.h
===================================================================
--- include/grub/efi/efi.h (revision 1998)
+++ include/grub/efi/efi.h (working copy)
@@ -24,6 +24,12 @@
#include <grub/dl.h>
#include <grub/efi/api.h>
+#define GRUB_EFI_SYSTEM_TABLE_SIZEOF(x) (sizeof(grub_efi_system_table->x))
+#define GRUB_EFI_SYSTEM_TABLE_VAR(x) ((void *)&(grub_efi_system_table->x))
+#define GRUB_EFI_SYSTEM_TABLE_PTR(x) ((void *)(grub_efi_system_table->x))
+#define GRUB_EFI_SIZEOF_OF_UINTN sizeof (grub_efi_uintn_t)
+#define GRUB_EFI_SYSTEM_TABLE(x) (grub_efi_system_table->x)
+
/* Functions. */
void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol,
void *registration);
Index: include/grub/types.h
===================================================================
--- include/grub/types.h (revision 1998)
+++ include/grub/types.h (working copy)
@@ -100,6 +100,16 @@
# define LONG_MAX 2147483647UL
#endif
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
+#endif
+
/* The type for representing a file offset. */
typedef grub_uint64_t grub_off_t;
Index: include/grub/efiemu/efiemu.h
===================================================================
--- include/grub/efiemu/efiemu.h (revision 0)
+++ include/grub/efiemu/efiemu.h (revision 0)
@@ -0,0 +1,180 @@
+#ifndef GRUB_EFI_EMU_HEADER
+#define GRUB_EFI_EMU_HEADER 1
+
+#include <grub/efi/api.h>
+
+#define GRUB_EFIEMU_PAGESIZE 4096
+
+struct grub_efiemu_segment
+{
+ struct grub_efiemu_segment *next;
+ grub_size_t size;
+ unsigned section;
+ int handle;
+ int ptv_rel_needed;
+ grub_off_t off;
+ void *srcptr;
+};
+typedef struct grub_efiemu_segment *grub_efiemu_segment_t;
+
+struct grub_efi_system_table32
+{
+ grub_efi_table_header_t hdr;
+ grub_efi_uint32_t firmware_vendor;
+ grub_efi_uint32_t firmware_revision;
+ grub_efi_uint32_t console_in_handler;
+ grub_efi_uint32_t con_in;
+ grub_efi_uint32_t console_out_handler;
+ grub_efi_uint32_t con_out;
+ grub_efi_uint32_t standard_error_handle;
+ grub_efi_uint32_t std_err;
+ grub_efi_uint32_t runtime_services;
+ grub_efi_uint32_t boot_services;
+ grub_efi_uint32_t num_table_entries;
+ grub_efi_uint32_t configuration_table;
+};
+typedef struct grub_efi_system_table32 grub_efi_system_table32_t;
+
+struct grub_efi_system_table64
+{
+ grub_efi_table_header_t hdr;
+ grub_efi_uint64_t firmware_vendor;
+ grub_efi_uint32_t firmware_revision;
+ grub_efi_uint64_t console_in_handler;
+ grub_efi_uint64_t con_in;
+ grub_efi_uint64_t console_out_handler;
+ grub_efi_uint64_t con_out;
+ grub_efi_uint64_t standard_error_handle;
+ grub_efi_uint64_t std_err;
+ grub_efi_uint64_t runtime_services;
+ grub_efi_uint64_t boot_services;
+ grub_efi_uint64_t num_table_entries;
+ grub_efi_uint64_t configuration_table;
+};
+typedef struct grub_efi_system_table64 grub_efi_system_table64_t;
+
+struct grub_efiemu_runtime_services32
+{
+ grub_efi_table_header_t hdr;
+
+ grub_efi_uint32_t get_time;
+
+ grub_efi_uint32_t set_time;
+
+ grub_efi_uint32_t get_wakeup_time;
+
+ grub_efi_uint32_t set_wakeup_time;
+
+ grub_efi_uint32_t set_virtual_address_map;
+
+ grub_efi_uint32_t convert_pointer;
+
+ grub_efi_uint32_t get_variable;
+
+ grub_efi_uint32_t get_next_variable_name;
+
+ grub_efi_uint32_t set_variable;
+
+ grub_efi_uint32_t get_next_high_monotonic_count;
+
+ grub_efi_uint32_t reset_system;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_runtime_services32 grub_efiemu_runtime_services32_t;
+
+
+struct grub_efiemu_configuration_table32
+{
+ grub_efi_guid_t vendor_guid;
+ grub_efi_uint32_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
+struct grub_efiemu_configuration_table64
+{
+ grub_efi_guid_t vendor_guid;
+ grub_efi_uint64_t vendor_table;
+} __attribute__ ((packed));
+typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table64_t;
+
+extern grub_efi_system_table32_t *grub_efiemu_system_table32;
+extern grub_efi_system_table64_t *grub_efiemu_system_table64;
+
+#define grub_efiemu_system_table ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? (void *)grub_efiemu_system_table64:(void *)grub_efiemu_system_table32)
+#define GRUB_EFIEMU_SIZEOF_OF_UINTN (grub_arch_efiemu_sizeof_uintn_t ())
+#define GRUB_EFIEMU_SYSTEM_TABLE(x) ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? grub_efiemu_system_table64->x:grub_efiemu_system_table32->x)
+#define GRUB_EFIEMU_SYSTEM_TABLE_SET(x,y) ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? (grub_efiemu_system_table64->x=(y)):(grub_efiemu_system_table32->x=(y)))
+
+#define GRUB_EFIEMU_SYSTEM_TABLE_PTR(x) ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? UINT_TO_PTR (grub_efiemu_system_table64->x):UINT_TO_PTR (grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_VAR(x) ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? (void *)&(grub_efiemu_system_table64->x):(void *)&(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF(x) ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? sizeof(grub_efiemu_system_table64->x):sizeof(grub_efiemu_system_table32->x))
+#define GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF_TOTAL ((grub_arch_efiemu_sizeof_uintn_t () == 8) ? sizeof(*grub_efiemu_system_table64):sizeof(*grub_efiemu_system_table32))
+
+grub_err_t
+grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid);
+
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+ void * (*get_table) (void *data),
+ void (*unload) (void *data),
+ void *data);
+
+int
+grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version);
+
+grub_err_t grub_efiemu_unload (void);
+
+grub_err_t grub_efiemu_prepare (void);
+
+int grub_arch_efiemu_sizeof_uintn_t (void);
+
+int grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key);
+
+/* loadcore.c */
+struct grub_efiemu_elf_sym
+{
+ int handle;
+ grub_off_t off;
+ unsigned section;
+};
+extern struct grub_efiemu_elf_sym *grub_efiemu_elfsyms;
+extern int grub_efiemu_nelfsyms;
+
+grub_err_t grub_efiemu_alloc_syms (void);
+grub_err_t grub_efiemu_request_symbols (int num);
+grub_err_t grub_efiemu_loadcore_unload(void);
+grub_err_t grub_efiemu_loadcore_init (grub_file_t file);
+grub_err_t grub_efiemu_loadcore_load (void);
+grub_err_t
+grub_efiemu_resolve_symbol (const char *name, int *handle, grub_off_t *off);
+grub_err_t
+grub_efiemu_register_symbol (const char *name, int handle, grub_off_t off);
+
+/* mm.c */
+int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+ grub_efi_memory_type_t type);
+void *grub_efiemu_mm_obtain_request (int handle);
+int
+grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
+ grub_efi_memory_descriptor_t *memory_map,
+ grub_efi_uintn_t *map_key,
+ grub_efi_uintn_t *descriptor_size,
+ grub_efi_uint32_t *descriptor_version);
+grub_err_t grub_efiemu_mm_unload (void);
+grub_err_t grub_efiemu_mm_do_alloc (void);
+grub_err_t grub_efiemu_mm_init (void);
+void *grub_efiemu_mm_obtain_request (int handle);
+void grub_efiemu_mm_return_request (int handle);
+
+grub_err_t
+grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
+ void (*unload) (void *data),
+ void *data);
+
+grub_err_t
+grub_efiemu_write_uint32 (void * addr, grub_uint32_t value, int plus_handle,
+ int minus_handle, int ptv_needed);
+grub_efi_memory_type_t grub_efiemu_mm_get_type (int handle);
+#endif /* GRUB_EFI_EMU_HEADER */
Property changes on: include/grub/efiemu/efiemu.h
___________________________________________________________________
Added: svn:mergeinfo
Index: include/grub/efiemu/acpi.h
===================================================================
--- include/grub/efiemu/acpi.h (revision 0)
+++ include/grub/efiemu/acpi.h (revision 0)
@@ -0,0 +1,42 @@
+
+struct grub_acpi_rsdp_v10
+{
+ grub_uint8_t signature[8];
+ grub_uint8_t checksum;
+ grub_uint8_t oemid[6];
+ grub_uint8_t revision;
+ grub_uint32_t rsdt_addr;
+} __attribute__ ((packed));
+struct grub_acpi_rsdp_v20
+{
+ struct grub_acpi_rsdp_v10 rsdpv1;
+ grub_uint32_t length;
+ grub_uint64_t xsdt_addr;
+ grub_uint8_t checksum;
+ grub_uint8_t reserved[3];
+} __attribute__ ((packed));
+struct grub_acpi_table_header
+{
+ grub_uint8_t signature[4];
+ grub_uint32_t length;
+ grub_uint8_t revision;
+ grub_uint8_t checksum;
+ grub_uint8_t oemid[6];
+ grub_uint8_t oemtable[8];
+ grub_uint32_t oemrev;
+ grub_uint8_t creator_id[4];
+ grub_uint32_t creator_rev;
+} __attribute__ ((packed));
+struct grub_acpi_fadt
+{
+ struct grub_acpi_table_header hdr;
+ grub_uint32_t facs_addr;
+ grub_uint32_t dsdt_addr;
+ grub_uint8_t somefields1[88];
+ grub_uint64_t facs_xaddr;
+ grub_uint64_t dsdt_xaddr;
+ grub_uint8_t somefields2[96];
+} __attribute__ ((packed));
+
+grub_uint8_t grub_efiemu_acpi_checksum (void *ptr, grub_size_t size);
+struct grub_acpi_rsdp_v10 *grub_machine_efiemu_get_rsdp (void);
Index: loader/linux_normal_efiemu.c
===================================================================
--- loader/linux_normal_efiemu.c (revision 0)
+++ loader/linux_normal_efiemu.c (revision 0)
@@ -0,0 +1,64 @@
+/* linux_normal.c - boot linux */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2004,2005,2006,2007 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/loader.h>
+#include <grub/err.h>
+#include <grub/normal.h>
+#include <grub/dl.h>
+
+void grub_rescue_cmd_linuxefi (int argc, char *argv[]);
+void grub_rescue_cmd_initrdefi (int argc, char *argv[]);
+
+
+static grub_err_t
+grub_normal_linuxefi_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_linuxefi (argc, args);
+ return grub_errno;
+}
+
+
+static grub_err_t
+grub_normal_initrd_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_rescue_cmd_initrdefi (argc, args);
+ return grub_errno;
+}
+
+GRUB_MOD_INIT(linux_normal)
+{
+ (void) mod; /* To stop warning. */
+ grub_register_command ("linux_efiemu", grub_normal_linuxefi_command,
+ GRUB_COMMAND_FLAG_BOTH,
+ "linux_efiemu FILE [ARGS...]",
+ "Load a linux kernel.", 0);
+
+ grub_register_command ("initrd_efiemu", grub_normal_initrd_command,
+ GRUB_COMMAND_FLAG_BOTH,
+ "initrd_efiemu FILE",
+ "Load an initrd.", 0);
+}
+
+GRUB_MOD_FINI(linux_normal)
+{
+ grub_unregister_command ("linux");
+ grub_unregister_command ("initrd");
+}
Index: loader/i386/efi/linux.c
===================================================================
--- loader/i386/efi/linux.c (revision 1998)
+++ loader/i386/efi/linux.c (working copy)
@@ -32,6 +32,7 @@
#include <grub/efi/efi.h>
#include <grub/efi/uga_draw.h>
#include <grub/pci.h>
+#include <grub/autoefi.h>
#define GRUB_LINUX_CL_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000
@@ -114,7 +115,7 @@
if (! mmap)
return 0;
- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+ ret = GRUB_EFI (get_memory_map) (&mmap_size, mmap, 0, &desc_size, 0);
grub_free (mmap);
if (ret < 0)
@@ -188,7 +189,7 @@
return 0;
tmp_mmap_size = mmap_size;
- if (grub_efi_get_memory_map (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
+ if (GRUB_EFI (get_memory_map) (&tmp_mmap_size, mmap, 0, &desc_size, 0) <= 0)
grub_fatal ("cannot get memory map");
mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
@@ -293,7 +294,7 @@
#endif
static grub_err_t
-grub_linux_boot (void)
+grub_linux_efi_boot (void)
{
struct linux_kernel_params *params;
grub_efi_uintn_t mmap_size;
@@ -314,8 +315,8 @@
(unsigned) gdt_desc.limit, (unsigned long) gdt_desc.base);
mmap_size = find_mmap_size ();
- if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
- &desc_size, &desc_version) <= 0)
+ if (GRUB_EFI (get_memory_map) (&mmap_size, mmap_buf, &map_key,
+ &desc_size, &desc_version) <= 0)
grub_fatal ("cannot get memory map");
e820_num = 0;
@@ -391,7 +392,7 @@
params->mmap_size = e820_num;
- if (! grub_efi_exit_boot_services (map_key))
+ if (! GRUB_EFI (exit_boot_services) (map_key))
grub_fatal ("cannot exit boot services");
/* Note that no boot services are available from here. */
@@ -513,6 +514,7 @@
return 0;
}
+#ifdef GRUB_MACHINE_EFI
static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
static int
@@ -562,9 +564,15 @@
return 0;
}
+#endif
+#ifndef GRUB_MACHINE_EFI
void
+grub_rescue_cmd_linuxefi (int argc, char *argv[])
+#else
+void
grub_rescue_cmd_linux (int argc, char *argv[])
+#endif
{
grub_file_t file = 0;
struct linux_kernel_header lh;
@@ -667,7 +675,11 @@
params->video_cursor_x = grub_getxy () >> 8;
params->video_cursor_y = grub_getxy () & 0xff;
params->video_page = 0; /* ??? */
+#ifdef GRUB_MACHINE_EFI
params->video_mode = grub_efi_system_table->con_out->mode->mode;
+#else
+ params->video_mode = 0;
+#endif
params->video_width = (grub_getwh () >> 8);
params->video_ega_bx = 0;
params->video_height = (grub_getwh () & 0xff);
@@ -677,15 +689,15 @@
if (grub_le_to_cpu16 (params->version) >= 0x0206)
{
params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
- params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+ params->v0206.efi_system_table = PTR_TO_UINT32 (GRUB_EFI (system_table));
#ifdef __x86_64__
- params->v0206.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
+ params->v0206.efi_system_table_hi = (grub_uint32_t) (PTR_TO_UINT64 (GRUB_EFI (system_table)) >> 32);
#endif
}
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
{
params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
- params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
+ params->v0204.efi_system_table = PTR_TO_UINT32 (GRUB_EFI (system_table));
}
#if 0
@@ -807,11 +819,13 @@
video_type = GRUB_VIDEO_TYPE_EFI;
}
+#ifdef GRUB_EFI_MACHINE_EFI
if (video_type)
{
if (! grub_linux_setup_video (params))
- params->have_vga = video_type;
+ params->have_vga = video_type;
}
+#endif
/* Specify the boot file. */
dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
@@ -835,7 +849,7 @@
if (grub_errno == GRUB_ERR_NONE)
{
- grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
+ grub_loader_set (grub_linux_efi_boot, grub_linux_unload, 1);
loaded = 1;
}
@@ -851,8 +865,13 @@
}
}
+#ifndef GRUB_MACHINE_EFI
void
+grub_rescue_cmd_initrdefi (int argc, char *argv[])
+#else
+void
grub_rescue_cmd_initrd (int argc, char *argv[])
+#endif
{
grub_file_t file = 0;
grub_ssize_t size;
@@ -900,7 +919,7 @@
/* Find the highest address to put the initrd. */
mmap_size = find_mmap_size ();
- if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
+ if (GRUB_EFI (get_memory_map) (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
grub_fatal ("cannot get memory map");
addr = 0;
@@ -956,4 +975,12 @@
GRUB_MOD_INIT(linux)
{
+#ifndef GRUB_MACHINE_EFI
+ grub_rescue_register_command ("linuxefi",
+ grub_rescue_cmd_linuxefi,
+ "load linux");
+ grub_rescue_register_command ("initrdefi",
+ grub_rescue_cmd_initrdefi,
+ "load initrd");
+#else
grub_rescue_register_command ("linux",
grub_rescue_cmd_linux,
"load linux");
grub_rescue_register_command ("initrd",
grub_rescue_cmd_initrd,
"load initrd");
+#endif
my_mod = mod;
}
GRUB_MOD_FINI(linux)
{
+#ifndef GRUB_MACHINE_EFI
+ grub_rescue_unregister_command ("linuxefi");
+ grub_rescue_unregister_command ("initrdefi");
+#else
grub_rescue_unregister_command ("linux");
grub_rescue_unregister_command ("initrd");
+#endif
}
next prev parent reply other threads:[~2009-03-01 10:49 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-28 16:17 Efiemu phcoder
2009-03-01 10:49 ` phcoder [this message]
2009-03-01 20:00 ` Efiemu Bean
2009-03-01 21:13 ` Efiemu phcoder
2009-03-20 19:32 ` Efiemu phcoder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49AA682D.4040602@gmail.com \
--to=phcoder@gmail.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.