Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Make kernel self-relocatable [PATCH]



On Tue, Apr 11, 2023 at 08:32:58AM +0000, Emmanuel Dreyfus wrote:
> It would be nice if that limitation was removed. bootx64.efi could load 
> the kernel where room is available, then kernel start routine would
> detect the undesisrable load address, and would perform self-relocation. 

Attached are an updated kernel patch, that copies the symbols. The previous
version missed them.

I also include the patch for bootx64.efi. It adds a bootstrap command:
reloc {default|none|addr}

default means the current behavior: bootx64.efi loads the kernel, then
copies it to the address taken from ELF header, that is 0x200000.

none means load the kernel and launch it as is without a copy to the
right address. The associated kernel patch will take care of copying
the kernel at the right place (0x200000) and start over.

addr is a specified address where bootx64.efi will copy the kernel.
The associated kernel patch will then take care of copying it at
the right place and start over.

-- 
Emmanuel Dreyfus
manu%netbsd.org@localhost
Index: sys/arch/amd64/amd64/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/locore.S,v
retrieving revision 1.218
diff -U4 -r1.218 locore.S
--- sys/arch/amd64/amd64/locore.S	3 Mar 2023 14:32:48 -0000	1.218
+++ sys/arch/amd64/amd64/locore.S	13 Apr 2023 06:33:58 -0000
@@ -455,8 +455,18 @@
 ENTRY(start)
 #ifndef XENPV
 	.code32
 
+	/* Discover load address */
+	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
+
+
 	/* Warm boot */
 	movw	$0x1234,0x472
 
 	/*
@@ -1756,4 +1766,136 @@
 
 LABEL(nomds_leave)
 	NOMDS_LEAVE
 LABEL(nomds_leave_end)
+
+/* This is adapted from sys/arch/i386/stand/efiboot/bootx64/startprog64.S */
+
+/*
+ * Ported to boot 386BSD by Julian Elischer (julian%tfs.com@localhost) Sept 1992
+ *
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution%CS.CMU.EDU@localhost
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+/*
+  Copyright 1988, 1989, 1990, 1991, 1992
+   by Intel Corporation, Santa Clara, California.
+
+                All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#define CODE_SEGMENT    0x08
+#define DATA_SEGMENT    0x10
+
+	.text
+	.p2align 4,,15
+
+	.code32
+
+/*
+ * selfreloc(loadddr edi)
+ */
+ENTRY(selfreloc_start)
+	movl	%edi, %eax
+	movl	%edi, %esi				/* src */
+	movl	$_RELOC(kernel_text), %edi		/* dest */
+	movl	16(%esp),%ecx				/* esym */
+	subl	$_RELOC(kernel_text), %ecx			/* size */
+
+	shrl	$2, %ecx		/* count for copy by words */
+	rep
+	movsl
+
+	/* load current selfreloc_start addesss in $edi */
+	movl	%eax, %edi	
+	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	$DATA_SEGMENT, %eax
+	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	CODE_SEGMENT
+	.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
? sys/arch/i386/stand/boot/biosboot/.depend
? sys/arch/i386/stand/boot/biosboot/.gdbinit
? sys/arch/i386/stand/boot/biosboot/biosboot.d
? sys/arch/i386/stand/boot/biosboot/boot
? sys/arch/i386/stand/boot/biosboot/boot.map
? sys/arch/i386/stand/boot/biosboot/boot.sym
? sys/arch/i386/stand/boot/biosboot/boot2.d
? sys/arch/i386/stand/boot/biosboot/conf.d
? sys/arch/i386/stand/boot/biosboot/devopen.d
? sys/arch/i386/stand/boot/biosboot/exec.d
? sys/arch/i386/stand/boot/biosboot/exec_multiboot1.d
? sys/arch/i386/stand/boot/biosboot/exec_multiboot2.d
? sys/arch/i386/stand/boot/biosboot/lib
? sys/arch/i386/stand/boot/biosboot/vers.c
? sys/arch/i386/stand/boot/biosboot/vers.d
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/.depend
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/bootxx_ext2fs
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/bootxx_ext2fs.map
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/bootxx_ext2fs.sym
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/label.d
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/lib
? sys/arch/i386/stand/bootxx/bootxx_ext2fs/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/.depend
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/bootxx_ffsv1
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/bootxx_ffsv1.map
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/bootxx_ffsv1.sym
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/label.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/lib
? sys/arch/i386/stand/bootxx/bootxx_ffsv1/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/.depend
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/bootxx_ffsv2
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/bootxx_ffsv2.map
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/bootxx_ffsv2.sym
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/label.d
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/lib
? sys/arch/i386/stand/bootxx/bootxx_ffsv2/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/.depend
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/bootxx_lfsv1
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/bootxx_lfsv1.map
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/bootxx_lfsv1.sym
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/label.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/lib
? sys/arch/i386/stand/bootxx/bootxx_lfsv1/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/.depend
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/bootxx_lfsv2
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/bootxx_lfsv2.map
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/bootxx_lfsv2.sym
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/label.d
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/lib
? sys/arch/i386/stand/bootxx/bootxx_lfsv2/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_msdos/.depend
? sys/arch/i386/stand/bootxx/bootxx_msdos/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_msdos/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_msdos/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_msdos/bootxx_msdos
? sys/arch/i386/stand/bootxx/bootxx_msdos/bootxx_msdos.map
? sys/arch/i386/stand/bootxx/bootxx_msdos/bootxx_msdos.sym
? sys/arch/i386/stand/bootxx/bootxx_msdos/label.d
? sys/arch/i386/stand/bootxx/bootxx_msdos/lib
? sys/arch/i386/stand/bootxx/bootxx_msdos/pbr.d
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/.depend
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/.gdbinit
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/boot1.d
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/bootxx.d
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/bootxx_ustarfs
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/bootxx_ustarfs.map
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/bootxx_ustarfs.sym
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/label.d
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/lib
? sys/arch/i386/stand/bootxx/bootxx_ustarfs/pbr.d
? sys/arch/i386/stand/cdboot/.depend
? sys/arch/i386/stand/cdboot/.gdbinit
? sys/arch/i386/stand/cdboot/bootxx_cd9660
? sys/arch/i386/stand/cdboot/cdboot.d
? sys/arch/i386/stand/dosboot/.depend
? sys/arch/i386/stand/dosboot/.gdbinit
? sys/arch/i386/stand/dosboot/devopen.d
? sys/arch/i386/stand/dosboot/dosboot.com
? sys/arch/i386/stand/dosboot/dosboot.list
? sys/arch/i386/stand/dosboot/dosboot.sym
? sys/arch/i386/stand/dosboot/exec.d
? sys/arch/i386/stand/dosboot/exec_multiboot1.d
? sys/arch/i386/stand/dosboot/exec_multiboot2.d
? sys/arch/i386/stand/dosboot/getopt.d
? sys/arch/i386/stand/dosboot/lib
? sys/arch/i386/stand/dosboot/main.d
? sys/arch/i386/stand/dosboot/vers.c
? sys/arch/i386/stand/dosboot/vers.d
? sys/arch/i386/stand/efiboot/bootia32/.depend
? sys/arch/i386/stand/efiboot/bootia32/.gdbinit
? sys/arch/i386/stand/efiboot/bootia32/biosdisk.d
? sys/arch/i386/stand/efiboot/bootia32/boot.d
? sys/arch/i386/stand/efiboot/bootia32/bootia32.efi
? sys/arch/i386/stand/efiboot/bootia32/bootinfo.d
? sys/arch/i386/stand/efiboot/bootia32/bootinfo_biosgeom.d
? sys/arch/i386/stand/efiboot/bootia32/bootmenu.d
? sys/arch/i386/stand/efiboot/bootia32/conf.d
? sys/arch/i386/stand/efiboot/bootia32/dev_net.d
? sys/arch/i386/stand/efiboot/bootia32/devopen.d
? sys/arch/i386/stand/efiboot/bootia32/diskbuf.d
? sys/arch/i386/stand/efiboot/bootia32/efiboot.d
? sys/arch/i386/stand/efiboot/bootia32/efibootia32.d
? sys/arch/i386/stand/efiboot/bootia32/efichar.d
? sys/arch/i386/stand/efiboot/bootia32/eficons.d
? sys/arch/i386/stand/efiboot/bootia32/efidelay.d
? sys/arch/i386/stand/efiboot/bootia32/efidev.d
? sys/arch/i386/stand/efiboot/bootia32/efidisk.d
? sys/arch/i386/stand/efiboot/bootia32/efidisk_ll.d
? sys/arch/i386/stand/efiboot/bootia32/efigetsecs.d
? sys/arch/i386/stand/efiboot/bootia32/efimemory.d
? sys/arch/i386/stand/efiboot/bootia32/efinet.d
? sys/arch/i386/stand/efiboot/bootia32/efipxe.d
? sys/arch/i386/stand/efiboot/bootia32/exec.d
? sys/arch/i386/stand/efiboot/bootia32/exec_multiboot1.d
? sys/arch/i386/stand/efiboot/bootia32/exec_multiboot2.d
? sys/arch/i386/stand/efiboot/bootia32/lib
? sys/arch/i386/stand/efiboot/bootia32/menuutils.d
? sys/arch/i386/stand/efiboot/bootia32/multiboot32.d
? sys/arch/i386/stand/efiboot/bootia32/nfs.d
? sys/arch/i386/stand/efiboot/bootia32/panic.d
? sys/arch/i386/stand/efiboot/bootia32/parseutils.d
? sys/arch/i386/stand/efiboot/bootia32/pread.d
? sys/arch/i386/stand/efiboot/bootia32/self_reloc.d
? sys/arch/i386/stand/efiboot/bootia32/start.d
? sys/arch/i386/stand/efiboot/bootia32/startprog32.d
? sys/arch/i386/stand/efiboot/bootia32/vers.c
? sys/arch/i386/stand/efiboot/bootia32/vers.d
? sys/arch/i386/stand/efiboot/bootx64/.depend
? sys/arch/i386/stand/efiboot/bootx64/.gdbinit
? sys/arch/i386/stand/efiboot/bootx64/biosdisk.d
? sys/arch/i386/stand/efiboot/bootx64/boot.d
? sys/arch/i386/stand/efiboot/bootx64/bootinfo.d
? sys/arch/i386/stand/efiboot/bootx64/bootinfo_biosgeom.d
? sys/arch/i386/stand/efiboot/bootx64/bootmenu.d
? sys/arch/i386/stand/efiboot/bootx64/bootx64.efi
? sys/arch/i386/stand/efiboot/bootx64/conf.d
? sys/arch/i386/stand/efiboot/bootx64/dev_net.d
? sys/arch/i386/stand/efiboot/bootx64/devopen.d
? sys/arch/i386/stand/efiboot/bootx64/diskbuf.d
? sys/arch/i386/stand/efiboot/bootx64/efiboot.d
? sys/arch/i386/stand/efiboot/bootx64/efibootx64.d
? sys/arch/i386/stand/efiboot/bootx64/efichar.d
? sys/arch/i386/stand/efiboot/bootx64/eficons.d
? sys/arch/i386/stand/efiboot/bootx64/efidelay.d
? sys/arch/i386/stand/efiboot/bootx64/efidev.d
? sys/arch/i386/stand/efiboot/bootx64/efidisk.d
? sys/arch/i386/stand/efiboot/bootx64/efidisk_ll.d
? sys/arch/i386/stand/efiboot/bootx64/efigetsecs.d
? sys/arch/i386/stand/efiboot/bootx64/efimemory.d
? sys/arch/i386/stand/efiboot/bootx64/efinet.d
? sys/arch/i386/stand/efiboot/bootx64/efipxe.d
? sys/arch/i386/stand/efiboot/bootx64/exec.d
? sys/arch/i386/stand/efiboot/bootx64/exec_multiboot1.d
? sys/arch/i386/stand/efiboot/bootx64/exec_multiboot2.d
? sys/arch/i386/stand/efiboot/bootx64/lib
? sys/arch/i386/stand/efiboot/bootx64/menuutils.d
? sys/arch/i386/stand/efiboot/bootx64/multiboot64.d
? sys/arch/i386/stand/efiboot/bootx64/nfs.d
? sys/arch/i386/stand/efiboot/bootx64/panic.d
? sys/arch/i386/stand/efiboot/bootx64/parseutils.d
? sys/arch/i386/stand/efiboot/bootx64/pread.d
? sys/arch/i386/stand/efiboot/bootx64/self_reloc.d
? sys/arch/i386/stand/efiboot/bootx64/start.d
? sys/arch/i386/stand/efiboot/bootx64/startprog64.d
? sys/arch/i386/stand/efiboot/bootx64/vers.c
? sys/arch/i386/stand/efiboot/bootx64/vers.d
? sys/arch/i386/stand/fatboot/fat12/.depend
? sys/arch/i386/stand/fatboot/fat12/.gdbinit
? sys/arch/i386/stand/fatboot/fat12/bootxx_fat12
? sys/arch/i386/stand/fatboot/fat12/fatboot.d
? sys/arch/i386/stand/fatboot/fat16/.depend
? sys/arch/i386/stand/fatboot/fat16/.gdbinit
? sys/arch/i386/stand/fatboot/fat16/bootxx_fat16
? sys/arch/i386/stand/fatboot/fat16/fatboot.d
? sys/arch/i386/stand/mbr/gptmbr/.depend
? sys/arch/i386/stand/mbr/gptmbr/.gdbinit
? sys/arch/i386/stand/mbr/gptmbr/gptmbr.bin
? sys/arch/i386/stand/mbr/gptmbr/gptmbr.d
? sys/arch/i386/stand/mbr/mbr/.depend
? sys/arch/i386/stand/mbr/mbr/.gdbinit
? sys/arch/i386/stand/mbr/mbr/mbr
? sys/arch/i386/stand/mbr/mbr/mbr.d
? sys/arch/i386/stand/mbr/mbr_bootsel/.depend
? sys/arch/i386/stand/mbr/mbr_bootsel/.gdbinit
? sys/arch/i386/stand/mbr/mbr_bootsel/mbr.d
? sys/arch/i386/stand/mbr/mbr_bootsel/mbr_bootsel
? sys/arch/i386/stand/mbr/mbr_com0/.depend
? sys/arch/i386/stand/mbr/mbr_com0/.gdbinit
? sys/arch/i386/stand/mbr/mbr_com0/mbr.d
? sys/arch/i386/stand/mbr/mbr_com0/mbr_com0
? sys/arch/i386/stand/mbr/mbr_com0_9600/.depend
? sys/arch/i386/stand/mbr/mbr_com0_9600/.gdbinit
? sys/arch/i386/stand/mbr/mbr_com0_9600/mbr.d
? sys/arch/i386/stand/mbr/mbr_com0_9600/mbr_com0_9600
? sys/arch/i386/stand/mbr/mbr_ext/.depend
? sys/arch/i386/stand/mbr/mbr_ext/.gdbinit
? sys/arch/i386/stand/mbr/mbr_ext/mbr.d
? sys/arch/i386/stand/mbr/mbr_ext/mbr_ext
? sys/arch/i386/stand/misc/pfdisk.doc
? sys/arch/i386/stand/misc/pfdisktc.zip
? sys/arch/i386/stand/misc/rawrite.doc
? sys/arch/i386/stand/pxeboot/.depend
? sys/arch/i386/stand/pxeboot/.gdbinit
? sys/arch/i386/stand/pxeboot/conf.d
? sys/arch/i386/stand/pxeboot/dev_net.d
? sys/arch/i386/stand/pxeboot/devopen.d
? sys/arch/i386/stand/pxeboot/exec.d
? sys/arch/i386/stand/pxeboot/exec_multiboot1.d
? sys/arch/i386/stand/pxeboot/exec_multiboot2.d
? sys/arch/i386/stand/pxeboot/lib
? sys/arch/i386/stand/pxeboot/main.d
? sys/arch/i386/stand/pxeboot/nfs.d
? sys/arch/i386/stand/pxeboot/pxe.d
? sys/arch/i386/stand/pxeboot/pxe_call.d
? sys/arch/i386/stand/pxeboot/pxeboot_ia32.bin
? sys/arch/i386/stand/pxeboot/pxeboot_ia32.list
? sys/arch/i386/stand/pxeboot/pxeboot_ia32.sym
? sys/arch/i386/stand/pxeboot/vers.c
? sys/arch/i386/stand/pxeboot/vers.d
Index: sys/arch/i386/stand/efiboot/boot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/boot.c,v
retrieving revision 1.21
diff -U4 -r1.21 boot.c
--- sys/arch/i386/stand/efiboot/boot.c	8 Jun 2022 21:43:45 -0000	1.21
+++ sys/arch/i386/stand/efiboot/boot.c	13 Apr 2023 06:34:23 -0000
@@ -82,8 +82,9 @@
 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 *);
 
 const struct bootblk_command commands[] = {
@@ -108,8 +109,9 @@
 	{ "menu",	command_menu },
 #endif
 	{ "modules",	command_modules },
 	{ "multiboot",	command_multiboot },
+	{ "reloc",	command_reloc },
 	{ "rndseed",	rnd_add },
 	{ "splash",	splash_add },
 	{ "text",	command_text },
 	{ "userconf",	userconf_add },
@@ -405,8 +407,9 @@
 	       "menu (reenters boot menu, if defined in boot.cfg)\n"
 #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"
 	       "userconf {command}\n"
@@ -640,8 +643,50 @@
 		printf("boot returned\n");
 }
 
 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;
 	char *upath, *ufirmware;
Index: sys/arch/i386/stand/efiboot/efiboot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/efiboot.c,v
retrieving revision 1.12
diff -U4 -r1.12 efiboot.c
--- sys/arch/i386/stand/efiboot/efiboot.c	9 Feb 2020 12:13:39 -0000	1.12
+++ sys/arch/i386/stand/efiboot/efiboot.c	13 Apr 2023 06:34:23 -0000
@@ -35,9 +35,11 @@
 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: sys/arch/i386/stand/efiboot/efiboot.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/efiboot.h,v
retrieving revision 1.11
diff -U4 -r1.11 efiboot.h
--- sys/arch/i386/stand/efiboot/efiboot.h	7 Sep 2021 11:41:31 -0000	1.11
+++ sys/arch/i386/stand/efiboot/efiboot.h	13 Apr 2023 06:34:23 -0000
@@ -51,9 +51,15 @@
 	BOOT_DEVICE_TYPE_NET
 } 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: sys/arch/i386/stand/efiboot/bootia32/efibootia32.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c,v
retrieving revision 1.5
diff -U4 -r1.5 efibootia32.c
--- sys/arch/i386/stand/efiboot/bootia32/efibootia32.c	13 Sep 2019 02:19:45 -0000	1.5
+++ sys/arch/i386/stand/efiboot/bootia32/efibootia32.c	13 Apr 2023 06:34:23 -0000
@@ -75,9 +75,9 @@
 {
 
 	(*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);
 }
 
 /* ARGSUSED */
Index: sys/arch/i386/stand/efiboot/bootia32/startprog32.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S,v
retrieving revision 1.2
diff -U4 -r1.2 startprog32.S
--- sys/arch/i386/stand/efiboot/bootia32/startprog32.S	24 Feb 2017 12:24:25 -0000	1.2
+++ sys/arch/i386/stand/efiboot/bootia32/startprog32.S	13 Apr 2023 06:34:23 -0000
@@ -116,8 +116,13 @@
 	/* Copy kernel */
 	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
 	movl	%edi, %eax
Index: sys/arch/i386/stand/efiboot/bootx64/efibootx64.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c,v
retrieving revision 1.5
diff -U4 -r1.5 efibootx64.c
--- sys/arch/i386/stand/efiboot/bootx64/efibootx64.c	13 Sep 2019 02:19:46 -0000	1.5
+++ sys/arch/i386/stand/efiboot/bootx64/efibootx64.c	13 Apr 2023 06:34:23 -0000
@@ -79,9 +79,9 @@
 		newsp -= argc;
 		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);
 }
 
 /* ARGSUSED */
Index: sys/arch/i386/stand/efiboot/bootx64/startprog64.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S,v
retrieving revision 1.3
diff -U4 -r1.3 startprog64.S
--- sys/arch/i386/stand/efiboot/bootx64/startprog64.S	11 Feb 2017 10:23:39 -0000	1.3
+++ sys/arch/i386/stand/efiboot/bootx64/startprog64.S	13 Apr 2023 06:34:23 -0000
@@ -96,8 +96,12 @@
 	cld		/* LynxOS depends on it */
 
 	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: sys/arch/i386/stand/lib/exec.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/exec.c,v
retrieving revision 1.78
diff -U4 -r1.78 exec.c
--- sys/arch/i386/stand/lib/exec.c	21 Sep 2022 14:29:45 -0000	1.78
+++ sys/arch/i386/stand/lib/exec.c	13 Apr 2023 06:34:23 -0000
@@ -464,8 +464,9 @@
 	u_long marks[MARK_MAX];
 	struct btinfo_symtab btinfo_symtab;
 	u_long extmem;
 	u_long basemem;
+	u_long entry;
 	int error;
 #ifdef EFIBOOT
 	int i;
 #endif
@@ -496,8 +497,10 @@
 		errno = error;
 		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;
 	marks[MARK_DATA] -= efi_loadaddr;
@@ -551,8 +554,10 @@
 	    sizeof(struct btinfo_framebuffer));
 
 	if (callback != NULL)
 		(*callback)();
+
+	entry = marks[MARK_ENTRY];
 #ifdef EFIBOOT
 	/* Copy bootinfo to safe arena. */
 	for (i = 0; i < bootinfo->nentries; i++) {
 		struct btinfo_common *bi = (void *)(u_long)bootinfo->entry[i];
@@ -562,10 +567,24 @@
 	}
 
 	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");
 
 out:


Home | Main Index | Thread Index | Old Index