Add support for loading kernels over NFS.
This commit is contained in:
parent
269297e942
commit
a158dd7e2e
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue