All of lore.kernel.org
 help / color / mirror / Atom feed
* for ppc, include all modules in the core image
@ 2012-10-16 10:28 Paulo Flabiano Smorigo/Brazil/IBM
  2012-10-18 18:08 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 5+ messages in thread
From: Paulo Flabiano Smorigo/Brazil/IBM @ 2012-10-16 10:28 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 957 bytes --]

Hi all!

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).

-- 
Paulo Flabiano Smorigo
Software Engineer
Linux Technology Center - IBM Systems & Technology Group

[-- Attachment #2: ppc_include_modules.patch --]
[-- Type: text/x-patch, Size: 9303 bytes --]

=== modified file 'ChangeLog'
--- ChangeLog	2012-10-12 14:37:49 +0000
+++ ChangeLog	2012-10-16 00:22:26 +0000
@@ -1,3 +1,24 @@
+2012-10-15  Paulo Flabiano Smorigo  <pfsmorigo@br.ibm.com>
+
+	For ppc, include all modules inside core.elf just in case of grub
+	rescue. The additional modules aren't loaded automatically, only
+	when the insmod command is called.
+
+	* grub-core/kern/dl.c (grub_dl_load_core_by_name): New function that
+	search for modules inside the core by its name.
+	(grub_dl_load): If the file is not found try using the new funtion.
+	* include/grub/dl.h (grub_dl_load_core_by_name): New proto.
+	* grub-core/kern/corecmd.c (grub_core_cmd_insmod): Add a call to the
+	new funtion.
+	* include/grub/kernel.h (OBJ_TYPE_ELF_STALE): New enum value.
+	* util/resolve.c (grub_util_create_complementary_module_list): New
+	function.
+	* include/grub/util/resolve.h
+	(grub_util_create_complementary_module_list): New proto.
+	* util/grub-mkimage.c (generate_image): Include additional modules
+	using the new function.
+	Based on suggestions from Gustavo Luiz Duarte.
+
 2012-10-12  Christoph Junghans  <ottxor@gentoo.org>
 
 	* grub-core/Makefile.am (moddep.lst): Use $(AWK) rather than awk.

=== modified file 'grub-core/kern/corecmd.c'
--- grub-core/kern/corecmd.c	2012-02-24 10:18:06 +0000
+++ grub-core/kern/corecmd.c	2012-10-15 23:33:08 +0000
@@ -89,6 +89,9 @@
   else
     mod = grub_dl_load (argv[0]);
 
+  if (!mod)
+    grub_dl_load_core_by_name (argv[0]);
+
   if (mod)
     grub_dl_ref (mod);
 

=== modified file 'grub-core/kern/dl.c'
--- grub-core/kern/dl.c	2012-03-19 10:10:11 +0000
+++ grub-core/kern/dl.c	2012-10-15 23:33:08 +0000
@@ -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)
@@ -47,6 +48,7 @@
 #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);
@@ -659,6 +661,57 @@
   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)
@@ -718,13 +771,19 @@
     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;

=== modified file 'include/grub/dl.h'
--- include/grub/dl.h	2012-02-29 13:51:09 +0000
+++ include/grub/dl.h	2012-10-15 23:33:08 +0000
@@ -181,6 +181,7 @@
 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);

=== modified file 'include/grub/kernel.h'
--- include/grub/kernel.h	2012-02-29 18:02:18 +0000
+++ include/grub/kernel.h	2012-10-15 23:33:08 +0000
@@ -25,6 +25,7 @@
 enum
 {
   OBJ_TYPE_ELF,
+  OBJ_TYPE_ELF_STALE,
   OBJ_TYPE_MEMDISK,
   OBJ_TYPE_CONFIG,
   OBJ_TYPE_PREFIX

=== modified file 'include/grub/util/resolve.h'
--- include/grub/util/resolve.h	2007-07-21 23:32:33 +0000
+++ include/grub/util/resolve.h	2012-10-15 23:33:08 +0000
@@ -32,4 +32,9 @@
 				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 */

=== modified file 'util/grub-mkimage.c'
--- util/grub-mkimage.c	2012-06-26 01:38:10 +0000
+++ util/grub-mkimage.c	2012-10-15 23:33:08 +0000
@@ -711,7 +711,7 @@
   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;
@@ -727,6 +727,10 @@
 
   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)
@@ -761,6 +765,10 @@
     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);
 
@@ -835,6 +843,25 @@
       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;
+    }
+
   if (memdisk_path)
     {
       struct grub_module_header *header;
@@ -1639,6 +1666,14 @@
       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;
+    }
 }
 
 \f

=== modified file 'util/resolve.c'
--- util/resolve.c	2012-03-02 10:18:11 +0000
+++ util/resolve.c	2012-10-15 23:33:08 +0000
@@ -271,3 +271,60 @@
     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;
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-02-02  6:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-16 10:28 for ppc, include all modules in the core image Paulo Flabiano Smorigo/Brazil/IBM
2012-10-18 18:08 ` Vladimir 'φ-coder/phcoder' Serbinenko
2012-10-22 17:30   ` Paulo Flabiano Smorigo/Brazil/IBM
2012-10-22 17:53     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-02-02  6:33       ` Andrey Borzenkov

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.