2013-05-02 20:54:52 +00:00
|
|
|
|
From 3c4e4115b161354823e6b6a6f6c9da2fa3f3962c Mon Sep 17 00:00:00 2001
|
2012-10-18 17:47:39 +00:00
|
|
|
|
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
|
|
|
|
|
Date: Mon, 15 Oct 2012 17:21:01 -0300
|
2013-05-02 20:54:52 +00:00
|
|
|
|
Subject: [PATCH 355/364] for ppc, include all modules in the core image
|
2012-10-18 17:47:39 +00:00
|
|
|
|
|
|
|
|
|
This patch implements the solution suggested by Gustavo Luiz Duarte
|
|
|
|
|
<gustavold@linux.vnet.ibm.com>:
|
|
|
|
|
|
|
|
|
|
Adding more modules to be built-in to the grub core ELF is easy. It is a
|
|
|
|
|
parameter passed by grub2-install to grub2-mkimage. However, there is a downside
|
|
|
|
|
on adding many modules to the core ELF: they are fully initialized in the grub's
|
|
|
|
|
first stage. It means you could hit a bug on a module you don't need and end up
|
|
|
|
|
with a non-bootable system.
|
|
|
|
|
|
|
|
|
|
Another downside is that you wouldn't get updates for these built-in modules, as
|
|
|
|
|
updating the grub2 package only updates the modules residing in /boot and not
|
|
|
|
|
the grub core ELF in the PReP partition.
|
|
|
|
|
|
|
|
|
|
A proper solution would be to add to grub the ability of having built-in
|
|
|
|
|
*inactive* modules which would be loaded and initialized only on demand (i.e.
|
|
|
|
|
explicitly calling the insmod command).
|
|
|
|
|
|
|
|
|
|
This patch fix this bugzilla:
|
|
|
|
|
https://bugzilla.redhat.com/show_bug.cgi?id=866559
|
|
|
|
|
---
|
2013-05-02 20:54:52 +00:00
|
|
|
|
grub-core/kern/corecmd.c | 3 ++
|
|
|
|
|
grub-core/kern/dl.c | 67 ++++++++++++++++++++++++++++++++++++++++++---
|
|
|
|
|
include/grub/dl.h | 1 +
|
|
|
|
|
include/grub/kernel.h | 1 +
|
|
|
|
|
include/grub/util/resolve.h | 5 ++++
|
|
|
|
|
util/grub-mkimage.c | 37 ++++++++++++++++++++++++-
|
|
|
|
|
util/resolve.c | 57 ++++++++++++++++++++++++++++++++++++++
|
2012-10-18 17:47:39 +00:00
|
|
|
|
7 files changed, 166 insertions(+), 5 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
2013-05-02 20:54:52 +00:00
|
|
|
|
index cfab676..a4465eb 100644
|
2012-10-18 17:47:39 +00:00
|
|
|
|
--- a/grub-core/kern/corecmd.c
|
|
|
|
|
+++ b/grub-core/kern/corecmd.c
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -83,6 +83,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
|
2012-10-18 17:47:39 +00:00
|
|
|
|
else
|
|
|
|
|
mod = grub_dl_load (argv[0]);
|
|
|
|
|
|
|
|
|
|
+ if (!mod)
|
|
|
|
|
+ grub_dl_load_core_by_name (argv[0]);
|
|
|
|
|
+
|
|
|
|
|
if (mod)
|
|
|
|
|
grub_dl_ref (mod);
|
|
|
|
|
|
|
|
|
|
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
2013-05-02 20:54:52 +00:00
|
|
|
|
index 570be12..fe46aa4 100644
|
2012-10-18 17:47:39 +00:00
|
|
|
|
--- a/grub-core/kern/dl.c
|
|
|
|
|
+++ b/grub-core/kern/dl.c
|
|
|
|
|
@@ -32,6 +32,7 @@
|
|
|
|
|
#include <grub/env.h>
|
|
|
|
|
#include <grub/cache.h>
|
|
|
|
|
#include <grub/i18n.h>
|
|
|
|
|
+#include <grub/kernel.h>
|
|
|
|
|
|
|
|
|
|
/* Platforms where modules are in a readonly area of memory. */
|
|
|
|
|
#if defined(GRUB_MACHINE_QEMU)
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -51,6 +52,7 @@
|
2012-10-18 17:47:39 +00:00
|
|
|
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
|
|
|
|
|
|
|
|
|
grub_dl_t grub_dl_head = 0;
|
|
|
|
|
+char grub_use_stale_modules = 0;
|
|
|
|
|
|
|
|
|
|
grub_err_t
|
|
|
|
|
grub_dl_add (grub_dl_t mod);
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -668,6 +670,57 @@ grub_dl_load_core (void *addr, grub_size_t size)
|
2012-10-18 17:47:39 +00:00
|
|
|
|
return mod;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* Load a module from core using a symbolic name. */
|
|
|
|
|
+grub_dl_t
|
|
|
|
|
+grub_dl_load_core_by_name (const char *name)
|
|
|
|
|
+{
|
|
|
|
|
+ struct grub_module_header *header;
|
|
|
|
|
+ grub_dl_t mod;
|
|
|
|
|
+ char *module_addr;
|
|
|
|
|
+
|
|
|
|
|
+ mod = (grub_dl_t) grub_zalloc (sizeof (*mod));
|
|
|
|
|
+ if (! mod)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+ grub_use_stale_modules = 1;
|
|
|
|
|
+
|
|
|
|
|
+ FOR_MODULES (header)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* Not an ELF module, skip. */
|
|
|
|
|
+ if ((header->type != OBJ_TYPE_ELF) &&
|
|
|
|
|
+ (header->type != OBJ_TYPE_ELF_STALE))
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ module_addr = (char *) header + sizeof (struct grub_module_header);
|
|
|
|
|
+ grub_dl_resolve_name (mod, (Elf_Ehdr *) module_addr);
|
|
|
|
|
+
|
|
|
|
|
+ if (grub_strcmp(name, mod->name) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ grub_printf ("WARNING: You are using the built-in '%s' module!\n", name);
|
|
|
|
|
+
|
|
|
|
|
+ mod = grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
|
|
|
|
|
+ (header->size - sizeof (struct grub_module_header)));
|
|
|
|
|
+
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ mod = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (! mod)
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ if (grub_errno == GRUB_ERR_IO)
|
|
|
|
|
+ grub_errno = GRUB_ERR_NONE;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (grub_strcmp (mod->name, name) != 0)
|
|
|
|
|
+ grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
|
|
|
|
|
+
|
|
|
|
|
+ return mod;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
/* Load a module from the file FILENAME. */
|
|
|
|
|
grub_dl_t
|
|
|
|
|
grub_dl_load_file (const char *filename)
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -740,13 +793,19 @@ grub_dl_load (const char *name)
|
2012-10-18 17:47:39 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /* First, try to load module from the grub directory */
|
|
|
|
|
filename = grub_xasprintf ("%s/" GRUB_TARGET_CPU "-" GRUB_PLATFORM "/%s.mod",
|
|
|
|
|
grub_dl_dir, name);
|
|
|
|
|
- if (! filename)
|
|
|
|
|
- return 0;
|
|
|
|
|
+ if (filename)
|
|
|
|
|
+ {
|
|
|
|
|
+ mod = grub_dl_load_file (filename);
|
|
|
|
|
+ grub_free (filename);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- mod = grub_dl_load_file (filename);
|
|
|
|
|
- grub_free (filename);
|
|
|
|
|
+ /* If the module isn't loaded, check if there is a stale module available and
|
|
|
|
|
+ * use it*/
|
|
|
|
|
+ if (! mod && grub_use_stale_modules)
|
|
|
|
|
+ mod = grub_dl_load_core_by_name (name);
|
|
|
|
|
|
|
|
|
|
if (! mod)
|
|
|
|
|
return 0;
|
|
|
|
|
diff --git a/include/grub/dl.h b/include/grub/dl.h
|
|
|
|
|
index 3119978..30f12f9 100644
|
|
|
|
|
--- a/include/grub/dl.h
|
|
|
|
|
+++ b/include/grub/dl.h
|
|
|
|
|
@@ -181,6 +181,7 @@ typedef struct grub_dl *grub_dl_t;
|
|
|
|
|
grub_dl_t grub_dl_load_file (const char *filename);
|
|
|
|
|
grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
|
|
|
|
|
grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
|
|
|
|
|
+grub_dl_t grub_dl_load_core_by_name (const char *name);
|
|
|
|
|
int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
|
|
|
|
|
void grub_dl_unload_unneeded (void);
|
|
|
|
|
int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
|
|
|
|
|
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
2013-05-02 20:54:52 +00:00
|
|
|
|
index 73ea416..e837b1f 100644
|
2012-10-18 17:47:39 +00:00
|
|
|
|
--- a/include/grub/kernel.h
|
|
|
|
|
+++ b/include/grub/kernel.h
|
|
|
|
|
@@ -25,6 +25,7 @@
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
OBJ_TYPE_ELF,
|
|
|
|
|
+ OBJ_TYPE_ELF_STALE,
|
|
|
|
|
OBJ_TYPE_MEMDISK,
|
|
|
|
|
OBJ_TYPE_CONFIG,
|
2013-05-02 20:54:52 +00:00
|
|
|
|
OBJ_TYPE_PREFIX,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
diff --git a/include/grub/util/resolve.h b/include/grub/util/resolve.h
|
|
|
|
|
index f42df32..1d0252c 100644
|
|
|
|
|
--- a/include/grub/util/resolve.h
|
|
|
|
|
+++ b/include/grub/util/resolve.h
|
|
|
|
|
@@ -32,4 +32,9 @@ grub_util_resolve_dependencies (const char *prefix,
|
|
|
|
|
const char *dep_list_file,
|
|
|
|
|
char *modules[]);
|
|
|
|
|
|
|
|
|
|
+struct grub_util_path_list *
|
|
|
|
|
+grub_util_create_complementary_module_list (const char *prefix,
|
|
|
|
|
+ const char *dep_list_file,
|
|
|
|
|
+ struct grub_util_path_list *path_list);
|
|
|
|
|
+
|
|
|
|
|
#endif /* ! GRUB_UTIL_RESOLVE_HEADER */
|
|
|
|
|
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
2013-05-02 20:54:52 +00:00
|
|
|
|
index 41f795a..fa601ec 100644
|
2012-10-18 17:47:39 +00:00
|
|
|
|
--- a/util/grub-mkimage.c
|
|
|
|
|
+++ b/util/grub-mkimage.c
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -729,7 +729,7 @@ generate_image (const char *dir, const char *prefix,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
size_t prefix_size = 0;
|
|
|
|
|
char *kernel_path;
|
|
|
|
|
size_t offset;
|
|
|
|
|
- struct grub_util_path_list *path_list, *p, *next;
|
|
|
|
|
+ struct grub_util_path_list *path_list, *path_list_comp = 0, *p, *next;
|
|
|
|
|
grub_size_t bss_size;
|
|
|
|
|
grub_uint64_t start_address;
|
|
|
|
|
void *rel_section = 0;
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -745,6 +745,10 @@ generate_image (const char *dir, const char *prefix,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
|
|
|
|
|
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
|
|
|
|
|
|
|
|
|
|
+ if (image_target->id == IMAGE_PPC)
|
|
|
|
|
+ path_list_comp = grub_util_create_complementary_module_list (dir,
|
|
|
|
|
+ "moddep.lst", path_list);
|
|
|
|
|
+
|
|
|
|
|
kernel_path = grub_util_get_path (dir, "kernel.img");
|
|
|
|
|
|
|
|
|
|
if (image_target->voidp_sizeof == 8)
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -791,6 +795,10 @@ generate_image (const char *dir, const char *prefix,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
|
|
|
|
|
+ sizeof (struct grub_module_header));
|
|
|
|
|
|
|
|
|
|
+ for (p = path_list_comp; p; p = p->next)
|
|
|
|
|
+ total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name))
|
|
|
|
|
+ + sizeof (struct grub_module_header));
|
|
|
|
|
+
|
|
|
|
|
grub_util_info ("the total module size is 0x%llx",
|
|
|
|
|
(unsigned long long) total_module_size);
|
|
|
|
|
|
2013-05-02 20:54:52 +00:00
|
|
|
|
@@ -865,6 +873,25 @@ generate_image (const char *dir, const char *prefix,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
offset += mod_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ for (p = path_list_comp; p; p = p->next)
|
|
|
|
|
+ {
|
|
|
|
|
+ struct grub_module_header *header;
|
|
|
|
|
+ size_t mod_size, orig_size;
|
|
|
|
|
+
|
|
|
|
|
+ orig_size = grub_util_get_image_size (p->name);
|
|
|
|
|
+ mod_size = ALIGN_ADDR (orig_size);
|
|
|
|
|
+
|
|
|
|
|
+ header = (struct grub_module_header *) (kernel_img + offset);
|
|
|
|
|
+ memset (header, 0, sizeof (struct grub_module_header));
|
|
|
|
|
+ header->type = grub_host_to_target32 (OBJ_TYPE_ELF_STALE);
|
|
|
|
|
+ header->size = grub_host_to_target32 (mod_size + sizeof (*header));
|
|
|
|
|
+ offset += sizeof (*header);
|
|
|
|
|
+ memset (kernel_img + offset + orig_size, 0, mod_size - orig_size);
|
|
|
|
|
+
|
|
|
|
|
+ grub_util_load_image (p->name, kernel_img + offset);
|
|
|
|
|
+ offset += mod_size;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
2013-05-02 20:54:52 +00:00
|
|
|
|
{
|
|
|
|
|
size_t i;
|
|
|
|
|
for (i = 0; i < npubkeys; i++)
|
|
|
|
|
@@ -1714,6 +1741,14 @@ generate_image (const char *dir, const char *prefix,
|
2012-10-18 17:47:39 +00:00
|
|
|
|
free (path_list);
|
|
|
|
|
path_list = next;
|
|
|
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ while (path_list_comp)
|
|
|
|
|
+ {
|
|
|
|
|
+ next = path_list_comp->next;
|
|
|
|
|
+ free ((void *) path_list_comp->name);
|
|
|
|
|
+ free (path_list_comp);
|
|
|
|
|
+ path_list_comp = next;
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diff --git a/util/resolve.c b/util/resolve.c
|
|
|
|
|
index 1af24e6..997db99 100644
|
|
|
|
|
--- a/util/resolve.c
|
|
|
|
|
+++ b/util/resolve.c
|
|
|
|
|
@@ -271,3 +271,60 @@ grub_util_resolve_dependencies (const char *prefix,
|
|
|
|
|
return prev;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+struct grub_util_path_list *
|
|
|
|
|
+grub_util_create_complementary_module_list (const char *prefix,
|
|
|
|
|
+ const char *dep_list_file,
|
|
|
|
|
+ struct grub_util_path_list *path_list)
|
|
|
|
|
+{
|
|
|
|
|
+ char *path;
|
|
|
|
|
+ FILE *fp;
|
|
|
|
|
+ struct grub_util_path_list *path_list_comp = 0;
|
|
|
|
|
+ struct grub_util_path_list *new_path;
|
|
|
|
|
+ char skip;
|
|
|
|
|
+
|
|
|
|
|
+ path = grub_util_get_path (prefix, dep_list_file);
|
|
|
|
|
+ fp = fopen (path, "r");
|
|
|
|
|
+ if (! fp)
|
|
|
|
|
+ grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
|
|
|
|
|
+
|
|
|
|
|
+ while (fgets (buf, sizeof (buf), fp))
|
|
|
|
|
+ {
|
|
|
|
|
+ char *p;
|
|
|
|
|
+ struct grub_util_path_list *pl;
|
|
|
|
|
+
|
|
|
|
|
+ skip = 0;
|
|
|
|
|
+
|
|
|
|
|
+ /* Get the target name. */
|
|
|
|
|
+ p = strchr (buf, ':');
|
|
|
|
|
+ if (! p)
|
|
|
|
|
+ grub_util_error (_("invalid line format: %s"), buf);
|
|
|
|
|
+
|
|
|
|
|
+ *p++ = '\0';
|
|
|
|
|
+
|
|
|
|
|
+ /* kernel is not a module */
|
|
|
|
|
+ if (strcmp(buf, "kernel") == 0)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ /* Check if the module is already in the core. */
|
|
|
|
|
+ for (pl = path_list; pl; pl = pl->next)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (strcmp(buf, get_module_name(pl->name)) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ skip = 1;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (skip)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ /* Add the new path. */
|
|
|
|
|
+ new_path = (struct grub_util_path_list *) xmalloc (sizeof (*new_path));
|
|
|
|
|
+ new_path->name = get_module_path (prefix, buf);
|
|
|
|
|
+ new_path->next = path_list_comp;
|
|
|
|
|
+ path_list_comp = new_path;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return path_list_comp;
|
|
|
|
|
+}
|
|
|
|
|
--
|
2013-05-02 20:54:52 +00:00
|
|
|
|
1.8.1.4
|
2012-10-18 17:47:39 +00:00
|
|
|
|
|