From: "Grégoire Sutre" <gregoire.sutre@labri.fr>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: Re: [PATCH] grub-probe support for NetBSD
Date: Tue, 29 Dec 2009 02:31:46 +0100 [thread overview]
Message-ID: <4B395C02.9060500@labri.fr> (raw)
In-Reply-To: <4B37B094.7040102@labri.fr>
[-- Attachment #1: Type: text/plain, Size: 667 bytes --]
Hi,
Here is a new version of the patch (the change log remains the same as
in the original email). The new version does not attempt to read from a
floppy device in grub_util_biosdisk_open. Indeed, on NetBSD, reading
from the floppy device (e.g. cat /dev/fd0a) takes a _long_ time to abort
when there is no floppy in the drive.
With this patch (and with a few other changes [1] discussed here or on
bug-grub), I could successfully install grub with grub-install on a USB
stick (and then boot from it) on NetBSD 5.0 i386 and amd64.
Regards,
Grégoire
[1]
http://pkgsrc-wip.cvs.sourceforge.net/viewvc/pkgsrc-wip/wip/grub2-current/patches/
[-- Attachment #2: patch-grub-probe-netbsd --]
[-- Type: text/plain, Size: 8182 bytes --]
--- util/getroot.c.orig 2009-12-29 00:43:31.000000000 +0100
+++ util/getroot.c
@@ -266,8 +266,14 @@ find_root_device (const char *dir, dev_t
char *cwd;
cwd = xgetcwd ();
+#if defined(__NetBSD__)
+ /* Convert this block device to its character (raw) device */
+ res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3);
+ sprintf (res, "%s/r%s", cwd, ent->d_name);
+#else
res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2);
sprintf (res, "%s/%s", cwd, ent->d_name);
+#endif
strip_extra_slashes (res);
free (cwd);
--- util/grub-probe.c.orig 2009-12-29 00:43:31.000000000 +0100
+++ util/grub-probe.c
@@ -111,7 +111,7 @@ probe (const char *path, char *device_na
if (path == NULL)
{
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
if (! grub_util_check_char_device (device_name))
grub_util_error ("%s is not a character device.\n", device_name);
#else
--- util/hostdisk.c.orig 2009-12-29 00:43:31.000000000 +0100
+++ util/hostdisk.c
@@ -97,6 +97,15 @@ struct hd_geometry
# include <sys/disk.h>
#endif
+#if defined(__NetBSD__)
+# include <sys/ioctl.h>
+# include <sys/disklabel.h> /* struct disklabel */
+# include <util.h> /* getrawpartition */
+# ifndef RAW_FLOPPY_MAJOR
+# define RAW_FLOPPY_MAJOR 9
+# endif /* ! RAW_FLOPPY_MAJOR */
+#endif
+
struct
{
char *drive;
@@ -191,16 +200,20 @@ grub_util_biosdisk_open (const char *nam
return GRUB_ERR_NONE;
}
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
- defined(__FreeBSD_kernel__) || defined(__APPLE__)
+ defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
{
+# if defined(__NetBSD__)
+ struct disklabel label;
+# else
unsigned long long nr;
+# endif
int fd;
fd = open (map[drive].device, O_RDONLY);
if (fd == -1)
return grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk size", map[drive].device);
-# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
# else
if (fstat (fd, &st) < 0 || ! S_ISBLK (st.st_mode))
@@ -214,6 +227,11 @@ grub_util_biosdisk_open (const char *nam
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# elif defined(__APPLE__)
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
+# elif defined(__NetBSD__)
+ /* Do not attempt to read from a floppy device as it may take a long
+ time before aborting if there is no floppy in the drive. */
+ if ((major(st.st_rdev) == RAW_FLOPPY_MAJOR) ||
+ ioctl (fd, DIOCGDINFO, &label))
# else
if (ioctl (fd, BLKGETSIZE64, &nr))
# endif
@@ -224,14 +242,16 @@ grub_util_biosdisk_open (const char *nam
close (fd);
-#if defined (__APPLE__)
+# if defined (__APPLE__)
disk->total_sectors = nr;
-#else
+# elif defined(__NetBSD__)
+ disk->total_sectors = label.d_secperunit;
+# else
disk->total_sectors = nr / 512;
if (nr % 512)
grub_util_error ("unaligned device size");
-#endif
+# endif
grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
@@ -683,7 +703,7 @@ make_device_name (int drive, int dos_par
dos_part_str = xasprintf (",%d", dos_part + 1);
if (bsd_part >= 0)
- bsd_part_str = xasprintf (",%c", dos_part + 'a');
+ bsd_part_str = xasprintf (",%c", bsd_part + 'a');
ret = xasprintf ("%s%s%s", map[drive].drive,
dos_part_str ? : "",
@@ -853,6 +873,26 @@ convert_system_partition_to_system_disk
}
return path;
+#elif defined(__NetBSD__)
+ /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */
+ char *path = xstrdup (os_dev);
+ if (strncmp ("/dev/rwd", path, 8) == 0 ||
+ strncmp ("/dev/rsd", path, 8) == 0 ||
+ strncmp ("/dev/rcd", path, 8) == 0)
+ {
+ char *q;
+ q = path + strlen(path) - 1; /* last character */
+ if (grub_isalpha(*q) && grub_isdigit(*(q-1)))
+ {
+ int rawpart;
+ rawpart = getrawpartition();
+ if (rawpart < 0)
+ rawpart = 3; /* default on i386 */
+ *q = 'a' + rawpart;
+ }
+ }
+ return path;
+
#else
# warning "The function `convert_system_partition_to_system_disk' might not work on your OS correctly."
return xstrdup (os_dev);
@@ -923,7 +963,7 @@ grub_util_biosdisk_get_grub_dev (const c
== 0)
return make_device_name (drive, -1, -1);
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
if (! S_ISCHR (st.st_mode))
#else
if (! S_ISBLK (st.st_mode))
@@ -1107,6 +1147,133 @@ grub_util_biosdisk_get_grub_dev (const c
return make_device_name (drive, dos_part, bsd_part);
}
+#elif defined(__NetBSD__)
+ /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */
+ /* Adaptation of the Linux code above.
+ Here, get the start sector of a partition from the disklabel, and
+ compare it with each partition GRUB recognizes. */
+ {
+ char *name;
+ grub_disk_t disk;
+ int fd;
+ struct disklabel label;
+ int index;
+ u_int32_t p_offset;
+ int dos_part = -1;
+ int bsd_part = -1;
+ auto int find_partition (grub_disk_t disk,
+ const grub_partition_t partition);
+
+ int find_partition (grub_disk_t disk __attribute__ ((unused)),
+ const grub_partition_t partition)
+ {
+ struct grub_msdos_partition *pcdata = NULL;
+
+ if (strcmp (partition->partmap->name, "part_msdos") == 0)
+ pcdata = partition->data;
+
+ if (pcdata)
+ {
+ if (pcdata->bsd_part < 0)
+ grub_util_info ("DOS partition %d starts from %lu",
+ pcdata->dos_part, partition->start);
+ else
+ grub_util_info ("BSD partition %d,%c starts from %lu",
+ pcdata->dos_part, pcdata->bsd_part + 'a',
+ partition->start);
+ }
+ else
+ {
+ grub_util_info ("Partition %d starts from %lu",
+ partition->index, partition->start);
+ }
+
+ if (p_offset == partition->start)
+ {
+ if (pcdata)
+ {
+ dos_part = pcdata->dos_part;
+ bsd_part = pcdata->bsd_part;
+ }
+ else
+ {
+ dos_part = partition->index;
+ bsd_part = -1;
+ }
+ return 1;
+ }
+
+ return 0;
+ }
+
+ name = make_device_name (drive, -1, -1);
+
+ /*
+ * Since os_dev and convert_system_partition_to_system_disk (os_dev) are
+ * different, we know that os_dev is of the form /dev/[wsc]d[0-9]+[a-z].
+ */
+
+ index = os_dev[strlen(os_dev) - 1] - 'a';
+
+ fd = open (os_dev, O_RDONLY);
+ if (fd == -1)
+ {
+ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk label", os_dev);
+ free (name);
+ return 0;
+ }
+
+ if (ioctl (fd, DIOCGDINFO, &label))
+ {
+ grub_error (GRUB_ERR_BAD_DEVICE,
+ "cannot get disk label of `%s'", os_dev);
+ close (fd);
+ free (name);
+ return 0;
+ }
+
+ close (fd);
+
+ if (index >= label.d_npartitions)
+ {
+ grub_error (GRUB_ERR_BAD_DEVICE,
+ "no disk label entry for `%s'", os_dev);
+ close (fd);
+ free (name);
+ return 0;
+ }
+
+ p_offset = label.d_partitions[index].p_offset;
+ grub_util_info ("%s starts from %lu", os_dev, p_offset);
+
+ if (p_offset == 0)
+ return name; /* use whole disk */
+
+ grub_util_info ("opening the device %s", name);
+ disk = grub_disk_open (name);
+ free (name);
+
+ if (! disk)
+ return 0;
+
+ grub_partition_iterate (disk, find_partition);
+ if (grub_errno != GRUB_ERR_NONE)
+ {
+ grub_disk_close (disk);
+ return 0;
+ }
+
+ if (dos_part < 0)
+ {
+ grub_disk_close (disk);
+ grub_error (GRUB_ERR_BAD_DEVICE,
+ "cannot find the partition of `%s'", os_dev);
+ return 0;
+ }
+
+ return make_device_name (drive, dos_part, bsd_part);
+ }
+
#else
# warning "The function `grub_util_biosdisk_get_grub_dev' might not work on your OS correctly."
return make_device_name (drive, -1, -1);
next prev parent reply other threads:[~2009-12-29 1:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-27 19:08 [PATCH] grub-probe support for NetBSD Grégoire Sutre
2009-12-29 1:31 ` Grégoire Sutre [this message]
2010-01-01 11:39 ` Robert Millan
2010-01-02 11:35 ` Grégoire Sutre
2010-01-02 11:40 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-02 11:46 ` Grégoire Sutre
2010-01-03 16:27 ` Robert Millan
2010-01-04 1:32 ` Grégoire Sutre
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=4B395C02.9060500@labri.fr \
--to=gregoire.sutre@labri.fr \
--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.