Port-amd64 archive

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

[PATCH] mutliboot2 second round



Please find attached a patch for multiboot 2 on amd64 that I hope
addresses Maxime's concerns:
- multiboot locore moved to a separate file
- kernel copy was cleaned up (but there are two versions, see below)
- the 32 bit C code is now built from C

There is a decision to make when copying the kernel to 
KERNTEXTOFF - KERNBASE in multiboot_locore.S (see #if without_memove): 
calling memmove() which requires setting up a stack in the text segment,
or just do a rep movsq that assumes aligned non overlapping copy.

-- 
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.200
diff -U4 -r1.200 locore.S
--- sys/arch/amd64/amd64/locore.S	15 Jan 2020 18:47:23 -0000	1.200
+++ sys/arch/amd64/amd64/locore.S	30 Jan 2020 01:55:55 -0000
@@ -157,8 +157,9 @@
 #include "opt_realmem.h"
 
 #include "opt_compat_netbsd.h"
 #include "opt_compat_netbsd32.h"
+#include "opt_multiboot.h"
 #include "opt_xen.h"
 #include "opt_svs.h"
 
 #include "assym.h"
@@ -561,8 +562,10 @@
 	/*
 	 * Done with the parameters!
 	 */
 
+	.globl	_C_LABEL(begin)
+_C_LABEL(begin):
 	/* First, reset the PSL. */
 	pushl	$PSL_MBO
 	popfl
 
@@ -876,8 +879,22 @@
 	movq	%rax,_C_LABEL(lwp0uarea)(%rip)
 	leaq	(USPACE-FRAMESIZE)(%rax),%rsp
 	xorq	%rbp,%rbp			/* mark end of frames */
 
+#if defined(MULTIBOOT)
+	/* 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.
+	 */
+	movb	_C_LABEL(multiboot2_enabled),%al
+	cmpb	$0,%al
+	je	no_multiboot2_post_reloc
+	pushq	%rsi
+	call	_C_LABEL(multiboot2_post_reloc)
+	popq	%rsi
+no_multiboot2_post_reloc:
+#endif 
 	xorw	%ax,%ax
 	movw	%ax,%gs
 	movw	%ax,%fs
 
Index: sys/arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.345
diff -U4 -r1.345 machdep.c
--- sys/arch/amd64/amd64/machdep.c	9 Jan 2020 00:42:24 -0000	1.345
+++ sys/arch/amd64/amd64/machdep.c	30 Jan 2020 01:55:55 -0000
@@ -112,8 +112,9 @@
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.345 2020/01/09 00:42:24 manu Exp $");
 
 #include "opt_modular.h"
+#include "opt_multiboot.h"
 #include "opt_user_ldt.h"
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
 #include "opt_cpureset_delay.h"
@@ -183,8 +184,10 @@
 #include <x86/cputypes.h>
 #include <x86/cpuvar.h>
 #include <x86/machdep.h>
 
+#include <i386/multiboot.h>
+
 #include <x86/x86/tsc.h>
 
 #include <dev/isa/isareg.h>
 #include <machine/isa_machdep.h>
@@ -370,8 +373,12 @@
 	pmap_update(pmap_kernel());
 
 	initmsgbuf((void *)msgbuf_vaddr, round_page(sz));
 
+#ifdef MULTIBOOT
+	multiboot2_print_info();
+#endif
+
 	minaddr = 0;
 
 	/*
 	 * Allocate a submap for physio.
@@ -1503,8 +1510,13 @@
 #ifdef DDB
 	db_machine_init();
 #endif
 
+#if defined(MULTIBOOT)
+        if (multiboot2_ksyms_addsyms_elf())
+                return;
+#endif
+
 #ifndef XENPV
 	symtab = lookup_bootinfo(BTINFO_SYMTAB);
 	if (symtab) {
 #ifdef KASLR
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.554
diff -U4 -r1.554 GENERIC
--- sys/arch/amd64/conf/GENERIC	9 Jan 2020 00:42:24 -0000	1.554
+++ sys/arch/amd64/conf/GENERIC	30 Jan 2020 01:55:55 -0000
@@ -25,8 +25,10 @@
 #ident		"GENERIC-$Revision: 1.554 $"
 
 maxusers	64		# estimated number of users
 
+options 	MULTIBOOT	# Multiboot support (see multiboot(8)) 
+
 # delay between "rebooting ..." message and hardware reset, in milliseconds
 #options 	CPURESET_DELAY=2000
 
 # This option allows you to force a serial console at the specified
Index: sys/arch/amd64/conf/Makefile.amd64
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/Makefile.amd64,v
retrieving revision 1.80
diff -U4 -r1.80 Makefile.amd64
--- sys/arch/amd64/conf/Makefile.amd64	14 Nov 2019 16:23:52 -0000	1.80
+++ sys/arch/amd64/conf/Makefile.amd64	30 Jan 2020 01:55:55 -0000
@@ -85,17 +85,27 @@
 ##
 ## (4) local objects, compile rules, and dependencies
 ##
 
+KCOMPILE32.c=    ${CC} ${COPTS.${<:T}} -m32 -DELFSIZE=64 \
+                 ${CFLAGS:C/-mcmodel=[a-z]*/-mcmodel=32/} \
+		 ${CPPFLAGS} -c $< -o $@32
+
+NORMAL_C32?=    @${_MKSHMSG} "compile  ${.CURDIR:T}/${.TARGET}" && \
+                ${_MKSHECHO} ${KCOMPILE32.c} ${PROF} && \
+                ${KCOMPILE32.c} ${PROF} && \
+		${OBJCOPY} -O elf64-x86-64 --debugging $@32 $@ && \
+		${COMPILE_CTFCONVERT}
+
 ##
 ## (5) link settings
 ##
 TEXTADDR?=	0xffffffff80200000
 .if defined(KASLR)
 EXTRA_LINKFLAGS=	--split-by-file=0x100000 -r -d
 KERNLDSCRIPT?= ${AMD64}/conf/kern.ldscript.kaslr
 .else
-EXTRA_LINKFLAGS=	-z max-page-size=0x200000
+EXTRA_LINKFLAGS=	-z max-page-size=0x1000
 KERNLDSCRIPT?= ${AMD64}/conf/kern.ldscript
 .endif
 LINKFLAGS_NORMAL=	-X
 
Index: sys/arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.115
diff -U4 -r1.115 files.amd64
--- sys/arch/amd64/conf/files.amd64	9 Jan 2020 00:42:24 -0000	1.115
+++ sys/arch/amd64/conf/files.amd64	30 Jan 2020 01:55:55 -0000
@@ -29,8 +29,14 @@
 
 defflag			USER_LDT
 defflag eisa.h		EISA
 
+# Multiboot support
+defflag opt_multiboot.h MULTIBOOT
+file    arch/amd64/amd64/multiboot_locore.S	multiboot
+file    arch/x86/x86/multiboot2.c               multiboot
+file    arch/x86/x86/multiboot32.c              multiboot compile-with "${NORMAL_C32}"
+
 # Start code
 file	arch/amd64/amd64/locore.S		machdep
 file	arch/amd64/amd64/vector.S		machdep
 file	arch/amd64/amd64/copy.S			machdep
Index: sys/arch/amd64/conf/kern.ldscript
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/conf/kern.ldscript,v
retrieving revision 1.31
diff -U4 -r1.31 kern.ldscript
--- sys/arch/amd64/conf/kern.ldscript	9 Jan 2020 00:42:24 -0000	1.31
+++ sys/arch/amd64/conf/kern.ldscript	30 Jan 2020 01:55:55 -0000
@@ -15,13 +15,16 @@
 {
 	.text : AT (ADDR(.text) & 0x0fffffff)
 	{
 		. = ALIGN(__PAGE_SIZE);
+		*(multiboot)
+		. = ALIGN(__PAGE_SIZE);
 		__text_user_start = . ;
 		*(.text.user)
 		. = ALIGN(__PAGE_SIZE);
 		__text_user_end = . ;
 
+		multiboot32.o(.text)
 		*(.text)
 		*(.text.*)
 		*(.stub)
 		. = ALIGN(__LARGE_PAGE_SIZE);
Index: sys/arch/x86/x86/multiboot2.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/multiboot2.c,v
retrieving revision 1.3
diff -U4 -r1.3 multiboot2.c
--- sys/arch/x86/x86/multiboot2.c	10 Dec 2019 02:06:07 -0000	1.3
+++ sys/arch/x86/x86/multiboot2.c	30 Jan 2020 01:55:55 -0000
@@ -48,20 +48,9 @@
 #include <x86/efi.h>
 
 #include <machine/bootinfo.h>
 #include <arch/i386/include/multiboot2.h>
-
-#ifdef _LOCORE64
-typedef uint64_t   locore_vaddr_t;
-typedef Elf64_Shdr locore_Elf_Shdr;
-typedef Elf64_Word locore_Elf_Word;
-typedef Elf64_Addr locore_Elf_Addr;
-#else
-typedef vaddr_t   locore_vaddr_t;
-typedef Elf_Shdr locore_Elf_Shdr;
-typedef Elf_Word locore_Elf_Word;
-typedef Elf_Addr locore_Elf_Addr;
-#endif
+#include <arch/x86/include/multiboot32.h>
 
 #if !defined(MULTIBOOT)
 #  error "MULTIBOOT not defined; this cannot happen."
 #endif
@@ -75,27 +64,8 @@
 #define BS_PRINT(efisystbl, wstring) 					\
 	efi_systbl->st_coutif->ei_outputstring(efi_systbl->st_coutif,	\
 	    (efi_char *)__UNCONST(wstring))
 
-struct multiboot_symbols {
-	uint32_t s_symstart;
-	uint32_t s_symsize;
-	uint32_t s_strstart;
-	uint32_t s_strsize;
-};	
-
-void multiboot2_copy_syms(struct multiboot_tag_elf_sections *,
-			  struct multiboot_symbols *,
-			  bool *, int **, void *, vaddr_t);
-/*
- * Because of clashes between multiboot.h and multiboot2.h we
- * cannot include both, and we need to redefine here:
- */
-void            multiboot2_pre_reloc(char *);
-void            multiboot2_post_reloc(void);
-void            multiboot2_print_info(void);
-bool            multiboot2_ksyms_addsyms_elf(void); 
-
 extern int              biosbasemem;
 extern int              biosextmem;
 #ifdef __i386__
 extern int              biosmem_implicit;
@@ -110,244 +80,16 @@
  * There is no way to perform dynamic allocation
  * at this time, hence we need to waste memory, 
  * with the hope data will fit.
  */
-char multiboot_info[16384] = "\0\0\0\0";
+char multiboot2_info[MULTIBOOT2_INFO_MAXLEN] = "\0\0\0\0";
 bool multiboot2_enabled = false;
-bool has_syms = false;
+bool multiboot2_has_syms = false;
 struct multiboot_symbols Multiboot_Symbols;
 
-
 #define RELOC(type, x) ((type)((vaddr_t)(x) - KERNBASE))
 
 static void
-efi_exit_bs(struct efi_systbl *efi_systbl, void *efi_ih)
-{
-	struct efi_bs *efi_bs;
-	struct efi_md *desc;
-	uintn bufsize, key, size;
-	uint32_t vers;
-
-	if (efi_systbl == NULL)
-		panic("EFI system table is NULL");
-
-	if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG)
-		panic("EFI system table signature is wrong");
-
-	efi_bs = efi_systbl->st_bs;
-
-	if (efi_bs == NULL)
-		panic("EFI BS is NULL");
-
-	if (efi_bs->bs_hdr.th_sig != EFI_BS_SIG)
-		panic("EFI BS signature is wrong");
-
-	if (efi_ih == NULL)
-		panic("EFI IH is NULL");
-
-	bufsize = 16384;
-
-	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
-	    bufsize, (void **)&desc) != 0)
-		panic("EFI AllocatePool failed");
-
-	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) == 0)
-		goto exit_bs;
-
-	(void)efi_bs->bs_freepool((void *)desc);
-
-	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
-	    bufsize, (void **)&desc) != 0)
-		panic("EFI AllocatePool failed");
-
-	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) != 0)
-		panic("EFI GetMemoryMap failed");
-
-exit_bs:
-	if (efi_bs->bs_exitbootservices(efi_ih, key) != 0)
-		panic("EFI ExitBootServices failed");
-
-	return;
-}
-
-void
-multiboot2_copy_syms(struct multiboot_tag_elf_sections *mbt_elf, 
-		     struct multiboot_symbols *ms,
-		     bool *has_symsp, int **esymp, void *endp,
-		     vaddr_t kernbase)
-{
-	int i;
-	locore_Elf_Shdr *symtabp, *strtabp;
-	locore_Elf_Word symsize, strsize;
-	locore_Elf_Addr symaddr, straddr;
-	locore_Elf_Addr symstart, strstart;
-	locore_Elf_Addr cp1src, cp1dst;
-	locore_Elf_Word cp1size;
-	locore_Elf_Addr cp2src, cp2dst;
-	locore_Elf_Word cp2size;
-
-	/*
-	 * Locate a symbol table and its matching string table in the
-	 * section headers passed in by the boot loader.  Set 'symtabp'
-	 * and 'strtabp' with pointers to the matching entries.
-	 */
-	symtabp = strtabp = NULL;
-	for (i = 0; i < mbt_elf->num && symtabp == NULL &&
-	    strtabp == NULL; i++) {
-		locore_Elf_Shdr *shdrp;
-
-		shdrp = &((locore_Elf_Shdr *)mbt_elf->sections)[i];
-
-		if ((shdrp->sh_type == SHT_SYMTAB) &&
-		    shdrp->sh_link != SHN_UNDEF) {
-			locore_Elf_Shdr *shdrp2;
-
-			shdrp2 = &((locore_Elf_Shdr *)mbt_elf->sections)
-			    [shdrp->sh_link];
-
-			if (shdrp2->sh_type == SHT_STRTAB) {
-				symtabp = (locore_Elf_Shdr *)shdrp;
-				strtabp = (locore_Elf_Shdr *)shdrp2;
-			}
-		}
-	}
-	if (symtabp == NULL || strtabp == NULL)
-		return;
-
-	symaddr = symtabp->sh_addr;
-	straddr = strtabp->sh_addr;
-	symsize = symtabp->sh_size;
-	strsize = strtabp->sh_size;
-
-	/*
-	 * Copy the symbol and string tables just after the kernel's
-	 * end address, in this order.  Only the contents of these ELF
-	 * sections are copied; headers are discarded.  esym is later
-	 * updated to point to the lowest "free" address after the tables
-	 * so that they are mapped appropriately when enabling paging.
-	 *
-	 * We need to be careful to not overwrite valid data doing the
-	 * copies, hence all the different cases below.  We can assume
-	 * that if the tables start before the kernel's end address,
-	 * they will not grow over this address.
-	 */
-        if ((void *)(uintptr_t)symaddr < endp &&
-	    (void *)(uintptr_t)straddr < endp) {
-		cp1src = symaddr; cp1size = symsize;
-		cp2src = straddr; cp2size = strsize;
-        } else if ((void *)(uintptr_t)symaddr > endp &&
-		   (void *)(uintptr_t)straddr < endp) {
-		cp1src = symaddr; cp1size = symsize;
-		cp2src = straddr; cp2size = strsize;
-        } else if ((void *)(uintptr_t)symaddr < endp &&
-		   (void *)(uintptr_t)straddr > endp) {
-		cp1src = straddr; cp1size = strsize;
-		cp2src = symaddr; cp2size = symsize;
-	} else {
-		/* symaddr and straddr are both over end */
-		if (symaddr < straddr) {
-			cp1src = symaddr; cp1size = symsize;
-			cp2src = straddr; cp2size = strsize;
-		} else {
-			cp1src = straddr; cp1size = strsize;
-			cp2src = symaddr; cp2size = symsize;
-		}
-	}
-
-	cp1dst = (locore_Elf_Addr)(uintptr_t)endp;
-	cp2dst = (locore_Elf_Addr)(uintptr_t)endp + cp1size;
-
-	(void)memcpy((void *)(uintptr_t)cp1dst,
-		     (void *)(uintptr_t)cp1src, cp1size);
-	(void)memcpy((void *)(uintptr_t)cp2dst,
-		     (void *)(uintptr_t)cp2src, cp2size);
-
-	symstart = (cp1src == symaddr) ? cp1dst : cp2dst;
-	strstart = (cp1src == straddr) ? cp1dst : cp2dst;
-
-	ms->s_symstart = symstart + kernbase;
-	ms->s_symsize  = symsize;
-	ms->s_strstart = strstart + kernbase;
-	ms->s_strsize  = strsize;
-
-	*has_symsp = true;
-	*esymp = (int *)((uintptr_t)endp + symsize + strsize + kernbase);
-
-}
-
-void
-multiboot2_pre_reloc(char *mbi)
-{
-	uint32_t mbi_size;
-	void *mbidest = RELOC(void *, multiboot_info);
-	char *cp;
-	struct multiboot_tag_module *mbt;
-	struct multiboot_tag_elf_sections *mbt_elf = NULL;
-	struct efi_systbl *efi_systbl = NULL;
-	void *efi_ih = NULL;
-	bool has_bs = false;
-
-	mbi_size = *(uint32_t *)mbi;
-	if (mbi_size < sizeof(multiboot_info))
-		memcpy(mbidest, mbi, mbi_size);
-	else
-		panic("multiboot_info too big"); /* will not show up */
-
-	*RELOC(bool *, &multiboot2_enabled) = true;
-
-	for (cp = mbi + (2 * sizeof(uint32_t));
-	     cp - mbi < mbi_size;
-	     cp += roundup(mbt->size, MULTIBOOT_INFO_ALIGN)) {
-		mbt = (struct multiboot_tag_module *)cp;
-		switch (mbt->type) {
-		case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
-			mbt_elf = (struct multiboot_tag_elf_sections *)mbt;
-			break;
-#ifdef __LP64__
-		case MULTIBOOT_TAG_TYPE_EFI64:
-			efi_systbl = (struct efi_systbl *)
-				((struct multiboot_tag_efi64 *)mbt)->pointer;
-			break;
-		case MULTIBOOT_TAG_TYPE_EFI64_IH:
-			efi_ih = (void *)
-			    ((struct multiboot_tag_efi64_ih *)mbt)->pointer;
-			break;
-#else
-		case MULTIBOOT_TAG_TYPE_EFI32:
-			efi_systbl = (struct efi_systbl *)
-				((struct multiboot_tag_efi32 *)mbt)->pointer;
-			break;
-		case MULTIBOOT_TAG_TYPE_EFI32_IH:
-			efi_ih = (void *)
-			    ((struct multiboot_tag_efi32_ih *)mbt)->pointer;
-			break;
-#endif
-		case MULTIBOOT_TAG_TYPE_EFI_BS:
-#if notyet
-			has_bs = true;
-#endif
-			break;
-		default:
-			break;
-		}
-	}
-
-	/* Broken */
-	if (has_bs)
-		efi_exit_bs(efi_systbl, efi_ih);	
-
-	if (mbt_elf)
-		multiboot2_copy_syms(mbt_elf,
-		    RELOC(struct multiboot_symbols *, &Multiboot_Symbols),
-		    RELOC(bool *, &has_syms),
-		    RELOC(int **, &esym),
-		    RELOC(void *, &end),
-		    KERNBASE);
-
-	return;
-}
-
-static void
 bootinfo_add(struct btinfo_common *item, int type, int len)    
 {
 	int i;  
 	struct bootinfo *bip = (struct bootinfo *)&bootinfo;
@@ -564,9 +306,9 @@
 			break;
 	}
 
 	bootinfo_add((struct btinfo_common *)bim, BTINFO_MEMMAP,
-	    sizeof(bimbuf));
+	    (char*)&bim->entry[bim->num] - (char *)bim);
 
 	return;
 }
 
@@ -643,18 +385,18 @@
 multiboot2_post_reloc(void)
 {
 	uint32_t mbi_size;
 	struct multiboot_tag *mbt;
-	char *mbi = multiboot_info;
+	char *mbi = multiboot2_info;
 	char *cp;
 	int module_count = 0;
 	struct btinfo_framebuffer fbinfo;
 	bool has_fbinfo = false;
 
 	if (multiboot2_enabled == false)
 		goto out;
 
-	mbi_size = *(uint32_t *)multiboot_info;
+	mbi_size = *(uint32_t *)multiboot2_info;
 	if (mbi_size < 2 * sizeof(uint32_t))
 		goto out;
 
 	bootinfo.bi_nentries = 0;
@@ -798,9 +540,9 @@
 		tag_name = "EFI boot services available"; break;
 	case MULTIBOOT_TAG_TYPE_EFI32_IH:
 		tag_name = "EFI ImageHandle"; break;
 	case MULTIBOOT_TAG_TYPE_EFI64_IH:
-		tag_name = "EFI ImaheHandle"; break;
+		tag_name = "EFI ImageHandle"; break;
 	case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
 		tag_name = "load base"; break;
 	default:
 		tag_name = ""; break;
@@ -822,14 +564,14 @@
 
 	if (multiboot2_enabled == false)
 		goto out;
 
-	total_size = *(uint32_t *)multiboot_info;
-	reserved = *(uint32_t *)multiboot_info + 1;
-	mbt = (struct multiboot_tag *)(uint32_t *)multiboot_info + 2;
+	total_size = *(uint32_t *)multiboot2_info;
+	reserved = *(uint32_t *)multiboot2_info + 1;
+	mbt = (struct multiboot_tag *)(uint32_t *)multiboot2_info + 2;
 
-	for (cp = multiboot_info + sizeof(total_size) + sizeof(reserved);
-	     cp - multiboot_info < total_size;
+	for (cp = multiboot2_info + sizeof(total_size) + sizeof(reserved);
+	     cp - multiboot2_info < total_size;
 	     cp = cp + roundup(mbt->size, MULTIBOOT_TAG_ALIGN)) {
 		const char *tag_name;
 
 		mbt = (struct multiboot_tag *)cp;
@@ -1020,9 +762,9 @@
 	vaddr_t symstart = (vaddr_t)ms->s_symstart;
 	vaddr_t strstart = (vaddr_t)ms->s_strstart;
 	Elf_Ehdr ehdr;
 
-	if (!multiboot2_enabled || !has_syms)
+	if (!multiboot2_enabled || !multiboot2_has_syms)
 		return false;
 
 	KASSERT(esym != 0);
 
Index: sys/arch/i386/conf/files.i386
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/files.i386,v
retrieving revision 1.401
diff -U4 -r1.401 files.i386
--- sys/arch/i386/conf/files.i386	18 Oct 2019 01:38:28 -0000	1.401
+++ sys/arch/i386/conf/files.i386	30 Jan 2020 01:55:55 -0000
@@ -51,8 +51,9 @@
 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/x86/x86/multiboot32.c	multiboot
 
 file	arch/i386/i386/autoconf.c
 file	arch/i386/i386/aout_machdep.c	exec_aout
 file	arch/i386/i386/busfunc.S
Index: sys/arch/i386/i386/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/locore.S,v
retrieving revision 1.177
diff -U4 -r1.177 locore.S
--- sys/arch/i386/i386/locore.S	15 Jan 2020 18:47:23 -0000	1.177
+++ sys/arch/i386/i386/locore.S	30 Jan 2020 01:55:55 -0000
@@ -576,8 +576,15 @@
 
 	.align 16
 multiboot2_loader:
 	movl    $_RELOC(tmpstk),%esp
+	push	$KERNBASE			/* vaddr_t kernbase */
+	push	$_RELOC(end)			/* void *end */
+	push    $RELOC(esym)			/* int **esymp */
+	push	$_RELOC(multiboot2_has_syms)	/* bool *has_syms */
+	push	$_RELOC(Multiboot_Symbols)      /* struct multiboot_symbol * */
+	push	$_RELOC(multiboot2_enabled)	/* boot *mb2_enabled */
+	push	$_RELOC(multiboot2_info) 	/* void *mbidest */
 	pushl	%ebx		/* Address of Multiboot information */
 	call	_C_LABEL(multiboot2_pre_reloc)
 	addl	$4,%esp
 	jmp	2f
--- /dev/null	2020-01-29 04:23:58.514243519 +0100
+++ sys/arch/x86/x86/multiboot32.c	2020-01-30 02:52:04.282668388 +0100
@@ -0,0 +1,276 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include "opt_multiboot.h"
+
+#include <sys/cdefs_elf.h>
+#include <sys/param.h>
+#include <sys/ksyms.h>
+#include <sys/common_ansi.h>
+
+#include <x86/efi.h>
+
+#include <machine/bootinfo.h>
+#include <arch/x86/include/multiboot32.h>
+#include <arch/i386/include/multiboot2.h>
+
+#if !defined(MULTIBOOT)
+#  error "MULTIBOOT not defined; this cannot happen."
+#endif
+
+static void
+efi_exit_bs(struct efi_systbl *efi_systbl, void *efi_ih)
+{
+	struct efi_bs *efi_bs;
+	struct efi_md *desc;
+	uintn bufsize, key, size;
+	uint32_t vers;
+
+	if (efi_systbl == NULL)
+		goto out;
+
+	if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG)
+		goto out;
+
+	efi_bs = efi_systbl->st_bs;
+
+	if (efi_bs == NULL)
+		goto out;
+
+	if (efi_bs->bs_hdr.th_sig != EFI_BS_SIG)
+		goto out;
+
+	if (efi_ih == NULL)
+		goto out;
+
+	bufsize = 16384;
+
+	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
+	    bufsize, (void **)&desc) != 0)
+		goto out;
+
+	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) == 0)
+		goto exit_bs;
+
+	(void)efi_bs->bs_freepool((void *)desc);
+
+	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
+	    bufsize, (void **)&desc) != 0)
+		goto exit_bs;
+
+	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) != 0)
+		goto exit_bs;
+
+exit_bs:
+	if (efi_bs->bs_exitbootservices(efi_ih, key) != 0)
+		goto out;
+
+out:
+	return;
+}
+
+void
+multiboot2_copy_syms(struct multiboot_tag_elf_sections *mbt_elf, 
+		     struct multiboot_symbols *ms,
+		     bool *has_symsp, int **esymp, void *endp,
+		     vaddr_t kernbase)
+{
+	Elf_Shdr *symtabp, *strtabp;
+	Elf_Word symsize, strsize;
+	Elf_Addr symaddr, straddr;
+	Elf_Addr symstart, strstart;
+	Elf_Addr cp1src, cp1dst;
+	Elf_Word cp1size;
+	Elf_Addr cp2src, cp2dst;
+	Elf_Word cp2size;
+	int i;
+
+	/*
+	 * Locate a symbol table and its matching string table in the
+	 * section headers passed in by the boot loader.  Set 'symtabp'
+	 * and 'strtabp' with pointers to the matching entries.
+	 */
+	symtabp = strtabp = NULL;
+	for (i = 0; i < mbt_elf->num && symtabp == NULL &&
+	    strtabp == NULL; i++) {
+		Elf_Shdr *shdrp;
+
+		shdrp = &((Elf_Shdr *)mbt_elf->sections)[i];
+
+		if ((shdrp->sh_type == SHT_SYMTAB) &&
+		    shdrp->sh_link != SHN_UNDEF) {
+			Elf_Shdr *shdrp2;
+
+			shdrp2 = &((Elf_Shdr *)mbt_elf->sections)
+			    [shdrp->sh_link];
+
+			if (shdrp2->sh_type == SHT_STRTAB) {
+				symtabp = (Elf_Shdr *)shdrp;
+				strtabp = (Elf_Shdr *)shdrp2;
+			}
+		}
+	}
+	if (symtabp == NULL || strtabp == NULL)
+		return;
+
+	symaddr = symtabp->sh_addr;
+	straddr = strtabp->sh_addr;
+	symsize = symtabp->sh_size;
+	strsize = strtabp->sh_size;
+
+	/*
+	 * Copy the symbol and string tables just after the kernel's
+	 * end address, in this order.  Only the contents of these ELF
+	 * sections are copied; headers are discarded.  esym is later
+	 * updated to point to the lowest "free" address after the tables
+	 * so that they are mapped appropriately when enabling paging.
+	 *
+	 * We need to be careful to not overwrite valid data doing the
+	 * copies, hence all the different cases below.  We can assume
+	 * that if the tables start before the kernel's end address,
+	 * they will not grow over this address.
+	 */
+        if ((void *)(uintptr_t)symaddr < endp &&
+	    (void *)(uintptr_t)straddr < endp) {
+		cp1src = symaddr; cp1size = symsize;
+		cp2src = straddr; cp2size = strsize;
+        } else if ((void *)(uintptr_t)symaddr > endp &&
+		   (void *)(uintptr_t)straddr < endp) {
+		cp1src = symaddr; cp1size = symsize;
+		cp2src = straddr; cp2size = strsize;
+        } else if ((void *)(uintptr_t)symaddr < endp &&
+		   (void *)(uintptr_t)straddr > endp) {
+		cp1src = straddr; cp1size = strsize;
+		cp2src = symaddr; cp2size = symsize;
+	} else {
+		/* symaddr and straddr are both over end */
+		if (symaddr < straddr) {
+			cp1src = symaddr; cp1size = symsize;
+			cp2src = straddr; cp2size = strsize;
+		} else {
+			cp1src = straddr; cp1size = strsize;
+			cp2src = symaddr; cp2size = symsize;
+		}
+	}
+
+	cp1dst = (Elf_Addr)(uintptr_t)endp;
+	cp2dst = (Elf_Addr)(uintptr_t)endp + cp1size;
+
+	(void)memcpy((void *)(uintptr_t)cp1dst,
+		     (void *)(uintptr_t)cp1src, cp1size);
+	(void)memcpy((void *)(uintptr_t)cp2dst,
+		     (void *)(uintptr_t)cp2src, cp2size);
+
+	symstart = (cp1src == symaddr) ? cp1dst : cp2dst;
+	strstart = (cp1src == straddr) ? cp1dst : cp2dst;
+
+	ms->s_symstart = symstart + kernbase;
+	ms->s_symsize  = symsize;
+	ms->s_strstart = strstart + kernbase;
+	ms->s_strsize  = strsize;
+
+	*has_symsp = true;
+	*esymp = (int *)((uintptr_t)endp + symsize +
+		 strsize + (uintptr_t)kernbase);
+}
+
+void 
+multiboot2_pre_reloc(char *mbi, void *mbidest,
+		     bool *mb2_enabled, struct multiboot_symbols *ms,
+		     bool *has_symsp, int **esymp, void *endp,
+		     vaddr_t kernbase)
+{
+	uint32_t mbi_size;
+	char *cp;
+	struct multiboot_tag_module *mbt;
+	struct multiboot_tag_elf_sections *mbt_elf = NULL;
+	struct efi_systbl *efi_systbl = NULL;
+	void *efi_ih = NULL;
+	bool has_bs = false;
+
+	mbi_size = *(uint32_t *)mbi;
+	if (mbi_size >= MULTIBOOT2_INFO_MAXLEN)
+		return;
+
+	memcpy(mbidest, mbi, mbi_size);
+	*mb2_enabled = true;
+
+	for (cp = mbi + (2 * sizeof(uint32_t));
+	     cp - mbi < mbi_size;
+	     cp += roundup(mbt->size, MULTIBOOT_INFO_ALIGN)) {
+		mbt = (struct multiboot_tag_module *)cp;
+		switch (mbt->type) {
+		case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
+			mbt_elf = (struct multiboot_tag_elf_sections *)mbt;
+			break;
+#ifdef __LP64__
+		case MULTIBOOT_TAG_TYPE_EFI64:
+			efi_systbl = (struct efi_systbl *)
+				((struct multiboot_tag_efi64 *)mbt)->pointer;
+			break;
+		case MULTIBOOT_TAG_TYPE_EFI64_IH:
+			efi_ih = (void *)
+			    ((struct multiboot_tag_efi64_ih *)mbt)->pointer;
+			break;
+#else
+		case MULTIBOOT_TAG_TYPE_EFI32:
+			efi_systbl = (struct efi_systbl *)
+				((struct multiboot_tag_efi32 *)mbt)->pointer;
+			break;
+		case MULTIBOOT_TAG_TYPE_EFI32_IH:
+			efi_ih = (void *)
+			    ((struct multiboot_tag_efi32_ih *)mbt)->pointer;
+			break;
+#endif
+		case MULTIBOOT_TAG_TYPE_EFI_BS:
+#if notyet
+			has_bs = true;
+#endif
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Broken */
+	if (has_bs)
+		efi_exit_bs(efi_systbl, efi_ih);	
+
+	if (mbt_elf)
+		multiboot2_copy_syms(mbt_elf, ms, 
+				     has_symsp, esymp, endp,
+				     kernbase);
+ 
+	return;
+}
--- /dev/null	2020-01-29 04:23:58.514243519 +0100
+++ sys/arch/x86/include/multiboot32.h	2020-01-30 02:52:33.403858811 +0100
@@ -0,0 +1,62 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: multiboot2.c,v 1.3 2019/12/10 02:06:07 manu Exp $");
+#include <arch/i386/include/multiboot2.h>
+
+#define MULTIBOOT2_INFO_MAXLEN 16384
+
+struct multiboot_symbols {
+        uint32_t s_symstart;
+        uint32_t s_symsize;
+        uint32_t s_strstart;
+        uint32_t s_strsize;
+};
+
+extern char multiboot2_info[MULTIBOOT2_INFO_MAXLEN];
+extern int multiboot2_info_maxlen;
+extern bool multiboot2_enabled;
+extern bool multiboot2_has_syms;
+extern struct multiboot_symbols Multiboot_Symbols;
+
+void multiboot2_copy_syms(struct multiboot_tag_elf_sections *,
+                          struct multiboot_symbols *,
+                          bool *, int **, void *, vaddr_t);
+
+void multiboot2_pre_reloc(char *, void *,
+                          bool *, struct multiboot_symbols *,
+                          bool *, int **, void *, vaddr_t);
+void multiboot2_post_reloc(void);
+void multiboot2_print_info(void);
+bool multiboot2_ksyms_addsyms_elf(void);
+
+
--- /dev/null	2020-01-29 04:23:58.514243519 +0100
+++ sys/arch/amd64/amd64/multiboot_locore.S	2020-01-28 03:10:06.352932197 +0100
@@ -0,0 +1,293 @@
+/*	$NetBSD$ */
+
+/*
+ * Copyright (c) 2019, 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Override user-land alignment before including asm.h */
+#define	ALIGN_DATA	.align	8
+#define ALIGN_TEXT	.align 16,0x90
+#define _ALIGN_TEXT	ALIGN_TEXT
+
+#include <machine/asm.h>
+
+#include "opt_copy_symtab.h"
+#include "opt_ddb.h"
+#include "opt_ddbparam.h"
+#include "opt_modular.h"
+#include "opt_realmem.h"
+
+#include "opt_multiboot.h"
+#include "opt_xen.h"
+
+#include "assym.h"
+#include "ksyms.h"
+
+#include <sys/errno.h>
+#include <sys/syscall.h>
+
+#include <machine/segments.h>
+#include <machine/specialreg.h>
+#include <machine/bootinfo.h>
+
+#ifndef XENPV
+#include <arch/i386/include/multiboot.h>
+#endif 
+
+#define CODE_SEGMENT	0x08
+#define DATA_SEGMENT	0x10
+
+#define	_RELOC(x)	((x) - KERNBASE)
+#define	RELOC(x)	_RELOC(_C_LABEL(x))
+
+	.data
+	/* Space for the temporary stack */
+	.size	tmpstk, tmpstk - .
+	.space	512
+tmpstk:
+
+.section multiboot
+	.align	8
+	.globl	Multiboot2_Header
+_C_LABEL(Multiboot2_Header):
+	.int	MULTIBOOT2_HEADER_MAGIC
+	.int	MULTIBOOT2_ARCHITECTURE_I386
+	.int	Multiboot2_Header_end - Multiboot2_Header
+	.int	-(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 \
+		+ (Multiboot2_Header_end - Multiboot2_Header))
+
+	.int	1	/* MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST */
+	.int	12	/* sizeof(multiboot_header_tag_information_request) */
+			/* + sizeof(uint32_t) * requests */
+	.int	4	/* MULTIBOOT_TAG_TYPE_BASIC_MEMINFO */
+	.align	8
+
+	.int	3	/* MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS */
+	.int	16	/* sizeof(struct multiboot_tag_efi64) */
+	.quad	(multiboot2_entry - KERNBASE)
+	.align	8
+
+	.int	9	/* MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 */
+	.int	16	/* sizeof(struct multiboot_tag_efi64) */
+	.quad	(multiboot2_entry - KERNBASE)
+	.align	8
+
+#if notyet
+	/*
+	 * Could be used to get an early console for debug,
+	 * but this is broken.
+	 */
+	.int	7	/* MULTIBOOT_HEADER_TAG_EFI_BS */
+	.int	8	/* sizeof(struct multiboot_tag) */
+	.align	8
+#endif
+
+	.int	0	/* MULTIBOOT_HEADER_TAG_END */
+	.int	8	/* sizeof(struct multiboot_tag) */
+	.align	8
+	.globl	Multiboot2_Header_end
+_C_LABEL(Multiboot2_Header_end):
+
+	.text
+
+multiboot2_entry:
+	.code64
+	/*
+	 * 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 multiboot2_info
+	 *
+	 * Here we will:
+	 * - copy the kernel to 0x200000 (KERNTEXTOFF - KERNBASE)
+	 *	as almost all the code in locore.S assume it is there. 
+	 *	This is derived from 
+	 *	src/sys/arch/i386/stand/efiboot/bootx64/startprog64.S
+	 * - Call multiboot_pre_reloc() and join main bootstrap code
+	 */
+
+	cli
+
+	/*
+	 * Discover our load address and use it to get multiboot2_entry address
+	 */
+	mov	$_RELOC(tmpstk),%rsp
+	call	next
+next:	pop	%r8
+	sub	$(next - multiboot2_entry), %r8
+
+	/*
+	 * Save multiboot_info for later. We cannot use	
+	 * temporary stack for that since we are going to
+	 * overwrite it.
+	 */
+	movl	%ebx, (multiboot2_info_ptr - multiboot2_entry)(%r8)
+
+	/*
+	 * Set %r10 to (multiboot2_loader - kernel_text)
+	 */
+	mov	$multiboot2_loader, %r10
+	sub	$kernel_text, %r10
+
+	/*
+	 * Get relocated multiboot2_loader entry point in %r9
+	 */
+	mov	$(KERNTEXTOFF - KERNBASE), %r9
+	add	%r10, %r9
+
+	/* Copy kernel */
+	mov	$(KERNTEXTOFF - KERNBASE), %rdi	/* dest */
+	mov	%r8, %rsi		
+	sub	$multiboot2_entry, %rsi
+	add	$kernel_text, %rsi		/* src */
+	mov	$__kernel_end, %rcx
+	sub	$kernel_text, %rcx		/* size */
+
+#if without_memove
+	/* Assume aligned, non overlapping copy */
+	shrq	$3, %rcx
+	rep
+	movsq
+#else
+	/*
+	 * Calling memmove() require a minimal stack to
+	 * hold the return address. This stack cannot be
+	 * tmpstk in the data segment since memove() will
+	 * overwrite it. 
+	 *
+	 * We store the return address in .Llocalstk
+	 * point the stack pointer on it, and jump to 
+	 * memmove(), which address is computed in %rax 
+	 */
+	lea	(.Llocalstk - multiboot2_entry)(%r8), %rsp
+	push	%r8
+	push	%r9
+
+	mov	%r8, %rax
+	sub	$multiboot2_entry, %rax
+	add	$memmove, %rax
+
+	/* memmove(%rdi dst, %rsi src, %rdx len) */
+	mov	%rcx, %rdx
+	call	*%rax
+	jmp	.Lafter_memmove
+	
+	.size	.Llocalstk, .Llocalstk - .
+	.space	32
+.Llocalstk:
+
+.Lafter_memmove:
+	pop	%r9
+	pop	%r8
+#endif
+	mov	%r8, %rdi	/* %rdi: loaded multiboot2_entry address */
+	mov	%r9, %rsi	/* %rsi: kernel entry address */
+
+	/* Prepare jump address */
+	lea	(multiboot2_loader32a - multiboot2_entry)(%rdi), %rax
+	movl	%eax, (multiboot2_loader32r - multiboot2_entry)(%rdi)
+
+	/* Setup GDT */
+	lea	(gdt - multiboot2_entry)(%rdi), %rax
+	mov	%rax, (gdtrr - multiboot2_entry)(%rdi)
+	lgdt	(gdtr - multiboot2_entry)(%rdi)
+
+	/* Jump to set %cs */
+	ljmp	*(multiboot2_loader32r - multiboot2_entry)(%rdi)
+
+	.align	4
+	.code32
+multiboot2_loader32a:
+	movl	$DATA_SEGMENT, %eax
+	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	multiboot2_loader32b
+
+	.align	4
+multiboot2_loader32b:
+	xor	%eax, %eax
+
+	/* 
+	* Reload multiboot info from target location
+	*/	
+	movl	_RELOC(multiboot2_info_ptr), %ebx
+	call	*%esi
+
+	.align	16
+multiboot2_loader32r:
+	.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	0
+
+multiboot2_info_ptr:
+	.long	0
+	
+	.align 16
+multiboot2_loader:
+	movl	$_RELOC(tmpstk),%esp
+	push	$KERNBASE_LO			/* vaddr_t kernbase */
+	push	$_RELOC(end)			/* void *end */
+	push    $RELOC(esym)			/* int **esymp */
+	push	$_RELOC(multiboot2_has_syms)	/* bool *has_syms */
+	push	$_RELOC(Multiboot_Symbols)      /* struct multiboot_symbol * */
+	push	$_RELOC(multiboot2_enabled)	/* boot *mb2_enabled */
+	push	$_RELOC(multiboot2_info) 	/* void *mbidest */
+	push	%ebx				/* char *mbi */
+	call	_C_LABEL(multiboot2_pre_reloc)
+
+	/* Make esym a 64 bit pointer */
+	movl	$RELOC(esym),%ebp
+	movl	$KERNBASE_HI,4(%ebp)
+
+	jmp	begin


Home | Main Index | Thread Index | Old Index