Add support for loading kernels over NFS.

This commit is contained in:
jmcneill 2018-11-15 23:52:33 +00:00
parent 269297e942
commit a158dd7e2e
9 changed files with 75 additions and 36 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: boot.c,v 1.13 2018/11/02 01:22:39 jmcneill Exp $ */ /* $NetBSD: boot.c,v 1.14 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org> * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@ -72,7 +72,7 @@ static const char *efi_memory_type[] = {
static char default_device[32]; static char default_device[32];
static char initrd_path[255]; static char initrd_path[255];
static char dtb_path[255]; static char dtb_path[255];
static char bootfile[255]; static char netbsd_path[255];
#define DEFTIMEOUT 5 #define DEFTIMEOUT 5
#define DEFFILENAME names[0] #define DEFFILENAME names[0]
@ -146,7 +146,6 @@ command_dev(char *arg)
} else { } else {
efi_block_show(); efi_block_show();
efi_net_show(); efi_net_show();
efi_pxe_show();
} }
if (strlen(default_device) > 0) { if (strlen(default_device) > 0) {
@ -323,9 +322,9 @@ get_dtb_path(void)
int int
set_bootfile(const char *arg) set_bootfile(const char *arg)
{ {
if (strlen(arg) + 1 > sizeof(bootfile)) if (strlen(arg) + 1 > sizeof(netbsd_path))
return ERANGE; return ERANGE;
strcpy(bootfile, arg); strcpy(netbsd_path, arg);
return 0; return 0;
} }
@ -388,7 +387,7 @@ boot(void)
print_banner(); print_banner();
printf("Press return to boot now, any other key for boot prompt\n"); printf("Press return to boot now, any other key for boot prompt\n");
if (bootfile[0] != '\0') if (netbsd_path[0] != '\0')
currname = -1; currname = -1;
else else
currname = 0; currname = 0;
@ -396,13 +395,13 @@ boot(void)
for (; currname < (int)NUMNAMES; currname++) { for (; currname < (int)NUMNAMES; currname++) {
if (currname >= 0) if (currname >= 0)
set_bootfile(names[currname]); set_bootfile(names[currname]);
printf("booting %s - starting in ", bootfile); printf("booting %s - starting in ", netbsd_path);
c = awaitkey(DEFTIMEOUT, 1); c = awaitkey(DEFTIMEOUT, 1);
if (c != '\r' && c != '\n' && c != '\0') if (c != '\r' && c != '\n' && c != '\0')
bootprompt(); /* does not return */ bootprompt(); /* does not return */
exec_netbsd(bootfile, ""); exec_netbsd(netbsd_path, "");
} }
bootprompt(); /* does not return */ bootprompt(); /* does not return */

View File

@ -1,4 +1,4 @@
/* $NetBSD: conf.c,v 1.3 2018/09/03 00:04:02 jmcneill Exp $ */ /* $NetBSD: conf.c,v 1.4 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
@ -34,6 +34,7 @@
#include <lib/libsa/ufs.h> #include <lib/libsa/ufs.h>
#include <lib/libsa/dosfs.h> #include <lib/libsa/dosfs.h>
#include <lib/libsa/tftp.h> #include <lib/libsa/tftp.h>
#include <lib/libsa/nfs.h>
#include <lib/libsa/net.h> #include <lib/libsa/net.h>
#include <lib/libsa/dev_net.h> #include <lib/libsa/dev_net.h>
@ -59,3 +60,4 @@ int nfsys = __arraycount(file_system);
struct fs_ops null_fs_ops = FS_OPS(null); struct fs_ops null_fs_ops = FS_OPS(null);
struct fs_ops tftp_fs_ops = FS_OPS(tftp); struct fs_ops tftp_fs_ops = FS_OPS(tftp);
struct fs_ops nfs_fs_ops = FS_OPS(nfs);

View File

@ -1,4 +1,4 @@
/* $NetBSD: dev_net.c,v 1.1 2018/09/03 00:04:02 jmcneill Exp $ */ /* $NetBSD: dev_net.c,v 1.2 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
@ -37,6 +37,7 @@
#include <lib/libsa/netif.h> #include <lib/libsa/netif.h>
#include <lib/libsa/bootparam.h> #include <lib/libsa/bootparam.h>
#include <lib/libsa/bootp.h> #include <lib/libsa/bootp.h>
#include <lib/libsa/nfs.h>
#include "dev_net.h" #include "dev_net.h"
@ -68,6 +69,18 @@ net_open(struct open_file *f, ...)
printf("boot: client ip: %s\n", inet_ntoa(myip)); printf("boot: client ip: %s\n", inet_ntoa(myip));
printf("boot: server ip: %s\n", inet_ntoa(rootip)); printf("boot: server ip: %s\n", inet_ntoa(rootip));
if (rootpath[0] != '\0')
printf("boot: server path: %s\n", rootpath);
if (bootfile[0] != '\0')
printf("boot: file name: %s\n", bootfile);
}
if (rootpath[0] != '\0') {
error = nfs_mount(net_socket, rootip, rootpath);
if (error) {
printf("NFS mount error=%d\n", errno);
goto fail;
}
} }
f->f_devdata = &net_socket; f->f_devdata = &net_socket;

View File

@ -1,4 +1,4 @@
/* $NetBSD: devopen.c,v 1.3 2018/09/03 00:04:02 jmcneill Exp $ */ /* $NetBSD: devopen.c,v 1.4 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
@ -36,7 +36,12 @@ devopen(struct open_file *f, const char *fname, char **file)
int error; int error;
error = efi_net_open(f, fname, file); error = efi_net_open(f, fname, file);
file_system[0] = error ? null_fs_ops : tftp_fs_ops; if (error)
file_system[0] = null_fs_ops;
else if (rootpath[0] != '\0')
file_system[0] = nfs_fs_ops;
else
file_system[0] = tftp_fs_ops;
if (error) if (error)
error = efi_block_open(f, fname, file); error = efi_block_open(f, fname, file);

View File

@ -1,4 +1,4 @@
/* $NetBSD: efiboot.h,v 1.8 2018/10/26 20:56:35 mrg Exp $ */ /* $NetBSD: efiboot.h,v 1.9 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org> * Copyright (c) 2016 Kimihiro Nonaka <nonaka@netbsd.org>
@ -33,6 +33,7 @@
#include <lib/libkern/libkern.h> #include <lib/libkern/libkern.h>
#include <loadfile.h> #include <loadfile.h>
#include <net.h>
#include "efiboot_machdep.h" #include "efiboot_machdep.h"
@ -45,6 +46,7 @@ struct boot_command {
/* conf.c */ /* conf.c */
extern struct fs_ops null_fs_ops; extern struct fs_ops null_fs_ops;
extern struct fs_ops tftp_fs_ops; extern struct fs_ops tftp_fs_ops;
extern struct fs_ops nfs_fs_ops;
/* boot.c */ /* boot.c */
void boot(void); void boot(void);
@ -82,15 +84,19 @@ int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int); int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
/* efinet.c */ /* efinet.c */
struct efi_net_if {
const char *if_name;
uint8_t if_mac[6];
};
int efi_net_open(struct open_file *, ...); int efi_net_open(struct open_file *, ...);
void efi_net_probe(void); void efi_net_probe(void);
void efi_net_show(void); void efi_net_show(void);
int efi_net_get_booted_interface_unit(void); int efi_net_get_booted_interface_unit(void);
int efi_net_get_booted_macaddr(uint8_t *);
extern struct netif_driver efinetif; extern struct netif_driver efinetif;
/* efipxe.c */ /* efipxe.c */
void efi_pxe_probe(void); void efi_pxe_probe(void);
void efi_pxe_show(void);
bool efi_pxe_match_booted_interface(const EFI_MAC_ADDRESS *, UINT32); bool efi_pxe_match_booted_interface(const EFI_MAC_ADDRESS *, UINT32);
/* exec.c */ /* exec.c */

View File

@ -1,4 +1,4 @@
/* $NetBSD: efifdt.c,v 1.13 2018/11/02 01:22:39 jmcneill Exp $ */ /* $NetBSD: efifdt.c,v 1.14 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca> * Copyright (c) 2018 Jared McNeill <jmcneill@invisible.ca>
@ -194,6 +194,7 @@ void
efi_fdt_bootargs(const char *bootargs) efi_fdt_bootargs(const char *bootargs)
{ {
struct efi_block_part *bpart = efi_block_boot_part(); struct efi_block_part *bpart = efi_block_boot_part();
uint8_t macaddr[6];
int chosen; int chosen;
chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH); chosen = fdt_path_offset(fdt_data, FDT_CHOSEN_NODE_PATH);
@ -229,6 +230,8 @@ efi_fdt_bootargs(const char *bootargs)
default: default:
break; break;
} }
} else if (efi_net_get_booted_macaddr(macaddr) == 0) {
fdt_setprop(fdt_data, chosen, "netbsd,booted-mac-address", macaddr, sizeof(macaddr));
} }
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: efinet.c,v 1.3 2018/09/04 21:29:54 jmcneill Exp $ */ /* $NetBSD: efinet.c,v 1.4 2018/11/15 23:52:33 jmcneill Exp $ */
/*- /*-
* Copyright (c) 2001 Doug Rabson * Copyright (c) 2001 Doug Rabson
@ -465,7 +465,7 @@ efi_net_show(void)
eni = dif->dif_private; eni = dif->dif_private;
net = eni->net; net = eni->net;
printf("net net%d", dif->dif_unit); printf("net%d", dif->dif_unit);
if (net->Mode != NULL) { if (net->Mode != NULL) {
for (UINT32 x = 0; x < net->Mode->HwAddressSize; x++) { for (UINT32 x = 0; x < net->Mode->HwAddressSize; x++) {
printf("%c%02x", x == 0 ? ' ' : ':', printf("%c%02x", x == 0 ? ' ' : ':',
@ -500,6 +500,27 @@ efi_net_get_booted_interface_unit(void)
return -1; return -1;
} }
int
efi_net_get_booted_macaddr(uint8_t *mac)
{
const struct netif_dif *dif;
const struct efinetinfo *eni;
EFI_SIMPLE_NETWORK *net;
int i;
for (i = 0; i < efinetif.netif_nifs; i++) {
dif = &efinetif.netif_ifs[i];
eni = dif->dif_private;
net = eni->net;
if (eni->bootdev && net->Mode != NULL && net->Mode->HwAddressSize == 6) {
memcpy(mac, net->Mode->PermanentAddress.Addr, 6);
return 0;
}
}
return -1;
}
int int
efi_net_open(struct open_file *f, ...) efi_net_open(struct open_file *f, ...)
{ {
@ -508,7 +529,7 @@ efi_net_open(struct open_file *f, ...)
struct devdesc desc; struct devdesc desc;
intmax_t dev; intmax_t dev;
va_list ap; va_list ap;
int n; int n, error;
va_start(ap, f); va_start(ap, f);
fname = va_arg(ap, const char *); fname = va_arg(ap, const char *);
@ -551,5 +572,9 @@ efi_net_open(struct open_file *f, ...)
strlcpy(desc.d_name, "net", sizeof(desc.d_name)); strlcpy(desc.d_name, "net", sizeof(desc.d_name));
desc.d_unit = dev; desc.d_unit = dev;
return DEV_OPEN(f->f_dev)(f, &desc); error = DEV_OPEN(f->f_dev)(f, &desc);
if (error)
return error;
return 0;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: efipxe.c,v 1.1 2018/09/03 00:04:02 jmcneill Exp $ */ /* $NetBSD: efipxe.c,v 1.2 2018/11/15 23:52:33 jmcneill Exp $ */
/* $OpenBSD: efipxe.c,v 1.3 2018/01/30 20:19:06 naddy Exp $ */ /* $OpenBSD: efipxe.c,v 1.3 2018/01/30 20:19:06 naddy Exp $ */
/* /*
@ -112,21 +112,6 @@ efi_pxe_probe(void)
} }
} }
void
efi_pxe_show(void)
{
const struct efipxeinfo *epi;
UINT32 i, n;
n = 0;
TAILQ_FOREACH(epi, &efi_pxelist, list) {
printf("pxe pxe%d", n++);
for (i = 0; i < epi->addrsz; i++)
printf("%c%02x", i == 0 ? ' ' : ':', epi->mac.Addr[i]);
printf("\n");
}
}
bool bool
efi_pxe_match_booted_interface(const EFI_MAC_ADDRESS *mac, UINT32 addrsz) efi_pxe_match_booted_interface(const EFI_MAC_ADDRESS *mac, UINT32 addrsz)
{ {

View File

@ -1,4 +1,4 @@
$NetBSD: version,v 1.7 2018/11/01 00:43:38 jmcneill Exp $ $NetBSD: version,v 1.8 2018/11/15 23:52:33 jmcneill Exp $
NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this NOTE ANY CHANGES YOU MAKE TO THE EFI BOOTLOADER HERE. The format of this
file is important - make sure the entries are appended on end, last item file is important - make sure the entries are appended on end, last item
@ -11,3 +11,4 @@ is taken as the current.
1.4: Add bootfile support. 1.4: Add bootfile support.
1.5: EFI runtime support. 1.5: EFI runtime support.
1.6: Add GPT support. 1.6: Add GPT support.
1.7: Add NFS support.