Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Multiboot2 kernel support for i386
details: https://anonhg.NetBSD.org/src/rev/9ac54acdf02b
branches: trunk
changeset: 966204:9ac54acdf02b
user: manu <manu%NetBSD.org@localhost>
date: Fri Oct 18 01:38:28 2019 +0000
description:
Multiboot2 kernel support for i386
That implementation works either with BIOS or UEFI bootstrap
This requires the following kernel changes:
Add UEFI boot services and I/O method protoypes
src/sys/arch/x86/include/efi.h 1.8 - 1.9
Fix EFI system table mapping in virtual space
src/sys/arch/x86/x86/efi.c 1.19 - 1.20
Make sure no bioscall is issued when booting off UEFI system
src/sys/arch/i386/i386/machdep.c 1.821 - 1.822
src/sys/arch/i386/pci/piixpcib.c 1.22 - 1.23
And the following bootstrap changes:
Add kernel symbols for multiboot1
src/sys/arch/i386/stand/lib/exec_multiboot1.c 1.2 - 1.3
src/sys/arch/i386/stand/lib/libi386.h 1.45 - 1.47
Fix kernel symbols for multiboot2
src/sys/arch/i386/stand/lib/exec_multiboot2.c 1.2 - 1.3
diffstat:
sys/arch/i386/conf/files.i386 | 3 +-
sys/arch/i386/i386/locore.S | 233 ++++++++-
sys/arch/i386/i386/machdep.c | 12 +-
sys/arch/i386/i386/multiboot.c | 19 +-
sys/arch/i386/include/multiboot.h | 23 +-
sys/arch/x86/x86/multiboot2.c | 1009 +++++++++++++++++++++++++++++++++++++
6 files changed, 1274 insertions(+), 25 deletions(-)
diffs (truncated from 1471 to 300 lines):
diff -r 40050110bb6b -r 9ac54acdf02b sys/arch/i386/conf/files.i386
--- a/sys/arch/i386/conf/files.i386 Fri Oct 18 01:24:51 2019 +0000
+++ b/sys/arch/i386/conf/files.i386 Fri Oct 18 01:38:28 2019 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.i386,v 1.400 2019/02/15 08:54:01 nonaka Exp $
+# $NetBSD: files.i386,v 1.401 2019/10/18 01:38:28 manu Exp $
#
# new style config file for i386 architecture
#
@@ -51,6 +51,7 @@
defflag opt_multiboot.h MULTIBOOT
obsolete defparam MULTIBOOT_SYMTAB_SPACE
file arch/i386/i386/multiboot.c multiboot
+file arch/x86/x86/multiboot2.c multiboot
file arch/i386/i386/autoconf.c
file arch/i386/i386/aout_machdep.c exec_aout
diff -r 40050110bb6b -r 9ac54acdf02b sys/arch/i386/i386/locore.S
--- a/sys/arch/i386/i386/locore.S Fri Oct 18 01:24:51 2019 +0000
+++ b/sys/arch/i386/i386/locore.S Fri Oct 18 01:38:28 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.172 2019/10/12 06:31:03 maxv Exp $ */
+/* $NetBSD: locore.S,v 1.173 2019/10/18 01:38:28 manu Exp $ */
/*
* Copyright-o-rama!
@@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.172 2019/10/12 06:31:03 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.173 2019/10/18 01:38:28 manu Exp $");
#include "opt_copy_symtab.h"
#include "opt_ddb.h"
@@ -346,12 +346,52 @@
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+ .align 8
+ .globl Multiboot2_Header
+_C_LABEL(Multiboot2_Header):
+ .long MULTIBOOT2_HEADER_MAGIC
+ .long MULTIBOOT2_ARCHITECTURE_I386
+ .long Multiboot2_Header_end - Multiboot2_Header
+ .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 \
+ + (Multiboot2_Header_end - Multiboot2_Header))
+
+ .long 1 /* MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST */
+ .long 12 /* sizeof(multiboot_header_tag_information_request) */
+ /* + sizeof(uint32_t) * requests */
+ .long 4 /* MULTIBOOT_TAG_TYPE_BASIC_MEMINFO */
+ .long 0 /* pad for 8 bytes alignment */
+
+ .long 8 /* MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 */
+ .long 12 /* sizeof(struct multiboot_tag_efi32) */
+ .long efi_multiboot2_loader - KERNBASE
+ .long 0 /* pad for 8 bytes alignment */
+
+#if notyet
+ /*
+ * Could be used to get an early console for debug,
+ * but this is broken.
+ */
+ .long 7 /* MULTIBOOT_HEADER_TAG_EFI_BS */
+ .long 8 /* sizeof(struct multiboot_tag) */
+#endif
+
+ .long 0 /* MULTIBOOT_HEADER_TAG_END */
+ .long 8 /* sizeof(struct multiboot_tag) */
+ .globl Multiboot2_Header_end
+_C_LABEL(Multiboot2_Header_end):
+
1:
/* Check if we are being executed by a Multiboot-compliant boot
* loader. */
cmpl $MULTIBOOT_INFO_MAGIC,%eax
- jne 1f
+ je multiboot1_loader
+ cmpl $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
+ je multiboot2_loader
+
+ jmp 1f
+
+multiboot1_loader:
/*
* Indeed, a multiboot-compliant boot loader executed us. We switch
* to the temporary stack, and copy the received Multiboot information
@@ -361,10 +401,187 @@
*/
movl $_RELOC(tmpstk),%esp
pushl %ebx /* Address of Multiboot information */
- call _C_LABEL(multiboot_pre_reloc)
+ call _C_LABEL(multiboot1_pre_reloc)
addl $4,%esp
jmp 2f
+
+efi_multiboot2_loader:
+ /*
+ * EFI32 multiboot2 entry point. We are left here without
+ * stack and with no idea of where we were loaded in memory.
+ * The only inputs are
+ * %eax MULTIBOOT2_BOOTLOADER_MAGIC
+ * %ebx pointer to multiboot_info
+ *
+ * Here we will copy the kernel to 0x100000 (KERNTEXTOFF - KERNBASE)
+ * as almost all the code in locore.S assume it is there. Once done,
+ * we join the main start code .This is derived from
+ * src/sys/arch/i386/stand/efiboot/bootia32/startprog32.S
+ */
+
+ cli
+
+ /*
+ * Discover our load address and store it in %edx
+ */
+ movl $_RELOC(tmpstk),%esp
+ call next
+next: popl %edx
+ subl $(next - efi_multiboot2_loader), %edx
+
+ /*
+ * Save multiboot_info for later. We cannot use
+ * temporary stack for that since we are going to
+ * overwrite it.
+ */
+ movl %ebx, (multiboot2_info_ptr - efi_multiboot2_loader)(%edx)
+
+ /*
+ * Get relocated multiboot2_loader entry point in %ebx
+ */
+ movl $(KERNTEXTOFF - KERNBASE), %ebx
+ addl $(multiboot2_loader - start), %ebx
+
+ /* Copy kernel */
+ movl $(KERNTEXTOFF - KERNBASE), %edi /* dest */
+ movl %edx, %esi
+ subl $(efi_multiboot2_loader - start), %esi /* src */
+ movl $(__kernel_end - 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 */
+
+ /* Prepare jump address */
+ lea (efi_multiboot2_loader32a - efi_multiboot2_loader)(%edx), %eax
+ movl %eax, (efi_multiboot2_loader32r - efi_multiboot2_loader)(%edx)
+
+ /* Setup GDT */
+ lea (gdt - efi_multiboot2_loader)(%edx), %eax
+ movl %eax, (gdtrr - efi_multiboot2_loader)(%edx)
+ lgdt (gdtr - efi_multiboot2_loader)(%edx)
+
+ /* Jump to set %cs */
+ ljmp *(efi_multiboot2_loader32r - efi_multiboot2_loader)(%edx)
+
+ .align 4
+efi_multiboot2_loader32a:
+ movl $0x10, %eax /* #define DATA_SEGMENT 0x10 */
+ movw %ax, %ds
+ movw %ax, %es
+ movw %ax, %fs
+ movw %ax, %gs
+ movw %ax, %ss
+
+ /* Already set new stack pointer */
+ movl %esp, %ebp
+
+ /* 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 efi_multiboot2_loader32b
+
+ .align 4
+efi_multiboot2_loader32b:
+ xor %eax, %eax
+ movl %ebx, (efi_multiboot2_loader32r - efi_multiboot2_loader)(%edx)
+ /*
+ * Reload multiboot info from target location
+ */
+ movl _RELOC(multiboot2_info_ptr), %ebx
+ ljmp *(efi_multiboot2_loader32r - efi_multiboot2_loader)(%edx)
+
+ .align 16
+efi_multiboot2_loader32r:
+ .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 0
+multiboot2_info_ptr:
+ .long 0
+
+ .align 16
+multiboot2_loader:
+ movl $_RELOC(tmpstk),%esp
+ pushl %ebx /* Address of Multiboot information */
+ call _C_LABEL(multiboot2_pre_reloc)
+ addl $4,%esp
+ jmp 2f
+#endif /* MULTIBOOT */
1:
/*
@@ -834,8 +1051,12 @@
/* It is now safe to parse the Multiboot information structure
* we saved before from C code. Note that we cannot delay its
* parsing any more because initgdt (called below) needs to make
- * use of this information. */
- call _C_LABEL(multiboot_post_reloc)
+ * use of this information.
+ * We call both multiboot 1 and 2 flavors, they now if they
+ * have something to do on their own.
+ */
+ call _C_LABEL(multiboot1_post_reloc)
+ call _C_LABEL(multiboot2_post_reloc)
#endif
subl $NGDT*8, %esp /* space for temporary gdt */
diff -r 40050110bb6b -r 9ac54acdf02b sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c Fri Oct 18 01:24:51 2019 +0000
+++ b/sys/arch/i386/i386/machdep.c Fri Oct 18 01:38:28 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.822 2019/10/18 01:00:24 manu Exp $ */
+/* $NetBSD: machdep.c,v 1.823 2019/10/18 01:38:28 manu Exp $ */
Home |
Main Index |
Thread Index |
Old Index