Re: amd64: EFI boot over network try to load kernel from hd0

2017-11-25 Thread Patrick Wildt
On Fri, Nov 24, 2017 at 04:48:08PM -0700, Andrew Hewus Fresh wrote:
> A version of this patch that applies cleanly lets me autoinstall
> OpenBSD on a FreeNAS under bhyve.
> So this seems useful and works for me.
> 
> Anyway, I wrote down notes of what I had to do.  I should probably try
> vmm on this hardware again, but time constraints and all that.
> 
> https://gist.github.com/afresh1/804fc0a315ee41e88a24f1aa5e2d3552

Updated diff, ok?

diff --git a/sys/arch/amd64/stand/efiboot/Makefile.common 
b/sys/arch/amd64/stand/efiboot/Makefile.common
index 6dc1cdebd4d..40f5cd2282d 100644
--- a/sys/arch/amd64/stand/efiboot/Makefile.common
+++ b/sys/arch/amd64/stand/efiboot/Makefile.common
@@ -24,7 +24,7 @@ AFLAGS+=  -pipe -fPIC
 
 .PATH: ${.CURDIR}/..
 SRCS+= self_reloc.c
-SRCS+= efiboot.c efidev.c
+SRCS+= efiboot.c efidev.c efipxe.c
 SRCS+= conf.c
 
 .PATH: ${S}/stand/boot
diff --git a/sys/arch/amd64/stand/efiboot/conf.c 
b/sys/arch/amd64/stand/efiboot/conf.c
index 9d825543ec0..befac5a4210 100644
--- a/sys/arch/amd64/stand/efiboot/conf.c
+++ b/sys/arch/amd64/stand/efiboot/conf.c
@@ -30,12 +30,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #include "disk.h"
 #include "efiboot.h"
 #include "efidev.h"
+#include "efipxe.h"
 
 const char version[] = "3.35";
 
@@ -50,7 +52,7 @@ void (*i386_probe1[])(void) = {
cninit, efi_memprobe
 };
 void (*i386_probe2[])(void) = {
-   efi_diskprobe, diskprobe
+   efi_pxeprobe, efi_diskprobe, diskprobe
 };
 
 struct i386_boot_probes probe_list[] = {
@@ -61,6 +63,8 @@ int nibprobes = nitems(probe_list);
 
 
 struct fs_ops file_system[] = {
+   { tftp_open,   tftp_close,   tftp_read,   tftp_write,   tftp_seek,
+ tftp_stat,   tftp_readdir   },
{ ufs_open,ufs_close,ufs_read,ufs_write,ufs_seek,
  ufs_stat,ufs_readdir},
{ cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
@@ -75,10 +79,8 @@ struct fs_ops file_system[] = {
 int nfsys = nitems(file_system);
 
 struct devsw   devsw[] = {
-   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
-#if 0
{ "TFTP", tftpstrategy, tftpopen, tftpclose, tftpioctl },
-#endif
+   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
 };
 int ndevs = nitems(devsw);
 
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c 
b/sys/arch/amd64/stand/efiboot/efiboot.c
index 90bd85576fd..4bbc6bdb5e5 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -52,9 +52,8 @@ static EFI_GUIDblkio_guid = BLOCK_IO_PROTOCOL;
 static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
 u_long  efi_loadaddr;
 
-static int  efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
-static int  efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *,
-   int);
+int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
+int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
 static void efi_heap_init(void);
 static void efi_memprobe_internal(void);
 static void efi_video_init(void);
@@ -101,6 +100,11 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
? 0x1e0 : 0x80;
efi_bootdp = dp0;
break;
+   } else if (DevicePathType(dp) == MESSAGING_DEVICE_PATH&&
+   DevicePathSubType(dp) == MSG_MAC_ADDR_DP) {
+   bios_bootdev = 0x0;
+   efi_bootdp = dp0;
+   break;
}
}
}
@@ -233,7 +237,7 @@ next:
  * Determine the number of nodes up to, but not including, the first
  * node of the specified type.
  */
-static int
+int
 efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype)
 {
int i;
@@ -246,7 +250,7 @@ efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype)
return (-1);
 }
 
-static int
+int
 efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn)
 {
int  i, cmp;
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.h 
b/sys/arch/amd64/stand/efiboot/efiboot.h
index 09ba95ebe9d..e1f726551f3 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.h
+++ b/sys/arch/amd64/stand/efiboot/efiboot.h
@@ -21,6 +21,7 @@ void   efi_cons_probe(struct consdev *);
 voidefi_memprobe(void);
 voidefi_hardprobe(void);
 voidefi_diskprobe(void);
+voidefi_pxeprobe(void);
 voidefi_cons_init(struct consdev *);
 int efi_cons_getc(dev_t);
 voidefi_cons_putc(dev_t, int);
diff --git a/sys/arch/amd64/stand/efiboot/eficall.h 
b/sys/arch/amd64/stand/efiboot/eficall.h
index 38b903efa20..f8cdd5c1228 100644
--- a/sys/arch/amd64/stand/efiboot/eficall.h
+++ b/sys/arch/amd64/stand/efiboot/eficall.h
@@ -44,10 +44,12 @@ extern uint64_t efi_call(int, void *, ...);
 efi_call(8, (_func), (_1), (_2), (_3), (_4), (_5), (_6), 

Re: amd64: EFI boot over network try to load kernel from hd0

2017-06-08 Thread Patrick Wildt
On Thu, Jun 08, 2017 at 11:42:44PM +0900, YASUOKA Masahiko wrote:
> Hi,
> 
> Tested the diff.  It works fine.
> 
> On Wed, 7 Jun 2017 20:23:43 +0200
> Patrick Wildt  wrote:
> > Do you want it to run diskless with root on NFS?  Well, I haven't
> > implemented that, but here's a diff that should allow you to load
> > the kernel from a TFTP server.
> > 
> > I have a similar diff on arm64 (which probably doesn't work with
> > u-boot's EFI API, but works on EDK2 machines) which I use for testing
> > kernels more easily.
> > 
> > I'm not sure how helpful this feature is for most people.  It's probably
> > nice for developers who want to boot different kernels over network, but
> > so far it does not support root on NFS, or only accidentally.
> 
> What the diff is missing is passing the mac address of booted NIC as
> "bootmac" parameter?
> 
> --yasuoka
> 

Does this do what you want it to do?

Patrick

diff --git a/sys/arch/amd64/stand/efiboot/Makefile.common 
b/sys/arch/amd64/stand/efiboot/Makefile.common
index d821e0bc39a..7742e201683 100644
--- a/sys/arch/amd64/stand/efiboot/Makefile.common
+++ b/sys/arch/amd64/stand/efiboot/Makefile.common
@@ -24,7 +24,7 @@ AFLAGS+=  -pipe -fPIC
 
 .PATH: ${.CURDIR}/..
 SRCS+= self_reloc.c
-SRCS+= efiboot.c efidev.c
+SRCS+= efiboot.c efidev.c efipxe.c
 SRCS+= conf.c
 
 .PATH: ${S}/stand/boot
diff --git a/sys/arch/amd64/stand/efiboot/conf.c 
b/sys/arch/amd64/stand/efiboot/conf.c
index 3b2059e414f..55ab425fab2 100644
--- a/sys/arch/amd64/stand/efiboot/conf.c
+++ b/sys/arch/amd64/stand/efiboot/conf.c
@@ -31,12 +31,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #include "disk.h"
 #include "efiboot.h"
 #include "efidev.h"
+#include "efipxe.h"
 
 const char version[] = "3.33";
 
@@ -51,7 +53,7 @@ void (*i386_probe1[])(void) = {
cninit, efi_memprobe
 };
 void (*i386_probe2[])(void) = {
-   efi_diskprobe, diskprobe
+   efi_pxeprobe, efi_diskprobe, diskprobe
 };
 
 struct i386_boot_probes probe_list[] = {
@@ -62,6 +64,8 @@ int nibprobes = nitems(probe_list);
 
 
 struct fs_ops file_system[] = {
+   { tftp_open,   tftp_close,   tftp_read,   tftp_write,   tftp_seek,
+ tftp_stat,   tftp_readdir   },
{ ufs_open,ufs_close,ufs_read,ufs_write,ufs_seek,
  ufs_stat,ufs_readdir},
{ cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
@@ -76,10 +80,8 @@ struct fs_ops file_system[] = {
 int nfsys = nitems(file_system);
 
 struct devsw   devsw[] = {
-   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
-#if 0
{ "TFTP", tftpstrategy, tftpopen, tftpclose, tftpioctl },
-#endif
+   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
 };
 int ndevs = nitems(devsw);
 
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c 
b/sys/arch/amd64/stand/efiboot/efiboot.c
index 9b6d5fc00fd..d753ffbf919 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -52,9 +52,8 @@ static EFI_GUIDblkio_guid = BLOCK_IO_PROTOCOL;
 static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
 u_long  efi_loadaddr;
 
-static int  efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
-static int  efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *,
-   int);
+int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
+int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
 static void efi_heap_init(void);
 static void efi_memprobe_internal(void);
 static void efi_video_init(void);
@@ -96,6 +95,11 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
bios_bootdev = 0x80;
efi_bootdp = dp0;
break;
+   } else if (DevicePathType(dp) == MESSAGING_DEVICE_PATH&&
+   DevicePathSubType(dp) == MSG_MAC_ADDR_DP) {
+   bios_bootdev = 0x0;
+   efi_bootdp = dp0;
+   break;
}
}
}
@@ -215,7 +219,7 @@ next:
free(handles, sz);
 }
 
-static int
+int
 efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype)
 {
int i;
@@ -228,7 +232,7 @@ efi_device_path_depth(EFI_DEVICE_PATH *dp, int dptype)
return (-1);
 }
 
-static int
+int
 efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn)
 {
int  i, cmp;
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.h 
b/sys/arch/amd64/stand/efiboot/efiboot.h
index 8a07d5b46b3..ac50556748c 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.h
+++ b/sys/arch/amd64/stand/efiboot/efiboot.h
@@ -21,6 +21,7 @@ void   efi_cons_probe(struct consdev *);
 voidefi_memprobe(void);
 voidefi_hardprobe(void);
 voidefi_diskprobe(void);
+voidefi_pxeprobe(void);
 voidefi_cons_init(struct consdev *);
 int   

Re: amd64: EFI boot over network try to load kernel from hd0

2017-06-08 Thread YASUOKA Masahiko
Hi,

Tested the diff.  It works fine.

On Wed, 7 Jun 2017 20:23:43 +0200
Patrick Wildt  wrote:
> Do you want it to run diskless with root on NFS?  Well, I haven't
> implemented that, but here's a diff that should allow you to load
> the kernel from a TFTP server.
> 
> I have a similar diff on arm64 (which probably doesn't work with
> u-boot's EFI API, but works on EDK2 machines) which I use for testing
> kernels more easily.
> 
> I'm not sure how helpful this feature is for most people.  It's probably
> nice for developers who want to boot different kernels over network, but
> so far it does not support root on NFS, or only accidentally.

What the diff is missing is passing the mac address of booted NIC as
"bootmac" parameter?

--yasuoka



Re: amd64: EFI boot over network try to load kernel from hd0

2017-06-07 Thread Patrick Wildt
On Wed, Jun 07, 2017 at 03:58:01PM +0200, Sven-Volker Nowarra wrote:
> Hi,
> 
> I setup a PXE boot server, to load my different clients. Now I have 2 single 
> EFI devices, which do not support PXE (both are Macminis). They prefer "EFI" 
> files. Both are capable running 64bit software, but require 32bit EFI 
> loaders. So I added a line in my dhcpd.conf to supply “BOOTIA32.EFI” file.  
> It get’s loaded via tftp, and displays on the clients console the well known 
> bsd prompt for booting: 
> 
>probing: pc0 mem 1576K 64K 2015M 11M 64K 52KI
>disk: hd0* hd1*
>>> OpenBSD/amd64 BOOTIA32 3.30
>open(hd0a:/etc/boot.conf): invalid argument
>boot> _
> 
> Here the client stops, for sure there is no harddrive. Somehow the efiboot 
> file does not provide the option to load the kernel via network, only hd0 or 
> hd1 is offered. I looked up the files in 
> /sys/arch/amd64/stand/efiboot/efiboot.c and the header files, but couldn't 
> find the references to IPv4 (or IPv6) booting, though the header files in 
> /usr/src/sys/stand/efi/include contain the structures for IPv4_DEVICE_PATH. 
> Can someone point me into the right direction?  
> 
> ---
> 
> On dhcp server: Macs boot differently over the net with dhcp and bootp. I use 
> a class definition, and inside s.th . like this:
> 
> class "AppleNBI-i386" {
> match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
> option dhcp-parameter-request-list 1,3,17,43,60;
> if (option dhcp-message-type = 1)
>{
>option vendor-class-identifier "AAPLBSDPC/i386";
>}
> if (option dhcp-message-type = 1)
>{
>option vendor-encapsulated-options 08:04:81:00:00:67;
>}
> if (substring (option vendor-class-identifier, 15, 10) = "Macmini1,1")
>{
>log(info, concat("DHCPd: Macmini1,1: vendor-class-identifier = ", option 
> vendor-class-identifier));
>filename "amd64/BOOTIA32.EFI";
>}
> ...
> 
> So I didn't need to setup dhcp with "option arch code 93", as described here:
> http://marc.info/?l=openbsd-tech=148517258726719=2
> 

Do you want it to run diskless with root on NFS?  Well, I haven't
implemented that, but here's a diff that should allow you to load
the kernel from a TFTP server.

I have a similar diff on arm64 (which probably doesn't work with
u-boot's EFI API, but works on EDK2 machines) which I use for testing
kernels more easily.

I'm not sure how helpful this feature is for most people.  It's probably
nice for developers who want to boot different kernels over network, but
so far it does not support root on NFS, or only accidentally.

Patrick

diff --git a/sys/arch/amd64/stand/efiboot/Makefile.common 
b/sys/arch/amd64/stand/efiboot/Makefile.common
index d821e0bc39a..7742e201683 100644
--- a/sys/arch/amd64/stand/efiboot/Makefile.common
+++ b/sys/arch/amd64/stand/efiboot/Makefile.common
@@ -24,7 +24,7 @@ AFLAGS+=  -pipe -fPIC
 
 .PATH: ${.CURDIR}/..
 SRCS+= self_reloc.c
-SRCS+= efiboot.c efidev.c
+SRCS+= efiboot.c efidev.c efipxe.c
 SRCS+= conf.c
 
 .PATH: ${S}/stand/boot
diff --git a/sys/arch/amd64/stand/efiboot/conf.c 
b/sys/arch/amd64/stand/efiboot/conf.c
index 3b2059e414f..55ab425fab2 100644
--- a/sys/arch/amd64/stand/efiboot/conf.c
+++ b/sys/arch/amd64/stand/efiboot/conf.c
@@ -31,12 +31,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
 #include "disk.h"
 #include "efiboot.h"
 #include "efidev.h"
+#include "efipxe.h"
 
 const char version[] = "3.33";
 
@@ -51,7 +53,7 @@ void (*i386_probe1[])(void) = {
cninit, efi_memprobe
 };
 void (*i386_probe2[])(void) = {
-   efi_diskprobe, diskprobe
+   efi_pxeprobe, efi_diskprobe, diskprobe
 };
 
 struct i386_boot_probes probe_list[] = {
@@ -62,6 +64,8 @@ int nibprobes = nitems(probe_list);
 
 
 struct fs_ops file_system[] = {
+   { tftp_open,   tftp_close,   tftp_read,   tftp_write,   tftp_seek,
+ tftp_stat,   tftp_readdir   },
{ ufs_open,ufs_close,ufs_read,ufs_write,ufs_seek,
  ufs_stat,ufs_readdir},
{ cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
@@ -76,10 +80,8 @@ struct fs_ops file_system[] = {
 int nfsys = nitems(file_system);
 
 struct devsw   devsw[] = {
-   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
-#if 0
{ "TFTP", tftpstrategy, tftpopen, tftpclose, tftpioctl },
-#endif
+   { "EFI", efistrategy, efiopen, eficlose, efiioctl },
 };
 int ndevs = nitems(devsw);
 
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c 
b/sys/arch/amd64/stand/efiboot/efiboot.c
index 9b6d5fc00fd..d753ffbf919 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -52,9 +52,8 @@ static EFI_GUIDblkio_guid = BLOCK_IO_PROTOCOL;
 static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
 u_long  efi_loadaddr;
 
-static int  efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
-static int  efi_device_path_ncmp(EFI_DEVICE_PATH *, 

Re: amd64: EFI boot over network try to load kernel from hd0

2017-06-07 Thread Ted Unangst
Sven-Volker Nowarra wrote:
> Here the client stops, for sure there is no harddrive. Somehow the efiboot 
> file does not provide the option to load the kernel via network, only hd0 or 
> hd1 is offered. I looked up the files in 
> /sys/arch/amd64/stand/efiboot/efiboot.c and the header files, but couldn't 
> find the references to IPv4 (or IPv6) booting, though the header files in 
> /usr/src/sys/stand/efi/include contain the structures for IPv4_DEVICE_PATH. 

Indeed, as you noticed, the EFI bootloader doesn't have network support.



amd64: EFI boot over network try to load kernel from hd0

2017-06-07 Thread Sven-Volker Nowarra
Hi,

I setup a PXE boot server, to load my different clients. Now I have 2 single 
EFI devices, which do not support PXE (both are Macminis). They prefer "EFI" 
files. Both are capable running 64bit software, but require 32bit EFI loaders. 
So I added a line in my dhcpd.conf to supply “BOOTIA32.EFI” file.  It get’s 
loaded via tftp, and displays on the clients console the well known bsd prompt 
for booting: 

   probing: pc0 mem 1576K 64K 2015M 11M 64K 52KI
   disk: hd0* hd1*
   >> OpenBSD/amd64 BOOTIA32 3.30
   open(hd0a:/etc/boot.conf): invalid argument
   boot> _

Here the client stops, for sure there is no harddrive. Somehow the efiboot file 
does not provide the option to load the kernel via network, only hd0 or hd1 is 
offered. I looked up the files in /sys/arch/amd64/stand/efiboot/efiboot.c and 
the header files, but couldn't find the references to IPv4 (or IPv6) booting, 
though the header files in /usr/src/sys/stand/efi/include contain the 
structures for IPv4_DEVICE_PATH. 
Can someone point me into the right direction?  

---

On dhcp server: Macs boot differently over the net with dhcp and bootp. I use a 
class definition, and inside s.th . like this:

class "AppleNBI-i386" {
match if substring (option vendor-class-identifier, 0, 14) = "AAPLBSDPC/i386";
option dhcp-parameter-request-list 1,3,17,43,60;
if (option dhcp-message-type = 1)
   {
   option vendor-class-identifier "AAPLBSDPC/i386";
   }
if (option dhcp-message-type = 1)
   {
   option vendor-encapsulated-options 08:04:81:00:00:67;
   }
if (substring (option vendor-class-identifier, 15, 10) = "Macmini1,1")
   {
   log(info, concat("DHCPd: Macmini1,1: vendor-class-identifier = ", option 
vendor-class-identifier));
   filename "amd64/BOOTIA32.EFI";
   }
...

So I didn't need to setup dhcp with "option arch code 93", as described here:
http://marc.info/?l=openbsd-tech=148517258726719=2