From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1NOyTT-0007j7-8x for mharc-grub-devel@gnu.org; Sun, 27 Dec 2009 14:08:19 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NOyTQ-0007he-1R for grub-devel@gnu.org; Sun, 27 Dec 2009 14:08:16 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NOyTK-0007fo-Kv for grub-devel@gnu.org; Sun, 27 Dec 2009 14:08:15 -0500 Received: from [199.232.76.173] (port=60645 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NOyTK-0007fk-GB for grub-devel@gnu.org; Sun, 27 Dec 2009 14:08:10 -0500 Received: from iona.labri.fr ([147.210.8.143]:38973) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NOyTJ-0003dX-Rc for grub-devel@gnu.org; Sun, 27 Dec 2009 14:08:10 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by iona.labri.fr (Postfix) with ESMTP id D10B236B79 for ; Sun, 27 Dec 2009 20:08:06 +0100 (CET) X-Virus-Scanned: amavisd-new at labri.fr Received: from iona.labri.fr ([127.0.0.1]) by localhost (iona.labri.fr [127.0.0.1]) (amavisd-new, port 10027) with LMTP id V7GEqhyk6TTF for ; Sun, 27 Dec 2009 20:08:06 +0100 (CET) Received: from [192.168.1.111] (c2433-1-88-160-112-182.fbx.proxad.net [88.160.112.182]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by iona.labri.fr (Postfix) with ESMTP id 0CA4236B74 for ; Sun, 27 Dec 2009 20:08:05 +0100 (CET) Message-ID: <4B37B094.7040102@labri.fr> Date: Sun, 27 Dec 2009 20:08:04 +0100 From: =?ISO-8859-1?Q?Gr=E9goire_Sutre?= Organization: CNRS / LaBRI User-Agent: Thunderbird 2.0.0.23 (X11/20091027) MIME-Version: 1.0 To: The development of GRUB 2 Content-Type: multipart/mixed; boundary="------------060904050009080306050209" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Subject: [PATCH] grub-probe support for NetBSD X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Dec 2009 19:08:16 -0000 This is a multi-part message in MIME format. --------------060904050009080306050209 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable 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=E9goire --------------060904050009080306050209 Content-Type: text/plain; name="ChangeLog" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ChangeLog" 2009-12-27 Gregoire Sutre 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. --------------060904050009080306050209 Content-Type: text/x-patch; name="patch-grub-probe-netbsd.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-grub-probe-netbsd.diff" 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 #endif +#if defined(__NetBSD__) +# include +# include /* struct disklabel */ +# include /* 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); --------------060904050009080306050209--