Module Name: src
Committed By: martin
Date: Fri Sep 13 07:00:14 UTC 2019
Modified Files:
src/share/man/man8/man8.x86 [netbsd-9]: boot.8
src/sys/arch/i386/stand/boot [netbsd-9]: boot2.c devopen.c devopen.h
src/sys/arch/i386/stand/efiboot [netbsd-9]: boot.c devopen.c devopen.h
efidisk.c
src/sys/arch/i386/stand/lib [netbsd-9]: Makefile biosdisk.c biosdisk.h
Log Message:
Pull up following revision(s) (requested by manu in ticket #200):
sys/arch/i386/stand/boot/boot2.c: revision 1.72
sys/arch/i386/stand/lib/biosdisk.c: revision 1.50
sys/arch/i386/stand/lib/biosdisk.c: revision 1.51
sys/arch/i386/stand/efiboot/devopen.c: revision 1.6
sys/arch/i386/stand/efiboot/devopen.h: revision 1.4
sys/arch/i386/stand/efiboot/devopen.c: revision 1.7
sys/arch/i386/stand/efiboot/efidisk.c: revision 1.8
share/man/man8/man8.x86/boot.8: revision 1.16
share/man/man8/man8.x86/boot.8: revision 1.17
sys/arch/i386/stand/lib/Makefile: revision 1.46
sys/arch/i386/stand/boot/devopen.h: revision 1.5
sys/arch/i386/stand/boot/devopen.c: revision 1.9
sys/arch/i386/stand/efiboot/boot.c: revision 1.14
sys/arch/i386/stand/efiboot/boot.c: revision 1.15
sys/arch/i386/stand/lib/biosdisk.h: revision 1.11
sys/arch/i386/stand/boot/boot2.c: revision 1.71
Add GPT and RAIDframe support to bootloaders
Classic BIOS (/boot) and EFI bootloaders can now name devices
using the NAME=gpt_label syntax, or using raid partitions. Here
are examples:
boot NAME=root:/netbsd
boot raid0e:/netbsd
Correct the memset(3)'s third argument in i386 biosdisk.c
The size of allocation is the size of the structure biosdisk, not the size
of a pointer.
Document new GPT and RAIDframe capacity of bootstrap code
While there, also document EFI setup and some bugs
Typo fixes, 'file system'; new sentence, new line; expand IA-32.
Bump date for previous.
Make sure devices names are copied including last byte
Fix from M. Levinson.
To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.15.2.1 src/share/man/man8/man8.x86/boot.8
cvs rdiff -u -r1.70 -r1.70.8.1 src/sys/arch/i386/stand/boot/boot2.c
cvs rdiff -u -r1.8 -r1.8.64.1 src/sys/arch/i386/stand/boot/devopen.c
cvs rdiff -u -r1.4 -r1.4.64.1 src/sys/arch/i386/stand/boot/devopen.h
cvs rdiff -u -r1.13 -r1.13.2.1 src/sys/arch/i386/stand/efiboot/boot.c
cvs rdiff -u -r1.5 -r1.5.6.1 src/sys/arch/i386/stand/efiboot/devopen.c
cvs rdiff -u -r1.3 -r1.3.6.1 src/sys/arch/i386/stand/efiboot/devopen.h
cvs rdiff -u -r1.7 -r1.7.4.1 src/sys/arch/i386/stand/efiboot/efidisk.c
cvs rdiff -u -r1.45 -r1.45.8.1 src/sys/arch/i386/stand/lib/Makefile
cvs rdiff -u -r1.49 -r1.49.6.1 src/sys/arch/i386/stand/lib/biosdisk.c
cvs rdiff -u -r1.10 -r1.10.6.1 src/sys/arch/i386/stand/lib/biosdisk.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man8/man8.x86/boot.8
diff -u src/share/man/man8/man8.x86/boot.8:1.15 src/share/man/man8/man8.x86/boot.8:1.15.2.1
--- src/share/man/man8/man8.x86/boot.8:1.15 Wed May 15 17:35:02 2019
+++ src/share/man/man8/man8.x86/boot.8 Fri Sep 13 07:00:14 2019
@@ -1,4 +1,4 @@
-.\" $NetBSD: boot.8,v 1.15 2019/05/15 17:35:02 maxv Exp $
+.\" $NetBSD: boot.8,v 1.15.2.1 2019/09/13 07:00:14 martin Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -32,7 +32,7 @@
.\"
.\" @(#)boot_i386.8 8.2 (Berkeley) 4/19/94
.\"
-.Dd May 15, 2019
+.Dd August 18, 2019
.Dt BOOT 8 x86
.Os
.Sh NAME
@@ -40,13 +40,9 @@
.Nd
system bootstrapping procedures
.Sh DESCRIPTION
-.Tn IA-32
-computers
-.Po
-the
+Intel Architecture, 32-bit (IA-32) computers (the
.Tn IBM PC
-and its clones
-.Pc
+and its clones)
that can run
.Nx Ns /i386
or
@@ -60,6 +56,11 @@ bootstrap
.Nx
from the system
.Tn BIOS
+.It efiboot
+bootstrap
+.Nx
+from the system
+.Tn UEFI
.It Xr x86/dosboot 8
bootstrap
.Nx
@@ -175,12 +176,32 @@ input of these commands:
.It Ic boot Oo Va device : Oc Ns Oo Va filename Oc Oo Fl 1234abcdmqsvxz Oc
The default
.Va device
-will be set to the disk that the boot loader was
-loaded from.
+will be set to the disk from which the boot loader was loaded.
+The partition is set to the first match in this list:
+.Bl -enum -compact
+.It
+The first
+.Xr gpt 8
+partition with the
+.Va bootme
+attribute set.
+.It
+The partition from which the boot loader was loaded from, if that
+can be detected.
+.It
+The first partition with a file system that could be bootable.
+.It
+The first partition.
+.El
To boot from an alternate disk, the full name of the device should
be given at the prompt.
.Va device
is of the form
+.Va NAME=partition_label
+when booting from a
+.Xr gpt 8
+partitioned disk.
+Otherwise, the syntax is
.Xo Va xd
.Op Va N Ns Op Va x
.Xc
@@ -192,8 +213,8 @@ is the unit number, and
.Va x
is the partition letter.
.Pp
-The following list of supported devices may vary from installation to
-installation:
+In the later case, the following list of supported devices may
+vary from installation to installation:
.Pp
.Bl -hang -compact
.It hd
@@ -203,6 +224,22 @@ lookalike controller(s), and SCSI disks
on SCSI controllers recognized by the BIOS.
.It fd
Floppy drives as numbered by the BIOS.
+.It cd
+CD-ROM drives as numbered by the BIOS.
+.It raid
+RAIDframe configured from hard disks recognized by the BIOS.
+Only RAID level 1 sets are supported by bootstrap code.
+If the RAID is partitioned, the first partition is used, or the
+first
+.Xr gpt 8
+partition that has the
+.Va bootme
+attribute set.
+Inner RAIDframe partitions can also be given to the
+.Ic dev
+command using he
+.Va NAME=partition_label
+syntax.
.El
.Pp
The default
@@ -700,6 +737,33 @@ the
.Nx
partition by
.Xr installboot 8 .
+.It Pa /usr/mdec/bootia32.efi
+.It Pa /usr/mdec/bootx64.efi
+.Tn UEFI
+bootstraps for
+.Nx Ns /i386
+and
+.Nx Ns /amd64 ,
+which should be copied to the
+.Pa /efi/boot
+directory in a
+.Tn FAT
+formatted partition of type
+.Tn EFI
+(Either
+.Xr mbr 8
+and
+.Xr gpt 8 ,
+see the
+.Sx BUGS
+section).
+.Nx
+.Tn UEFI
+bootstrap reads its configuration from the
+.Pa /efi/netBSD/boot.cfg
+file in the
+.Tn EFI
+partition.
.El
.Sh SEE ALSO
.Xr ddb 4 ,
@@ -756,3 +820,44 @@ is derived from the
field of the
.Nx
disklabel (if it is a hard disk).
+.Pp
+.Ic multiboot
+is not supported by
+.Tn UEFI
+bootstrap code.
+.Pp
+.Tn UEFI
+implementation are supposed to support either
+.Xr mbr 8
+or
+.Xr gpt 8
+partitionning, but some do not handle the later.
+.Tn UEFI
+Booting
+from a
+.Xr gpt 8
+partitioned disk is still possible in this case, by adding
+an overlapping
+.Tn EFI
+partition in the protective
+.Xr mbr 8
+block.
+This can be achieved using the following commands
+(you must adapt the hard disk and
+.Tn EFI
+partition start end size to fit your setup):
+.Dl Ic dd if=/dev/rwd0d bs=512 count=1 of=mbr
+.Dl Ic fdisk -FIfaui1s 4/34/32768 -c /usr/mdec/mbr mbr
+.Dl Ic dd if=mbr bs=512 count=1 of=/dev/rwd0d conv=notrunc
+The resulting
+.Xr mbr 8
+partition table will look like this:
+.Bd -unfilled -offset indent
+0: GPT Protective MBR (sysid 238)
+ start 1, size 2097151 (1024 MB, Cyls 0-130/138/8)
+ PBR is not bootable: Bad magic number (0x0000)
+1: Primary DOS with 16 bit FAT <32M (sysid 4)
+ start 34, size 32768 (16 MB, Cyls 0/0/35-2/10/42), Active
+2: <UNUSED>
+3: <UNUSED>
+.Ed
Index: src/sys/arch/i386/stand/boot/boot2.c
diff -u src/sys/arch/i386/stand/boot/boot2.c:1.70 src/sys/arch/i386/stand/boot/boot2.c:1.70.8.1
--- src/sys/arch/i386/stand/boot/boot2.c:1.70 Tue Nov 14 09:55:41 2017
+++ src/sys/arch/i386/stand/boot/boot2.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: boot2.c,v 1.70 2017/11/14 09:55:41 maxv Exp $ */
+/* $NetBSD: boot2.c,v 1.70.8.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -79,6 +79,7 @@
#include <libi386.h>
#include <bootmod.h>
#include <bootmenu.h>
+#include <biosdisk.h>
#include <vbe.h>
#include "devopen.h"
@@ -104,11 +105,16 @@ static const char * const names[][2] = {
#define NUMNAMES (sizeof(names)/sizeof(names[0]))
#define DEFFILENAME names[0][0]
+#ifndef NO_GPT
+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+#else
#define MAXDEVNAME 16
+#endif
static char *default_devname;
static int default_unit, default_partition;
static const char *default_filename;
+static const char *default_part_name;
char *sprint_bootsel(const char *);
static void bootit(const char *, int);
@@ -160,9 +166,16 @@ parsebootfile(const char *fname, char **
int *unit, int *partition, const char **file)
{
const char *col;
+ static char savedevname[MAXDEVNAME+1];
*fsname = "ufs";
- *devname = default_devname;
+ if (default_part_name == NULL) {
+ *devname = default_devname;
+ } else {
+ snprintf(savedevname, sizeof(savedevname),
+ "NAME=%s", default_part_name);
+ *devname = savedevname;
+ }
*unit = default_unit;
*partition = default_partition;
*file = default_filename;
@@ -171,7 +184,6 @@ parsebootfile(const char *fname, char **
return 0;
if ((col = strchr(fname, ':')) != NULL) { /* device given */
- static char savedevname[MAXDEVNAME+1];
int devlen;
int u = 0, p = 0;
int i = 0;
@@ -180,6 +192,17 @@ parsebootfile(const char *fname, char **
if (devlen > MAXDEVNAME)
return EINVAL;
+#ifndef NO_GPT
+ if (strstr(fname, "NAME=") == fname) {
+ strlcpy(savedevname, fname, devlen + 1);
+ *devname = savedevname;
+ *unit = -1;
+ *partition = -1;
+ fname = col + 1;
+ goto out;
+ }
+#endif
+
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
if (!isvalidname(fname[i]))
return EINVAL;
@@ -215,6 +238,7 @@ parsebootfile(const char *fname, char **
fname = col + 1;
}
+out:
if (*fname)
*file = fname;
@@ -231,8 +255,11 @@ sprint_bootsel(const char *filename)
if (parsebootfile(filename, &fsname, &devname, &unit,
&partition, &file) == 0) {
- snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
- 'a' + partition, file);
+ if (strstr(devname, "NAME=") == devname)
+ snprintf(buf, sizeof(buf), "%s:%s", devname, file);
+ else
+ snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
+ 'a' + partition, file);
return buf;
}
return "(invalid)";
@@ -319,7 +346,7 @@ boot2(int biosdev, uint64_t biossector)
/* try to set default device to what BIOS tells us */
bios2dev(biosdev, biossector, &default_devname, &default_unit,
- &default_partition);
+ &default_partition, &default_part_name);
/* if the user types "boot" without filename */
default_filename = DEFFILENAME;
@@ -401,13 +428,21 @@ command_help(char *arg)
{
printf("commands are:\n"
- "boot [xdNx:][filename] [-12acdqsvxz]\n"
+ "boot [dev:][filename] [-12acdqsvxz]\n"
+#ifndef NO_RAIDFRAME
+ " dev syntax is (hd|fd|cd|raid)[N[x]]\n"
+#else
+ " dev syntax is (hd|fd|cd)[N[x]]n"
+#endif
+#ifndef NO_GPT
+ " or NAME=gpt_label\n"
+#endif
" (ex. \"hd0a:netbsd.old -s\")\n"
- "pkboot [xdNx:][filename] [-12acdqsvxz]\n"
+ "pkboot [dev:][filename] [-12acdqsvxz]\n"
#if LIBSA_ENABLE_LS_OP
- "ls [path]\n"
+ "ls [dev:][path]\n"
#endif
- "dev xd[N[x]]:\n"
+ "dev [dev:]\n"
"consdev {pc|com[0123]|com[0123]kbd|auto}\n"
"vesa {modenum|on|off|enabled|disabled|list}\n"
#ifndef SMALL
@@ -415,7 +450,7 @@ command_help(char *arg)
#endif
"modules {on|off|enabled|disabled}\n"
"load {path_to_module}\n"
- "multiboot [xdNx:][filename] [<args>]\n"
+ "multiboot [dev:][filename] [<args>]\n"
"splash {path_to_image_file}\n"
"userconf {command}\n"
"rndseed {path_to_rndseed_file}\n"
@@ -490,8 +525,16 @@ command_dev(char *arg)
if (*arg == '\0') {
biosdisk_probe();
- printf("default %s%d%c\n", default_devname, default_unit,
- 'a' + default_partition);
+
+#ifndef NO_GPT
+ if (default_part_name)
+ printf("default NAME=%s on %s%d\n", default_part_name,
+ default_devname, default_unit);
+ else
+#endif
+ printf("default %s%d%c\n",
+ default_devname, default_unit,
+ 'a' + default_partition);
return;
}
@@ -505,6 +548,10 @@ command_dev(char *arg)
/* put to own static storage */
strncpy(savedevname, devname, MAXDEVNAME + 1);
default_devname = savedevname;
+
+ /* +5 to skip leading NAME= */
+ if (strstr(devname, "NAME=") == devname)
+ default_part_name = default_devname + 5;
}
static const struct cons_devs {
Index: src/sys/arch/i386/stand/boot/devopen.c
diff -u src/sys/arch/i386/stand/boot/devopen.c:1.8 src/sys/arch/i386/stand/boot/devopen.c:1.8.64.1
--- src/sys/arch/i386/stand/boot/devopen.c:1.8 Fri Dec 24 20:40:42 2010
+++ src/sys/arch/i386/stand/boot/devopen.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.c,v 1.8 2010/12/24 20:40:42 jakllsch Exp $ */
+/* $NetBSD: devopen.c,v 1.8.64.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -89,7 +89,8 @@ dev2bios(char *devname, int unit, int *b
}
void
-bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
+bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
+ int *partition, const char **part_name)
{
/* set default */
@@ -109,7 +110,7 @@ bios2dev(int biosdev, daddr_t sector, ch
} else
*devname = "fd";
- *partition = biosdisk_findpartition(biosdev, sector);
+ (void)biosdisk_findpartition(biosdev, sector, partition, part_name);
}
#ifdef _STANDALONE
@@ -128,9 +129,9 @@ devopen(struct open_file *f, const char
int biosdev;
int error;
- if ((error = parsebootfile(fname, &fsname, &devname,
- &unit, &partition, (const char **) file))
- || (error = dev2bios(devname, unit, &biosdev)))
+ error = parsebootfile(fname, &fsname, &devname,
+ &unit, &partition, (const char **) file);
+ if (error)
return error;
f->f_dev = &devsw[0]; /* must be biosdisk */
@@ -142,5 +143,26 @@ devopen(struct open_file *f, const char
}
#endif
+#ifndef NO_GPT
+ /* Search by GPT label name */
+ if (strstr(devname, "NAME=") == devname) {
+ f->f_dev = &devsw[0]; /* must be biosdisk */
+
+ return biosdisk_open_name(f, devname);
+ }
+#endif
+#ifndef NO_RAIDFRAME
+ /* Search by raidframe name */
+ if (strstr(devname, "raid") == devname) {
+ f->f_dev = &devsw[0]; /* must be biosdisk */
+
+ return biosdisk_open_name(f, devname);
+ }
+#endif
+
+ error = dev2bios(devname, unit, &biosdev);
+ if (error)
+ return error;
+
return biosdisk_open(f, biosdev, partition);
}
Index: src/sys/arch/i386/stand/boot/devopen.h
diff -u src/sys/arch/i386/stand/boot/devopen.h:1.4 src/sys/arch/i386/stand/boot/devopen.h:1.4.64.1
--- src/sys/arch/i386/stand/boot/devopen.h:1.4 Fri Dec 24 20:40:42 2010
+++ src/sys/arch/i386/stand/boot/devopen.h Fri Sep 13 07:00:13 2019
@@ -1,5 +1,5 @@
-/* $NetBSD: devopen.h,v 1.4 2010/12/24 20:40:42 jakllsch Exp $ */
+/* $NetBSD: devopen.h,v 1.4.64.1 2019/09/13 07:00:13 martin Exp $ */
extern int boot_biosdev;
-void bios2dev(int, daddr_t, char **, int *, int *);
+void bios2dev(int, daddr_t, char **, int *, int *, const char **);
Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.13 src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.1
--- src/sys/arch/i386/stand/efiboot/boot.c:1.13 Mon Jul 29 11:28:51 2019
+++ src/sys/arch/i386/stand/efiboot/boot.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: boot.c,v 1.13 2019/07/29 11:28:51 nonaka Exp $ */
+/* $NetBSD: boot.c,v 1.13.2.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -35,6 +35,7 @@
#include "bootcfg.h"
#include "bootmod.h"
#include "bootmenu.h"
+#include "biosdisk.h"
#include "devopen.h"
int errno;
@@ -113,6 +114,7 @@ const struct bootblk_command commands[]
static char *default_devname;
static int default_unit, default_partition;
static const char *default_filename;
+static const char *default_part_name;
static char *sprint_bootsel(const char *);
static void bootit(const char *, int);
@@ -122,9 +124,16 @@ parsebootfile(const char *fname, char **
int *partition, const char **file)
{
const char *col;
+ static char savedevname[MAXDEVNAME+1];
*fsname = "ufs";
- *devname = default_devname;
+ if (default_part_name == NULL) {
+ *devname = default_devname;
+ } else {
+ snprintf(savedevname, sizeof(savedevname),
+ "NAME=%s", default_part_name);
+ *devname = savedevname;
+ }
*unit = default_unit;
*partition = default_partition;
*file = default_filename;
@@ -133,7 +142,6 @@ parsebootfile(const char *fname, char **
return 0;
if ((col = strchr(fname, ':')) != NULL) { /* device given */
- static char savedevname[MAXDEVNAME+1];
int devlen;
int u = 0, p = 0;
int i = 0;
@@ -142,6 +150,15 @@ parsebootfile(const char *fname, char **
if (devlen > MAXDEVNAME)
return EINVAL;
+ if (strstr(fname, "NAME=") == fname) {
+ strlcpy(savedevname, fname, devlen + 1);
+ *devname = savedevname;
+ *unit = -1;
+ *partition = -1;
+ fname = col + 1;
+ goto out;
+ }
+
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
if (!isvalidname(fname[i]))
return EINVAL;
@@ -177,6 +194,7 @@ parsebootfile(const char *fname, char **
fname = col + 1;
}
+out:
if (*fname)
*file = fname;
@@ -193,8 +211,11 @@ snprint_bootdev(char *buf, size_t bufsiz
for (i = 0; i < __arraycount(no_partition_devs); i++)
if (strcmp(devname, no_partition_devs[i]) == 0)
break;
- snprintf(buf, bufsize, "%s%d%c", devname, unit,
- i < __arraycount(no_partition_devs) ? '\0' : 'a' + partition);
+ if (strstr(devname, "NAME=") == devname)
+ strlcpy(buf, devname, bufsize);
+ else
+ snprintf(buf, bufsize, "%s%d%c", devname, unit,
+ i < __arraycount(no_partition_devs) ? '\0' : 'a' + partition);
return buf;
}
@@ -262,7 +283,7 @@ boot(void)
/* try to set default device to what BIOS tells us */
bios2dev(boot_biosdev, boot_biossector, &default_devname, &default_unit,
- &default_partition);
+ &default_partition, &default_part_name);
/* if the user types "boot" without filename */
default_filename = DEFFILENAME;
@@ -339,24 +360,32 @@ command_help(char *arg)
{
printf("commands are:\n"
- "boot [xdNx:][filename] [-12acdqsvxz]\n"
+ "boot [dev:][filename] [-12acdqsvxz]\n"
+#ifndef NO_RAIDFRAME
+ " dev syntax is (hd|fd|cd|raid)[N[x]]\n"
+#else
+ " dev syntax is (hd|fd|cd)[N[x]]\n"
+#endif
+#ifndef NO_GPT
+ " or NAME=gpt_label\n"
+#endif
" (ex. \"hd0a:netbsd.old -s\")\n"
- "pkboot [xdNx:][filename] [-12acdqsvxz]\n"
- "dev [xd[N[x]]:]\n"
+ "pkboot [dev:][filename] [-12acdqsvxz]\n"
+ "dev [dev:]\n"
"consdev {pc|com[0123][,{speed}]|com,{ioport}[,{speed}]}\n"
"devpath\n"
"efivar\n"
"gop [{modenum|list}]\n"
"load {path_to_module}\n"
#if LIBSA_ENABLE_LS_OP
- "ls [path]\n"
+ "ls [dev:][path]\n"
#endif
"memmap [{sorted|unsorted|compact}]\n"
#ifndef SMALL
"menu (reenters boot menu, if defined in boot.cfg)\n"
#endif
"modules {on|off|enabled|disabled}\n"
- "multiboot [xdNx:][filename] [<args>]\n"
+ "multiboot [dev:][filename] [<args>]\n"
"rndseed {path_to_rndseed_file}\n"
"splash {path_to_image_file}\n"
"text [{modenum|list}]\n"
@@ -433,8 +462,14 @@ command_dev(char *arg)
if (*arg == '\0') {
efi_disk_show();
efi_net_show();
- printf("default %s\n", snprint_bootdev(buf, sizeof(buf),
- default_devname, default_unit, default_partition));
+
+ if (default_part_name != NULL)
+ printf("default NAME=%s\n", default_part_name);
+ else
+ printf("default %s\n",
+ snprint_bootdev(buf, sizeof(buf),
+ default_devname, default_unit,
+ default_partition));
return;
}
@@ -448,6 +483,10 @@ command_dev(char *arg)
/* put to own static storage */
strncpy(savedevname, devname, MAXDEVNAME + 1);
default_devname = savedevname;
+
+ /* +5 to skip leading NAME= */
+ if (strstr(devname, "NAME=") == devname)
+ default_part_name = default_devname + 5;
}
static const struct cons_devs {
Index: src/sys/arch/i386/stand/efiboot/devopen.c
diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.5 src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.1
--- src/sys/arch/i386/stand/efiboot/devopen.c:1.5 Wed Apr 11 10:32:09 2018
+++ src/sys/arch/i386/stand/efiboot/devopen.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.c,v 1.5 2018/04/11 10:32:09 nonaka Exp $ */
+/* $NetBSD: devopen.c,v 1.5.6.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -78,8 +78,10 @@ dev2bios(char *devname, int unit, int *b
}
void
-bios2dev(int biosdev, daddr_t sector, char **devname, int *unit, int *partition)
+bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
+ int *partition, const char **part_name)
{
+ static char savedevname[MAXDEVNAME+1];
*unit = biosdev & 0x7f;
@@ -96,7 +98,12 @@ bios2dev(int biosdev, daddr_t sector, ch
} else
*devname = "hd";
- *partition = biosdisk_findpartition(biosdev, sector);
+ (void)biosdisk_findpartition(biosdev, sector, partition, part_name);
+ if (*part_name != NULL) {
+ snprintf(savedevname, sizeof(savedevname),
+ "NAME=%s", *part_name);
+ *devname = savedevname;
+ }
}
struct btinfo_bootpath bibp;
@@ -130,6 +137,20 @@ devopen(struct open_file *f, const char
if (error)
return error;
+ /* Search by GPT label or raidframe name */
+ if ((strstr(devname, "NAME=") == devname) ||
+ (strstr(devname, "raid") == devname)) {
+ f->f_dev = &devsw[0]; /* must be biosdisk */
+
+ if (!kernel_loaded) {
+ strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
+ BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
+ }
+
+ error = biosdisk_open_name(f, devname);
+ return error;
+ }
+
memcpy(file_system, file_system_disk, sizeof(*file_system) * nfsys);
nfsys = nfsys_disk;
@@ -194,7 +215,7 @@ devopen(struct open_file *f, const char
*/
if (strcmp(devname, "esp") == 0) {
bios2dev(boot_biosdev, boot_biossector, &devname, &unit,
- &partition);
+ &partition, NULL);
if (efidisk_get_efi_system_partition(boot_biosdev, &partition))
return ENXIO;
}
Index: src/sys/arch/i386/stand/efiboot/devopen.h
diff -u src/sys/arch/i386/stand/efiboot/devopen.h:1.3 src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.1
--- src/sys/arch/i386/stand/efiboot/devopen.h:1.3 Wed Apr 11 10:32:09 2018
+++ src/sys/arch/i386/stand/efiboot/devopen.h Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.h,v 1.3 2018/04/11 10:32:09 nonaka Exp $ */
+/* $NetBSD: devopen.h,v 1.3.6.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -34,9 +34,9 @@ extern struct fs_ops file_system_nfs;
extern struct fs_ops file_system_tftp;
extern struct fs_ops file_system_null;
-#define MAXDEVNAME 16
+#define MAXDEVNAME 39 /* mxmimum is "NAME=" + 34 char part_name */
-void bios2dev(int, daddr_t, char **, int *, int *);
+void bios2dev(int, daddr_t, char **, int *, int *, const char **);
struct devdesc {
char d_name[MAXDEVNAME];
Index: src/sys/arch/i386/stand/efiboot/efidisk.c
diff -u src/sys/arch/i386/stand/efiboot/efidisk.c:1.7 src/sys/arch/i386/stand/efiboot/efidisk.c:1.7.4.1
--- src/sys/arch/i386/stand/efiboot/efidisk.c:1.7 Wed Apr 17 06:50:34 2019
+++ src/sys/arch/i386/stand/efiboot/efidisk.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: efidisk.c,v 1.7 2019/04/17 06:50:34 nonaka Exp $ */
+/* $NetBSD: efidisk.c,v 1.7.4.1 2019/09/13 07:00:13 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -30,7 +30,9 @@
#include "efiboot.h"
+#include <sys/param.h> /* for howmany, required by <dev/raidframe/raidframevar.h> */
#include <sys/disklabel.h>
+#include <sys/disklabel_gpt.h>
#include "biosdisk.h"
#include "biosdisk_ll.h"
@@ -40,6 +42,40 @@
static struct efidiskinfo_lh efi_disklist;
static int nefidisks;
+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+
+#include <dev/raidframe/raidframevar.h>
+#define RF_COMPONENT_INFO_OFFSET 16384 /* from sys/dev/raidframe/rf_netbsdkintf.c */
+#define RF_COMPONENT_LABEL_VERSION 2 /* from <dev/raidframe/rf_raid.h> */
+
+#define RAIDFRAME_NDEV 16 /* abitrary limit to 15 raidframe devices */
+struct efi_raidframe {
+ int last_unit;
+ int serial;
+ const struct efidiskinfo *edi;
+ int parent_part;
+ char parent_name[MAXDEVNAME + 1];
+ daddr_t offset;
+ daddr_t size;
+};
+
+static void
+dealloc_biosdisk_part(struct biosdisk_partition *part, int nparts)
+{
+ int i;
+
+ for (i = 0; i < nparts; i++) {
+ if (part[i].part_name != NULL) {
+ dealloc(part[i].part_name, BIOSDISK_PART_NAME_LEN);
+ part[i].part_name = NULL;
+ }
+ }
+
+ dealloc(part, sizeof(*part) * nparts);
+
+ return;
+}
+
void
efi_disk_probe(void)
{
@@ -124,14 +160,51 @@ next:
}
}
+static void
+efi_raidframe_probe(struct efi_raidframe *raidframe, int *raidframe_count,
+ const struct efidiskinfo *edi,
+ struct biosdisk_partition *part, int parent_part)
+
+{
+ int i = *raidframe_count;
+ struct RF_ComponentLabel_s label;
+
+ if (i + 1 > RAIDFRAME_NDEV)
+ return;
+
+ if (biosdisk_read_raidframe(edi->dev, part->offset, &label) != 0)
+ return;
+
+ if (label.version != RF_COMPONENT_LABEL_VERSION)
+ return;
+
+ raidframe[i].last_unit = label.last_unit;
+ raidframe[i].serial = label.serial_number;
+ raidframe[i].edi = edi;
+ raidframe[i].parent_part = parent_part;
+ if (part->part_name)
+ strlcpy(raidframe[i].parent_name, part->part_name, MAXDEVNAME);
+ else
+ raidframe[i].parent_name[0] = '\0';
+ raidframe[i].offset = part->offset;
+ raidframe[i].size = label.__numBlocks;
+
+ (*raidframe_count)++;
+
+ return;
+}
+
+
void
efi_disk_show(void)
{
const struct efidiskinfo *edi;
+ struct efi_raidframe raidframe[RAIDFRAME_NDEV];
+ int raidframe_count = 0;
EFI_BLOCK_IO_MEDIA *media;
struct biosdisk_partition *part;
uint64_t size;
- int i, nparts;
+ int i, j, nparts;
bool first;
TAILQ_FOREACH(edi, &efi_disklist, list) {
@@ -164,7 +237,7 @@ efi_disk_show(void)
if (edi->type != BIOSDISK_TYPE_HD)
continue;
- if (biosdisk_readpartition(edi->dev, &part, &nparts))
+ if (biosdisk_readpartition(edi->dev, 0, 0, &part, &nparts))
continue;
for (i = 0; i < nparts; i++) {
@@ -172,11 +245,18 @@ efi_disk_show(void)
continue;
if (part[i].fstype == FS_UNUSED)
continue;
+ if (part[i].fstype == FS_RAID) {
+ efi_raidframe_probe(raidframe, &raidframe_count,
+ edi, &part[i], i);
+ }
if (first) {
printf(" ");
first = false;
}
- printf(" hd%d%c(", edi->dev & 0x7f, i + 'a');
+ if (part[i].part_name != NULL)
+ printf(" NAME=%s(", part[i].part_name);
+ else
+ printf(" hd%d%c(", edi->dev & 0x7f, i + 'a');
if (part[i].guid != NULL)
printf("%s", part[i].guid->name);
else if (part[i].fstype < FSMAXTYPES)
@@ -187,7 +267,66 @@ efi_disk_show(void)
}
if (!first)
printf("\n");
- dealloc(part, sizeof(*part) * nparts);
+ dealloc_biosdisk_part(part, nparts);
+ }
+
+ for (i = 0; i < raidframe_count; i++) {
+ size_t secsize = raidframe[i].edi->bio->Media->BlockSize;
+ printf("raidframe raid%d serial %d in ",
+ raidframe[i].last_unit, raidframe[i].serial);
+ if (raidframe[i].parent_name[0])
+ printf("NAME=%s size ", raidframe[i].parent_name);
+ else
+ printf("hd%d%c size ",
+ raidframe[i].edi->dev & 0x7f,
+ raidframe[i].parent_part + 'a');
+ if (raidframe[i].size >= (10ULL * 1024 * 1024 * 1024 / secsize))
+ printf("%"PRIu64" GB",
+ raidframe[i].size / (1024 * 1024 * 1024 / secsize));
+ else
+ printf("%"PRIu64" MB",
+ raidframe[i].size / (1024 * 1024 / secsize));
+ printf("\n");
+
+ if (biosdisk_readpartition(raidframe[i].edi->dev,
+ raidframe[i].offset + RF_PROTECTED_SECTORS,
+ raidframe[i].size,
+ &part, &nparts))
+ continue;
+
+ first = 1;
+ for (j = 0; j < nparts; j++) {
+ bool bootme = part[j].attr & GPT_ENT_ATTR_BOOTME;
+
+ if (part[j].size == 0)
+ continue;
+ if (part[j].fstype == FS_UNUSED)
+ continue;
+ if (part[j].fstype == FS_RAID) /* raid in raid? */
+ continue;
+ if (first) {
+ printf(" ");
+ first = 0;
+ }
+ if (part[j].part_name != NULL)
+ printf(" NAME=%s(", part[j].part_name);
+ else
+ printf(" raid%d%c(",
+ raidframe[i].last_unit, j + 'a');
+ if (part[j].guid != NULL)
+ printf("%s", part[j].guid->name);
+ else if (part[j].fstype < FSMAXTYPES)
+ printf("%s",
+ fstypenames[part[j].fstype]);
+ else
+ printf("%d", part[j].fstype);
+ printf("%s)", bootme ? ", bootme" : "");
+ }
+
+ if (first == 0)
+ printf("\n");
+
+ dealloc_biosdisk_part(part, nparts);
}
}
@@ -227,7 +366,7 @@ efidisk_get_efi_system_partition(int dev
if (edi->type != BIOSDISK_TYPE_HD)
return ENOTSUP;
- if (biosdisk_readpartition(edi->dev, &part, &nparts))
+ if (biosdisk_readpartition(edi->dev, 0, 0, &part, &nparts))
return EIO;
for (i = 0; i < nparts; i++) {
@@ -238,7 +377,7 @@ efidisk_get_efi_system_partition(int dev
if (guid_is_equal(part[i].guid->guid, &GET_efi))
break;
}
- dealloc(part, sizeof(*part) * nparts);
+ dealloc_biosdisk_part(part, nparts);
if (i == nparts)
return ENOENT;
Index: src/sys/arch/i386/stand/lib/Makefile
diff -u src/sys/arch/i386/stand/lib/Makefile:1.45 src/sys/arch/i386/stand/lib/Makefile:1.45.8.1
--- src/sys/arch/i386/stand/lib/Makefile:1.45 Fri Feb 2 01:02:41 2018
+++ src/sys/arch/i386/stand/lib/Makefile Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.45 2018/02/02 01:02:41 mrg Exp $
+# $NetBSD: Makefile,v 1.45.8.1 2019/09/13 07:00:13 martin Exp $
S?= ${.CURDIR}/../../../..
@@ -17,6 +17,7 @@ CPPFLAGS= -I$S/lib/libsa ${I386CPPFLAGS}
#CPPFLAGS+= -DDISK_DEBUG
#CPPFLAGS+= -DNO_DISKLABEL
#CPPFLAGS+= -DNO_GPT
+#CPPFLAGS+= -DNO_RAIDFRAME
#CPPFLAGS+= -DSAVE_MEMORY
SRCS= pcio.c conio.S comio.S comio_direct.c biosvideomode.S
Index: src/sys/arch/i386/stand/lib/biosdisk.c
diff -u src/sys/arch/i386/stand/lib/biosdisk.c:1.49 src/sys/arch/i386/stand/lib/biosdisk.c:1.49.6.1
--- src/sys/arch/i386/stand/lib/biosdisk.c:1.49 Mon Apr 2 09:44:18 2018
+++ src/sys/arch/i386/stand/lib/biosdisk.c Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: biosdisk.c,v 1.49 2018/04/02 09:44:18 nonaka Exp $ */
+/* $NetBSD: biosdisk.c,v 1.49.6.1 2019/09/13 07:00:13 martin Exp $ */
/*
* Copyright (c) 1996, 1998
@@ -78,6 +78,7 @@
#include <sys/uuid.h>
#include <fs/cd9660/iso.h>
+#include <fs/unicode.h>
#include <lib/libsa/saerrno.h>
#include <machine/cpu.h>
@@ -89,6 +90,12 @@
#include "bootinfo.h"
#endif
+#ifndef NO_GPT
+#define MAXDEVNAME 39 /* "NAME=" + 34 char part_name */
+#else
+#define MAXDEVNAME 16
+#endif
+
#ifndef BIOSDISK_BUFSIZE
#define BIOSDISK_BUFSIZE 2048 /* must be large enough for a CD sector */
#endif
@@ -104,6 +111,24 @@ struct biosdisk {
#endif
};
+#include <dev/raidframe/raidframevar.h>
+#define RF_COMPONENT_INFO_OFFSET 16384 /* from sys/dev/raidframe/rf_netbsdkintf.c */
+#define RF_COMPONENT_LABEL_VERSION 2 /* from <dev/raidframe/rf_raid.h> */
+
+#define RAIDFRAME_NDEV 16 /* abitrary limit to 15 raidframe devices */
+struct raidframe {
+ int last_unit;
+ int serial;
+ int biosdev;
+ int parent_part;
+#ifndef NO_GPT
+ char parent_name[MAXDEVNAME + 1];
+#endif
+ daddr_t offset;
+ daddr_t size;
+};
+
+
#ifndef NO_GPT
const struct uuid GET_nbsd_raid = GPT_ENT_TYPE_NETBSD_RAIDFRAME;
const struct uuid GET_nbsd_ffs = GPT_ENT_TYPE_NETBSD_FFS;
@@ -111,7 +136,7 @@ const struct uuid GET_nbsd_lfs = GPT_ENT
const struct uuid GET_nbsd_swap = GPT_ENT_TYPE_NETBSD_SWAP;
const struct uuid GET_nbsd_ccd = GPT_ENT_TYPE_NETBSD_CCD;
const struct uuid GET_nbsd_cgd = GPT_ENT_TYPE_NETBSD_CGD;
-#ifdef EFIBOOT
+
const struct uuid GET_efi = GPT_ENT_TYPE_EFI;
const struct uuid GET_mbr = GPT_ENT_TYPE_MBR;
const struct uuid GET_fbsd = GPT_ENT_TYPE_FREEBSD;
@@ -157,7 +182,6 @@ const struct gpt_part gpt_parts[] = {
{ &GET_apple_ufs, "Apple UFS" },
{ &GET_bios, "BIOS Boot (GRUB)" },
};
-#endif
#endif /* NO_GPT */
#ifdef _STANDALONE
@@ -167,12 +191,54 @@ static struct btinfo_bootwedge bi_wedge;
#define MBR_PARTS(buf) ((char *)(buf) + offsetof(struct mbr_sector, mbr_parts))
-#define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */
-
#ifndef devb2cdb
#define devb2cdb(bno) (((bno) * DEV_BSIZE) / ISO_DEFAULT_BLOCK_SIZE)
#endif
+static void
+dealloc_biosdisk(struct biosdisk *d)
+{
+#ifndef NO_GPT
+ int i;
+
+ for (i = 0; i < __arraycount(d->part); i++) {
+ if (d->part[i].part_name != NULL)
+ dealloc(d->part[i].part_name, BIOSDISK_PART_NAME_LEN);
+ }
+#endif
+
+ dealloc(d, sizeof(*d));
+
+ return;
+}
+
+static struct biosdisk_partition *
+copy_biosdisk_part(struct biosdisk *d)
+{
+ struct biosdisk_partition *part;
+
+ part = alloc(sizeof(d->part));
+ if (part == NULL)
+ goto out;
+
+ memcpy(part, d->part, sizeof(d->part));
+
+#ifndef NO_GPT
+ int i;
+
+ for (i = 0; i < __arraycount(d->part); i++) {
+ if (d->part[i].part_name != NULL) {
+ part[i].part_name = alloc(BIOSDISK_PART_NAME_LEN);
+ memcpy(part[i].part_name, d->part[i].part_name,
+ BIOSDISK_PART_NAME_LEN);
+ }
+ }
+#endif
+
+out:
+ return part;
+}
+
int
biosdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
void *buf, size_t *rsize)
@@ -228,7 +294,7 @@ alloc_biosdisk(int biosdev)
#ifdef DISK_DEBUG
printf("no geometry information\n");
#endif
- dealloc(d, sizeof(*d));
+ dealloc_biosdisk(d);
return NULL;
}
return d;
@@ -262,8 +328,33 @@ guid_is_equal(const struct uuid *a, cons
return (memcmp(a, b, sizeof(*a)) == 0 ? true : false);
}
+#ifndef NO_GPT
+static void
+part_name_utf8(const uint16_t *utf16_src, size_t utf16_srclen,
+ char *utf8_dst, size_t utf8_dstlen)
+{
+ char *c = utf8_dst;
+ size_t r = utf8_dstlen - 1;
+ size_t n;
+ int j;
+
+ if (utf8_dst == NULL)
+ return;
+
+ for (j = 0; j < utf16_srclen && utf16_src[j] != 0x0000; j++) {
+ n = wput_utf8(c, r, le16toh(utf16_src[j]));
+ if (n == 0)
+ break;
+ c += n; r -= n;
+ }
+ *c = '\0';
+
+ return;
+}
+#endif
+
static int
-check_gpt(struct biosdisk *d, daddr_t sector)
+check_gpt(struct biosdisk *d, daddr_t rf_offset, daddr_t sector)
{
struct gpt_hdr gpth;
const struct gpt_ent *ep;
@@ -296,7 +387,7 @@ check_gpt(struct biosdisk *d, daddr_t se
return -1;
}
- if (gpth.hdr_lba_self != sector)
+ if (gpth.hdr_lba_self + rf_offset != sector)
return -1;
#ifdef _STANDALONE
@@ -308,7 +399,7 @@ check_gpt(struct biosdisk *d, daddr_t se
sectors = sizeof(d->buf)/d->ll.secsize; /* sectors per buffer */
entries = sizeof(d->buf)/gpth.hdr_entsz; /* entries per buffer */
- entblk = gpth.hdr_lba_table;
+ entblk = gpth.hdr_lba_table + rf_offset;
crc = crc32(0, NULL, 0);
j = 0;
@@ -344,7 +435,7 @@ check_gpt(struct biosdisk *d, daddr_t se
d->part[j].fstype = FS_CGD;
else
d->part[j].fstype = FS_OTHER;
-#ifdef EFIBOOT
+#ifndef NO_GPT
for (int k = 0;
k < __arraycount(gpt_parts);
k++) {
@@ -352,6 +443,13 @@ check_gpt(struct biosdisk *d, daddr_t se
d->part[j].guid = &gpt_parts[k];
}
d->part[j].attr = ep[i].ent_attr;
+
+ d->part[j].part_name =
+ alloc(BIOSDISK_PART_NAME_LEN);
+ part_name_utf8(ep[i].ent_name,
+ sizeof(ep[i].ent_name),
+ d->part[j].part_name,
+ BIOSDISK_PART_NAME_LEN);
#endif
j++;
}
@@ -370,7 +468,7 @@ check_gpt(struct biosdisk *d, daddr_t se
}
static int
-read_gpt(struct biosdisk *d)
+read_gpt(struct biosdisk *d, daddr_t rf_offset, daddr_t rf_size)
{
struct biosdisk_extinfo ed;
daddr_t gptsector[2];
@@ -380,23 +478,30 @@ read_gpt(struct biosdisk *d)
/* No GPT on floppy and CD */
return -1;
- gptsector[0] = GPT_HDR_BLKNO;
- if (set_geometry(&d->ll, &ed) == 0 && d->ll.flags & BIOSDISK_INT13EXT) {
- gptsector[1] = ed.totsec - 1;
- /* Sanity check values returned from BIOS */
- if (ed.sbytes >= 512 && (ed.sbytes & (ed.sbytes - 1)) == 0)
- d->ll.secsize = ed.sbytes;
+ if (rf_offset && rf_size) {
+ gptsector[0] = rf_offset + GPT_HDR_BLKNO;
+ gptsector[1] = rf_offset + rf_size - 1;
} else {
+ gptsector[0] = GPT_HDR_BLKNO;
+ if (set_geometry(&d->ll, &ed) == 0 &&
+ d->ll.flags & BIOSDISK_INT13EXT) {
+ gptsector[1] = ed.totsec - 1;
+ /* Sanity check values returned from BIOS */
+ if (ed.sbytes >= 512 &&
+ (ed.sbytes & (ed.sbytes - 1)) == 0)
+ d->ll.secsize = ed.sbytes;
+ } else {
#ifdef DISK_DEBUG
- printf("Unable to determine extended disk geometry - "
- "using CHS\n");
+ printf("Unable to determine extended disk geometry - "
+ "using CHS\n");
#endif
- /* at least try some other reasonable values then */
- gptsector[1] = d->ll.chs_sectors - 1;
+ /* at least try some other reasonable values then */
+ gptsector[1] = d->ll.chs_sectors - 1;
+ }
}
for (i = 0; i < __arraycount(gptsector); i++) {
- error = check_gpt(d, gptsector[i]);
+ error = check_gpt(d, rf_offset, gptsector[i]);
if (error == 0)
break;
}
@@ -546,7 +651,7 @@ check_cd9660(struct biosdisk *d)
#endif
static int
-read_label(struct biosdisk *d)
+read_label(struct biosdisk *d, daddr_t offset)
{
struct disklabel dflt_lbl;
struct mbr_partition mbr[MBR_PART_COUNT];
@@ -573,11 +678,11 @@ read_label(struct biosdisk *d)
* find NetBSD Partition in DOS partition table
* XXX check magic???
*/
- ext_base = 0;
- next_ext = 0;
+ ext_base = offset;
+ next_ext = offset;
for (;;) {
this_ext = ext_base + next_ext;
- next_ext = 0;
+ next_ext = offset;
if (readsects(&d->ll, this_ext, 1, d->buf, 0)) {
#ifdef DISK_DEBUG
printf("error reading MBR sector %u\n", this_ext);
@@ -607,14 +712,14 @@ read_label(struct biosdisk *d)
return error;
}
if (MBR_IS_EXTENDED(typ)) {
- next_ext = mbr[i].mbrp_start;
+ next_ext = mbr[i].mbrp_start + offset;
continue;
}
#ifdef COMPAT_386BSD_MBRPART
- if (this_ext == 0 && typ == MBR_PTYPE_386BSD)
+ if (this_ext == offset && typ == MBR_PTYPE_386BSD)
sector_386bsd = sector;
#endif
- if (this_ext != 0) {
+ if (this_ext != offset) {
if (dflt_lbl.d_npartitions >= MAXPARTITIONS)
continue;
p = &dflt_lbl.d_partitions[dflt_lbl.d_npartitions++];
@@ -624,15 +729,15 @@ read_label(struct biosdisk *d)
p->p_size = mbr[i].mbrp_size;
p->p_fstype = xlat_mbr_fstype(typ);
}
- if (next_ext == 0)
+ if (next_ext == offset)
break;
- if (ext_base == 0) {
+ if (ext_base == offset) {
ext_base = next_ext;
- next_ext = 0;
+ next_ext = offset;
}
}
- sector = 0;
+ sector = offset;
#ifdef COMPAT_386BSD_MBRPART
if (sector_386bsd != -1) {
printf("old BSD partition ID!\n");
@@ -671,31 +776,74 @@ read_label(struct biosdisk *d)
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
static int
-read_partitions(struct biosdisk *d)
+read_partitions(struct biosdisk *d, daddr_t offset, daddr_t size)
{
int error;
error = -1;
#ifndef NO_GPT
- error = read_gpt(d);
+ error = read_gpt(d, offset, size);
if (error == 0)
return 0;
#endif
#ifndef NO_DISKLABEL
- error = read_label(d);
+ error = read_label(d, offset);
#endif
return error;
}
#endif
+#ifndef NO_RAIDFRAME
+static void
+raidframe_probe(struct raidframe *raidframe, int *raidframe_count,
+ struct biosdisk *d, int part)
+{
+ int i = *raidframe_count;
+ struct RF_ComponentLabel_s label;
+ daddr_t offset;
+
+ if (i + 1 > RAIDFRAME_NDEV)
+ return;
+
+ offset = d->part[part].offset;
+ if ((biosdisk_read_raidframe(d->ll.dev, offset, &label)) != 0)
+ return;
+
+ if (label.version != RF_COMPONENT_LABEL_VERSION)
+ printf("Unexpected raidframe label version\n");
+
+ raidframe[i].last_unit = label.last_unit;
+ raidframe[i].serial = label.serial_number;
+ raidframe[i].biosdev = d->ll.dev;
+ raidframe[i].parent_part = part;
+#ifndef NO_GPT
+ if (d->part[part].part_name)
+ strlcpy(raidframe[i].parent_name,
+ d->part[part].part_name, MAXDEVNAME);
+ else
+ raidframe[i].parent_name[0] = '\0';
+#endif
+ raidframe[i].offset = offset;
+ raidframe[i].size = label.__numBlocks;
+
+ (*raidframe_count)++;
+
+ return;
+}
+#endif
+
void
biosdisk_probe(void)
{
- struct biosdisk d;
+ struct biosdisk *d;
struct biosdisk_extinfo ed;
+#ifndef NO_RAIDFRAME
+ struct raidframe raidframe[RAIDFRAME_NDEV];
+ int raidframe_count = 0;
+#endif
uint64_t size;
int first;
int i;
@@ -705,26 +853,31 @@ biosdisk_probe(void)
for (i = 0; i < MAX_BIOSDISKS + 2; i++) {
first = 1;
- memset(&d, 0, sizeof(d));
+ d = alloc(sizeof(*d));
+ if (d == NULL) {
+ printf("Out of memory\n");
+ return;
+ }
+ memset(d, 0, sizeof(*d));
memset(&ed, 0, sizeof(ed));
if (i >= MAX_BIOSDISKS)
- d.ll.dev = 0x00 + i - MAX_BIOSDISKS; /* fd */
+ d->ll.dev = 0x00 + i - MAX_BIOSDISKS; /* fd */
else
- d.ll.dev = 0x80 + i; /* hd/cd */
- if (set_geometry(&d.ll, &ed))
- continue;
+ d->ll.dev = 0x80 + i; /* hd/cd */
+ if (set_geometry(&d->ll, &ed))
+ goto next_disk;
printf("disk ");
- switch (d.ll.type) {
+ switch (d->ll.type) {
case BIOSDISK_TYPE_CD:
printf("cd0\n cd0a\n");
break;
case BIOSDISK_TYPE_FD:
- printf("fd%d\n", d.ll.dev & 0x7f);
- printf(" fd%da\n", d.ll.dev & 0x7f);
+ printf("fd%d\n", d->ll.dev & 0x7f);
+ printf(" fd%da\n", d->ll.dev & 0x7f);
break;
case BIOSDISK_TYPE_HD:
- printf("hd%d", d.ll.dev & 0x7f);
- if (d.ll.flags & BIOSDISK_INT13EXT) {
+ printf("hd%d", d->ll.dev & 0x7f);
+ if (d->ll.flags & BIOSDISK_INT13EXT) {
printf(" size ");
size = ed.totsec * ed.sbytes;
if (size >= (10ULL * 1024 * 1024 * 1024))
@@ -738,38 +891,132 @@ biosdisk_probe(void)
break;
}
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
- if (d.ll.type != BIOSDISK_TYPE_HD)
- continue;
+ if (d->ll.type != BIOSDISK_TYPE_HD)
+ goto next_disk;
- if (read_partitions(&d) != 0)
- continue;
+ if (read_partitions(d, 0, 0) != 0)
+ goto next_disk;
for (part = 0; part < BIOSDISKNPART; part++) {
- if (d.part[part].size == 0)
+ if (d->part[part].size == 0)
continue;
- if (d.part[part].fstype == FS_UNUSED)
+ if (d->part[part].fstype == FS_UNUSED)
continue;
+#ifndef NO_RAIDFRAME
+ if (d->part[part].fstype == FS_RAID)
+ raidframe_probe(raidframe,
+ &raidframe_count, d, part);
+#endif
if (first) {
printf(" ");
first = 0;
}
- printf(" hd%d%c(", d.ll.dev & 0x7f, part + 'a');
-#ifdef EFIBOOT
- if (d.part[part].guid != NULL)
- printf("%s", d.part[part].guid->name);
+#ifndef NO_GPT
+ if (d->part[part].part_name != NULL)
+ printf(" NAME=%s(", d->part[part].part_name);
+ else
+#endif
+ printf(" hd%d%c(", d->ll.dev & 0x7f, part + 'a');
+
+#ifndef NO_GPT
+ if (d->part[part].guid != NULL)
+ printf("%s", d->part[part].guid->name);
else
#endif
- if (d.part[part].fstype < FSMAXTYPES)
+
+ if (d->part[part].fstype < FSMAXTYPES)
printf("%s",
- fstypenames[d.part[part].fstype]);
+ fstypenames[d->part[part].fstype]);
else
- printf("%d", d.part[part].fstype);
+ printf("%d", d->part[part].fstype);
printf(")");
}
#endif
if (first == 0)
printf("\n");
+
+next_disk:
+ dealloc_biosdisk(d);
}
+
+#ifndef NO_RAIDFRAME
+ for (i = 0; i < raidframe_count; i++) {
+ size_t secsize;
+
+ if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+ printf("Out of memory\n");
+ return;
+ }
+
+ secsize = d->ll.secsize;
+
+ printf("raidframe raid%d serial %d in ",
+ raidframe[i].last_unit, raidframe[i].serial);
+#ifndef NO_GPT
+ if (raidframe[i].parent_name[0])
+ printf("NAME=%s size ", raidframe[i].parent_name);
+ else
+#endif
+ printf("hd%d%c size ", d->ll.dev & 0x7f,
+ raidframe[i].parent_part + 'a');
+ if (raidframe[i].size >= (10ULL * 1024 * 1024 * 1024 / secsize))
+ printf("%"PRIu64" GB",
+ raidframe[i].size / (1024 * 1024 * 1024 / secsize));
+ else
+ printf("%"PRIu64" MB",
+ raidframe[i].size / (1024 * 1024 / secsize));
+ printf("\n");
+
+ if (read_partitions(d,
+ raidframe[i].offset + RF_PROTECTED_SECTORS,
+ raidframe[i].size) != 0)
+ goto next_raidrame;
+
+ first = 1;
+ for (part = 0; part < BIOSDISKNPART; part++) {
+#ifndef NO_GPT
+ bool bootme = d->part[part].attr & GPT_ENT_ATTR_BOOTME;
+#else
+ bool bootme = 0;
+#endif
+
+ if (d->part[part].size == 0)
+ continue;
+ if (d->part[part].fstype == FS_UNUSED)
+ continue;
+ if (d->part[part].fstype == FS_RAID)
+ continue;
+ if (first) {
+ printf(" ");
+ first = 0;
+ }
+#ifndef NO_GPT
+ if (d->part[part].part_name != NULL)
+ printf(" NAME=%s(", d->part[part].part_name);
+ else
+#endif
+ printf(" raid%d%c(", raidframe[i].last_unit,
+ part + 'a');
+#ifndef NO_GPT
+ if (d->part[part].guid != NULL)
+ printf("%s", d->part[part].guid->name);
+ else
+#endif
+ if (d->part[part].fstype < FSMAXTYPES)
+ printf("%s",
+ fstypenames[d->part[part].fstype]);
+ else
+ printf("%d", d->part[part].fstype);
+ printf("%s)", bootme ? ", bootme" : "");
+ }
+
+next_raidrame:
+ if (first == 0)
+ printf("\n");
+
+ dealloc_biosdisk(d);
+ }
+#endif
}
/* Determine likely partition for possible sector number of dos
@@ -777,68 +1024,97 @@ biosdisk_probe(void)
*/
int
-biosdisk_findpartition(int biosdev, daddr_t sector)
+biosdisk_findpartition(int biosdev, daddr_t sector,
+ int *partition, const char **part_name)
{
#if defined(NO_DISKLABEL) && defined(NO_GPT)
+ *partition = 0;
+ *part_name = NULL;
return 0;
#else
+ int i;
struct biosdisk *d;
- int partition = 0;
-#ifdef EFIBOOT
- int candidate = 0;
+ int biosboot_sector_part = -1;
+ int bootable_fs_part = -1;
+ int boot_part = 0;
+#ifndef NO_GPT
+ int gpt_bootme_part = -1;
+ static char namebuf[MAXDEVNAME + 1];
#endif
#ifdef DISK_DEBUG
printf("looking for partition device %x, sector %"PRId64"\n", biosdev, sector);
#endif
+ /* default ot first partition */
+ *partition = 0;
+ *part_name = NULL;
+
/* Look for netbsd partition that is the dos boot one */
d = alloc_biosdisk(biosdev);
if (d == NULL)
- return 0;
+ return -1;
- if (read_partitions(d) == 0) {
- for (partition = (BIOSDISKNPART-1); --partition;) {
- if (d->part[partition].fstype == FS_UNUSED)
+ if (read_partitions(d, 0, 0) == 0) {
+ for (i = 0; i < BIOSDISKNPART; i++) {
+ if (d->part[i].fstype == FS_UNUSED)
continue;
-#ifdef EFIBOOT
- switch (d->part[partition].fstype) {
+
+ if (d->part[i].offset == sector &&
+ biosboot_sector_part == -1)
+ biosboot_sector_part = i;
+
+#ifndef NO_GPT
+ if (d->part[i].attr & GPT_ENT_ATTR_BOOTME &&
+ gpt_bootme_part == -1)
+ gpt_bootme_part = i;
+#endif
+ switch (d->part[i].fstype) {
case FS_BSDFFS:
case FS_BSDLFS:
case FS_RAID:
case FS_CCD:
case FS_CGD:
case FS_ISO9660:
- if (d->part[partition].attr & GPT_ENT_ATTR_BOOTME)
- goto found;
- candidate = partition;
+ if (bootable_fs_part == -1)
+ bootable_fs_part = i;
break;
default:
- if (d->part[partition].attr & GPT_ENT_ATTR_BOOTME)
- candidate = partition;
break;
}
-#else
- if (d->part[partition].offset == sector)
- break;
+ }
+
+#ifndef NO_GPT
+ if (gpt_bootme_part != -1)
+ boot_part = gpt_bootme_part;
+ else
#endif
+ if (biosboot_sector_part != -1)
+ boot_part = biosboot_sector_part;
+ else if (bootable_fs_part != -1)
+ boot_part = bootable_fs_part;
+ else
+ boot_part = 0;
+
+ *partition = boot_part;
+#ifndef NO_GPT
+ if (part_name && d->part[boot_part].part_name) {
+ strlcpy(namebuf, d->part[boot_part].part_name,
+ BIOSDISK_PART_NAME_LEN);
+ *part_name = namebuf;
}
-#ifdef EFIBOOT
-found:
- if (partition == 0 && candidate != 0)
- partition = candidate;
#endif
}
- dealloc(d, sizeof(*d));
- return partition;
+ dealloc_biosdisk(d);
+ return 0;
#endif /* NO_DISKLABEL && NO_GPT */
}
int
-biosdisk_readpartition(int biosdev, struct biosdisk_partition **partpp,
- int *rnum)
+biosdisk_readpartition(int biosdev, daddr_t offset, daddr_t size,
+ struct biosdisk_partition **partpp, int *rnum)
{
#if defined(NO_DISKLABEL) && defined(NO_GPT)
return ENOTSUP;
@@ -852,27 +1128,70 @@ biosdisk_readpartition(int biosdev, stru
if (d == NULL)
return ENOMEM;
- if (read_partitions(d)) {
+ if (read_partitions(d, offset, size)) {
rv = EINVAL;
goto out;
}
- part = alloc(sizeof(d->part));
+ part = copy_biosdisk_part(d);
if (part == NULL) {
rv = ENOMEM;
goto out;
}
- memcpy(part, d->part, sizeof(d->part));
*partpp = part;
*rnum = (int)__arraycount(d->part);
rv = 0;
out:
- dealloc(d, sizeof(*d));
+ dealloc_biosdisk(d);
return rv;
#endif /* NO_DISKLABEL && NO_GPT */
}
+#ifndef NO_RAIDFRAME
+int
+biosdisk_read_raidframe(int biosdev, daddr_t offset,
+ struct RF_ComponentLabel_s *label)
+{
+#if defined(NO_DISKLABEL) && defined(NO_GPT)
+ return ENOTSUP;
+#else
+ struct biosdisk *d;
+ struct biosdisk_extinfo ed;
+ daddr_t size;
+ int rv = -1;
+
+ /* Look for netbsd partition that is the dos boot one */
+ d = alloc_biosdisk(biosdev);
+ if (d == NULL)
+ goto out;
+
+ if (d->ll.type != BIOSDISK_TYPE_HD)
+ /* No raidframe on floppy and CD */
+ goto out;
+
+ if (set_geometry(&d->ll, &ed) != 0)
+ goto out;
+
+ /* Sanity check values returned from BIOS */
+ if (ed.sbytes >= 512 &&
+ (ed.sbytes & (ed.sbytes - 1)) == 0)
+ d->ll.secsize = ed.sbytes;
+
+ offset += (RF_COMPONENT_INFO_OFFSET / d->ll.secsize);
+ size = roundup(sizeof(*label), d->ll.secsize) / d->ll.secsize;
+ if (readsects(&d->ll, offset, size, d->buf, 0))
+ goto out;
+ memcpy(label, d->buf, sizeof(*label));
+ rv = 0;
+out:
+ if (d != NULL)
+ dealloc_biosdisk(d);
+ return rv;
+#endif /* NO_DISKLABEL && NO_GPT */
+}
+#endif /* NO_RAIDFRAME */
+
#ifdef _STANDALONE
static void
add_biosdisk_bootinfo(void)
@@ -886,6 +1205,39 @@ add_biosdisk_bootinfo(void)
}
#endif
+#ifndef NO_GPT
+static daddr_t
+raidframe_part_offset(struct biosdisk *d, int part)
+{
+ struct biosdisk raidframe;
+ daddr_t rf_offset;
+ daddr_t rf_size;
+ int i, candidate;
+
+ memset(&raidframe, 0, sizeof(raidframe));
+ raidframe.ll = d->ll;
+
+ rf_offset = d->part[part].offset + RF_PROTECTED_SECTORS;
+ rf_size = d->part[part].size;
+ if (read_gpt(&raidframe, rf_offset, rf_size) != 0)
+ return RF_PROTECTED_SECTORS;
+
+ candidate = 0;
+ for (i = 0; i < BIOSDISKNPART; i++) {
+ if (raidframe.part[i].size == 0)
+ continue;
+ if (raidframe.part[i].fstype == FS_UNUSED)
+ continue;
+#ifndef NO_GPT
+ if (raidframe.part[i].attr & GPT_ENT_ATTR_BOOTME)
+ candidate = i;
+#endif
+ }
+
+ return RF_PROTECTED_SECTORS + raidframe.part[candidate].offset;
+}
+#endif
+
int
biosdisk_open(struct open_file *f, ...)
/* struct open_file *f, int biosdev, int partition */
@@ -915,7 +1267,7 @@ biosdisk_open(struct open_file *f, ...)
#endif
#if !defined(NO_DISKLABEL) || !defined(NO_GPT)
- error = read_partitions(d);
+ error = read_partitions(d, 0, 0);
if (error == -1) {
error = 0;
goto nolabel;
@@ -935,7 +1287,11 @@ biosdisk_open(struct open_file *f, ...)
d->boff = d->part[partition].offset;
if (d->part[partition].fstype == FS_RAID)
+#ifndef NO_GPT
+ d->boff += raidframe_part_offset(d, partition);
+#else
d->boff += RF_PROTECTED_SECTORS;
+#endif
#ifdef _STANDALONE
bi_wedge.startblk = d->part[partition].offset;
@@ -956,10 +1312,327 @@ nolabel:
out:
va_end(ap);
if (error)
- dealloc(d, sizeof(*d));
+ dealloc_biosdisk(d);
+ return error;
+}
+
+#ifndef NO_GPT
+static int
+biosdisk_find_name(const char *fname, int *biosdev,
+ daddr_t *offset, daddr_t *size)
+{
+ struct biosdisk *d;
+ char name[MAXDEVNAME + 1];
+ char *sep;
+#ifndef NO_RAIDFRAME
+ struct raidframe raidframe[RAIDFRAME_NDEV];
+ int raidframe_count = 0;
+#endif
+ int i;
+ int part;
+ int ret = -1;
+
+ /* Strip leadinf NAME= and cut after the coloon included */
+ strlcpy(name, fname + 5, MAXDEVNAME);
+ sep = strchr(name, ':');
+ if (sep)
+ *sep = '\0';
+
+ for (i = 0; i < MAX_BIOSDISKS; i++) {
+ d = alloc(sizeof(*d));
+ if (d == NULL) {
+ printf("Out of memory\n");
+ goto out;
+ }
+
+ memset(d, 0, sizeof(*d));
+ d->ll.dev = 0x80 + i; /* hd/cd */
+ if (set_geometry(&d->ll, NULL))
+ goto next_disk;
+
+ if (d->ll.type != BIOSDISK_TYPE_HD)
+ goto next_disk;
+
+ if (read_partitions(d, 0, 0) != 0)
+ goto next_disk;
+
+ for (part = 0; part < BIOSDISKNPART; part++) {
+ if (d->part[part].size == 0)
+ continue;
+ if (d->part[part].fstype == FS_UNUSED)
+ continue;
+#ifndef NO_RAIDFRAME
+ if (d->part[part].fstype == FS_RAID) {
+ raidframe_probe(raidframe,
+ &raidframe_count, d, part);
+ /*
+ * Do not match RAID partition for a name,
+ * we want to report an inner partition.
+ */
+ continue;
+ }
+#endif
+ if (d->part[part].part_name != NULL &&
+ strcmp(d->part[part].part_name, name) == 0) {
+ *biosdev = d->ll.dev;
+ *offset = d->part[part].offset;
+ *size = d->part[part].size;
+ ret = 0;
+ goto out;
+ }
+
+ }
+next_disk:
+ dealloc_biosdisk(d);
+ d = NULL;
+ }
+
+#ifndef NO_RAIDFRAME
+ for (i = 0; i < raidframe_count; i++) {
+ int candidate = -1;
+
+ if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+ printf("Out of memory\n");
+ goto out;
+ }
+
+ if (read_partitions(d,
+ raidframe[i].offset + RF_PROTECTED_SECTORS,
+ raidframe[i].size) != 0)
+ goto next_raidframe;
+
+ for (part = 0; part < BIOSDISKNPART; part++) {
+ bool bootme = d->part[part].attr & GPT_ENT_ATTR_BOOTME;
+ if (d->part[part].size == 0)
+ continue;
+ if (d->part[part].fstype == FS_UNUSED)
+ continue;
+ if (d->part[part].part_name == NULL)
+ continue;
+ if (strcmp(d->part[part].part_name, name) == 0) {
+ *biosdev = raidframe[i].biosdev;
+ *offset = raidframe[i].offset
+ + RF_PROTECTED_SECTORS
+ + d->part[part].offset;
+ *size = d->part[part].size;
+ ret = 0;
+ goto out;
+ }
+ if (strcmp(raidframe[i].parent_name, name) == 0) {
+ if (candidate == -1 || bootme)
+ candidate = part;
+ continue;
+ }
+ }
+
+ if (candidate != -1) {
+ *biosdev = raidframe[i].biosdev;
+ *offset = raidframe[i].offset
+ + RF_PROTECTED_SECTORS
+ + d->part[candidate].offset;
+ *size = d->part[candidate].size;
+ ret = 0;
+ goto out;
+ }
+
+next_raidframe:
+ dealloc_biosdisk(d);
+ d = NULL;
+ }
+#endif
+
+out:
+ if (d != NULL)
+ dealloc_biosdisk(d);
+
+ return ret;
+}
+#endif
+
+#ifndef NO_RAIDFRAME
+static int
+biosdisk_find_raid(const char *name, int *biosdev,
+ daddr_t *offset, daddr_t *size)
+{
+ struct biosdisk *d = NULL;
+ struct raidframe raidframe[RAIDFRAME_NDEV];
+ int raidframe_count = 0;
+ int i;
+ int target_unit = 0;
+ int target_part;
+ int part;
+ int ret = -1;
+
+ if (strstr(name, "raid") != name)
+ goto out;
+
+#define isnum(c) ((c) >= '0' && (c) <= '9')
+ i = 4; /* skip leading "raid" */
+ if (!isnum(name[i]))
+ goto out;
+ do {
+ target_unit *= 10;
+ target_unit += name[i++] - '0';
+ } while (isnum(name[i]));
+
+#define isvalidpart(c) ((c) >= 'a' && (c) <= 'z')
+
+ if (!isvalidpart(name[i]))
+ goto out;
+ target_part = name[i] - 'a';
+
+ for (i = 0; i < MAX_BIOSDISKS; i++) {
+ d = alloc(sizeof(*d));
+ if (d == NULL) {
+ printf("Out of memory\n");
+ goto out;
+ }
+
+ memset(d, 0, sizeof(*d));
+ d->ll.dev = 0x80 + i; /* hd/cd */
+ if (set_geometry(&d->ll, NULL))
+ goto next_disk;
+
+ if (d->ll.type != BIOSDISK_TYPE_HD)
+ goto next_disk;
+
+ if (read_partitions(d, 0, 0) != 0)
+ goto next_disk;
+
+ for (part = 0; part < BIOSDISKNPART; part++) {
+ if (d->part[part].size == 0)
+ continue;
+ if (d->part[part].fstype != FS_RAID)
+ continue;
+ raidframe_probe(raidframe,
+ &raidframe_count, d, part);
+
+ }
+next_disk:
+ dealloc_biosdisk(d);
+ d = NULL;
+ }
+
+ for (i = 0; i < raidframe_count; i++) {
+ if (raidframe[i].last_unit != target_unit)
+ continue;
+
+ if ((d = alloc_biosdisk(raidframe[i].biosdev)) == NULL) {
+ printf("Out of memory\n");
+ goto out;
+ }
+
+ if (read_partitions(d,
+ raidframe[i].offset + RF_PROTECTED_SECTORS,
+ raidframe[i].size) != 0)
+ goto next_raidframe;
+
+ for (part = 0; part < BIOSDISKNPART; part++) {
+ if (d->part[part].size == 0)
+ continue;
+ if (d->part[part].fstype == FS_UNUSED)
+ continue;
+ if (part == target_part) {
+ *biosdev = raidframe[i].biosdev;
+ *offset = raidframe[i].offset
+ + RF_PROTECTED_SECTORS
+ + d->part[part].offset;
+ *size = d->part[part].size;
+ ret = 0;
+ goto out;
+ }
+ }
+next_raidframe:
+ dealloc_biosdisk(d);
+ d = NULL;
+ }
+out:
+ if (d != NULL)
+ dealloc_biosdisk(d);
+
+ return ret;
+}
+#endif
+
+int
+biosdisk_open_name(struct open_file *f, const char *name)
+{
+#if defined(NO_GPT) && defined(NO_RAIDFRAME)
+ return ENXIO;
+#else
+ struct biosdisk *d = NULL;
+ int biosdev;
+ daddr_t offset;
+ daddr_t size;
+ int error = -1;
+
+#ifndef NO_GPT
+ if (strstr(name, "NAME=") == name)
+ error = biosdisk_find_name(name, &biosdev, &offset, &size);
+#endif
+#ifndef NO_RAIDFRAME
+ if (strstr(name, "raid") == name)
+ error = biosdisk_find_raid(name, &biosdev, &offset, &size);
+#endif
+
+ if (error != 0) {
+ printf("%s not found\n", name);
+ error = ENXIO;
+ goto out;
+ }
+
+ d = alloc_biosdisk(biosdev);
+ if (d == NULL) {
+ error = ENXIO;
+ goto out;
+ }
+
+#ifdef _STANDALONE
+ bi_disk.biosdev = d->ll.dev;
+ bi_disk.partition = 0;
+ bi_disk.labelsector = -1;
+
+ bi_wedge.biosdev = d->ll.dev;
+
+ /*
+ * If we did not get wedge match info from check_gpt()
+ * compute it now.
+ */
+ if (bi_wedge.matchblk == -1) {
+ if (readsects(&d->ll, offset, 1, d->buf, 1)) {
+#ifdef DISK_DEBUG
+ printf("Error reading sector at %"PRId64"\n", offset);
+#endif
+ error = EIO;
+ goto out;
+ }
+
+ bi_wedge.matchblk = offset;
+ bi_wedge.matchnblks = 1;
+
+ md5(bi_wedge.matchhash, d->buf, d->ll.secsize);
+ }
+#endif
+
+ d->boff = offset;
+
+#ifdef _STANDALONE
+ bi_wedge.startblk = offset;
+ bi_wedge.nblks = size;
+
+ add_biosdisk_bootinfo();
+#endif
+
+ f->f_devdata = d;
+out:
+ if (error && d != NULL)
+ dealloc_biosdisk(d);
return error;
+#endif
}
+
+
#ifndef LIBSA_NO_FS_CLOSE
int
biosdisk_close(struct open_file *f)
@@ -970,7 +1643,7 @@ biosdisk_close(struct open_file *f)
if (d->ll.type == BIOSDISK_TYPE_FD)
wait_sec(3); /* 2s is enough on all PCs I found */
- dealloc(d, sizeof(*d));
+ dealloc_biosdisk(d);
f->f_devdata = NULL;
return 0;
}
Index: src/sys/arch/i386/stand/lib/biosdisk.h
diff -u src/sys/arch/i386/stand/lib/biosdisk.h:1.10 src/sys/arch/i386/stand/lib/biosdisk.h:1.10.6.1
--- src/sys/arch/i386/stand/lib/biosdisk.h:1.10 Mon Apr 2 09:44:18 2018
+++ src/sys/arch/i386/stand/lib/biosdisk.h Fri Sep 13 07:00:13 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: biosdisk.h,v 1.10 2018/04/02 09:44:18 nonaka Exp $ */
+/* $NetBSD: biosdisk.h,v 1.10.6.1 2019/09/13 07:00:13 martin Exp $ */
/*
* Copyright (c) 1996
@@ -25,25 +25,33 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define BIOSDISK_PART_NAME_LEN 36
+
struct biosdisk_partition {
daddr_t offset;
daddr_t size;
int fstype;
-#ifdef EFIBOOT
+#ifndef NO_GPT
const struct gpt_part {
const struct uuid *guid;
const char *name;
} *guid;
uint64_t attr;
+ char *part_name; /* maximum BIOSDISK_PART_NAME_LEN */
#endif
};
int biosdisk_strategy(void *, int, daddr_t, size_t, void *, size_t *);
int biosdisk_open(struct open_file *, ...);
+int biosdisk_open_name(struct open_file *, const char *);
int biosdisk_close(struct open_file *);
int biosdisk_ioctl(struct open_file *, u_long, void *);
-int biosdisk_findpartition(int, daddr_t);
-int biosdisk_readpartition(int, struct biosdisk_partition **, int *);
+int biosdisk_findpartition(int, daddr_t, int *, const char **);
+int biosdisk_readpartition(int, daddr_t, daddr_t,
+ struct biosdisk_partition **, int *);
+
+struct RF_ComponentLabel_s;
+int biosdisk_read_raidframe(int, daddr_t, struct RF_ComponentLabel_s *);
#if !defined(NO_GPT)
struct uuid;