All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hollis Blanchard <hollis@penguinppc.org>
To: grub-devel@gnu.org
Subject: [patch] set prefix on PPC
Date: Sun, 13 Feb 2005 10:54:52 -0600	[thread overview]
Message-ID: <20050213165452.GA4503@miracle> (raw)

Any comments on this patch?

This code sets the GRUB "prefix" environment variable from the OF
/chosen/bootpath property. It must therefore translate between the two
syntaxes.

I believe most of this code could be moved to a kern/ieee1275/device.c
file, but that can wait until there is another supported OF platform.

I have verified that this works (a config file is loaded) from disk, and
netbooting is not broken. The subdirectory stuff works as well.

-Hollis

2005-02-13  Hollis Blanchard  <hollis@penguinppc.org>

	* include/grub/powerpc/ieee1275/ieee1275.h
	(grub_ieee1275_get_dev_encoding): New prototype.
	(grub_ieee1275_get_filename): Likewise.
	* kern/powerpc/ieee1275/init.c (translate_path): New function.
	(grub_set_prefix): Likewise.
	(grub_machine_init): Call grub_set_prefix.
	* kern/powerpc/ieee1275/openfw.c (GRUB_PARSE_FILENAME): New
	constant.
	(GRUB_PARSE_PARTITION): Likewise.
	(grub_ieee1275_get_devargs): New function.
	(grub_ieee1275_get_devname): Likewise.
	(grub_ieee1275_parse_args): Likewise.
	(grub_ieee1275_get_filename): Likewise.
	(grub_ieee1275_get_dev_encoding): Likewise.

Index: include/grub/powerpc/ieee1275/ieee1275.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/ieee1275.h,v
retrieving revision 1.14
diff -u -p -r1.14 ieee1275.h
--- include/grub/powerpc/ieee1275/ieee1275.h	31 Jan 2005 21:28:34 -0000	1.14
+++ include/grub/powerpc/ieee1275/ieee1275.h	13 Feb 2005 17:16:17 -0000
@@ -132,5 +132,8 @@ int EXPORT_FUNC(grub_claimmap) (grub_add
 
 void EXPORT_FUNC(abort) (void);
 
+char *EXPORT_FUNC(grub_ieee1275_get_dev_encoding) (const char *path);
+char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
+
 
 #endif /* ! GRUB_IEEE1275_MACHINE_HEADER */
Index: kern/powerpc/ieee1275/init.c
===================================================================
RCS file: /cvsroot/grub/grub2/kern/powerpc/ieee1275/init.c,v
retrieving revision 1.13
diff -u -p -r1.13 init.c
--- kern/powerpc/ieee1275/init.c	4 Jan 2005 14:01:45 -0000	1.13
+++ kern/powerpc/ieee1275/init.c	13 Feb 2005 17:16:17 -0000
@@ -42,6 +42,68 @@ abort (void)
   for (;;);
 }
 
+/* Translate an OF filesystem path (separated by backslashes), into a GRUB
+   path (separated by forward slashes).  */
+static void
+translate_path (char *filepath)
+{
+  char *backslash;
+
+  backslash = grub_strchr (filepath, '\\');
+  while (backslash != 0)
+    {
+      *backslash = '/';
+      backslash = grub_strchr (filepath, '\\');
+    }
+}
+
+static void
+grub_set_prefix (void)
+{
+  char bootpath[64]; /* XXX check length */
+  char *filename;
+  char *prefix;
+  grub_ieee1275_phandle_t chosen;
+
+  grub_ieee1275_finddevice ("/chosen", &chosen);
+  if (grub_ieee1275_get_property (chosen, "bootpath", &bootpath,
+				  sizeof (bootpath), 0))
+    { 
+      /* Should never happen.  */
+      grub_printf ("/chosen/bootpath property missing!\n");
+      grub_env_set ("prefix", "");
+    }
+
+  /* Transform an OF device path to a GRUB path.  */
+
+  prefix = grub_ieee1275_get_dev_encoding (bootpath);
+
+  filename = grub_ieee1275_get_filename (bootpath);
+  if (filename)
+    {
+      char *newprefix;
+      char *lastslash = grub_strrchr (filename, '\\');
+
+      /* Truncate at last directory.  */
+      if (lastslash)
+        {
+	  *lastslash = '\0';
+	  translate_path (filename);
+
+	  newprefix = grub_malloc (grub_strlen (prefix)
+				   + grub_strlen (filename));
+	  grub_sprintf (newprefix, "%s%s", prefix, filename);
+	  grub_free (prefix);
+	  prefix = newprefix;
+	}
+    }
+
+  grub_env_set ("prefix", prefix);
+
+  grub_free (filename);
+  grub_free (prefix);
+}
+
 void
 grub_machine_init (void)
 {
@@ -65,7 +127,7 @@ grub_machine_init (void)
     }
   grub_mm_init_region ((void *) heap_start, heap_len);
 
-  grub_env_set ("prefix", "");
+  grub_set_prefix ();
 
   grub_ofdisk_init ();
 }
Index: kern/powerpc/ieee1275/openfw.c
===================================================================
RCS file: /cvsroot/grub/grub2/kern/powerpc/ieee1275/openfw.c,v
retrieving revision 1.7
diff -u -p -r1.7 openfw.c
--- kern/powerpc/ieee1275/openfw.c	3 Jan 2005 17:44:25 -0000	1.7
+++ kern/powerpc/ieee1275/openfw.c	13 Feb 2005 17:16:17 -0000
@@ -23,6 +23,11 @@
 #include <grub/mm.h>
 #include <grub/machine/ieee1275.h>
 
+enum {
+  GRUB_PARSE_FILENAME,
+  GRUB_PARSE_PARTITION,
+};
+
 /* Walk children of 'devpath', calling hook for each.  */
 grub_err_t
 grub_children_iterate (char *devpath,
@@ -64,7 +69,7 @@ grub_children_iterate (char *devpath,
       if (actual == -1)
 	continue;
 
-      grub_sprintf(fullname, "%s/%s", devpath, childname);
+      grub_sprintf (fullname, "%s/%s", devpath, childname);
 
       alias.type = childtype;
       alias.path = childpath;
@@ -199,3 +204,133 @@ grub_claimmap (grub_addr_t addr, grub_si
 
   return 0;
 }
+
+/* Get the device arguments of the Open Firmware device specifier `path'.  */
+static char *
+grub_ieee1275_get_devargs (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+  char *end;
+
+  if (! colon)
+    return 0;
+
+  end = colon + grub_strlen (colon);
+
+  return grub_strndup (colon + 1, end - colon);
+}
+
+/* Get the device path of the Open Firmware device specifier `path'.  */
+static char *
+grub_ieee1275_get_devname (const char *path)
+{
+  char *colon = grub_strchr (path, ':');
+
+  if (! colon)
+    return grub_strdup (path);
+
+  return grub_strndup (path, (grub_size_t)(colon - path));
+}
+
+static char *
+grub_ieee1275_parse_args (const char *path, int field)
+{
+  char type[64]; /* XXX check size.  */
+  char *device = grub_ieee1275_get_devname (path);
+  char *args = grub_ieee1275_get_devargs (path);
+  char *ret = 0;
+  grub_ieee1275_phandle_t dev;
+
+  if (!args)
+    /* Shouldn't happen.  */
+    return 0;
+
+  /* We need to know what type of device it is in order to parse the full
+     file path properly.  */
+  if (grub_ieee1275_finddevice (device, &dev))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device);
+      goto out;
+    }
+  if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0))
+    {
+      grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+		  "Device %s lacks a device_type property\n", device);
+      goto out;
+    }
+
+  if (!grub_strcmp ("block", type))
+    {
+      /* Example: "disk:<partition number>,<file name>".  */
+      char *comma = grub_strchr (args, ',');
+
+      if (field == GRUB_PARSE_FILENAME)
+	{
+	  if (comma)
+	    {
+	      char *filepath = comma + 1;
+
+	      ret = grub_malloc (grub_strlen (filepath) + 1);
+	      /* Make sure filepath has leading backslash.  */
+	      if (filepath[0] != '\\')
+		grub_sprintf (ret, "\\%s", filepath);
+	      else
+		grub_strcpy (ret, filepath);
+	    }
+	}
+      else if (field == GRUB_PARSE_PARTITION)
+        {
+	  if (!comma)
+	    ret = grub_strdup (args);
+	  else
+	    ret = grub_strndup (args, (grub_size_t)(comma - args));
+	}
+    }
+  else
+    {
+      /* XXX Handle net devices by configuring & registering a grub_net_dev
+	 here, then return its name?
+	 Example path: "net:<server ip>,<file name>,<client ip>,<gateway
+	 ip>,<bootp retries>,<tftp retries>".  */
+      grub_printf ("Unsupported type %s for device %s\n", type, device);
+    }
+
+out:
+  grub_free (device);
+  grub_free (args);
+  return ret;
+}
+
+char *
+grub_ieee1275_get_filename (const char *path)
+{
+  return grub_ieee1275_parse_args (path, GRUB_PARSE_FILENAME);
+}
+
+char *
+grub_ieee1275_get_dev_encoding (const char *path)
+{
+  char *device = grub_ieee1275_get_devname (path);
+  char *partition = grub_ieee1275_parse_args (path, GRUB_PARSE_PARTITION);
+  char *encoding;
+
+  if (partition)
+    {
+      unsigned int partno = grub_strtoul (partition, 0, 0);
+      partno--; /* GRUB partition numbering is 0-based.  */
+
+      /* XXX Assume partno will only require two bytes? */
+      encoding = grub_malloc (grub_strlen (device) + 5);
+      grub_sprintf (encoding, "(%s,%d)", device, partno);
+    }
+  else
+    {
+      encoding = grub_malloc (grub_strlen (device) + 2);
+      grub_sprintf (encoding, "(%s)", device);
+    }
+
+  grub_free (partition);
+  grub_free (device);
+
+  return encoding;
+}



             reply	other threads:[~2005-02-13 18:01 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-13 16:54 Hollis Blanchard [this message]
2005-02-13 18:35 ` [patch] set prefix on PPC Marco Gerards
2005-02-13 19:52   ` Hollis Blanchard
2005-02-14 19:01     ` Marco Gerards
2005-02-15 16:39       ` Hollis Blanchard
2005-02-15 21:31         ` Marco Gerards
2005-02-20  0:21           ` Hollis Blanchard
2005-02-20 17:50             ` Marco Gerards
2005-02-24  4:44               ` Hollis Blanchard
2005-04-14 16:35                 ` Marco Gerards
2005-02-21 19:01 ` Marco Gerards
2005-02-24  4:40   ` Hollis Blanchard
2005-04-14 17:05     ` Marco Gerards
2005-04-17 17:10       ` partition numbering (was: set prefix on PPC) Hollis Blanchard
2005-04-17 17:44         ` partition numbering Marco Gerards
2005-04-17 18:23           ` Hollis Blanchard
2005-04-17 18:57             ` Marco Gerards
2005-04-17 19:24             ` Yoshinori K. Okuji
2005-04-17 19:45               ` Marco Gerards
  -- strict thread matches above, loose matches on Subject: below --
2005-04-14  2:38 [patch] set prefix on PPC Hollis Blanchard
2005-04-14 17:13 ` Marco Gerards
2005-04-15 20:24 ` Marco Gerards
2005-04-17 18:42   ` Hollis Blanchard
2005-04-17 19:23     ` Marco Gerards
2005-04-17 18:33 Hollis Blanchard
2005-04-17 19:38 ` Marco Gerards
2005-04-17 20:32   ` Hollis Blanchard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050213165452.GA4503@miracle \
    --to=hollis@penguinppc.org \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.