aboutsummaryrefslogtreecommitdiff
path: root/grub-core/kern/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'grub-core/kern/main.c')
-rw-r--r--grub-core/kern/main.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 99477c7..19dc988 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -30,10 +30,10 @@
#include <grub/reader.h>
#include <grub/parser.h>
-/* This is actualy platform-independant but used only on some platforms. */
-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || \
- defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) || \
- defined (GRUB_MACHINE_ARM)
+#ifdef GRUB_MACHINE_PCBIOS
+#include <grub/machine/memory.h>
+#endif
+
grub_addr_t
grub_modules_get_end (void)
{
@@ -47,7 +47,6 @@ grub_modules_get_end (void)
return grub_modbase + modinfo->size;
}
-#endif
/* Load all modules in core. */
static void
@@ -69,6 +68,8 @@ grub_load_modules (void)
}
}
+static char *load_config;
+
static void
grub_load_config (void)
{
@@ -78,9 +79,17 @@ grub_load_config (void)
/* Not an embedded config, skip. */
if (header->type != OBJ_TYPE_CONFIG)
continue;
-
- grub_parser_execute ((char *) header +
- sizeof (struct grub_module_header));
+
+ load_config = grub_malloc (header->size - sizeof (struct grub_module_header) + 1);
+ if (!load_config)
+ {
+ grub_print_error ();
+ break;
+ }
+ grub_memcpy (load_config, (char *) header +
+ sizeof (struct grub_module_header),
+ header->size - sizeof (struct grub_module_header));
+ load_config[header->size - sizeof (struct grub_module_header)] = 0;
break;
}
}
@@ -170,7 +179,16 @@ grub_set_prefix_and_root (void)
else
grub_free (fwdevice);
if (fwpath && !path)
- path = fwpath;
+ {
+ grub_size_t len = grub_strlen (fwpath);
+ while (len > 1 && fwpath[len - 1] == '/')
+ fwpath[--len] = 0;
+ if (len >= sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1
+ && grub_memcmp (fwpath + len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1), GRUB_TARGET_CPU "-" GRUB_PLATFORM,
+ sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1) == 0)
+ fwpath[len - (sizeof (GRUB_TARGET_CPU "-" GRUB_PLATFORM) - 1)] = 0;
+ path = fwpath;
+ }
else
grub_free (fwpath);
if (device)
@@ -205,6 +223,30 @@ grub_load_normal_mode (void)
grub_command_execute ("normal", 0, 0);
}
+static void
+reclaim_module_space (void)
+{
+ grub_addr_t modstart, modend;
+
+ if (!grub_modbase)
+ return;
+
+#ifdef GRUB_MACHINE_PCBIOS
+ modstart = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR;
+#else
+ modstart = grub_modbase;
+#endif
+ modend = grub_modules_get_end ();
+ grub_modbase = 0;
+
+#if GRUB_KERNEL_PRELOAD_SPACE_REUSABLE
+ grub_mm_init_region ((void *) modstart, modend - modstart);
+#else
+ (void) modstart;
+ (void) modend;
+#endif
+}
+
/* The main routine. */
void __attribute__ ((noreturn))
grub_main (void)
@@ -212,11 +254,17 @@ grub_main (void)
/* First of all, initialize the machine. */
grub_machine_init ();
+ grub_boot_time ("After machine init.");
+
/* Hello. */
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("Welcome to GRUB!\n\n");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+ grub_load_config ();
+
+ grub_boot_time ("Before loading embedded modules.");
+
/* Load pre-loaded modules and free the space. */
grub_register_exported_symbols ();
#ifdef GRUB_LINKER_HAVE_INIT
@@ -224,15 +272,28 @@ grub_main (void)
#endif
grub_load_modules ();
+ grub_boot_time ("After loading embedded modules.");
+
/* It is better to set the root device as soon as possible,
for convenience. */
grub_set_prefix_and_root ();
grub_env_export ("root");
grub_env_export ("prefix");
+ /* Reclaim space used for modules. */
+ reclaim_module_space ();
+
+ grub_boot_time ("After reclaiming module space.");
+
grub_register_core_commands ();
- grub_load_config ();
+ grub_boot_time ("Before execution of embedded config.");
+
+ if (load_config)
+ grub_parser_execute (load_config);
+
+ grub_boot_time ("After execution of embedded config. Attempt to go to normal mode");
+
grub_load_normal_mode ();
grub_rescue_run ();
}