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