From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1NPQwL-0000AP-BE for mharc-grub-devel@gnu.org; Mon, 28 Dec 2009 20:32:01 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NPQwK-0000AC-6t for grub-devel@gnu.org; Mon, 28 Dec 2009 20:32:00 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NPQwE-00009F-5P for grub-devel@gnu.org; Mon, 28 Dec 2009 20:31:58 -0500 Received: from [199.232.76.173] (port=50584 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NPQwE-00009B-2L for grub-devel@gnu.org; Mon, 28 Dec 2009 20:31:54 -0500 Received: from iona.labri.fr ([147.210.8.143]:57585) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NPQwD-00074y-DE for grub-devel@gnu.org; Mon, 28 Dec 2009 20:31:53 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by iona.labri.fr (Postfix) with ESMTP id 54CD236BAB for ; Tue, 29 Dec 2009 02:31:48 +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 tbhoF48sjJjt for ; Tue, 29 Dec 2009 02:31:48 +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 7A1EA36BAA for ; Tue, 29 Dec 2009 02:31:47 +0100 (CET) Message-ID: <4B395C02.9060500@labri.fr> Date: Tue, 29 Dec 2009 02:31:46 +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 References: <4B37B094.7040102@labri.fr> In-Reply-To: <4B37B094.7040102@labri.fr> Content-Type: multipart/mixed; boundary="------------000708070809080700030001" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Subject: Re: [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: Tue, 29 Dec 2009 01:32:00 -0000 This is a multi-part message in MIME format. --------------000708070809080700030001 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Hi, Here is a new version of the patch (the change log remains the same as=20 in the original email). The new version does not attempt to read from a=20 floppy device in grub_util_biosdisk_open. Indeed, on NetBSD, reading=20 from the floppy device (e.g. cat /dev/fd0a) takes a _long_ time to abort=20 when there is no floppy in the drive. With this patch (and with a few other changes [1] discussed here or on=20 bug-grub), I could successfully install grub with grub-install on a USB=20 stick (and then boot from it) on NetBSD 5.0 i386 and amd64. Regards, Gr=E9goire [1]=20 http://pkgsrc-wip.cvs.sourceforge.net/viewvc/pkgsrc-wip/wip/grub2-current= /patches/ --------------000708070809080700030001 Content-Type: text/plain; name="patch-grub-probe-netbsd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-grub-probe-netbsd" --- 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 #endif +#if defined(__NetBSD__) +# include +# include /* struct disklabel */ +# include /* 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); --------------000708070809080700030001--