Various ppc updates.

This commit is contained in:
Peter Jones 2012-10-18 13:47:39 -04:00
parent 8ea95694cb
commit f2e5630d7d
5 changed files with 776 additions and 1 deletions

View file

@ -0,0 +1,230 @@
From 3e00d82827f80461f9fe6da37acd84235c08e5a5 Mon Sep 17 00:00:00 2001
From: Gustavo Luiz Duarte <gustavold@linux.vnet.ibm.com>
Date: Fri, 28 Sep 2012 19:42:07 -0400
Subject: [PATCH] Issue separate DNS queries for ipv4 and ipv6
Adding multiple questions on a single DNS query is not supportted by
most DNS servers. This patch issues two separate DNS queries
sequentially for ipv4 and then for ipv6.
There are 4 possible config options:
DNS_OPTION_IPV4: issue only one ipv4 query
DNS_OPTION_IPV6: issue only one ipv6 query
DNS_OPTION_PREFER_IPV4: issue the ipv4 query first and fallback to ipv6
DNS_OPTION_PREFER_IPV6: issue the ipv6 query first and fallback to ipv4
However, there is no code yet to set such config option. The default is
DNS_OPTION_PREFER_IPV4.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=860829
---
grub-core/net/dns.c | 99 ++++++++++++++++++++++++++++++++++++-----------------
include/grub/net.h | 9 +++++
2 files changed, 76 insertions(+), 32 deletions(-)
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index 3381ea7..725725c 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -34,6 +34,14 @@ struct dns_cache_element
#define DNS_CACHE_SIZE 1021
#define DNS_HASH_BASE 423
+typedef enum grub_dns_qtype_id
+ {
+ GRUB_DNS_QTYPE_A = 1,
+ GRUB_DNS_QTYPE_AAAA = 28
+ } grub_dns_qtype_id_t;
+
+static grub_dns_option_t dns_type_option = DNS_OPTION_PREFER_IPV4;
+
static struct dns_cache_element dns_cache[DNS_CACHE_SIZE];
static struct grub_net_network_level_address *dns_servers;
static grub_size_t dns_nservers, dns_servers_alloc;
@@ -410,13 +418,13 @@ recv_hook (grub_net_udp_socket_t sock __attribute__ ((unused)),
return GRUB_ERR_NONE;
}
-grub_err_t
-grub_net_dns_lookup (const char *name,
+static grub_err_t
+grub_net_dns_lookup_qtype (const char *name,
const struct grub_net_network_level_address *servers,
grub_size_t n_servers,
grub_size_t *naddresses,
struct grub_net_network_level_address **addresses,
- int cache)
+ int cache, grub_dns_qtype_id_t qtype)
{
grub_size_t send_servers = 0;
grub_size_t i, j;
@@ -471,8 +479,7 @@ grub_net_dns_lookup (const char *name,
+ GRUB_NET_MAX_LINK_HEADER_SIZE
+ GRUB_NET_UDP_HEADER_SIZE
+ sizeof (struct dns_header)
- + grub_strlen (name) + 2 + 4
- + 2 + 4);
+ + grub_strlen (name) + 2 + 4);
if (!nb)
{
grub_free (data.name);
@@ -482,7 +489,7 @@ grub_net_dns_lookup (const char *name,
+ GRUB_NET_MAX_LINK_HEADER_SIZE
+ GRUB_NET_UDP_HEADER_SIZE);
grub_netbuff_put (nb, sizeof (struct dns_header)
- + grub_strlen (name) + 2 + 4 + 2 + 4);
+ + grub_strlen (name) + 2 + 4);
head = (struct dns_header *) nb->data;
optr = (grub_uint8_t *) (head + 1);
for (iptr = name; *iptr; )
@@ -509,18 +516,7 @@ grub_net_dns_lookup (const char *name,
/* Type: A. */
*optr++ = 0;
- *optr++ = 1;
-
- /* Class. */
- *optr++ = 0;
- *optr++ = 1;
-
- /* Compressed name. */
- *optr++ = 0xc0;
- *optr++ = 0x0c;
- /* Type: AAAA. */
- *optr++ = 0;
- *optr++ = 28;
+ *optr++ = qtype;
/* Class. */
*optr++ = 0;
@@ -529,7 +525,7 @@ grub_net_dns_lookup (const char *name,
head->id = data.id;
head->flags = FLAGS_RD;
head->ra_z_r_code = 0;
- head->qdcount = grub_cpu_to_be16_compile_time (2);
+ head->qdcount = grub_cpu_to_be16_compile_time (1);
head->ancount = grub_cpu_to_be16_compile_time (0);
head->nscount = grub_cpu_to_be16_compile_time (0);
head->arcount = grub_cpu_to_be16_compile_time (0);
@@ -587,16 +583,47 @@ grub_net_dns_lookup (const char *name,
if (*data.naddresses)
return GRUB_ERR_NONE;
if (data.dns_err)
- return grub_error (GRUB_ERR_NET_NO_DOMAIN,
- N_("no DNS record found"));
-
+ {
+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n",
+ N_("no DNS record found"), qtype, name);
+ return GRUB_ERR_NET_NO_DOMAIN;
+ }
if (err)
{
grub_errno = err;
return err;
}
- return grub_error (GRUB_ERR_TIMEOUT,
- N_("no DNS reply received"));
+ grub_dprintf ("dns", "%s. QTYPE: %u QNAME: %s\n",
+ N_("no DNS reply received"), qtype, name);
+ return GRUB_ERR_TIMEOUT;
+}
+
+grub_err_t
+grub_net_dns_lookup (const char *name,
+ const struct grub_net_network_level_address *servers,
+ grub_size_t n_servers,
+ grub_size_t *naddresses,
+ struct grub_net_network_level_address **addresses,
+ int cache)
+{
+ if (dns_type_option == DNS_OPTION_IPV6 || dns_type_option == DNS_OPTION_PREFER_IPV6)
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
+ addresses, cache, GRUB_DNS_QTYPE_AAAA);
+ else
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
+ addresses, cache, GRUB_DNS_QTYPE_A);
+ if (!*naddresses)
+ {
+ if (dns_type_option == DNS_OPTION_PREFER_IPV4)
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
+ addresses, cache, GRUB_DNS_QTYPE_AAAA);
+ else if (dns_type_option == DNS_OPTION_PREFER_IPV6)
+ grub_net_dns_lookup_qtype (name, servers, n_servers, naddresses,
+ addresses, cache, GRUB_DNS_QTYPE_A);
+ }
+ if (!*naddresses)
+ return GRUB_ERR_NET_NO_DOMAIN;
+ return GRUB_ERR_NONE;
}
static grub_err_t
@@ -604,22 +631,28 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_err_t err;
- grub_size_t naddresses, i;
+ struct grub_net_network_level_address cmd_server;
+ struct grub_net_network_level_address *servers;
+ grub_size_t nservers, i, naddresses = 0;
struct grub_net_network_level_address *addresses = 0;
if (argc != 2 && argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
if (argc == 2)
{
- struct grub_net_network_level_address server;
- err = grub_net_resolve_address (args[1], &server);
+ err = grub_net_resolve_address (args[1], &cmd_server);
if (err)
return err;
- err = grub_net_dns_lookup (args[0], &server, 1, &naddresses,
- &addresses, 0);
+ servers = &cmd_server;
+ nservers = 1;
}
else
- err = grub_net_dns_lookup (args[0], dns_servers, dns_nservers, &naddresses,
- &addresses, 0);
+ {
+ servers = dns_servers;
+ nservers = dns_nservers;
+ }
+
+ grub_net_dns_lookup (args[0], servers, nservers, &naddresses,
+ &addresses, 0);
for (i = 0; i < naddresses; i++)
{
@@ -628,7 +661,9 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)),
grub_printf ("%s\n", buf);
}
grub_free (addresses);
- return GRUB_ERR_NONE;
+ if (naddresses)
+ return GRUB_ERR_NONE;
+ return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found"));
}
static grub_err_t
diff --git a/include/grub/net.h b/include/grub/net.h
index 3877451..a7e5b2c 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -505,6 +505,15 @@ grub_err_t
grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
const grub_net_network_level_address_t *proto_addr,
grub_net_link_level_address_t *hw_addr);
+
+typedef enum
+ {
+ DNS_OPTION_IPV4,
+ DNS_OPTION_IPV6,
+ DNS_OPTION_PREFER_IPV4,
+ DNS_OPTION_PREFER_IPV6
+ } grub_dns_option_t;
+
grub_err_t
grub_net_dns_lookup (const char *name,
const struct grub_net_network_level_address *servers,
--
1.7.11.4

View file

@ -0,0 +1,174 @@
From be9ee2df83a927d49184026154dd8d5039a8b664 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Date: Thu, 20 Sep 2012 18:07:39 -0300
Subject: [PATCH] IBM client architecture (CAS) reboot support
This is an implementation of IBM client architecture (CAS) reboot for GRUB.
There are cases where the POWER firmware must reboot in order to support
specific features requested by a kernel. The kernel calls
ibm,client-architecture-support and it may either return or reboot with the new
feature set. eg:
Calling ibm,client-architecture-support.../
Elapsed time since release of system processors: 70959 mins 50 secs
Welcome to GRUB!
Instead of return to the GRUB menu, it will check if the flag for CAS reboot is
set. If so, grub will automatically boot the last booted kernel using the same
parameters
---
grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++
grub-core/normal/main.c | 19 ++++++++++++
grub-core/script/execute.c | 7 +++++
include/grub/ieee1275/ieee1275.h | 2 ++
4 files changed, 91 insertions(+)
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
index 40abaa3..c2b1bdf 100644
--- a/grub-core/kern/ieee1275/openfw.c
+++ b/grub-core/kern/ieee1275/openfw.c
@@ -523,3 +523,66 @@ grub_ieee1275_canonicalise_devname (const char *path)
return NULL;
}
+/* Check if it's a CAS reboot. If so, set the script to be executed. */
+int
+grub_ieee1275_cas_reboot (char *script)
+{
+ grub_uint32_t ibm_ca_support_reboot;
+ grub_uint32_t ibm_fw_nbr_reboots;
+ char property_value[10];
+ grub_ssize_t actual;
+ grub_ieee1275_ihandle_t options;
+
+ if (grub_ieee1275_finddevice ("/options", &options) < 0)
+ return -1;
+
+ /* Check two properties, one is enough to get cas reboot value */
+ ibm_ca_support_reboot = 0;
+ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
+ "ibm,client-architecture-support-reboot",
+ &ibm_ca_support_reboot,
+ sizeof (ibm_ca_support_reboot),
+ &actual) >= 0)
+ grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
+ ibm_ca_support_reboot);
+
+ ibm_fw_nbr_reboots = 0;
+ if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots",
+ property_value, sizeof (property_value),
+ &actual) >= 0)
+ {
+ property_value[sizeof (property_value) - 1] = 0;
+ ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10);
+ grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots);
+ }
+
+ if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
+ {
+ if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
+ {
+ if (actual > 1024)
+ script = grub_realloc (script, actual + 1);
+ grub_ieee1275_get_property (options, "boot-last-label", script, actual,
+ &actual);
+ return 0;
+ }
+ }
+
+ grub_ieee1275_set_boot_last_label ("");
+
+ return -1;
+}
+
+int grub_ieee1275_set_boot_last_label (const char *text)
+{
+ grub_ieee1275_ihandle_t options;
+ grub_ssize_t actual;
+
+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text));
+ if (! grub_ieee1275_finddevice ("/options", &options) &&
+ options != (grub_ieee1275_ihandle_t) -1)
+ grub_ieee1275_set_property (options, "boot-last-label", text,
+ grub_strlen (text), &actual);
+ return 0;
+}
+
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 39bb734..aa0b3e5 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -32,6 +32,9 @@
#include <grub/i18n.h>
#include <grub/charset.h>
#include <grub/script_sh.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
GRUB_MOD_LICENSE ("GPLv3+");
@@ -296,6 +299,22 @@ grub_normal_execute (const char *config, int nested, int batch)
{
menu = read_config_file (config);
+#ifdef GRUB_MACHINE_IEEE1275
+ int boot;
+ boot = 0;
+ char *script;
+ script = grub_malloc (1024);
+ if (! grub_ieee1275_cas_reboot (script))
+ {
+ char *dummy[1] = { NULL };
+ if (! grub_script_execute_sourcecode (script, 0, dummy))
+ boot = 1;
+ }
+ grub_free (script);
+ if (boot)
+ grub_command_execute ("boot", 0, 0);
+#endif
+
/* Ignore any error. */
grub_errno = GRUB_ERR_NONE;
}
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index b5e6eb0..4397540 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -27,6 +27,9 @@
#include <grub/normal.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
/* Max digits for a char is 3 (0xFF is 255), similarly for an int it
is sizeof (int) * 3, and one extra for a possible -ve sign. */
@@ -820,6 +823,10 @@ grub_script_execute_sourcecode (const char *source, int argc, char **args)
old_scope = scope;
scope = &new_scope;
+#ifdef GRUB_MACHINE_IEEE1275
+ grub_ieee1275_set_boot_last_label (source);
+#endif
+
while (source)
{
char *line;
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index 38a75fd..416a544 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -208,5 +208,7 @@ int EXPORT_FUNC(grub_ieee1275_devices_iterate) (int (*hook)
char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path);
char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path);
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
#endif /* ! GRUB_IEEE1275_HEADER */
--
1.7.10.4

View file

@ -0,0 +1,28 @@
From 4414df5e72937b0bb1c4a0bb66cd1132ec2a5720 Mon Sep 17 00:00:00 2001
From: Gustavo Luiz Duarte <gustavold@linux.vnet.ibm.com>
Date: Tue, 25 Sep 2012 18:40:55 -0400
Subject: [PATCH] Fix crash on http
Don't free file->data on receiving FIN flag since it is used all over without
checking. http_close() will be called later to free that memory.
https://bugzilla.redhat.com/show_bug.cgi?id=860834
---
grub-core/net/http.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/net/http.c b/grub-core/net/http.c
index a7542d1..a5f6f31 100644
--- a/grub-core/net/http.c
+++ b/grub-core/net/http.c
@@ -386,7 +386,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial)
data->sock = grub_net_tcp_open (file->device->net->server,
HTTP_PORT, http_receive,
- http_err, http_err,
+ http_err, NULL,
file);
if (!data->sock)
{
--
1.7.11.4

View file

@ -0,0 +1,332 @@
From 4613775aee8b413ba89bfb7233d49a4288e13390 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Date: Mon, 15 Oct 2012 17:21:01 -0300
Subject: [PATCH] for ppc, include all modules in the core image
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
---
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 ++++++++++++++++++++++++++++++++++++
7 files changed, 166 insertions(+), 5 deletions(-)
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
index 16c03df..8684139 100644
--- a/grub-core/kern/corecmd.c
+++ b/grub-core/kern/corecmd.c
@@ -100,6 +100,9 @@ grub_core_cmd_insmod (struct grub_command *cmd __attribute__ ((unused)),
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
index 5b0aa65..a498682 100644
--- 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)
@@ -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 @@ grub_dl_load_core (void *addr, grub_size_t size)
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 @@ grub_dl_load (const char *name)
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
index eef4c3f..4cd2cb0 100644
--- 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,
OBJ_TYPE_PREFIX
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
index a551bbb..b06f37a 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -711,7 +711,7 @@ generate_image (const char *dir, const char *prefix,
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 @@ generate_image (const char *dir, const char *prefix,
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 @@ generate_image (const char *dir, const char *prefix,
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 @@ generate_image (const char *dir, const char *prefix,
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 @@ generate_image (const char *dir, const char *prefix,
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;
+}
--
1.7.10.4

View file

@ -41,7 +41,7 @@
Name: grub2 Name: grub2
Epoch: 1 Epoch: 1
Version: 2.00 Version: 2.00
Release: 9%{?dist} Release: 10%{?dist}
Summary: Bootloader with support for Linux, Multiboot and more Summary: Bootloader with support for Linux, Multiboot and more
Group: System Environment/Base Group: System Environment/Base
@ -68,6 +68,10 @@ Patch24: grub-2.00-no-insmod-on-sb.patch
Patch25: grub-2.00-efidisk-ahci-workaround.patch Patch25: grub-2.00-efidisk-ahci-workaround.patch
Patch26: grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch Patch26: grub-2.00-increase-the-ieee1275-device-path-buffer-size.patch
Patch27: grub-2.00-Handle-escapes-in-labels.patch Patch27: grub-2.00-Handle-escapes-in-labels.patch
Patch28: grub-2.00-fix-http-crash.patch
Patch29: grub-2.00-Issue-separate-DNS-queries-for-ipv4-and-ipv6.patch
Patch30: grub-2.00-cas-reboot-support.patch
Patch31: grub-2.00-for-ppc-include-all-modules-in-the-core-image.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@ -421,6 +425,13 @@ fi
%doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0 %doc grub-%{tarversion}/themes/starfield/COPYING.CC-BY-SA-3.0
%changelog %changelog
* Thu Oct 18 2012 Peter Jones <pjones@redhat.com> - 2.00-10
- Various PPC fixes.
- Fix crash fetching from http (gustavold, #860834)
- Issue separate dns queries for ipv4 and ipv6 (gustavold, #860829)
- Support IBM CAS reboot (pfsmorigo, #859223)
- Include all modules in the core image on ppc (pfsmorigo, #866559)
* Mon Oct 01 2012 Peter Jones <pjones@redhat.com> - 1:2.00-9 * Mon Oct 01 2012 Peter Jones <pjones@redhat.com> - 1:2.00-9
- Work around bug with using "\x20" in linux command line. - Work around bug with using "\x20" in linux command line.
Related: rhbz#855849 Related: rhbz#855849