From: Hollis Blanchard <hollis@penguinppc.org>
To: grub-devel@gnu.org
Subject: Re: [patch] set prefix on PPC
Date: Sun, 17 Apr 2005 13:33:50 -0500 [thread overview]
Message-ID: <20050417183350.GA30191@miracle> (raw)
Updated patch which uses devaliases.
-Hollis
2005-04-17 Hollis Blanchard <hollis@penguinppc.org>
* include/grub/powerpc/ieee1275/ieee1275.h
(grub_ieee1275_encode_devname): New prototype.
(grub_ieee1275_get_filename): Likewise.
* kern/powerpc/ieee1275/init.c (grub_translate_ieee175_path): New
function.
(grub_set_prefix): Likewise.
(grub_machine_init): Call grub_set_prefix.
* kern/powerpc/ieee1275/openfw.c: Fix typos.
(grub_parse_type): New enum.
(grub_ieee1275_get_devargs): New function.
(grub_ieee1275_get_devname): Likewise.
(grub_ieee1275_parse_args): Likewise.
(grub_ieee1275_get_filename): Likewise.
(grub_ieee1275_encode_devname): Likewise.
Index: include/grub/powerpc/ieee1275/ieee1275.h
===================================================================
RCS file: /cvsroot/grub/grub2/include/grub/powerpc/ieee1275/ieee1275.h,v
retrieving revision 1.15
diff -u -p -r1.15 ieee1275.h
--- include/grub/powerpc/ieee1275/ieee1275.h 26 Mar 2005 17:34:50 -0000 1.15
+++ include/grub/powerpc/ieee1275/ieee1275.h 17 Apr 2005 18:47:25 -0000
@@ -134,5 +134,7 @@ void EXPORT_FUNC(abort) (void);
void EXPORT_FUNC (grub_reboot) (void);
void EXPORT_FUNC (grub_halt) (void);
+char *EXPORT_FUNC(grub_ieee1275_encode_devname) (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.15
diff -u -p -r1.15 init.c
--- kern/powerpc/ieee1275/init.c 30 Mar 2005 18:59:00 -0000 1.15
+++ kern/powerpc/ieee1275/init.c 17 Apr 2005 18:47:25 -0000
@@ -46,6 +46,69 @@ abort (void)
for (;;);
}
+/* Translate an OF filesystem path (separated by backslashes), into a GRUB
+ path (separated by forward slashes). */
+static void
+grub_translate_ieee1275_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", "");
+ return;
+ }
+
+ /* Transform an OF device path to a GRUB path. */
+
+ prefix = grub_ieee1275_encode_devname (bootpath);
+
+ filename = grub_ieee1275_get_filename (bootpath);
+ if (filename)
+ {
+ char *newprefix;
+ char *lastslash = grub_strrchr (filename, '\\');
+
+ /* Truncate at last directory. */
+ if (lastslash)
+ {
+ *lastslash = '\0';
+ grub_translate_ieee1275_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 +128,7 @@ grub_machine_init (void)
}
grub_mm_init_region ((void *) grub_heap_start, grub_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.8
diff -u -p -r1.8 openfw.c
--- kern/powerpc/ieee1275/openfw.c 26 Mar 2005 17:34:50 -0000 1.8
+++ kern/powerpc/ieee1275/openfw.c 17 Apr 2005 18:47:26 -0000
@@ -23,6 +23,12 @@
#include <grub/mm.h>
#include <grub/machine/ieee1275.h>
+enum grub_ieee1275_parse_type
+{
+ GRUB_PARSE_FILENAME,
+ GRUB_PARSE_PARTITION,
+};
+
/* Walk children of 'devpath', calling hook for each. */
grub_err_t
grub_children_iterate (char *devpath,
@@ -64,7 +70,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;
@@ -76,7 +82,7 @@ grub_children_iterate (char *devpath,
return 0;
}
-/* Iterate through all device aliasses. Thisfunction can be used to
+/* Iterate through all device aliases. This function can be used to
find a device of a specific type. */
grub_err_t
grub_devalias_iterate (int (*hook) (struct grub_ieee1275_devalias *alias))
@@ -200,6 +206,155 @@ grub_claimmap (grub_addr_t addr, grub_si
return 0;
}
+/* Get the device arguments of the Open Firmware node name `path'. */
+static char *
+grub_ieee1275_get_devargs (const char *path)
+{
+ char *colon = grub_strchr (path, ':');
+
+ if (! colon)
+ return 0;
+
+ return grub_strdup (colon + 1);
+}
+
+/* Get the device path of the Open Firmware node name `path'. */
+static char *
+grub_ieee1275_get_devname (const char *path)
+{
+ char *colon = grub_strchr (path, ':');
+ char *newpath = 0;
+ int pathlen = grub_strlen (path);
+ auto int match_alias (struct grub_ieee1275_devalias *alias);
+
+ int match_alias (struct grub_ieee1275_devalias *curalias)
+ {
+ if (! grub_strncmp (curalias->path, path, pathlen))
+ {
+ newpath = grub_strndup (curalias->name, grub_strlen (curalias->name));
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (colon)
+ pathlen = (int)(colon - path);
+
+ /* Try to find an alias for this device. */
+ grub_devalias_iterate (match_alias);
+
+ if (! newpath)
+ newpath = grub_strdup (path);
+
+ return newpath;
+}
+
+static char *
+grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype)
+{
+ 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 fail;
+ }
+ 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 fail;
+ }
+
+ if (!grub_strcmp ("block", type))
+ {
+ /* The syntax of the device arguments is defined in the CHRP and PReP
+ IEEE1275 bindings: "[partition][,[filename]]". */
+ char *comma = grub_strchr (args, ',');
+
+ if (ptype == 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 (ptype == 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);
+ }
+
+fail:
+ 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);
+}
+
+/* Convert a device name from IEEE1275 syntax to GRUB syntax. */
+char *
+grub_ieee1275_encode_devname (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. */
+
+ /* Assume partno will require less than five bytes to encode. */
+ encoding = grub_malloc (grub_strlen (device) + 3 + 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;
+}
+
void
grub_reboot (void)
{
next reply other threads:[~2005-04-17 19:00 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-17 18:33 Hollis Blanchard [this message]
2005-04-17 19:38 ` [patch] set prefix on PPC Marco Gerards
2005-04-17 20:32 ` Hollis Blanchard
2005-04-19 3:59 ` [patch] set prefix on PPC - briQ results Hollis Blanchard
2005-04-19 17:36 ` Marco Gerards
2005-04-21 2:16 ` Hollis Blanchard
2005-04-21 7:18 ` 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-02-13 16:54 Hollis Blanchard
2005-02-13 18:35 ` 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
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=20050417183350.GA30191@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.