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
This commit is contained in:
parent
1281ec5b00
commit
b2a4053feb
|
@ -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 @@ defparam opt_beep.h BEEP_ONHALT_PERIOD=250
|
|||
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
|
||||
|
|
|
@ -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 @@ _C_LABEL(Multiboot_Header):
|
|||
.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 @@ _C_LABEL(Multiboot_Header):
|
|||
*/
|
||||
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 @@ begin:
|
|||
/* 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 */
|
||||
|
|
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009, 2017
|
||||
|
@ -67,7 +67,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.822 2019/10/18 01:00:24 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.823 2019/10/18 01:38:28 manu Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_freebsd.h"
|
||||
|
@ -420,7 +420,8 @@ cpu_startup(void)
|
|||
initmsgbuf((void *)msgbuf_vaddr, sz);
|
||||
|
||||
#ifdef MULTIBOOT
|
||||
multiboot_print_info();
|
||||
multiboot1_print_info();
|
||||
multiboot2_print_info();
|
||||
#endif
|
||||
|
||||
#if NCARDBUS > 0
|
||||
|
@ -1063,7 +1064,10 @@ init386_ksyms(void)
|
|||
#endif
|
||||
|
||||
#if defined(MULTIBOOT)
|
||||
if (multiboot_ksyms_addsyms_elf())
|
||||
if (multiboot1_ksyms_addsyms_elf())
|
||||
return;
|
||||
|
||||
if (multiboot2_ksyms_addsyms_elf())
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: multiboot.c,v 1.25 2019/10/18 01:19:00 manu Exp $ */
|
||||
/* $NetBSD: multiboot.c,v 1.26 2019/10/18 01:38:28 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.25 2019/10/18 01:19:00 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.26 2019/10/18 01:38:28 manu Exp $");
|
||||
|
||||
#include "opt_multiboot.h"
|
||||
|
||||
|
@ -84,7 +84,7 @@ extern int * esym;
|
|||
/*
|
||||
* Copy of the Multiboot information structure passed to us by the boot
|
||||
* loader. The Multiboot_Info structure has some pointers adjusted to the
|
||||
* other variables -- see multiboot_pre_reloc() -- so you oughtn't access
|
||||
* other variables -- see multiboot1_pre_reloc() -- so you oughtn't access
|
||||
* them directly. In other words, always access them through the
|
||||
* Multiboot_Info variable.
|
||||
*/
|
||||
|
@ -129,7 +129,7 @@ static void setup_memmap(struct multiboot_info *);
|
|||
* can be obtained using the RELOC macro.
|
||||
*/
|
||||
void
|
||||
multiboot_pre_reloc(struct multiboot_info *mi)
|
||||
multiboot1_pre_reloc(struct multiboot_info *mi)
|
||||
{
|
||||
#define RELOC(type, x) ((type)((vaddr_t)(x) - KERNBASE))
|
||||
struct multiboot_info *midest =
|
||||
|
@ -175,7 +175,7 @@ multiboot_pre_reloc(struct multiboot_info *mi)
|
|||
* that no devices have been initialized yet (not even the console!).
|
||||
*/
|
||||
void
|
||||
multiboot_post_reloc(void)
|
||||
multiboot1_post_reloc(void)
|
||||
{
|
||||
struct multiboot_info *mi;
|
||||
|
||||
|
@ -202,7 +202,7 @@ multiboot_post_reloc(void)
|
|||
* the console has to be available.
|
||||
*/
|
||||
void
|
||||
multiboot_print_info(void)
|
||||
multiboot1_print_info(void)
|
||||
{
|
||||
struct multiboot_info *mi = &Multiboot_Info;
|
||||
struct multiboot_symbols *ms = &Multiboot_Symbols;
|
||||
|
@ -269,7 +269,7 @@ bootinfo_add(struct btinfo_common *item, int type, int len)
|
|||
* that this data is properly copied into upper memory during relocation.
|
||||
*
|
||||
* WARNING: This code runs before the kernel has relocated itself. See
|
||||
* the note in multiboot_pre_reloc() for more information.
|
||||
* the note in multiboot1_pre_reloc() for more information.
|
||||
*/
|
||||
static void
|
||||
copy_syms(struct multiboot_info *mi)
|
||||
|
@ -685,11 +685,14 @@ setup_memory(struct multiboot_info *mi)
|
|||
* passed in by Multiboot; false otherwise.
|
||||
*/
|
||||
bool
|
||||
multiboot_ksyms_addsyms_elf(void)
|
||||
multiboot1_ksyms_addsyms_elf(void)
|
||||
{
|
||||
struct multiboot_info *mi = &Multiboot_Info;
|
||||
struct multiboot_symbols *ms = &Multiboot_Symbols;
|
||||
|
||||
if (! Multiboot_Loader)
|
||||
return false;
|
||||
|
||||
if (mi->mi_flags & MULTIBOOT_INFO_HAS_ELF_SYMS) {
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: multiboot.h,v 1.10 2018/11/13 11:01:54 mlelstv Exp $ */
|
||||
/* $NetBSD: multiboot.h,v 1.11 2019/10/18 01:38:28 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -40,6 +40,12 @@
|
|||
#define MULTIBOOT_HEADER_HAS_VBE 0x00000004
|
||||
#define MULTIBOOT_HEADER_HAS_ADDR 0x00010000
|
||||
|
||||
#if defined(_LOCORE)
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
|
||||
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
|
||||
#define MULTIBOOT2_ARCHITECTURE_I386 0
|
||||
#endif
|
||||
|
||||
#if !defined(_LOCORE)
|
||||
struct multiboot_header {
|
||||
uint32_t mh_magic;
|
||||
|
@ -219,13 +225,18 @@ struct multiboot_module {
|
|||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Prototypes for public functions defined in multiboot.c.
|
||||
* Prototypes for public functions defined in multiboot.c and multiboot2.c
|
||||
*/
|
||||
#if !defined(_LOCORE) && defined(_KERNEL)
|
||||
void multiboot_pre_reloc(struct multiboot_info *);
|
||||
void multiboot_post_reloc(void);
|
||||
void multiboot_print_info(void);
|
||||
bool multiboot_ksyms_addsyms_elf(void);
|
||||
void multiboot1_pre_reloc(struct multiboot_info *);
|
||||
void multiboot1_post_reloc(void);
|
||||
void multiboot1_print_info(void);
|
||||
bool multiboot1_ksyms_addsyms_elf(void);
|
||||
|
||||
void multiboot2_pre_reloc(struct multiboot_info *);
|
||||
void multiboot2_post_reloc(void);
|
||||
void multiboot2_print_info(void);
|
||||
bool multiboot2_ksyms_addsyms_elf(void);
|
||||
#endif /* !defined(_LOCORE) */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue