From: "Grégoire Sutre" <gregoire.sutre@labri.fr>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: [PATCH] grub-probe support for NetBSD
Date: Sun, 27 Dec 2009 20:08:04 +0100 [thread overview]
Message-ID: <4B37B094.7040102@labri.fr> (raw)
[-- 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);
next reply other threads:[~2009-12-27 19:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-27 19:08 Grégoire Sutre [this message]
2009-12-29 1:31 ` [PATCH] grub-probe support for NetBSD 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
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=4B37B094.7040102@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.