* [PATCH] grub-probe support for NetBSD
@ 2009-12-27 19:08 Grégoire Sutre
2009-12-29 1:31 ` Grégoire Sutre
2010-01-04 1:32 ` Grégoire Sutre
0 siblings, 2 replies; 8+ messages in thread
From: Grégoire Sutre @ 2009-12-27 19:08 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 865 bytes --]
Hi,
I finished adding NetBSD specific code for grub-probe. A patch and a
changelog entry are attached. A few notes:
- devices are required to be character (raw) devices. In NetBSD, those
are of the form "/dev/r[wsc]d[0-9]+[a-z]" for hard disk drives and
CD-ROM drives, as far as I know.
- in grub_util_biosdisk_open, the disk size is obtained from the disk
label.
- in grub_util_biosdisk_get_grub_dev, the code is derived from the Linux
code: we get the start sector of the partition from the disk label,
and we compare it with each partition GRUB recognizes. I don't think
we can do better, as device names correspond to disklabel entries, and
those can be quite arbitrary.
- in make_device_name, I fixed what I believe to be a typo, but I may be
wrong.
Please let me know if I missed something,
Grégoire
[-- Attachment #2: ChangeLog --]
[-- Type: text/plain, Size: 463 bytes --]
2009-12-27 Gregoire Sutre <gregoire.sutre@labri.fr>
Add grub-probe support for NetBSD.
* util/getroot.c (find_root_device): Convert block device to
character device on NetBSD.
* util/probe.c (probe): Require character device on NetBSD.
* util/hostdisk.c (grub_util_biosdisk_open): NetBSD specific code.
(convert_system_partition_to_system_disk): Likewise.
(grub_util_biosdisk_get_grub_dev): Likewise.
(make_device_name): Fixed a typo in bsd_part_str.
[-- Attachment #3: patch-grub-probe-netbsd.diff --]
[-- Type: text/x-patch, Size: 8267 bytes --]
diff -Naurp grub2_2009-12-27/util/getroot.c grub2/util/getroot.c
--- grub2_2009-12-27/util/getroot.c 2009-12-27 16:04:32.000000000 +0100
+++ grub2/util/getroot.c 2009-12-27 17:51:46.000000000 +0100
@@ -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);
diff -Naurp grub2_2009-12-27/util/grub-probe.c grub2/util/grub-probe.c
--- grub2_2009-12-27/util/grub-probe.c 2009-12-27 16:04:32.000000000 +0100
+++ grub2/util/grub-probe.c 2009-12-27 17:49:02.000000000 +0100
@@ -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
diff -Naurp grub2_2009-12-27/util/hostdisk.c grub2/util/hostdisk.c
--- grub2_2009-12-27/util/hostdisk.c 2009-12-27 16:04:32.000000000 +0100
+++ grub2/util/hostdisk.c 2009-12-27 18:21:15.000000000 +0100
@@ -97,6 +97,12 @@ 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 */
+#endif
+
struct
{
char *drive;
@@ -191,16 +197,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 +224,8 @@ grub_util_biosdisk_open (const char *nam
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# elif defined(__APPLE__)
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
+# elif defined(__NetBSD__)
+ if (ioctl (fd, DIOCGDINFO, &label))
# else
if (ioctl (fd, BLKGETSIZE64, &nr))
# endif
@@ -224,14 +236,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 +697,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 +867,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 +957,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 +1141,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);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
2009-12-27 19:08 [PATCH] grub-probe support for NetBSD Grégoire Sutre
@ 2009-12-29 1:31 ` Grégoire Sutre
2010-01-01 11:39 ` Robert Millan
2010-01-04 1:32 ` Grégoire Sutre
1 sibling, 1 reply; 8+ messages in thread
From: Grégoire Sutre @ 2009-12-29 1:31 UTC (permalink / raw)
To: The development of GRUB 2
[-- 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);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
2009-12-29 1:31 ` Grégoire Sutre
@ 2010-01-01 11:39 ` Robert Millan
2010-01-02 11:35 ` Grégoire Sutre
0 siblings, 1 reply; 8+ messages in thread
From: Robert Millan @ 2010-01-01 11:39 UTC (permalink / raw)
To: The development of GNU GRUB
On Tue, Dec 29, 2009 at 02:31:46AM +0100, Grégoire Sutre wrote:
> +#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
Can you avoid code duplication here? Something like:
#ifdef __NetBSD__
const char *template = "%s/r%s";
#else
const char *template = "%s/%s";
#endif
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
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-03 16:27 ` Robert Millan
0 siblings, 2 replies; 8+ messages in thread
From: Grégoire Sutre @ 2010-01-02 11:35 UTC (permalink / raw)
To: The development of GNU GRUB
Robert Millan wrote:
> On Tue, Dec 29, 2009 at 02:31:46AM +0100, Grégoire Sutre wrote:
>> +#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
>
> Can you avoid code duplication here? Something like:
>
> #ifdef __NetBSD__
> const char *template = "%s/r%s";
> #else
> const char *template = "%s/%s";
> #endif
Indeed, it's better. But we also need a variable for the extra length
(3 for NetBSD and 2 otherwise). I have updated the patch.
http://pkgsrc-wip.cvs.sourceforge.net/viewvc/*checkout*/pkgsrc-wip/wip/grub2-current/patches/patch-grub-probe-netbsd
The patch is not finished yet: as discussed on IRC, I'll try to
factorize Linux and NetBSD code in grub_util_biosdisk_get_grub_dev, and
to fix the floppy problem.
Grégoire
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
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
1 sibling, 1 reply; 8+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-01-02 11:40 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 1459 bytes --]
Grégoire Sutre wrote:
> Robert Millan wrote:
>> On Tue, Dec 29, 2009 at 02:31:46AM +0100, Grégoire Sutre wrote:
>>> +#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
>>
>> Can you avoid code duplication here? Something like:
>>
>> #ifdef __NetBSD__
>> const char *template = "%s/r%s";
>> #else
>> const char *template = "%s/%s";
>> #endif
>
> Indeed, it's better. But we also need a variable for the extra length
> (3 for NetBSD and 2 otherwise).
One byte is cheap. No need for gimmicks just to save one byte. You can
always allocate with +3
> I have updated the patch.
>
> http://pkgsrc-wip.cvs.sourceforge.net/viewvc/*checkout*/pkgsrc-wip/wip/grub2-current/patches/patch-grub-probe-netbsd
>
>
> The patch is not finished yet: as discussed on IRC, I'll try to
> factorize Linux and NetBSD code in grub_util_biosdisk_get_grub_dev,
> and to fix the floppy problem.
>
> Grégoire
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
2010-01-02 11:40 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-02 11:46 ` Grégoire Sutre
0 siblings, 0 replies; 8+ messages in thread
From: Grégoire Sutre @ 2010-01-02 11:46 UTC (permalink / raw)
To: The development of GNU GRUB
Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> One byte is cheap. No need for gimmicks just to save one byte. You can
> always allocate with +3
Ok :-)
Grégoire
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
2010-01-02 11:35 ` Grégoire Sutre
2010-01-02 11:40 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-03 16:27 ` Robert Millan
1 sibling, 0 replies; 8+ messages in thread
From: Robert Millan @ 2010-01-03 16:27 UTC (permalink / raw)
To: The development of GNU GRUB
On Sat, Jan 02, 2010 at 12:35:44PM +0100, Grégoire Sutre wrote:
>> Can you avoid code duplication here? Something like:
>>
>> #ifdef __NetBSD__
>> const char *template = "%s/r%s";
>> #else
>> const char *template = "%s/%s";
>> #endif
>
> Indeed, it's better. But we also need a variable for the extra length
> (3 for NetBSD and 2 otherwise). I have updated the patch.
I understand; don't worry about that, GCC is smart and space is cheap in
util/ anyway.
> http://pkgsrc-wip.cvs.sourceforge.net/viewvc/*checkout*/pkgsrc-wip/wip/grub2-current/patches/patch-grub-probe-netbsd
Would you please send patches as attachments? URLs don't make it easy for
review.
Thanks!
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] grub-probe support for NetBSD
2009-12-27 19:08 [PATCH] grub-probe support for NetBSD Grégoire Sutre
2009-12-29 1:31 ` Grégoire Sutre
@ 2010-01-04 1:32 ` Grégoire Sutre
1 sibling, 0 replies; 8+ messages in thread
From: Grégoire Sutre @ 2010-01-04 1:32 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 1179 bytes --]
Hi,
This the new version of the patch adding grub-probe (and grub-setup)
support for NetBSD. The main changes are:
- in function grub_util_biosdisk_get_grub_dev(), merge of the new
NetBSD code with the original Linux code.
- re-enabled disk size detection for floppy. This is done as for the
other devices via the disklabel. Hence, the floppy must have been
labeled before, which is the recommended usage according to [1].
I couldn't find another way to get the disk size for floppies.
For the record, an example of successfull installation on a floppy
(with grub-install) is also attached.
- as the floppy driver takes a long time to abort when the floppy drive
is empty, the option NORETRY is set on the floppy driver. The running
time of grub-probe gets divided by 6 (30s instead of 3 minutes). It
is still long, but is also due to the fact that grub-probe tries to
read the floppy 4 times. Of course, this is only if the device map
contains a floppy device, and grub-install --no-floppy does not suffer
from this problem.
Thanks,
Grégoire
[1] http://www.netbsd.org/docs/guide/en/chap-rmmedia.html
[-- Attachment #2: patch-grub-probe-netbsd --]
[-- Type: text/plain, Size: 12820 bytes --]
Description: adds support for NetBSD in GRUB utilities.
See: http://lists.gnu.org/archive/html/grub-devel/2009-12/msg00432.html
Change log
----------
2010-??-?? Gregoire Sutre <gregoire.sutre@labri.fr>
Add grub-probe support for NetBSD.
* util/getroot.c (find_root_device): Convert block device to
character device on NetBSD.
* util/probe.c (probe): Require character device on NetBSD.
* util/hostdisk.c: NetBSD specific headers.
(configure_device_driver): new function to tune device driver
parameters (currently only for NetBSD floppy driver).
(grub_util_biosdisk_open): NetBSD specific code (get disk size
via disklabel ioctl).
(open_device): call configure_device_driver on NetBSD.
(convert_system_partition_to_system_disk): NetBSD specific code.
(device_is_wholedisk): Likewise.
(grub_util_biosdisk_get_grub_dev): Likewise.
(make_device_name): Fixed a typo in bsd_part_str.
* configure.ac: check for opendisk() and getrawpartition() on
NetBSD and set LIBUTIL.
* Makefile.in: add LIBUTIL to LIBS.
--- util/getroot.c.orig 2010-01-02 14:42:38.000000000 +0100
+++ util/getroot.c
@@ -264,10 +264,17 @@ find_root_device (const char *dir, dev_t
/* Found! */
char *res;
char *cwd;
+#if defined(__NetBSD__)
+ /* Convert this block device to its character (raw) device. */
+ const char *template = "%s/r%s";
+#else
+ /* Keep the device name as it is. */
+ const char *template = "%s/%s";
+#endif
cwd = xgetcwd ();
- res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 2);
- sprintf (res, "%s/%s", cwd, ent->d_name);
+ res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3);
+ sprintf (res, template, cwd, ent->d_name);
strip_extra_slashes (res);
free (cwd);
--- util/grub-probe.c.orig 2010-01-02 14:42:38.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 2010-01-02 14:42:38.000000000 +0100
+++ util/hostdisk.c
@@ -97,6 +97,18 @@ struct hd_geometry
# include <sys/disk.h>
#endif
+#if defined(__NetBSD__)
+# include <sys/ioctl.h>
+# include <sys/disklabel.h> /* struct disklabel */
+# ifdef HAVE_GETRAWPARTITION
+# include <util.h> /* getrawpartition */
+# endif /* HAVE_GETRAWPARTITION */
+# include <sys/fdio.h>
+# ifndef RAW_FLOPPY_MAJOR
+# define RAW_FLOPPY_MAJOR 9
+# endif /* ! RAW_FLOPPY_MAJOR */
+#endif /* defined(__NetBSD__) */
+
struct
{
char *drive;
@@ -121,6 +133,31 @@ have_devfs (void)
}
#endif /* __linux__ */
+#if defined(__NetBSD__)
+/* Adjust device driver parameters. This function should be called just
+ after successfully opening the device. For now, it simply prevents the
+ floppy driver from retrying operations on failure, as otherwise the
+ driver takes a while to abort when there is no floppy in the drive. */
+static void
+configure_device_driver (int fd)
+{
+ struct stat st;
+
+ if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
+ return;
+ if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
+ {
+ int floppy_opts;
+
+ if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
+ return;
+ floppy_opts |= FDOPT_NORETRY;
+ if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
+ return;
+ }
+}
+#endif /* defined(__NetBSD__) */
+
static int
find_grub_drive (const char *name)
{
@@ -191,16 +228,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 +255,9 @@ grub_util_biosdisk_open (const char *nam
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# elif defined(__APPLE__)
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
+# elif defined(__NetBSD__)
+ configure_device_driver (fd);
+ if (ioctl (fd, DIOCGDINFO, &label) == -1)
# else
if (ioctl (fd, BLKGETSIZE64, &nr))
# endif
@@ -224,14 +268,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);
@@ -398,6 +444,10 @@ open_device (const grub_disk_t disk, gru
}
#endif /* ! __linux__ */
+#if defined(__NetBSD__)
+ configure_device_driver (fd);
+#endif /* defined(__NetBSD__) */
+
#if defined(__linux__) && (!defined(__GLIBC__) || \
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
/* Maybe libc doesn't have large file support. */
@@ -683,7 +733,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 +903,27 @@ 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 = -1;
+# ifdef HAVE_GETRAWPARTITION
+ rawpart = getrawpartition();
+# endif /* HAVE_GETRAWPARTITION */
+ if (rawpart >= 0)
+ *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);
@@ -871,6 +942,26 @@ device_is_wholedisk (const char *os_dev)
}
#endif
+#if defined(__NetBSD__)
+/* Try to determine whether a given device name corresponds to a whole disk.
+ This function should give in most cases a definite answer, but it may
+ actually give an approximate one in the following sense: if the return
+ value is 0 then the device name does not correspond to a whole disk. */
+static int
+device_is_wholedisk (const char *os_dev)
+{
+ int len = strlen (os_dev);
+ int rawpart = -1;
+
+# ifdef HAVE_GETRAWPARTITION
+ rawpart = getrawpartition();
+# endif /* HAVE_GETRAWPARTITION */
+ if (rawpart < 0)
+ return 1;
+ return (os_dev[len - 1] == ('a' + rawpart));
+}
+#endif /* defined(__NetBSD__) */
+
static int
find_system_device (const char *os_dev)
{
@@ -923,14 +1014,14 @@ 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))
#endif
return make_device_name (drive, -1, -1);
-#if defined(__linux__) || defined(__CYGWIN__)
+#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
Here, get the start sector of a partition by HDIO_GETGEO, and
@@ -938,12 +1029,24 @@ grub_util_biosdisk_get_grub_dev (const c
Cygwin /dev/sdXN emulation uses Windows partition mapping. It
does not count the extended partition and missing primary
- partitions. Use same method as on Linux here. */
+ partitions. Use same method as on Linux here.
+
+ For NetBSD, proceed as for Linux, except that the start sector is
+ obtained from the disk label. */
{
char *name;
grub_disk_t disk;
int fd;
+# if !defined(__NetBSD__)
+ const char *disk_info_msg = "geometry";
struct hd_geometry hdg;
+ unsigned long p_offset;
+# else /* defined(__NetBSD__) */
+ const char *disk_info_msg = "label";
+ struct disklabel label;
+ int index;
+ u_int32_t p_offset;
+# endif /* !defined(__NetBSD__) */
int dos_part = -1;
int bsd_part = -1;
auto int find_partition (grub_disk_t disk,
@@ -973,7 +1076,7 @@ grub_util_biosdisk_get_grub_dev (const c
partition->index, partition->start);
}
- if (hdg.start == partition->start)
+ if (p_offset == partition->start)
{
if (pcdata)
{
@@ -993,21 +1096,33 @@ grub_util_biosdisk_get_grub_dev (const c
name = make_device_name (drive, -1, -1);
+# if !defined(__NetBSD__)
if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
return name;
+# else /* defined(__NetBSD__) */
+ /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
+ * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z]
+ * and in particular it cannot be a floppy device. */
+ index = os_dev[strlen(os_dev) - 1] - 'a';
+# endif /* !defined(__NetBSD__) */
fd = open (os_dev, O_RDONLY);
if (fd == -1)
{
- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev);
+ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk %s", os_dev, disk_info_msg);
free (name);
return 0;
}
+# if !defined(__NetBSD__)
if (ioctl (fd, HDIO_GETGEO, &hdg))
+# else /* defined(__NetBSD__) */
+ configure_device_driver (fd);
+ if (ioctl (fd, DIOCGDINFO, &label) == -1)
+# endif /* !defined(__NetBSD__) */
{
grub_error (GRUB_ERR_BAD_DEVICE,
- "cannot get geometry of `%s'", os_dev);
+ "cannot get disk %s of `%s'", disk_info_msg, os_dev);
close (fd);
free (name);
return 0;
@@ -1015,9 +1130,22 @@ grub_util_biosdisk_get_grub_dev (const c
close (fd);
- grub_util_info ("%s starts from %lu", os_dev, hdg.start);
+# if !defined(__NetBSD__)
+ p_offset = hdg.start;
+# else /* defined(__NetBSD__) */
+ if (index >= label.d_npartitions)
+ {
+ grub_error (GRUB_ERR_BAD_DEVICE,
+ "no disk label entry for `%s'", os_dev);
+ free (name);
+ return 0;
+ }
+ p_offset = label.d_partitions[index].p_offset;
+# endif /* !defined(__NetBSD__) */
+
+ grub_util_info ("%s starts from %lu", os_dev, p_offset);
- if (hdg.start == 0 && device_is_wholedisk (os_dev))
+ if (p_offset == 0 && device_is_wholedisk (os_dev))
return name;
grub_util_info ("opening the device %s", name);
--- configure.ac.orig 2010-01-02 14:42:26.000000000 +0100
+++ configure.ac
@@ -208,6 +208,20 @@ AC_CHECK_FUNCS(memmove sbrk strdup lstat
AC_CHECK_HEADERS(sys/mkdev.h sys/sysmacros.h malloc.h termios.h sys/types.h)
AC_CHECK_HEADERS(unistd.h string.h strings.h sys/stat.h sys/fcntl.h)
+# For opendisk() and getrawpartition() on NetBSD.
+# Used in util/deviceiter.c and in util/hostdisk.c.
+AC_CHECK_HEADER([util.h], [
+ AC_CHECK_LIB([util], [opendisk], [
+ LIBUTIL="-lutil"
+ AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])
+ ])
+ AC_CHECK_LIB([util], [getrawpartition], [
+ LIBUTIL="-lutil"
+ AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used])
+ ])
+])
+AC_SUBST([LIBUTIL])
+
#
# Check for target programs.
#
--- Makefile.in.orig 2010-01-02 14:42:01.000000000 +0100
+++ Makefile.in
@@ -44,6 +44,9 @@ pkglibdir = $(libdir)/`echo @PACKAGE_TA
# Internationalization library.
LIBINTL = @LIBINTL@
+# Util library.
+LIBUTIL = @LIBUTIL@
+
XGETTEXT = @XGETTEXT@
MSGMERGE = @MSGMERGE@
MSGFMT = @MSGFMT@
@@ -75,7 +78,7 @@ MKDIR_P = @MKDIR_P@
mkinstalldirs = $(srcdir)/mkinstalldirs
-LIBS = @LIBS@ $(LIBINTL)
+LIBS = @LIBS@ $(LIBINTL) $(LIBUTIL)
CC = @CC@
CFLAGS = @CFLAGS@
[-- Attachment #3: Grub-Install-Floppy-NetBSD.txt --]
[-- Type: text/plain, Size: 446 bytes --]
Example Installation of GRUB 2 on a common 1440 KB floppy
*with grub-install* on NetBSD 5.0 i386/amd64
Format the floppy with:
$ fdformat -f /dev/rfd0a
Install a standard floppy disk label with:
$ disklabel -rw fd0a floppy
Create a filesystem on the floppy with:
$ newfs -m 0 /dev/rfd0a
Mount this filesystem e.g. on /mnt with:
$ mount /dev/fd0a /mnt
Finally, install grub with:
$ grub2-install --force --root-directory=/mnt/grub /dev/rfd0a
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-01-04 1:32 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-27 19:08 [PATCH] grub-probe support for NetBSD Grégoire Sutre
2009-12-29 1:31 ` Grégoire Sutre
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
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.