Module Name: src
Committed By: martin
Date: Fri Sep 27 09:32:22 UTC 2019
Modified Files:
src/sys/arch/i386/stand/efiboot [netbsd-9]: boot.c conf.c dev_net.c
devopen.c devopen.h
Log Message:
Pull up following revision(s) (requested by nonaka in ticket #253):
sys/arch/i386/stand/efiboot/conf.c: revision 1.3
sys/arch/i386/stand/efiboot/devopen.h: revision 1.5
sys/arch/i386/stand/efiboot/devopen.c: revision 1.8
sys/arch/i386/stand/efiboot/boot.c: revision 1.17
sys/arch/i386/stand/efiboot/dev_net.c: revision 1.3
x86 efiboot: pass a filename to BOOTP and parse a DHCP server provided filename.
To generate a diff of this commit:
cvs rdiff -u -r1.13.2.2 -r1.13.2.3 src/sys/arch/i386/stand/efiboot/boot.c
cvs rdiff -u -r1.2 -r1.2.6.1 src/sys/arch/i386/stand/efiboot/conf.c
cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/arch/i386/stand/efiboot/dev_net.c
cvs rdiff -u -r1.5.6.1 -r1.5.6.2 src/sys/arch/i386/stand/efiboot/devopen.c
cvs rdiff -u -r1.3.6.1 -r1.3.6.2 src/sys/arch/i386/stand/efiboot/devopen.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.2 src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.3
--- src/sys/arch/i386/stand/efiboot/boot.c:1.13.2.2 Tue Sep 17 19:32:00 2019
+++ src/sys/arch/i386/stand/efiboot/boot.c Fri Sep 27 09:32:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: boot.c,v 1.13.2.2 2019/09/17 19:32:00 martin Exp $ */
+/* $NetBSD: boot.c,v 1.13.2.3 2019/09/27 09:32:22 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -111,6 +111,7 @@ const struct bootblk_command commands[]
{ NULL, NULL },
};
+static char *default_fsname;
static char *default_devname;
static int default_unit, default_partition;
static const char *default_filename;
@@ -125,8 +126,11 @@ parsebootfile(const char *fname, char **
{
const char *col;
static char savedevname[MAXDEVNAME+1];
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+ const struct netboot_fstab *nf;
+#endif
- *fsname = "ufs";
+ *fsname = default_fsname;
if (default_part_name == NULL) {
*devname = default_devname;
} else {
@@ -152,6 +156,7 @@ parsebootfile(const char *fname, char **
if (strstr(fname, "NAME=") == fname) {
strlcpy(savedevname, fname, devlen + 1);
+ *fsname = "ufs";
*devname = savedevname;
*unit = -1;
*partition = -1;
@@ -188,6 +193,13 @@ parsebootfile(const char *fname, char **
if (i != devlen)
return ENXIO;
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+ nf = netboot_fstab_find(savedevname);
+ if (nf != NULL)
+ *fsname = (char *)nf->name;
+ else
+#endif
+ *fsname = "ufs";
*devname = savedevname;
*unit = u;
*partition = p;
@@ -278,6 +290,9 @@ boot(void)
{
int currname;
int c;
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+ const struct netboot_fstab *nf;
+#endif
boot_modules_enabled = !(boot_params.bp_flags & X86_BP_FLAGS_NOMODULES);
@@ -288,6 +303,14 @@ boot(void)
/* if the user types "boot" without filename */
default_filename = DEFFILENAME;
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+ nf = netboot_fstab_find(default_devname);
+ if (nf != NULL)
+ default_fsname = (char *)nf->name;
+ else
+#endif
+ default_fsname = "ufs";
+
if (!(boot_params.bp_flags & X86_BP_FLAGS_NOBOOTCONF)) {
#ifdef EFIBOOTCFG_FILENAME
int rv = EINVAL;
@@ -456,7 +479,7 @@ command_dev(char *arg)
{
static char savedevname[MAXDEVNAME + 1];
char buf[80];
- char *fsname, *devname;
+ char *devname;
const char *file; /* dummy */
if (*arg == '\0') {
@@ -474,7 +497,7 @@ command_dev(char *arg)
}
if (strchr(arg, ':') == NULL ||
- parsebootfile(arg, &fsname, &devname, &default_unit,
+ parsebootfile(arg, &default_fsname, &devname, &default_unit,
&default_partition, &file)) {
command_help(NULL);
return;
Index: src/sys/arch/i386/stand/efiboot/conf.c
diff -u src/sys/arch/i386/stand/efiboot/conf.c:1.2 src/sys/arch/i386/stand/efiboot/conf.c:1.2.6.1
--- src/sys/arch/i386/stand/efiboot/conf.c:1.2 Wed Apr 11 10:32:09 2018
+++ src/sys/arch/i386/stand/efiboot/conf.c Fri Sep 27 09:32:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: conf.c,v 1.2 2018/04/11 10:32:09 nonaka Exp $ */
+/* $NetBSD: conf.c,v 1.2.6.1 2019/09/27 09:32:22 martin Exp $ */
/*
* Copyright (c) 1997
@@ -54,20 +54,23 @@
#endif
#endif
#include <biosdisk.h>
+#include "devopen.h"
#include "efinet.h"
struct devsw devsw[] = {
{ "disk", biosdisk_strategy, biosdisk_open, biosdisk_close, biosdisk_ioctl },
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
{ "net", net_strategy, net_open, net_close, net_ioctl },
+#endif
};
int ndevs = __arraycount(devsw);
-#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
struct netif_driver *netif_drivers[] = {
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
&efinetif,
+#endif
};
int n_netif_drivers = __arraycount(netif_drivers);
-#endif
struct fs_ops file_system[] = {
#ifdef SUPPORT_CD9660
@@ -113,3 +116,15 @@ struct fs_ops file_system_nfs = FS_OPS(n
#ifdef SUPPORT_TFTP
struct fs_ops file_system_tftp = FS_OPS(tftp);
#endif
+
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+const struct netboot_fstab netboot_fstab[] = {
+#ifdef SUPPORT_NFS
+ { "nfs", &file_system_nfs },
+#endif
+#ifdef SUPPORT_TFTP
+ { "tftp", &file_system_tftp },
+#endif
+};
+const int nnetboot_fstab = __arraycount(netboot_fstab);
+#endif
Index: src/sys/arch/i386/stand/efiboot/dev_net.c
diff -u src/sys/arch/i386/stand/efiboot/dev_net.c:1.2 src/sys/arch/i386/stand/efiboot/dev_net.c:1.2.2.1
--- src/sys/arch/i386/stand/efiboot/dev_net.c:1.2 Fri Jul 26 11:30:31 2019
+++ src/sys/arch/i386/stand/efiboot/dev_net.c Fri Sep 27 09:32:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: dev_net.c,v 1.2 2019/07/26 11:30:31 nonaka Exp $ */
+/* $NetBSD: dev_net.c,v 1.2.2.1 2019/09/27 09:32:22 martin Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -76,23 +76,23 @@ int
net_open(struct open_file *f, ...)
{
va_list ap;
- char *devname; /* Device part of file name (or NULL). */
+ struct devdesc *dev;
int error = 0;
va_start(ap, f);
- devname = va_arg(ap, char *);
+ dev = va_arg(ap, struct devdesc *);
va_end(ap);
#ifdef NETIF_DEBUG
if (debug)
- printf("%s\n", devname);
+ printf("%s\n", dev->devname);
#endif
/* On first open, do netif open, mount, etc. */
if (netdev_opens == 0) {
/* Find network interface. */
if (netdev_sock < 0) {
- netdev_sock = netif_open(devname);
+ netdev_sock = netif_open(dev);
if (netdev_sock < 0) {
printf("netif_open() failed\n");
return ENXIO;
Index: src/sys/arch/i386/stand/efiboot/devopen.c
diff -u src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.1 src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.2
--- src/sys/arch/i386/stand/efiboot/devopen.c:1.5.6.1 Fri Sep 13 07:00:13 2019
+++ src/sys/arch/i386/stand/efiboot/devopen.c Fri Sep 27 09:32:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.c,v 1.5.6.1 2019/09/13 07:00:13 martin Exp $ */
+/* $NetBSD: devopen.c,v 1.5.6.2 2019/09/27 09:32:22 martin Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -57,6 +57,7 @@
#include "efiboot.h"
#include <lib/libsa/dev_net.h>
+#include <lib/libsa/net.h>
#include <biosdisk.h>
#include "devopen.h"
@@ -106,6 +107,40 @@ bios2dev(int biosdev, daddr_t sector, ch
}
}
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+const struct netboot_fstab *
+netboot_fstab_find(const char *name)
+{
+ int i;
+
+ if (strcmp(name, "net") == 0)
+ return &netboot_fstab[0];
+
+ for (i = 0; i < nnetboot_fstab; i++) {
+ if (strcmp(name, netboot_fstab[i].name) == 0)
+ return &netboot_fstab[i];
+ }
+
+ return NULL;
+}
+
+static const struct netboot_fstab *
+netboot_fstab_findn(const char *name, size_t len)
+{
+ int i;
+
+ if (strncmp(name, "net", len) == 0)
+ return &netboot_fstab[0];
+
+ for (i = 0; i < nnetboot_fstab; i++) {
+ if (strncmp(name, netboot_fstab[i].name, len) == 0)
+ return &netboot_fstab[i];
+ }
+
+ return NULL;
+}
+#endif
+
struct btinfo_bootpath bibp;
extern bool kernel_loaded;
@@ -115,28 +150,27 @@ extern bool kernel_loaded;
int
devopen(struct open_file *f, const char *fname, char **file)
{
-#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
- static const char *net_devnames[] = {
-#if defined(SUPPORT_NFS)
- "nfs",
-#endif
-#if defined(SUPPORT_TFTP)
- "tftp",
-#endif
- };
-#endif
- struct devdesc desc;
- struct devsw *dev;
char *fsname, *devname;
int unit, partition;
int biosdev;
- int i, n, error;
+ int i, error;
+#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
+ struct devdesc desc;
+ const struct netboot_fstab *nf;
+ char *filename;
+ size_t fsnamelen;
+ int n;
+#endif
error = parsebootfile(fname, &fsname, &devname, &unit, &partition,
(const char **) file);
if (error)
return error;
+ memcpy(file_system, file_system_disk,
+ sizeof(struct fs_ops) * nfsys_disk);
+ nfsys = nfsys_disk;
+
/* Search by GPT label or raidframe name */
if ((strstr(devname, "NAME=") == devname) ||
(strstr(devname, "raid") == devname)) {
@@ -151,64 +185,99 @@ devopen(struct open_file *f, const char
return error;
}
- memcpy(file_system, file_system_disk, sizeof(*file_system) * nfsys);
- nfsys = nfsys_disk;
-
+ /*
+ * Network
+ */
#if defined(SUPPORT_NFS) || defined(SUPPORT_TFTP)
- for (i = 0; i < __arraycount(net_devnames); i++) {
- if (strcmp(devname, net_devnames[i]) == 0) {
- fsname = devname;
- devname = "net";
- break;
+ nf = netboot_fstab_find(devname);
+ if (nf != NULL) {
+ n = 0;
+ if (strcmp(devname, "net") == 0) {
+ for (i = 0; i < nnetboot_fstab; i++) {
+ memcpy(&file_system[n++], netboot_fstab[i].ops,
+ sizeof(struct fs_ops));
+ }
+ } else {
+ memcpy(&file_system[n++], nf->ops,
+ sizeof(struct fs_ops));
}
- }
-#endif
+ nfsys = n;
- for (i = 1; i < ndevs; i++) {
- dev = &devsw[i];
- if (strcmp(devname, DEV_NAME(dev)) == 0) {
- if (strcmp(devname, "net") == 0) {
- n = 0;
-#if defined(SUPPORT_NFS)
- if (strcmp(fsname, "nfs") == 0) {
- memcpy(&file_system[n++], &file_system_nfs,
- sizeof(file_system_nfs));
- } else
-#endif
-#if defined(SUPPORT_TFTP)
- if (strcmp(fsname, "tftp") == 0) {
- memcpy(&file_system[n++], &file_system_tftp,
- sizeof(file_system_tftp));
- } else
-#endif
- {
-#if defined(SUPPORT_NFS)
- memcpy(&file_system[n++], &file_system_nfs,
- sizeof(file_system_nfs));
+#ifdef SUPPORT_BOOTP
+ try_bootp = 1;
#endif
-#if defined(SUPPORT_TFTP)
- memcpy(&file_system[n++], &file_system_tftp,
- sizeof(file_system_tftp));
-#endif
- }
- nfsys = n;
- try_bootp = 1;
- }
+ /* If we got passed a filename, pass it to the BOOTP server. */
+ if (fname) {
+ filename = strchr(fname, ':');
+ if (filename != NULL)
+ filename++;
+ else
+ filename = (char *)fname;
+ strlcpy(bootfile, filename, sizeof(bootfile));
+ }
- memset(&desc, 0, sizeof(desc));
- strlcpy(desc.d_name, devname, sizeof(desc.d_name));
- desc.d_unit = unit;
-
- f->f_dev = dev;
- if (!kernel_loaded) {
- strncpy(bibp.bootpath, *file,
- sizeof(bibp.bootpath));
- BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
+ memset(&desc, 0, sizeof(desc));
+ strlcpy(desc.d_name, "net", sizeof(desc.d_name));
+ desc.d_unit = unit;
+
+ f->f_dev = &devsw[1]; /* must be net */
+ if (!kernel_loaded) {
+ strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
+ BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
+ }
+ error = DEV_OPEN(f->f_dev)(f, &desc);
+ if (error)
+ return error;
+
+ /*
+ * If the DHCP server provided a file name:
+ * - If it contains a ":", assume it points to a NetBSD kernel.
+ * - If not, assume that the DHCP server was not able to pass
+ * a separate filename for the kernel. (The name probably was
+ * the same as used to load "efiboot".) Ignore it and use
+ * the default in this case.
+ * So we cater to simple DHCP servers while being able to use
+ * the power of conditional behaviour in modern ones.
+ */
+ filename = strchr(bootfile, ':');
+ if (filename != NULL) {
+ fname = bootfile;
+
+ fsnamelen = filename - fname;
+ nf = netboot_fstab_findn(fname, fsnamelen);
+ if (nf == NULL ||
+ strncmp(fname, "net", fsnamelen) == 0) {
+ printf("Invalid file system type specified in "
+ "%s\n", fname);
+ error = EINVAL;
+ goto neterr;
}
- return DEV_OPEN(f->f_dev)(f, &desc);
+
+ memcpy(file_system, nf->ops, sizeof(struct fs_ops));
+ nfsys = 1;
}
+
+ filename = fname ? strchr(fname, ':') : NULL;
+ if (filename != NULL) {
+ filename++;
+ if (*filename == '\0') {
+ printf("No file specified in %s\n", fname);
+ error = EINVAL;
+ goto neterr;
+ }
+ } else
+ filename = (char *)fname;
+
+ *file = filename;
+ return 0;
+
+neterr:
+ DEV_CLOSE(f->f_dev)(f);
+ f->f_dev = NULL;
+ return error;
}
+#endif
/*
* biosdisk
Index: src/sys/arch/i386/stand/efiboot/devopen.h
diff -u src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.1 src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.2
--- src/sys/arch/i386/stand/efiboot/devopen.h:1.3.6.1 Fri Sep 13 07:00:13 2019
+++ src/sys/arch/i386/stand/efiboot/devopen.h Fri Sep 27 09:32:22 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: devopen.h,v 1.3.6.1 2019/09/13 07:00:13 martin Exp $ */
+/* $NetBSD: devopen.h,v 1.3.6.2 2019/09/27 09:32:22 martin Exp $ */
/*-
* Copyright (c) 2016 Kimihiro Nonaka <[email protected]>
@@ -42,3 +42,13 @@ struct devdesc {
char d_name[MAXDEVNAME];
char d_unit;
};
+
+struct netboot_fstab {
+ const char *name;
+ struct fs_ops *ops;
+};
+
+extern const struct netboot_fstab netboot_fstab[];
+extern const int nnetboot_fstab;
+
+const struct netboot_fstab *netboot_fstab_find(const char *);