]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2006-04-25 Yoshinori K. Okuji <okuji@enbug.org>
authorokuji <okuji@localhost>
Tue, 25 Apr 2006 20:08:31 +0000 (20:08 +0000)
committerokuji <okuji@localhost>
Tue, 25 Apr 2006 20:08:31 +0000 (20:08 +0000)
        A new machine-specific function "grub_machine_set_prefix" is
        defined. This is called after loading modules, so that a prefix
        initialization can use modules. Also, this change adds an
        intensive debugging feature for the memory manager via the
        configure option "--enable-mm-debug".

        * partmap/gpt.c (gpt_partition_map_iterate): Add one more into
        PART.LEN.

        * kern/sparc64/ieee1275/init.c (abort): Removed.
        (grub_stop): Likewise.
        (grub_exit): New function.
        (grub_set_prefix): Renamed to ...
        (grub_machine_set_prefix): ... this.
        (grub_machine_init): Do not call grub_set_prefix.

        * kern/powerpc/ieee1275/init.c (grub_set_prefix): Renamed to ...
        (grub_machine_set_prefix): ... this.
        (grub_machine_init): Do not call grub_set_prefix.

        * kern/i386/pc/init.c (grub_machine_set_prefix): New function.
        (grub_machine_init): Do not set the prefix here.

        * kern/i386/efi/init.c (grub_machine_set_prefix): New function.

        * kern/efi/init.c: Include grub/mm.h.
        (grub_efi_set_prefix): New function.

        * kern/efi/efi.c (grub_exit): Call grub_efi_fini.
        (grub_efi_get_filename): New function.
        (grub_print_device_path): Renamed to ...
        (grub_efi_print_device_path): ... this.

        * kern/mm.c [MM_DEBUG] (grub_malloc): Undefined.
        [MM_DEBUG] (grub_realloc): Likewise.
        [MM_DEBUG] (grub_free): Likewise.
        [MM_DEBUG] (grub_memalign): Likewise.
        [MM_DEBUG] (grub_mm_debug): New variable.
        [MM_DEBUG] (grub_debug_malloc): New function.
        [MM_DEBUG] (grub_debug_free): New function.
        [MM_DEBUG] (grub_debug_realloc): New function.
        [MM_DEBUG] (grub_debug_memalign): New function.

        * kern/misc.c (grub_abort): Print a newline to distinguish
        the message.

        * kern/main.c (grub_main): Call grub_machine_set_prefix and
        grub_set_root_dev after loading modules. This is necessary when
        setting a prefix depends on modules.

        * include/grub/efi/efi.h (grub_print_device_path): Renamed to ...
        (grub_efi_print_device_path): ... this.
        (grub_efi_get_filename): New prototype.
        (grub_efi_set_prefix): Likewise.

        * include/grub/efi/disk.h: Include grub/efi/api.h, grub/symbol.h
        and grub/disk.h.
        (grub_efidisk_get_device_handle): New prototype.
        (grub_efidisk_get_device_name): Likewise.

        * include/grub/mm.h: Include config.h.
        (MM_DEBUG): Removed.
        [MM_DEBUG && !GRUB_UTIL] (grub_mm_debug): New prototype.
        [MM_DEBUG && !GRUB_UTIL] (grub_malloc): New macro.
        [MM_DEBUG && !GRUB_UTIL] (grub_realloc): Likewise.
        [MM_DEBUG && !GRUB_UTIL] (grub_memalign): Likewise.
        [MM_DEBUG && !GRUB_UTIL] (grub_free): Likewise.
        [MM_DEBUG && !GRUB_UTIL] (grub_debug_malloc): New prototype.
        [MM_DEBUG && !GRUB_UTIL] (grub_debug_realloc): New prototype.
        [MM_DEBUG && !GRUB_UTIL] (grub_debug_memalign): New prototype.
        [MM_DEBUG && !GRUB_UTIL] (grub_debug_free): New prototype.

        * include/grub/kernel.h (grub_machine_set_prefix): New prototype.

        * disk/efi/efidisk.c: Include grub/partition.h.
        (iterate_child_devices): New function.
        (add_device): First, compare only last device path nodes, so that
        devices are sorted by the types.
        (grub_efidisk_get_device_handle): New function.
        (grub_efidisk_get_device_name): Likewise.

        * configure.ac (--enable-mm-debug): New option to enable the
        memory manager debugging feature. This makes the binary much
        bigger, so is disabled by default.

19 files changed:
ChangeLog
config.h.in
configure
configure.ac
disk/efi/efidisk.c
include/grub/efi/disk.h
include/grub/efi/efi.h
include/grub/kernel.h
include/grub/mm.h
kern/efi/efi.c
kern/efi/init.c
kern/i386/efi/init.c
kern/i386/pc/init.c
kern/main.c
kern/misc.c
kern/mm.c
kern/powerpc/ieee1275/init.c
kern/sparc64/ieee1275/init.c
partmap/gpt.c

index 0924d172710ea38c2934f5a121cf863a473712d9..0d62c22dab1bac9e67983c75456a374c33df8401 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,90 @@
+2006-04-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+       A new machine-specific function "grub_machine_set_prefix" is
+       defined. This is called after loading modules, so that a prefix
+       initialization can use modules. Also, this change adds an
+       intensive debugging feature for the memory manager via the
+       configure option "--enable-mm-debug".
+       
+       * partmap/gpt.c (gpt_partition_map_iterate): Add one more into
+       PART.LEN.
+
+       * kern/sparc64/ieee1275/init.c (abort): Removed.
+       (grub_stop): Likewise.
+       (grub_exit): New function.
+       (grub_set_prefix): Renamed to ...
+       (grub_machine_set_prefix): ... this.
+       (grub_machine_init): Do not call grub_set_prefix.
+
+       * kern/powerpc/ieee1275/init.c (grub_set_prefix): Renamed to ...
+       (grub_machine_set_prefix): ... this.
+       (grub_machine_init): Do not call grub_set_prefix.
+
+       * kern/i386/pc/init.c (grub_machine_set_prefix): New function.
+       (grub_machine_init): Do not set the prefix here.
+
+       * kern/i386/efi/init.c (grub_machine_set_prefix): New function.
+
+       * kern/efi/init.c: Include grub/mm.h.
+       (grub_efi_set_prefix): New function.
+
+       * kern/efi/efi.c (grub_exit): Call grub_efi_fini.
+       (grub_efi_get_filename): New function.
+       (grub_print_device_path): Renamed to ...
+       (grub_efi_print_device_path): ... this.
+
+       * kern/mm.c [MM_DEBUG] (grub_malloc): Undefined.
+       [MM_DEBUG] (grub_realloc): Likewise.
+       [MM_DEBUG] (grub_free): Likewise.
+       [MM_DEBUG] (grub_memalign): Likewise.
+       [MM_DEBUG] (grub_mm_debug): New variable.
+       [MM_DEBUG] (grub_debug_malloc): New function.
+       [MM_DEBUG] (grub_debug_free): New function.
+       [MM_DEBUG] (grub_debug_realloc): New function.
+       [MM_DEBUG] (grub_debug_memalign): New function.
+
+       * kern/misc.c (grub_abort): Print a newline to distinguish
+       the message.
+
+       * kern/main.c (grub_main): Call grub_machine_set_prefix and
+       grub_set_root_dev after loading modules. This is necessary when
+       setting a prefix depends on modules.
+
+       * include/grub/efi/efi.h (grub_print_device_path): Renamed to ...
+       (grub_efi_print_device_path): ... this.
+       (grub_efi_get_filename): New prototype.
+       (grub_efi_set_prefix): Likewise.
+
+       * include/grub/efi/disk.h: Include grub/efi/api.h, grub/symbol.h
+       and grub/disk.h.
+       (grub_efidisk_get_device_handle): New prototype.
+       (grub_efidisk_get_device_name): Likewise.
+
+       * include/grub/mm.h: Include config.h.
+       (MM_DEBUG): Removed.
+       [MM_DEBUG && !GRUB_UTIL] (grub_mm_debug): New prototype.
+       [MM_DEBUG && !GRUB_UTIL] (grub_malloc): New macro.
+       [MM_DEBUG && !GRUB_UTIL] (grub_realloc): Likewise.
+       [MM_DEBUG && !GRUB_UTIL] (grub_memalign): Likewise.
+       [MM_DEBUG && !GRUB_UTIL] (grub_free): Likewise.
+       [MM_DEBUG && !GRUB_UTIL] (grub_debug_malloc): New prototype.
+       [MM_DEBUG && !GRUB_UTIL] (grub_debug_realloc): New prototype.
+       [MM_DEBUG && !GRUB_UTIL] (grub_debug_memalign): New prototype.
+       [MM_DEBUG && !GRUB_UTIL] (grub_debug_free): New prototype.
+
+       * include/grub/kernel.h (grub_machine_set_prefix): New prototype.
+
+       * disk/efi/efidisk.c: Include grub/partition.h.
+       (iterate_child_devices): New function.
+       (add_device): First, compare only last device path nodes, so that
+       devices are sorted by the types.
+       (grub_efidisk_get_device_handle): New function.
+       (grub_efidisk_get_device_name): Likewise.
+
+       * configure.ac (--enable-mm-debug): New option to enable the
+       memory manager debugging feature. This makes the binary much
+       bigger, so is disabled by default.
+
 2006-04-23  Yoshinori K. Okuji  <okuji@enbug.org>
 
        Use grub_abort instead of grub_stop, and grub_exit must be
index 9ac3fb5f07280152753fa75b928a6e3ebfe4c59f..ba432ac15bb5608095a7bbd893e9badfa9d84d17 100644 (file)
@@ -61,6 +61,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you enable memory manager debugging. */
+#undef MM_DEBUG
+
 /* Catch gcc bug */
 #undef NESTED_FUNC_ATTR
 
index 176e9c29f21d4e4945500b3d374f09119e7dfe91..66a55141959ad2e1c412963769d7daaac6799174 100644 (file)
--- a/configure
+++ b/configure
@@ -849,6 +849,7 @@ Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-largefile     omit support for large files
+  --enable-mm-debug       include memory manger debugging
 
 Some influential environment variables:
   CC          C compiler command
@@ -6563,6 +6564,17 @@ CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
 LDFLAGS="$tmp_LDFLAGS"
 
+# Check for options.
+# Check whether --enable-mm-debug or --disable-mm-debug was given.
+if test "${enable_mm_debug+set}" = set; then
+  enableval="$enable_mm_debug"
+
+cat >>confdefs.h <<\_ACEOF
+#define MM_DEBUG 1
+_ACEOF
+
+fi;
+
 # Output files.
                     ac_config_links="$ac_config_links include/grub/cpu:include/grub/$host_cpu include/grub/machine:include/grub/$host_cpu/$host_vendor"
 
index 1b38d57934bcb69f5c15c1c3bea7c82f54d94fdf..53e85e0c6b7fed8bd679a28c9fb27d173db1f461 100644 (file)
@@ -180,6 +180,13 @@ CFLAGS="$tmp_CFLAGS"
 CPPFLAGS="$tmp_CPPFLAGS"
 LDFLAGS="$tmp_LDFLAGS"
 
+# Check for options.
+AC_ARG_ENABLE([mm-debug], 
+             AS_HELP_STRING([--enable-mm-debug],
+                             [include memory manger debugging]),
+              [AC_DEFINE([MM_DEBUG], [1],
+                         [Define to 1 if you enable memory manager debugging.])])
+
 # Output files.
 AC_CONFIG_LINKS([include/grub/cpu:include/grub/$host_cpu
        include/grub/machine:include/grub/$host_cpu/$host_vendor])
index 8d5bc4d650b927aa8cab8e1ae08c70f73e68f807..2daf3d39f29d8db27ec064db379d26254a3a675c 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <grub/disk.h>
+#include <grub/partition.h>
 #include <grub/mm.h>
 #include <grub/types.h>
 #include <grub/misc.h>
@@ -236,6 +237,40 @@ find_parent_device (struct grub_efidisk_data *devices,
   return parent;
 }
 
+static int
+iterate_child_devices (struct grub_efidisk_data *devices,
+                      struct grub_efidisk_data *d,
+                      int (*hook) (struct grub_efidisk_data *child))
+{
+  struct grub_efidisk_data *p;
+  
+  for (p = devices; p; p = p->next)
+    {
+      grub_efi_device_path_t *dp, *ldp;
+
+      dp = duplicate_device_path (p->device_path);
+      if (! dp)
+       return 0;
+      
+      ldp = find_last_device_path (dp);
+      ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      ldp->length[0] = sizeof (*ldp);
+      ldp->length[1] = 0;
+      
+      if (compare_device_paths (dp, d->device_path) == 0)
+       if (hook (p))
+         {
+           grub_free (dp);
+           return 1;
+         }
+
+      grub_free (dp);
+    }
+
+  return 0;
+}
+
 /* Add a device into a list of devices in an ascending order.  */
 static void
 add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
@@ -247,7 +282,11 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
     {
       int ret;
 
-      ret = compare_device_paths ((*p)->device_path, d->device_path);
+      ret = compare_device_paths (find_last_device_path ((*p)->device_path),
+                                 find_last_device_path (d->device_path));
+      if (ret == 0)
+       ret = compare_device_paths ((*p)->device_path,
+                                   d->device_path);
       if (ret == 0)
        return;
       else if (ret > 0)
@@ -601,3 +640,222 @@ grub_efidisk_fini (void)
   free_devices (cd_devices);
   grub_disk_dev_unregister (&grub_efidisk_dev);
 }
+
+/* Some utility functions to map GRUB devices with EFI devices.  */
+grub_efi_handle_t
+grub_efidisk_get_device_handle (grub_disk_t disk)
+{
+  struct grub_efidisk_data *d;
+  char type;
+  
+  if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID)
+    return 0;
+  
+  d = disk->data;
+  type = disk->name[0];
+  
+  switch (type)
+    {
+    case 'f':
+      /* This is the simplest case.  */
+      return d->handle;
+
+    case 'c':
+      /* FIXME: probably this is not correct.  */
+      return d->handle;
+
+    case 'h':
+      /* If this is the whole disk, just return its own data.  */
+      if (! disk->partition)
+       return d->handle;
+
+      /* Otherwise, we must query the corresponding device to the firmware.  */
+      {
+       struct grub_efidisk_data *devices;
+       grub_efi_handle_t handle = 0;
+       auto int find_partition (struct grub_efidisk_data *c);
+
+       int find_partition (struct grub_efidisk_data *c)
+         {
+           grub_efi_hard_drive_device_path_t hd;
+
+           grub_memcpy (&hd, c->last_device_path, sizeof (hd));
+           
+           if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
+                == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
+               && (GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
+                   == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)
+               && (grub_partition_get_start (disk->partition)
+                   == hd.partition_start)
+               && (grub_partition_get_len (disk->partition)
+                   == hd.partition_size))
+             {
+               handle = c->handle;
+               return 1;
+             }
+             
+           return 0;
+         }
+       
+       devices = make_devices ();
+       iterate_child_devices (devices, d, find_partition);
+       free_devices (devices);
+       
+       if (handle != 0)
+         return handle;
+      }
+      break;
+
+    default:
+      break;
+    }
+  
+  return 0;
+}
+
+char *
+grub_efidisk_get_device_name (grub_efi_handle_t *handle)
+{
+  grub_efi_device_path_t *dp, *ldp;
+
+  dp = grub_efi_open_protocol (handle, &device_path_guid,
+                              GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+  if (! dp)
+    return 0;
+
+  ldp = find_last_device_path (dp);
+  if (! ldp)
+    return 0;
+
+  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+      && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
+         == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
+    {
+      /* This is a hard disk partition.  */
+      grub_disk_t parent = 0;
+      char *partition_name = 0;
+      char *device_name;
+      grub_efi_device_path_t *dup_dp, *dup_ldp;
+      grub_efi_hard_drive_device_path_t hd;
+      auto int find_parent_disk (const char *name);
+      auto int find_partition (grub_disk_t disk, const grub_partition_t part);
+
+      /* Find the disk which is the parent of a given hard disk partition.  */
+      int find_parent_disk (const char *name)
+       {
+         grub_disk_t disk;
+
+         disk = grub_disk_open (name);
+         if (! disk)
+           return 1;
+
+         if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+           {
+             struct grub_efidisk_data *d;
+             
+             d = disk->data;
+             if (compare_device_paths (d->device_path, dup_dp) == 0)
+               {
+                 parent = disk;
+                 return 1;
+               }
+           }
+
+         grub_disk_close (disk);
+         return 0;
+       }
+
+      /* Find the identical partition.  */
+      int find_partition (grub_disk_t disk __attribute__ ((unused)),
+                         const grub_partition_t part)
+       {
+         if (grub_partition_get_start (part) == hd.partition_start
+             && grub_partition_get_len (part) == hd.partition_size)
+           {
+             partition_name = grub_partition_get_name (part);
+             return 1;
+           }
+
+         return 0;
+       }
+
+      /* It is necessary to duplicate the device path so that GRUB
+        can overwrite it.  */
+      dup_dp = duplicate_device_path (dp);
+      if (! dup_dp)
+       return 0;
+
+      dup_ldp = find_last_device_path (dup_dp);
+      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+      dup_ldp->length[0] = sizeof (*dup_ldp);
+      dup_ldp->length[1] = 0;
+
+      grub_efidisk_iterate (find_parent_disk);
+      grub_free (dup_dp);
+
+      if (! parent)
+       return 0;
+
+      /* Find a partition which matches the hard drive device path.  */
+      grub_memcpy (&hd, ldp, sizeof (hd));
+      grub_partition_iterate (parent, find_partition);
+      
+      if (! partition_name)
+       {
+         grub_disk_close (parent);
+         return 0;
+       }
+
+      device_name = grub_malloc (grub_strlen (parent->name) + 1
+                                + grub_strlen (partition_name) + 1);
+      if (! device_name)
+       {
+         grub_free (partition_name);
+         grub_disk_close (parent);
+         return 0;
+       }
+
+      grub_sprintf (device_name, "%s,%s", parent->name, partition_name);
+      grub_free (partition_name);
+      grub_disk_close (parent);
+      return device_name;
+    }
+  else
+    {
+      /* This should be an entire disk.  */
+      auto int find_disk (const char *name);
+      char *device_name = 0;
+      
+      int find_disk (const char *name)
+       {
+         grub_disk_t disk;
+         
+         disk = grub_disk_open (name);
+         if (! disk)
+           return 1;
+
+         if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID)
+           {
+             struct grub_efidisk_data *d;
+             
+             d = disk->data;
+             if (compare_device_paths (d->device_path, dp) == 0)
+               {
+                 device_name = grub_strdup (disk->name);
+                 grub_disk_close (disk);
+                 return 1;
+               }
+           }
+
+         grub_disk_close (disk);
+         return 0;
+         
+       }
+      
+      grub_efidisk_iterate (find_disk);
+      return device_name;
+    }
+
+  return 0;
+}
index aa44e253fb0be3586ee80a95abc8984ec6842083..3f3de6b9eb45315246c6ea019acbd3dd4e4f7e0d 100644 (file)
 #ifndef GRUB_EFI_DISK_HEADER
 #define GRUB_EFI_DISK_HEADER   1
 
+#include <grub/efi/api.h>
+#include <grub/symbol.h>
+#include <grub/disk.h>
+
+grub_efi_handle_t
+EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk);
+char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle);
+
 void grub_efidisk_init (void);
 void grub_efidisk_fini (void);
 
index 8a2c2994e79c91067ccb1d2418cd932327252d47..17778fb661bdc434e9eef872289ab04f1ccad3df 100644 (file)
@@ -50,12 +50,14 @@ EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size,
                                      grub_efi_uintn_t *descriptor_size,
                                      grub_efi_uint32_t *descriptor_version);
 grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (void);
-void EXPORT_FUNC(grub_print_device_path) (grub_efi_device_path_t *dp);
+void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
+char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
 
 void grub_efi_mm_init (void);
 void grub_efi_mm_fini (void);
 void grub_efi_init (void);
 void grub_efi_fini (void);
+void grub_efi_set_prefix (void);
 
 /* Variables.  */
 extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table);
index 421abc27ea4284acace4aac7107a8a69555fd332..f283498b2ccf8b1ff587fdc2d652a8c6ef3be73f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002, 2005  Free Software Foundation, Inc.
+ *  Copyright (C) 2002,2005,2006  Free Software Foundation, Inc.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -55,6 +55,9 @@ void grub_machine_init (void);
 /* The machine-specific finalization.  */
 void grub_machine_fini (void);
 
+/* The machine-specific prefix initialization.  */
+void grub_machine_set_prefix (void);
+
 /* Register all the exported symbols. This is automatically generated.  */
 void grub_register_exported_symbols (void);
 
index e3193d2ff07bda3593cc78ecca9f86b2c22c8596..81f7eb87524241019b5b6ea0e69f6f5d28b4f2a8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <grub/types.h>
 #include <grub/symbol.h>
+#include <config.h>
 
 #ifndef NULL
 # define NULL  ((void *) 0)
@@ -35,9 +36,31 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size);
 void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
 
 /* For debugging.  */
-#define MM_DEBUG       1
-#if MM_DEBUG
+#if defined(MM_DEBUG) && !defined(GRUB_UTIL)
+/* Set this variable to 1 when you want to trace all memory function calls.  */
+extern int EXPORT_VAR(grub_mm_debug);
+
 void grub_mm_dump (unsigned lineno);
-#endif
+
+#define grub_malloc(size)      \
+  grub_debug_malloc (__FILE__, __LINE__, size)
+
+#define grub_realloc(ptr,size) \
+  grub_debug_realloc (__FILE__, __LINE__, ptr, size)
+
+#define grub_memalign(align,size)      \
+  grub_debug_memalign (__FILE__, __LINE__, align, size)
+
+#define grub_free(ptr) \
+  grub_debug_free (__FILE__, __LINE__, ptr)
+
+void *EXPORT_FUNC(grub_debug_malloc) (const char *file, int line,
+                                     grub_size_t size);
+void EXPORT_FUNC(grub_debug_free) (const char *file, int line, void *ptr);
+void *EXPORT_FUNC(grub_debug_realloc) (const char *file, int line, void *ptr,
+                                      grub_size_t size);
+void *EXPORT_FUNC(grub_debug_memalign) (const char *file, int line,
+                                       grub_size_t align, grub_size_t size);
+#endif /* MM_DEBUG && ! GRUB_UTIL */
 
 #endif /* ! GRUB_MM_H */
index c3d39dcdac8bc71e5d41faa635092b262de4ce24..d41b67b47b5d82a2e1b4b5e989ff293b51733aa0 100644 (file)
@@ -154,6 +154,7 @@ grub_efi_get_loaded_image (void)
 void
 grub_exit (void)
 {
+  grub_efi_fini ();
   grub_efi_system_table->boot_services->exit (grub_efi_image_handle,
                                              GRUB_EFI_SUCCESS,
                                              0, 0);
@@ -218,9 +219,68 @@ grub_arch_modules_addr (void)
   return (grub_addr_t) info;
 }
 
+char *
+grub_efi_get_filename (grub_efi_device_path_t *dp)
+{
+  char *name = 0;
+  
+  while (1)
+    {
+      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
+      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);
+
+      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
+       break;
+      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
+              && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
+       {
+         grub_efi_file_path_device_path_t *fp;
+         grub_efi_uint16_t len;
+         char *p;
+         grub_size_t size;
+
+         if (name)
+           {
+             size = grub_strlen (name);
+             name[size] = '/';
+             size++;
+           }
+         else
+           size = 0;
+         
+         len = GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4;
+         p = grub_realloc (name, size + len * 4 + 1);
+         if (! p)
+           {
+             grub_free (name);
+             return 0;
+           }
+
+         name = p;
+         fp = (grub_efi_file_path_device_path_t *) dp;
+         *grub_utf16_to_utf8 ((grub_uint8_t *) name + size,
+                              fp->path_name, len) = '\0';
+       }
+
+      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
+    }
+
+  if (name)
+    {
+      /* EFI breaks paths with backslashes.  */
+      char *p;
+
+      for (p = name; *p; p++)
+       if (*p == '\\')
+         *p = '/';
+    }
+
+  return name;
+}
+
 /* Print the chain of Device Path nodes. This is mainly for debugging. */
 void
-grub_print_device_path (grub_efi_device_path_t *dp)
+grub_efi_print_device_path (grub_efi_device_path_t *dp)
 {
   while (1)
     {
index 00c297581b95fb18cbc51b43be00a3a17c74fdd4..23ca144a0bef524e88248b666f96cfbad48283dd 100644 (file)
@@ -25,6 +25,7 @@
 #include <grub/term.h>
 #include <grub/misc.h>
 #include <grub/env.h>
+#include <grub/mm.h>
 #include <grub/machine/kernel.h>
 
 void
@@ -38,9 +39,45 @@ grub_efi_init (void)
   grub_efi_mm_init ();
 
   grub_efidisk_init ();
+}
+
+void
+grub_efi_set_prefix (void)
+{
+  grub_efi_loaded_image_t *image;
+  
+  image = grub_efi_get_loaded_image ();
+  if (image)
+    {
+      char *device;
+      char *file;
+
+      device = grub_efidisk_get_device_name (image->device_handle);
+      file = grub_efi_get_filename (image->file_path);
+      
+      if (device && file)
+       {
+         char *p;
+         char *prefix;
+         
+         /* Get the directory.  */
+         p = grub_strrchr (file, '/');
+         if (p)
+           *p = '\0';
 
-  /* FIXME: this must be set to something meaningful.  */
-  grub_env_set ("prefix", grub_prefix);
+         prefix = grub_malloc (1 + grub_strlen (device) + 1
+                               + grub_strlen (file) + 1);
+         if (prefix)
+           {
+             grub_sprintf (prefix, "(%s)%s", device, file);
+             grub_env_set ("prefix", prefix);
+             grub_free (prefix);
+           }
+       }
+      
+      grub_free (device);
+      grub_free (file);
+    }
 }
 
 void
index dab9dddfddf1da32a2e8a7d55d330730265f30cc..eaff52529509905c61ab3a22189780f7d7d75ee8 100644 (file)
@@ -40,6 +40,12 @@ grub_machine_fini (void)
   grub_efi_fini ();
 }
 
+void
+grub_machine_set_prefix (void)
+{
+  grub_efi_set_prefix ();
+}
+
 void
 grub_arch_sync_caches (void *address __attribute__ ((unused)),
                        grub_size_t len __attribute__ ((unused)))
index d88fb66bf7bbcb304e1e2bfa394d638f74def901..f553df74fe91288333e9466e5278e03ccad9b93c 100644 (file)
@@ -226,8 +226,11 @@ grub_machine_init (void)
   
   /* The memory system was initialized, thus register built-in devices.  */
   grub_biosdisk_init ();
+}
 
-
+void
+grub_machine_set_prefix (void)
+{
   /* Initialize the prefix.  */
   grub_env_set ("prefix", make_install_device ());
 }
index 5447033aa5c33f43125700fa9706822c1924fffe..ac671cb4488b94f069a57a1b146b8b082fe07b54 100644 (file)
@@ -118,14 +118,15 @@ grub_main (void)
   grub_printf ("Welcome to GRUB!\n\n");
   grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
 
-  /* It is better to set the root device as soon as possible,
-     for convenience.  */
-  grub_set_root_dev ();
-
   /* Load pre-loaded modules and free the space.  */
   grub_register_exported_symbols ();
   grub_load_modules ();
 
+  /* It is better to set the root device as soon as possible,
+     for convenience.  */
+  grub_machine_set_prefix ();
+  grub_set_root_dev ();
+
   /* Load the normal mode module.  */
   grub_load_normal_mode ();
   
index b91bd0a0811db9205fab7b54943005eb09c73b06..7617c031bc9bd26d585393a783e99757cce0ef6f 100644 (file)
@@ -964,9 +964,9 @@ grub_abort (void)
 {
   if (grub_term_get_current ())
     {
-      grub_printf ("Abort. Press any key to exit.");
+      grub_printf ("\nAborted. Press any key to exit.");
       grub_getkey ();
     }
-  
+
   grub_exit ();
 }
index f00141e7e1811edc3ef5425c5f564055ac57451b..cf921c8991eacb15fb980af98449f70e11b1a28c 100644 (file)
--- a/kern/mm.c
+++ b/kern/mm.c
 #include <grub/disk.h>
 #include <grub/dl.h>
 
+#ifdef MM_DEBUG
+# undef grub_malloc
+# undef grub_realloc
+# undef grub_free
+# undef grub_memalign
+#endif
+
 /* Magic words.  */
 #define GRUB_MM_FREE_MAGIC     0x2d3c2808
 #define GRUB_MM_ALLOC_MAGIC    0x6db08fa4
@@ -388,7 +395,9 @@ grub_realloc (void *ptr, grub_size_t size)
   return q;
 }
 
-#if MM_DEBUG
+#ifdef MM_DEBUG
+grub_mm_debug = 0;
+
 void
 grub_mm_dump (unsigned lineno)
 {
@@ -419,4 +428,51 @@ grub_mm_dump (unsigned lineno)
 
   grub_printf ("\n");
 }
+
+void *
+grub_debug_malloc (const char *file, int line, grub_size_t size)
+{
+  void *ptr;
+
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: malloc (0x%x) = ", file, line, size);
+  ptr = grub_malloc (size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void
+grub_debug_free (const char *file, int line, void *ptr)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: free (%p)\n", file, line, ptr);
+}
+
+void *
+grub_debug_realloc (const char *file, int line, void *ptr, grub_size_t size)
+{
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: realloc (%p, 0x%x) = ", file, line, ptr, size);
+  ptr = grub_realloc (ptr, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
+void *
+grub_debug_memalign (const char *file, int line, grub_size_t align,
+                   grub_size_t size)
+{
+  void *ptr;
+  
+  if (grub_mm_debug)
+    grub_printf ("%s:%d: memalign (0x%x, 0x%x) = ",
+                file, line, align, size);
+  ptr = grub_memalign (align, size);
+  if (grub_mm_debug)
+    grub_printf ("%p\n", ptr);
+  return ptr;
+}
+
 #endif /* MM_DEBUG */
index 023e2b6c008e2e0bd333dc1e1928aee08a6eb591..0f75b893c9e6392f792189955a63480cc638382b 100644 (file)
@@ -62,8 +62,8 @@ grub_translate_ieee1275_path (char *filepath)
     }
 }
 
-static void
-grub_set_prefix (void)
+void
+grub_machine_set_prefix (void)
 {
   char bootpath[64]; /* XXX check length */
   char *filename;
@@ -130,8 +130,6 @@ grub_machine_init (void)
     }
   grub_mm_init_region ((void *) grub_heap_start, grub_heap_len);
 
-  grub_set_prefix ();
-
   grub_ofdisk_init ();
 
   /* Process commandline.  */
index 3cc2a4118772c2bbf568aafc03e538388c9ef5c0..49c66e483ab63aa3666824fb8b0f2a4cc0c82b44 100644 (file)
@@ -79,13 +79,6 @@ grub_ieee1275_set_flag (enum grub_ieee1275_flag flag)
   grub_ieee1275_flags |= (1 << flag);
 }
 
-void
-abort (void)
-{
-  /* Trap to Open Firmware.  */
-  grub_ieee1275_enter ();
-}
-
 /* Translate an OF filesystem path (separated by backslashes), into a GRUB
    path (separated by forward slashes).  */
 static void
@@ -101,8 +94,8 @@ grub_translate_ieee1275_path (char *filepath)
     }
 }
 
-static void
-grub_set_prefix (void)
+void
+grub_machine_set_prefix (void)
 {
   char bootpath[64]; /* XXX check length */
   char *filename;
@@ -163,8 +156,6 @@ grub_machine_init (void)
                   grub_heap_len);
   grub_mm_init_region ((void *) grub_heap_start, grub_heap_len);
 
-  grub_set_prefix ();
-
   grub_ofdisk_init ();
 
   /* Process commandline.  */
@@ -215,9 +206,9 @@ grub_machine_fini (void)
 }
 
 void
-grub_stop (void)
+grub_exit (void)
 {
-  grub_ieee1275_exit ();
+  grub_ieee1275_enter ();
 }
 
 grub_uint32_t
index 98aba83d1f0d1790b1bf518fa90984e2187a7100..7106ae7caec9cca0c001f4be72f0677f0338e645 100644 (file)
@@ -121,7 +121,7 @@ gpt_partition_map_iterate (grub_disk_t disk,
          /* Calculate the first block and the size of the partition.  */
          part.start = grub_le_to_cpu64 (entry.start);
          part.len = (grub_le_to_cpu64 (entry.end)
-                     - grub_le_to_cpu64 (entry.start));
+                     - grub_le_to_cpu64 (entry.start) + 1);
          part.offset = entries;
          part.index = partno;
          part.partmap = &grub_gpt_partition_map;