Module Name:    src
Committed By:   martin
Date:           Sat May 13 13:26:57 UTC 2023

Modified Files:
        src/share/man/man4 [netbsd-10]: options.4
        src/share/man/man8/man8.x86 [netbsd-10]: boot.8 dosboot.8 pxeboot.8
        src/sys/arch/amd64/amd64 [netbsd-10]: locore.S
        src/sys/arch/amd64/conf [netbsd-10]: files.amd64 std.amd64
        src/sys/arch/i386/stand/efiboot [netbsd-10]: boot.c efiboot.c efiboot.h
            version
        src/sys/arch/i386/stand/efiboot/bootia32 [netbsd-10]: efibootia32.c
            startprog32.S
        src/sys/arch/i386/stand/efiboot/bootx64 [netbsd-10]: efibootx64.c
            startprog64.S
        src/sys/arch/i386/stand/lib [netbsd-10]: exec.c

Log Message:
Pull up following revision(s) (requested by manu in ticket #159):

        share/man/man8/man8.x86/boot.8: revision 1.27
        sys/arch/i386/stand/efiboot/version: revision 1.3
        share/man/man8/man8.x86/boot.8: revision 1.28
        share/man/man8/man8.x86/boot.8: revision 1.29
        sys/arch/i386/stand/lib/exec.c: revision 1.79
        sys/arch/i386/stand/efiboot/efiboot.c: revision 1.13
        sys/arch/i386/stand/efiboot/bootx64/efibootx64.c: revision 1.6
        sys/arch/i386/stand/efiboot/bootia32/efibootia32.c: revision 1.6
        sys/arch/i386/stand/efiboot/boot.c: revision 1.22
        sys/arch/amd64/amd64/locore.S: revision 1.219
        sys/arch/i386/stand/efiboot/bootia32/startprog32.S: revision 1.3
        sys/arch/i386/stand/efiboot/efiboot.h: revision 1.12
        sys/arch/amd64/conf/files.amd64: revision 1.121
        sys/arch/amd64/conf/std.amd64: revision 1.13
        share/man/man8/man8.x86/pxeboot.8: revision 1.6
        sys/arch/i386/stand/efiboot/bootx64/startprog64.S: revision 1.4
        sys/arch/amd64/amd64/locore.S: revision 1.220
        share/man/man8/man8.x86/dosboot.8: revision 1.4
        share/man/man4/options.4: revision 1.524

Add reloc keyworkd to let EFI bootstrap load amd64 kernel at any address

EFI bootstrap assumes it can copy the amd64 kernel to its ELF load
address (that is KERNTEXTOFF - KERNBASE = 0x200000), but it can
clash with previous UEFI memory allocation, as described here:
http://mail-index.netbsd.org/tech-kern/2023/04/07/msg028833.html

This change adds a reloc keyword for controling where the EFI
boostrap will copy the kernel image. Possible values are:
default - the default and prior behavior, copy at 0x200000.
none - do not copy and use the kernel image where it was loaded.
address - specify an explicit address where to copy the kernel.

This comes with an amd64 kernel patch that makes it self-relocatable.
It first discover where it was loaded in memory, and if this is
different than the expected 0x200000, hhe the kernel relocates
itself and start over at the right address.

Merge x86 boot options in x86/boot(8) and add undocumented UEFI options

We were supposed to keep the option list in x86/boot(8), x86/dosoot(8)
and x86/pxeboot(8) in sync, but it did not happen, hence it may work
better with all the options in x86/boot(8). Also add the undocumented
UEFI boot options.

Add a SELFRELOC kernel option for the sake of documentation clarity.
Instead of telling that x86/boot(8) reloc command needs a kernel able
to self relocate, we can tell it needs a kernel built with the
SELFRELOC option. This keeps the reader from wondering what could
make a kernel able to self relocate.

Remove XXX todo marker left by mistake

Raise the version for new feature (here reloc command)
Suggested by Masanobu SAITOH


To generate a diff of this commit:
cvs rdiff -u -r1.523 -r1.523.2.1 src/share/man/man4/options.4
cvs rdiff -u -r1.26 -r1.26.2.1 src/share/man/man8/man8.x86/boot.8
cvs rdiff -u -r1.3 -r1.3.22.1 src/share/man/man8/man8.x86/dosboot.8
cvs rdiff -u -r1.5 -r1.5.6.1 src/share/man/man8/man8.x86/pxeboot.8
cvs rdiff -u -r1.214 -r1.214.4.1 src/sys/arch/amd64/amd64/locore.S
cvs rdiff -u -r1.120 -r1.120.20.1 src/sys/arch/amd64/conf/files.amd64
cvs rdiff -u -r1.12 -r1.12.20.1 src/sys/arch/amd64/conf/std.amd64
cvs rdiff -u -r1.21 -r1.21.4.1 src/sys/arch/i386/stand/efiboot/boot.c
cvs rdiff -u -r1.12 -r1.12.24.1 src/sys/arch/i386/stand/efiboot/efiboot.c
cvs rdiff -u -r1.11 -r1.11.4.1 src/sys/arch/i386/stand/efiboot/efiboot.h
cvs rdiff -u -r1.2 -r1.2.26.1 src/sys/arch/i386/stand/efiboot/version
cvs rdiff -u -r1.5 -r1.5.26.1 \
    src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c
cvs rdiff -u -r1.2 -r1.2.52.1 \
    src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S
cvs rdiff -u -r1.5 -r1.5.26.1 \
    src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c
cvs rdiff -u -r1.3 -r1.3.50.1 \
    src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S
cvs rdiff -u -r1.78 -r1.78.4.1 src/sys/arch/i386/stand/lib/exec.c

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/man4/options.4
diff -u src/share/man/man4/options.4:1.523 src/share/man/man4/options.4:1.523.2.1
--- src/share/man/man4/options.4:1.523	Sun Aug 28 14:29:05 2022
+++ src/share/man/man4/options.4	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: options.4,v 1.523 2022/08/28 14:29:05 riastradh Exp $
+.\"	$NetBSD: options.4,v 1.523.2.1 2023/05/13 13:26:57 martin Exp $
 .\"
 .\" Copyright (c) 1996
 .\" 	Perry E. Metzger.  All rights reserved.
@@ -1307,6 +1307,14 @@ See
 and
 .Xr vnconfig 8
 for more information.
+.It Cd options SELFRELOC
+Make the kernel able to self relocate at bootstrap, so that it can
+run whatever its load address is. 
+This is intented to be used withe the 
+.Ic reloc
+boostrap command documented in
+.Xr x86/boot 8 ,
+to workaround UEFI bugs, and is only available on amd64.
 .It Cd options SPLDEBUG
 Help the kernel programmer find bugs related to the interrupt priority
 level.

Index: src/share/man/man8/man8.x86/boot.8
diff -u src/share/man/man8/man8.x86/boot.8:1.26 src/share/man/man8/man8.x86/boot.8:1.26.2.1
--- src/share/man/man8/man8.x86/boot.8:1.26	Tue Jun 22 03:39:21 2021
+++ src/share/man/man8/man8.x86/boot.8	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: boot.8,v 1.26 2021/06/22 03:39:21 gutteridge Exp $
+.\"	$NetBSD: boot.8,v 1.26.2.1 2023/05/13 13:26:56 martin Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -364,6 +364,8 @@ flag in
 Boot the system in silent mode.
 .El
 .It Ic consdev Ar dev\| Ns Oo Ns Ic \&, Ns Ar speed Oc
+[Not available for 
+.Xr x86/dosboot 8 ]
 Immediately switch the console to the specified device
 .Ar dev
 and reprint the banner.
@@ -397,16 +399,26 @@ Without an argument, print the current s
 .Ar device
 is of the form specified in
 .Ic boot .
+.It Ic devpath
+[Only available for UEFI boot] Dump UEFI device paths.
+.It Ic efivar
+[Only available for UEFI boot] Dump UEFI environment variables from NVRAM.
 .It Ic fs Ar file
+[Only available for BIOS and UEFI boot]
 Load a file system image from the specified
 .Ar file ,
 and request the kernel to use it as the root file system.
 The
 .Xr makefs 8
 utility may be used to create suitable file system images.
+.It Ic gop Op Va mode_index
+[Only available for UEFI boot] Without argument, list the available
+video modes. If an argument is given, select a video mode.
 .It Ic help
 Print an overview about commands and arguments.
 .It Ic load Ar module Op Ar arguments
+[Not available for 
+.Xr x86/dosboot 8 ]
 Load the specified kernel
 .Ar module ,
 and pass it the specified
@@ -520,12 +532,17 @@ See
 .Xr pciback 4 .
 .El
 .It Ic ls Op Ar path
+[Not available for
+.Xr x86/pxeboot 8 ]
 Print a directory listing of
 .Ar path ,
 containing inode number, filename, and file type.
 .Ar path
 can contain a device specification.
+.It Ic memmap
+[Only available for UEFI boot] Dump UEFI memory map.
 .It Ic menu
+[Only available for BIOS and UEFI boot]
 Display the boot menu and initiate a countdown,
 similarly to what would have happened if interactive mode
 had not been entered.
@@ -534,6 +551,8 @@ had not been entered.
            No \(or Li enabled \
            No \(or Li disabled\^ \
            Brc
+[Not available for
+.Xr x86/dosboot 8 ]
 The values
 .Ql enabled ,
 .Ql on
@@ -545,7 +564,18 @@ whereas
 .Ql disabled ,
 .Ql off
 will turn off the feature.
+.It Ic mode Va fstype
+[Only available for
+.Xr x86/dosboot 8 ]
+Switch file system type;
+.Va fstype
+should be one of
+.Ar dos
+or
+.Ar ufs .
 .It Ic multiboot Ar kernel Op Ar arguments
+[Not available for
+.Xr x86/dosboot 8 ]
 Boot the specified
 .Ar kernel ,
 using the
@@ -615,12 +645,32 @@ command.
 See the foreign operating system's documentation for the available
 .Ar arguments .
 .El
+.It Ic pkboot
+[Only available for BIOS and UEFI boot] Boot a kernel that has
+the
+.Cd KASLR
+option set, for Kernel Address Space Layout Randomizaton.
 .It Ic quit
 Reboot the system.
-.It Ic root Ar spec
-Pass an explicit root specification to the kernel.
-See BTINFO_ROOTDEVICE for details.
+.It Ic reloc Op Va default No \(or Va none No \(or Va address
+[Only UEFI boot] Sets where the kernel is copied by bootstrap
+before it is started. Values other than default require a kernel
+built with the
+.Cd SELFRELOC
+option, so that can relocate itself at the right address,
+otherwise a crash occurs at boot time.
+.Bl -tag -width default
+.It Va default
+Copy the kernel at ELF header load address, this is the historical
+behavior.
+.It Va none
+Leave the kernel where it was loaded and start it as is. 
+.It Va address
+Copy the kernel at given
+.Va address .
+.El
 .It Ic rndseed Ar file
+[Only available for BIOS and UEFI boot]
 Load the specified
 .Ar file
 and request the kernel to use it as a seed for the
@@ -646,16 +696,12 @@ Using the same seed file on more then on
 or for more than one boot on the same host,
 will reduce the quality of random numbers
 and may impact system security.
-.It Ic userconf Ar command
-Pass command
-.Ar command
-to
-.Xr userconf 4
-at boot time.
-These commands are processed before the interactive
-.Xr userconf 4
-shell is executed, if requested.
+.It Ic root Ar spec
+[Only available for BIOS and UEFI boot]
+Pass an explicit root specification to the kernel.
+See BTINFO_ROOTDEVICE for details.
 .It Ic splash Ar file
+[Only available for BIOS and UEFI boot]
 Load a graphical image from the specified
 .Ar file
 and request the kernel to use it as a splash screen.
@@ -670,12 +716,38 @@ GIF,
 PSD (composited view only),
 or
 PIC.
+.It Ic text Op Va mode_index
+[Only available UEFI boot] Without argument, list the available
+text modes (displayed as column x line in hexadecimal, therefore
+.Li 50x19 
+means 
+.Li 80
+columns and
+.Li 25
+lines). With an argument, select a text mode.
+.It Ic userconf Ar command
+[Not available for
+.Xr x86/dosboot 8 ]
+Pass command
+.Ar command
+to
+.Xr userconf 4
+at boot time.
+These commands are processed before the interactive
+.Xr userconf 4
+shell is executed, if requested.
+.It Ic version Op Ar full
+[Only available UEFI boot] Display UEFI bootstrap version. With the
+.Op full
+argumznt, also display information about UEFI itself.
 .It Ic vesa Bro Ar \^modenum \
         No \(or Li on \
         No \(or Li off \
         No \(or Li enabled \
         No \(or Li disabled \
         No \(or Li list Brc
+[Only available for BIOS and
+.Xr x86/pxeboot 8 ]
 Initialise the video card to the specified resolution and bit depth.
 The
 .Ar modenum

Index: src/share/man/man8/man8.x86/dosboot.8
diff -u src/share/man/man8/man8.x86/dosboot.8:1.3 src/share/man/man8/man8.x86/dosboot.8:1.3.22.1
--- src/share/man/man8/man8.x86/dosboot.8:1.3	Fri Feb 17 22:30:28 2017
+++ src/share/man/man8/man8.x86/dosboot.8	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: dosboot.8,v 1.3 2017/02/17 22:30:28 christos Exp $
+.\"	$NetBSD: dosboot.8,v 1.3.22.1 2023/05/13 13:26:56 martin Exp $
 .\"
 .\" Copyright (c) 1997
 .\" 	Matthias Drochner.  All rights reserved.
@@ -95,54 +95,16 @@ by prepending a block device name in ter
 followed by a colon (see
 .Xr x86/boot 8
 and examples).
-.It Fl adqsv
+.It Fl 1234abcdmqsvxz
 Flags passed to the kernel, see
 .Xr x86/boot 8 .
 .El
 .Pp
-The commands accepted after the
-.Fl c
-flag or in interactive mode are:
-.\" NOTE: some of this text is duplicated in the MI boot.8
-.\" and in other x86-specific *boot.8 files;
-.\" please try to keep all relevant files synchronized.
-.Bl -tag -width 04n -offset 04n
-.It Ic boot Oo Va device : Oc Ns Oo Va filename Oc Oo Fl 1234abcdmqsvxz Oc
-Boot
-.Nx .
 See
-.Cm boot
-in
 .Xr x86/boot 8
-for full details.
-.It Ic dev Op device
-Set the default device and partition for subsequent file system operations.
-Without an operand, print the current setting.
-This setting doesn't apply to
-.Tn MS-DOS
-mode.
-.It Ic help
-Print an overview about commands and arguments.
-.It Ic ls Op Pa path
-Print a directory listing of
-.Pa path ,
-containing inode number, filename and file type.
-This command works in UFS mode only.
-.Pa path
-can contain a device specification.
-.It Ic mode Va fstype
-Switch file system type;
-.Va fstype
-should be one of
-.Ar dos
-or
-.Ar ufs .
-.It Ic quit
-Leave the
-.Nm
-program and exit to
-.Tn MS-DOS .
-.El
+for commands accepted after the
+.Fl c
+flag or in interactive mode.
 .Pp
 .Nm
 is also installed in the

Index: src/share/man/man8/man8.x86/pxeboot.8
diff -u src/share/man/man8/man8.x86/pxeboot.8:1.5 src/share/man/man8/man8.x86/pxeboot.8:1.5.6.1
--- src/share/man/man8/man8.x86/pxeboot.8:1.5	Sat Aug 29 13:32:27 2020
+++ src/share/man/man8/man8.x86/pxeboot.8	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pxeboot.8,v 1.5 2020/08/29 13:32:27 fcambus Exp $
+.\"	$NetBSD: pxeboot.8,v 1.5.6.1 2023/05/13 13:26:56 martin Exp $
 .\"
 .\" Copyright (c) 2003
 .\" 	Matthias Drochner.  All rights reserved.
@@ -220,26 +220,9 @@ case to access the kernel file, matching
 kernel's behaviour.
 .El
 .Pp
-The commands accepted in interactive mode are:
-.\" NOTE: some of this text is duplicated in the MI boot.8
-.\" and in other x86-specific *boot.8 files;
-.\" please try to keep all relevant files synchronized.
-.Bl -tag -width 04n -offset 04n
-.It Ic boot Oo Va device : Oc Ns Oo Va filename Oc Oo Fl 1234abcdmqsvxz Oc
-Boot
-.Nx .
 See
-.Cm boot
-in
 .Xr x86/boot 8
-for full details.
-.It Ic help
-Print an overview about commands and arguments.
-.It Ic quit
-Leave the
-.Nm
-program.
-.El
+for the commands accepted in interactive mode.
 .Pp
 By default the output from
 .Nm

Index: src/sys/arch/amd64/amd64/locore.S
diff -u src/sys/arch/amd64/amd64/locore.S:1.214 src/sys/arch/amd64/amd64/locore.S:1.214.4.1
--- src/sys/arch/amd64/amd64/locore.S:1.214	Wed Sep  7 00:40:18 2022
+++ src/sys/arch/amd64/amd64/locore.S	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.214 2022/09/07 00:40:18 knakahara Exp $	*/
+/*	$NetBSD: locore.S,v 1.214.4.1 2023/05/13 13:26:57 martin Exp $	*/
 
 /*
  * Copyright-o-rama!
@@ -156,6 +156,7 @@
 #include "opt_ddbparam.h"
 #include "opt_modular.h"
 #include "opt_realmem.h"
+#include "opt_selfreloc.h"
 
 #include "opt_compat_netbsd.h"
 #include "opt_compat_netbsd32.h"
@@ -456,6 +457,16 @@ ENTRY(start)
 #ifndef XENPV
 	.code32
 
+#ifdef SELFRELOC
+	call	next
+next:	pop	%edi
+	sub     $(next - kernel_text), %edi 
+
+	/* If not KERNBASE, reloc ourselves to KERNBASE */
+	cmpl	$(KERNTEXTOFF_LO - KERNBASE_LO), %edi
+	jne	selfreloc_start
+#endif /* SELFRELOC */
+
 	/* Warm boot */
 	movw	$0x1234,0x472
 
@@ -1733,3 +1744,140 @@ LABEL(mds_leave_end)
 LABEL(nomds_leave)
 	NOMDS_LEAVE
 LABEL(nomds_leave_end)
+
+#ifdef SELFRELOC
+/*
+ * selfreloc(loadddr edi)
+ * This is adapted from sys/arch/i386/i386/locore.S
+ */
+	.code32
+ENTRY(selfreloc_start)
+	movl	%edi, %ebx		/* loadaddr saved in ebx */
+	movl	%edi, %esi				/* src */
+	movl	$_RELOC(kernel_text), %edi		/* dest */
+	movl	16(%esp),%ecx				/* esym */
+	subl	$_RELOC(kernel_text), %ecx		/* size */
+
+#if defined(NO_OVERLAP)
+        movl    %ecx, %eax
+#else 
+        movl    %edi, %eax
+        subl    %esi, %eax
+        cmpl    %ecx, %eax      /* overlapping? */
+        movl    %ecx, %eax
+        jb      .Lbackwards
+#endif
+        /* nope, copy forwards. */
+        shrl    $2, %ecx        /* copy by words */
+        rep
+        movsl
+        and     $3, %eax        /* any bytes left? */
+        jnz     .Ltrailing
+        jmp     .Lcopy_done
+
+.Ltrailing:
+        cmp     $2, %eax
+        jb      11f
+        movw    (%esi), %ax
+        movw    %ax, (%edi)
+        je      .Lcopy_done
+        movb    2(%esi), %al
+        movb    %al, 2(%edi)
+        jmp     .Lcopy_done
+11:     movb    (%esi), %al
+        movb    %al, (%edi)
+        jmp     .Lcopy_done
+
+#if !defined(NO_OVERLAP)
+.Lbackwards:
+        addl    %ecx, %edi      /* copy backwards. */
+        addl    %ecx, %esi
+        and     $3, %eax        /* any fractional bytes? */
+        jnz     .Lback_align
+.Lback_aligned:
+        shrl    $2, %ecx
+        subl    $4, %esi
+        subl    $4, %edi
+        std
+        rep
+        movsl
+        cld
+        jmp     .Lcopy_done
+
+.Lback_align:
+        sub     %eax, %esi
+        sub     %eax, %edi
+        cmp     $2, %eax
+        jb      11f
+        je      12f
+        movb    2(%esi), %al
+        movb    %al, 2(%edi)
+12:     movw    (%esi), %ax
+        movw    %ax, (%edi)
+        jmp     .Lback_aligned
+11:     movb    (%esi), %al
+        movb    %al, (%edi)
+        jmp     .Lback_aligned
+#endif
+        /* End of copy kernel */
+.Lcopy_done:
+	cld			/* LynxOS depends on it */
+
+	/* load current selfreloc_start addesss in $edi */
+	movl	%ebx, %edi	/* loadaddr was saved in ebx */
+	addl	$(selfreloc_start - kernel_text), %edi
+
+	/* Prepare jump address */
+	lea	(selfreloc_start32a - selfreloc_start)(%edi), %eax
+	movl	%eax, (selfreloc_start32r - selfreloc_start)(%edi)
+
+	/* Setup GDT */
+	lea	(gdt - selfreloc_start)(%edi), %eax
+	mov	%eax, (gdtrr - selfreloc_start)(%edi)
+	lgdt	(gdtr - selfreloc_start)(%edi)
+
+	/* Jump to set %cs */
+	ljmp	*(selfreloc_start32r - selfreloc_start)(%edi)
+
+	.align	4
+selfreloc_start32a:
+	movl	$0x10, %eax	/* #define DATA_SEGMENT 0x10 */
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* Disable Paging in CR0 */
+	movl	%cr0, %eax
+	andl	$(~CR0_PG), %eax
+	movl	%eax, %cr0
+
+	/* Disable PAE in CR4 */
+	movl	%cr4, %eax
+	andl	$(~CR4_PAE), %eax
+	movl	%eax, %cr4
+
+	jmp	selfreloc_start32b
+
+	.align	4
+selfreloc_start32b:
+	xor	%eax, %eax
+	movl	$_RELOC(start), %esi
+	jmp	*%esi
+
+	.align	16
+selfreloc_start32r:
+	.long	0
+	.long	0x08	/* #define	CODE_SEGMENT	0x08 */
+	.align	16
+gdt:
+	.long	0, 0
+	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00
+	.byte	0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00
+gdtr:
+	.word	gdtr - gdt
+gdtrr:
+	.quad
+END(selfreloc_start)
+#endif /* SELFRELOC */

Index: src/sys/arch/amd64/conf/files.amd64
diff -u src/sys/arch/amd64/conf/files.amd64:1.120 src/sys/arch/amd64/conf/files.amd64:1.120.20.1
--- src/sys/arch/amd64/conf/files.amd64:1.120	Wed Oct 21 13:31:51 2020
+++ src/sys/arch/amd64/conf/files.amd64	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-#	$NetBSD: files.amd64,v 1.120 2020/10/21 13:31:51 christos Exp $
+#	$NetBSD: files.amd64,v 1.120.20.1 2023/05/13 13:26:57 martin Exp $
 #
 # new style config file for amd64 architecture
 #
@@ -20,6 +20,9 @@ defparam opt_physmem.h	PHYSMEM_MAX_ADDR 
 # Enable GCC spectre V2 mitigation options
 defflag opt_spectre.h	SPECTRE_V2_GCC_MITIGATION
 
+# Enable kernel self-relocation at bootstrap
+defflag opt_selfreloc.h SELFRELOC
+
 #
 # XXX these are just here at the moment so that we can share files
 # with the i386 (they include the opt_*.h for these)

Index: src/sys/arch/amd64/conf/std.amd64
diff -u src/sys/arch/amd64/conf/std.amd64:1.12 src/sys/arch/amd64/conf/std.amd64:1.12.20.1
--- src/sys/arch/amd64/conf/std.amd64:1.12	Sat Apr 25 15:26:16 2020
+++ src/sys/arch/amd64/conf/std.amd64	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-# $NetBSD: std.amd64,v 1.12 2020/04/25 15:26:16 bouyer Exp $
+# $NetBSD: std.amd64,v 1.12.20.1 2023/05/13 13:26:57 martin Exp $
 #
 # standard, required NetBSD/amd64 'options'
 
@@ -15,6 +15,8 @@ options 	MULTIPROCESSOR
 options 	CHILD_MAX=1024	# 160 is too few
 options 	OPEN_MAX=1024	# 128 is too few
 
+options 	SELFRELOC
+
 mainbus0 at root
 cpu* at mainbus?
 ioapic* at mainbus? apid ?

Index: src/sys/arch/i386/stand/efiboot/boot.c
diff -u src/sys/arch/i386/stand/efiboot/boot.c:1.21 src/sys/arch/i386/stand/efiboot/boot.c:1.21.4.1
--- src/sys/arch/i386/stand/efiboot/boot.c:1.21	Wed Jun  8 21:43:45 2022
+++ src/sys/arch/i386/stand/efiboot/boot.c	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.21 2022/06/08 21:43:45 wiz Exp $	*/
+/*	$NetBSD: boot.c,v 1.21.4.1 2023/05/13 13:26:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -83,6 +83,7 @@ void	command_menu(char *);
 #endif
 void	command_modules(char *);
 void	command_multiboot(char *);
+void	command_reloc(char *);
 void	command_text(char *);
 void	command_version(char *);
 
@@ -109,6 +110,7 @@ const struct bootblk_command commands[] 
 #endif
 	{ "modules",	command_modules },
 	{ "multiboot",	command_multiboot },
+	{ "reloc",	command_reloc },
 	{ "rndseed",	rnd_add },
 	{ "splash",	splash_add },
 	{ "text",	command_text },
@@ -406,6 +408,7 @@ command_help(char *arg)
 #endif
 	       "modules {on|off|enabled|disabled}\n"
 	       "multiboot [dev:][filename] [<args>]\n"
+	       "reloc {address|none|default}\n"
 	       "rndseed {path_to_rndseed_file}\n"
 	       "splash {path_to_image_file}\n"
 	       "text [{modenum|list}]\n"
@@ -641,6 +644,48 @@ command_multiboot(char *arg)
 }
 
 void
+command_reloc(char *arg)
+{
+	char *ep;
+	
+	if (*arg == '\0') {
+		switch (efi_reloc_type) {
+		case RELOC_NONE:
+			printf("reloc: none\n");
+			break;
+		case RELOC_ADDR:
+			printf("reloc: %p\n", (void *)efi_kernel_reloc);
+			break;
+		case RELOC_DEFAULT:
+		default:
+			printf("reloc: default\n");
+			break;
+		}
+		goto out;
+	}
+
+	if (strcmp(arg, "default") == 0) {
+		efi_reloc_type = RELOC_DEFAULT;
+		goto out;
+	}
+
+	if (strcmp(arg, "none") == 0) {
+		efi_reloc_type = RELOC_NONE;
+		goto out;
+	}
+
+	errno = 0;
+	efi_kernel_reloc = strtoul(arg, &ep, 0);
+	if (ep == arg || *ep != '\0' || errno)
+		printf("could not parse address \"%s\"\n", arg);
+	else
+		efi_reloc_type = RELOC_ADDR;
+out:
+	return;
+
+}
+
+void
 command_version(char *arg)
 {
 	CHAR16 *path;

Index: src/sys/arch/i386/stand/efiboot/efiboot.c
diff -u src/sys/arch/i386/stand/efiboot/efiboot.c:1.12 src/sys/arch/i386/stand/efiboot/efiboot.c:1.12.24.1
--- src/sys/arch/i386/stand/efiboot/efiboot.c:1.12	Sun Feb  9 12:13:39 2020
+++ src/sys/arch/i386/stand/efiboot/efiboot.c	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.c,v 1.12 2020/02/09 12:13:39 jmcneill Exp $	*/
+/*	$NetBSD: efiboot.c,v 1.12.24.1 2023/05/13 13:26:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -36,7 +36,9 @@ EFI_DEVICE_PATH *efi_bootdp;
 enum efi_boot_device_type efi_bootdp_type = BOOT_DEVICE_TYPE_HD;
 EFI_LOADED_IMAGE *efi_li;
 uintptr_t efi_main_sp;
-physaddr_t efi_loadaddr, efi_kernel_start;
+physaddr_t efi_loadaddr, efi_kernel_start, efi_load_start;
+physaddr_t efi_kernel_reloc = 0;
+enum efi_reloc_type efi_reloc_type = RELOC_DEFAULT;
 u_long efi_kernel_size;
 bool efi_cleanuped;
 struct btinfo_efimemmap *btinfo_efimemmap = NULL;

Index: src/sys/arch/i386/stand/efiboot/efiboot.h
diff -u src/sys/arch/i386/stand/efiboot/efiboot.h:1.11 src/sys/arch/i386/stand/efiboot/efiboot.h:1.11.4.1
--- src/sys/arch/i386/stand/efiboot/efiboot.h:1.11	Tue Sep  7 11:41:31 2021
+++ src/sys/arch/i386/stand/efiboot/efiboot.h	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efiboot.h,v 1.11 2021/09/07 11:41:31 nia Exp $	*/
+/*	$NetBSD: efiboot.h,v 1.11.4.1 2023/05/13 13:26:56 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -52,7 +52,13 @@ extern enum efi_boot_device_type {
 } efi_bootdp_type;
 extern EFI_LOADED_IMAGE *efi_li;
 extern uintptr_t efi_main_sp;
-extern physaddr_t efi_loadaddr, efi_kernel_start;
+extern physaddr_t efi_loadaddr, efi_kernel_start, efi_load_start;
+extern physaddr_t efi_kernel_reloc;
+extern enum efi_reloc_type {
+	RELOC_DEFAULT,
+	RELOC_NONE,
+	RELOC_ADDR,
+} efi_reloc_type;
 extern u_long efi_kernel_size;
 extern bool efi_cleanuped;
 void efi_cleanup(void);

Index: src/sys/arch/i386/stand/efiboot/version
diff -u src/sys/arch/i386/stand/efiboot/version:1.2 src/sys/arch/i386/stand/efiboot/version:1.2.26.1
--- src/sys/arch/i386/stand/efiboot/version:1.2	Sat Aug  3 08:13:36 2019
+++ src/sys/arch/i386/stand/efiboot/version	Sat May 13 13:26:56 2023
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.2 2019/08/03 08:13:36 nonaka Exp $
+$NetBSD: version,v 1.2.26.1 2023/05/13 13:26:56 martin Exp $
 
 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
@@ -6,3 +6,4 @@ is taken as the current.
 
 1.0:	Initial version.
 1.1:	Add CD/DVD-ROM, serial, PXE boot and UEFI memory map compaction support.
+1.2:	Add reloc command

Index: src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c
diff -u src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.5 src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.5.26.1
--- src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c:1.5	Fri Sep 13 02:19:45 2019
+++ src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efibootia32.c,v 1.5 2019/09/13 02:19:45 manu Exp $	*/
+/*	$NetBSD: efibootia32.c,v 1.5.26.1 2023/05/13 13:26:57 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -76,7 +76,7 @@ startprog(physaddr_t entry, uint32_t arg
 
 	(*startprog32)(entry, argc, argv,
 	    (physaddr_t)startprog32 + startprog32_size,
-	    efi_kernel_start, efi_kernel_start + efi_loadaddr,
+	    efi_kernel_start, efi_load_start,
 	    efi_kernel_size, startprog32);
 }
 

Index: src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S
diff -u src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S:1.2 src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S:1.2.52.1
--- src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S:1.2	Fri Feb 24 12:24:25 2017
+++ src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: startprog32.S,v 1.2 2017/02/24 12:24:25 nonaka Exp $	*/
+/*	$NetBSD: startprog32.S,v 1.2.52.1 2023/05/13 13:26:57 martin Exp $	*/
 /*	NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp	*/
 
 /*
@@ -117,6 +117,11 @@ start:
 	movl	24(%ebp), %edi	/* dest */
 	movl	28(%ebp), %esi	/* src */
 	movl	32(%ebp), %ecx	/* size */
+
+	/* skip copy if same source and destination */
+	cmpl    %edi,%esi
+	jz      .Lcopy_done
+
 #if defined(NO_OVERLAP)
 	movl	%ecx, %eax
 #else

Index: src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c
diff -u src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c:1.5 src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c:1.5.26.1
--- src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c:1.5	Fri Sep 13 02:19:46 2019
+++ src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efibootx64.c,v 1.5 2019/09/13 02:19:46 manu Exp $	*/
+/*	$NetBSD: efibootx64.c,v 1.5.26.1 2023/05/13 13:26:57 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <non...@netbsd.org>
@@ -80,7 +80,7 @@ startprog(physaddr_t entry, uint32_t arg
 		memcpy(newsp, argv, sizeof(*argv) * argc);
 	}
 
-	(*startprog64)(efi_kernel_start, efi_kernel_start + efi_loadaddr,
+	(*startprog64)(efi_kernel_start, efi_load_start,
 	    (physaddr_t)newsp, efi_kernel_size, startprog64, entry);
 }
 

Index: src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S
diff -u src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S:1.3 src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S:1.3.50.1
--- src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S:1.3	Sat Feb 11 10:23:39 2017
+++ src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: startprog64.S,v 1.3 2017/02/11 10:23:39 nonaka Exp $	*/
+/*	$NetBSD: startprog64.S,v 1.3.50.1 2023/05/13 13:26:57 martin Exp $	*/
 /*	NetBSD: startprog.S,v 1.3 2003/02/01 14:48:18 dsl Exp	*/
 
 /* starts program in protected mode / flat space
@@ -97,6 +97,10 @@ start:
 
 	cli
 
+	/* skip copy if same source and destination */
+	cmpq	%rdi,%rsi
+	jz	.Lcopy_done
+
 	/* Copy kernel */
 	mov	%rcx, %r12		/* original kernel size */
 	movq	%rdi, %r11		/* for misaligned check */

Index: src/sys/arch/i386/stand/lib/exec.c
diff -u src/sys/arch/i386/stand/lib/exec.c:1.78 src/sys/arch/i386/stand/lib/exec.c:1.78.4.1
--- src/sys/arch/i386/stand/lib/exec.c:1.78	Wed Sep 21 14:29:45 2022
+++ src/sys/arch/i386/stand/lib/exec.c	Sat May 13 13:26:57 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.c,v 1.78 2022/09/21 14:29:45 riastradh Exp $	 */
+/*	$NetBSD: exec.c,v 1.78.4.1 2023/05/13 13:26:57 martin Exp $	 */
 
 /*
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -465,6 +465,7 @@ exec_netbsd(const char *file, physaddr_t
 	struct btinfo_symtab btinfo_symtab;
 	u_long extmem;
 	u_long basemem;
+	u_long entry;
 	int error;
 #ifdef EFIBOOT
 	int i;
@@ -497,6 +498,8 @@ exec_netbsd(const char *file, physaddr_t
 		goto out;
 	}
 #ifdef EFIBOOT
+	efi_load_start = marks[MARK_START];
+
 	/* adjust to the real load address */
 	marks[MARK_START] -= efi_loadaddr;
 	marks[MARK_ENTRY] -= efi_loadaddr;
@@ -552,6 +555,8 @@ exec_netbsd(const char *file, physaddr_t
 
 	if (callback != NULL)
 		(*callback)();
+
+	entry = marks[MARK_ENTRY];
 #ifdef EFIBOOT
 	/* Copy bootinfo to safe arena. */
 	for (i = 0; i < bootinfo->nentries; i++) {
@@ -563,8 +568,22 @@ exec_netbsd(const char *file, physaddr_t
 
 	efi_kernel_start = marks[MARK_START];
 	efi_kernel_size = image_end - (efi_loadaddr + efi_kernel_start);
+
+	switch (efi_reloc_type) {
+	case RELOC_NONE:
+		entry += (efi_load_start - efi_kernel_start);
+		efi_kernel_start = efi_load_start;
+		break;
+	case RELOC_ADDR:
+		entry += (efi_kernel_reloc - efi_kernel_start);
+		efi_kernel_start = efi_kernel_reloc;
+		break;
+	case RELOC_DEFAULT:
+	default:
+		break;
+	}
 #endif
-	startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
+	startprog(entry, BOOT_NARGS, boot_argv,
 	    x86_trunc_page(basemem * 1024));
 	panic("exec returned");
 

Reply via email to