Home | History | Annotate | Line # | Download | only in x86
      1 /*	$NetBSD: multiboot2.c,v 1.8 2021/10/07 12:52:27 msaitoh Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Julio M. Merino Vidal.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: multiboot2.c,v 1.8 2021/10/07 12:52:27 msaitoh Exp $");
     34 
     35 #include "opt_multiboot.h"
     36 
     37 #include <sys/param.h>
     38 #include <sys/systm.h>
     39 #include <sys/cdefs_elf.h>
     40 #include <sys/boot_flag.h>
     41 #include <sys/exec.h>
     42 #include <sys/exec_elf.h>
     43 #include <sys/optstr.h>
     44 #include <sys/ksyms.h>
     45 #include <sys/common_ansi.h>
     46 #include <sys/intr.h>
     47 
     48 #include <x86/efi.h>
     49 
     50 #include <machine/bootinfo.h>
     51 #include <arch/i386/include/multiboot2.h>
     52 
     53 #ifdef _LOCORE64
     54 typedef uint64_t   locore_vaddr_t;
     55 typedef Elf64_Shdr locore_Elf_Shdr;
     56 typedef Elf64_Word locore_Elf_Word;
     57 typedef Elf64_Addr locore_Elf_Addr;
     58 #else
     59 typedef vaddr_t   locore_vaddr_t;
     60 typedef Elf_Shdr locore_Elf_Shdr;
     61 typedef Elf_Word locore_Elf_Word;
     62 typedef Elf_Addr locore_Elf_Addr;
     63 #endif
     64 
     65 #if !defined(MULTIBOOT)
     66 #  error "MULTIBOOT not defined; this cannot happen."
     67 #endif
     68 
     69 /*
     70  * This is an attempt to get an early debug output. It
     71  * requires EFI Boot Services, and it does not work anyway:
     72  * it causes EFI to try to handle interrupts while the kernel
     73  * already took that over, hence we get a reboot.
     74  */
     75 #define BS_PRINT(efisystbl, wstring)					\
     76 	efi_systbl->st_coutif->ei_outputstring(efi_systbl->st_coutif,	\
     77 	    (efi_char *)__UNCONST(wstring))
     78 
     79 struct multiboot_symbols {
     80 	uint32_t s_symstart;
     81 	uint32_t s_symsize;
     82 	uint32_t s_strstart;
     83 	uint32_t s_strsize;
     84 };
     85 
     86 void multiboot2_copy_syms(struct multiboot_tag_elf_sections *,
     87 			  struct multiboot_symbols *,
     88 			  bool *, int **, void *, vaddr_t);
     89 /*
     90  * Because of clashes between multiboot.h and multiboot2.h we
     91  * cannot include both, and we need to redefine here:
     92  */
     93 void            multiboot2_pre_reloc(char *);
     94 void            multiboot2_post_reloc(void);
     95 void            multiboot2_print_info(void);
     96 bool            multiboot2_ksyms_addsyms_elf(void);
     97 
     98 extern int              biosbasemem;
     99 extern int              biosextmem;
    100 #ifdef __i386__
    101 extern int              biosmem_implicit;
    102 #endif
    103 extern int              boothowto;
    104 extern struct bootinfo  bootinfo;
    105 extern int              end;
    106 extern int *            esym;
    107 extern char             start;
    108 
    109 /*
    110  * There is no way to perform dynamic allocation
    111  * at this time, hence we need to waste memory,
    112  * with the hope data will fit.
    113  */
    114 char multiboot_info[16384] = "\0\0\0\0";
    115 bool multiboot2_enabled = false;
    116 bool has_syms = false;
    117 struct multiboot_symbols Multiboot_Symbols;
    118 
    119 #define RELOC(type, x) ((type)((vaddr_t)(x) - KERNBASE))
    120 
    121 static void
    122 efi_exit_bs(struct efi_systbl *efi_systbl, void *efi_ih)
    123 {
    124 	struct efi_bs *efi_bs;
    125 	struct efi_md *desc;
    126 	uintn bufsize, key, size;
    127 	uint32_t vers;
    128 
    129 	if (efi_systbl == NULL)
    130 		panic("EFI system table is NULL");
    131 
    132 	if (efi_systbl->st_hdr.th_sig != EFI_SYSTBL_SIG)
    133 		panic("EFI system table signature is wrong");
    134 
    135 	efi_bs = efi_systbl->st_bs;
    136 
    137 	if (efi_bs == NULL)
    138 		panic("EFI BS is NULL");
    139 
    140 	if (efi_bs->bs_hdr.th_sig != EFI_BS_SIG)
    141 		panic("EFI BS signature is wrong");
    142 
    143 	if (efi_ih == NULL)
    144 		panic("EFI IH is NULL");
    145 
    146 	bufsize = 16384;
    147 
    148 	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
    149 	    bufsize, (void **)&desc) != 0)
    150 		panic("EFI AllocatePool failed");
    151 
    152 	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) == 0)
    153 		goto exit_bs;
    154 
    155 	(void)efi_bs->bs_freepool((void *)desc);
    156 
    157 	if (efi_bs->bs_allocatepool(EFI_MD_TYPE_DATA,
    158 	    bufsize, (void **)&desc) != 0)
    159 		panic("EFI AllocatePool failed");
    160 
    161 	if (efi_bs->bs_getmemorymap(&bufsize, desc, &key, &size, &vers) != 0)
    162 		panic("EFI GetMemoryMap failed");
    163 
    164 exit_bs:
    165 	if (efi_bs->bs_exitbootservices(efi_ih, key) != 0)
    166 		panic("EFI ExitBootServices failed");
    167 
    168 	return;
    169 }
    170 
    171 void
    172 multiboot2_copy_syms(struct multiboot_tag_elf_sections *mbt_elf,
    173 		     struct multiboot_symbols *ms,
    174 		     bool *has_symsp, int **esymp, void *endp,
    175 		     vaddr_t kernbase)
    176 {
    177 	int i;
    178 	locore_Elf_Shdr *symtabp, *strtabp;
    179 	locore_Elf_Word symsize, strsize;
    180 	locore_Elf_Addr symaddr, straddr;
    181 	locore_Elf_Addr symstart, strstart;
    182 	locore_Elf_Addr cp1src, cp1dst;
    183 	locore_Elf_Word cp1size;
    184 	locore_Elf_Addr cp2src, cp2dst;
    185 	locore_Elf_Word cp2size;
    186 
    187 	/*
    188 	 * Locate a symbol table and its matching string table in the
    189 	 * section headers passed in by the boot loader.  Set 'symtabp'
    190 	 * and 'strtabp' with pointers to the matching entries.
    191 	 */
    192 	symtabp = strtabp = NULL;
    193 	for (i = 0; i < mbt_elf->num && symtabp == NULL &&
    194 	    strtabp == NULL; i++) {
    195 		locore_Elf_Shdr *shdrp;
    196 
    197 		shdrp = &((locore_Elf_Shdr *)mbt_elf->sections)[i];
    198 
    199 		if ((shdrp->sh_type == SHT_SYMTAB) &&
    200 		    shdrp->sh_link != SHN_UNDEF) {
    201 			locore_Elf_Shdr *shdrp2;
    202 
    203 			shdrp2 = &((locore_Elf_Shdr *)mbt_elf->sections)
    204 			    [shdrp->sh_link];
    205 
    206 			if (shdrp2->sh_type == SHT_STRTAB) {
    207 				symtabp = (locore_Elf_Shdr *)shdrp;
    208 				strtabp = (locore_Elf_Shdr *)shdrp2;
    209 			}
    210 		}
    211 	}
    212 	if (symtabp == NULL || strtabp == NULL)
    213 		return;
    214 
    215 	symaddr = symtabp->sh_addr;
    216 	straddr = strtabp->sh_addr;
    217 	symsize = symtabp->sh_size;
    218 	strsize = strtabp->sh_size;
    219 
    220 	/*
    221 	 * Copy the symbol and string tables just after the kernel's
    222 	 * end address, in this order.  Only the contents of these ELF
    223 	 * sections are copied; headers are discarded.  esym is later
    224 	 * updated to point to the lowest "free" address after the tables
    225 	 * so that they are mapped appropriately when enabling paging.
    226 	 *
    227 	 * We need to be careful to not overwrite valid data doing the
    228 	 * copies, hence all the different cases below.  We can assume
    229 	 * that if the tables start before the kernel's end address,
    230 	 * they will not grow over this address.
    231 	 */
    232 	if ((void *)(uintptr_t)symaddr < endp &&
    233 	    (void *)(uintptr_t)straddr < endp) {
    234 		cp1src = symaddr; cp1size = symsize;
    235 		cp2src = straddr; cp2size = strsize;
    236 	} else if ((void *)(uintptr_t)symaddr > endp &&
    237 		   (void *)(uintptr_t)straddr < endp) {
    238 		cp1src = symaddr; cp1size = symsize;
    239 		cp2src = straddr; cp2size = strsize;
    240 	} else if ((void *)(uintptr_t)symaddr < endp &&
    241 		   (void *)(uintptr_t)straddr > endp) {
    242 		cp1src = straddr; cp1size = strsize;
    243 		cp2src = symaddr; cp2size = symsize;
    244 	} else {
    245 		/* symaddr and straddr are both over end */
    246 		if (symaddr < straddr) {
    247 			cp1src = symaddr; cp1size = symsize;
    248 			cp2src = straddr; cp2size = strsize;
    249 		} else {
    250 			cp1src = straddr; cp1size = strsize;
    251 			cp2src = symaddr; cp2size = symsize;
    252 		}
    253 	}
    254 
    255 	cp1dst = (locore_Elf_Addr)(uintptr_t)endp;
    256 	cp2dst = (locore_Elf_Addr)(uintptr_t)endp + cp1size;
    257 
    258 	(void)memcpy((void *)(uintptr_t)cp1dst,
    259 		     (void *)(uintptr_t)cp1src, cp1size);
    260 	(void)memcpy((void *)(uintptr_t)cp2dst,
    261 		     (void *)(uintptr_t)cp2src, cp2size);
    262 
    263 	symstart = (cp1src == symaddr) ? cp1dst : cp2dst;
    264 	strstart = (cp1src == straddr) ? cp1dst : cp2dst;
    265 
    266 	ms->s_symstart = symstart + kernbase;
    267 	ms->s_symsize  = symsize;
    268 	ms->s_strstart = strstart + kernbase;
    269 	ms->s_strsize  = strsize;
    270 
    271 	*has_symsp = true;
    272 	*esymp = (int *)((uintptr_t)endp + symsize + strsize + kernbase);
    273 
    274 }
    275 
    276 void
    277 multiboot2_pre_reloc(char *mbi)
    278 {
    279 	uint32_t mbi_size;
    280 	void *mbidest = RELOC(void *, multiboot_info);
    281 	char *cp;
    282 	struct multiboot_tag_module *mbt;
    283 	struct multiboot_tag_elf_sections *mbt_elf = NULL;
    284 	struct efi_systbl *efi_systbl = NULL;
    285 	void *efi_ih = NULL;
    286 	bool has_bs = false;
    287 
    288 	mbi_size = *(uint32_t *)mbi;
    289 	if (mbi_size < sizeof(multiboot_info))
    290 		memcpy(mbidest, mbi, mbi_size);
    291 	else
    292 		panic("multiboot_info too big"); /* will not show up */
    293 
    294 	*RELOC(bool *, &multiboot2_enabled) = true;
    295 
    296 	for (cp = mbi + (2 * sizeof(uint32_t));
    297 	     cp - mbi < mbi_size;
    298 	     cp += roundup(mbt->size, MULTIBOOT_INFO_ALIGN)) {
    299 		mbt = (struct multiboot_tag_module *)cp;
    300 		switch (mbt->type) {
    301 		case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
    302 			mbt_elf = (struct multiboot_tag_elf_sections *)mbt;
    303 			break;
    304 #ifdef __LP64__
    305 		case MULTIBOOT_TAG_TYPE_EFI64:
    306 			efi_systbl = (struct efi_systbl *)
    307 				((struct multiboot_tag_efi64 *)mbt)->pointer;
    308 			break;
    309 		case MULTIBOOT_TAG_TYPE_EFI64_IH:
    310 			efi_ih = (void *)
    311 			    ((struct multiboot_tag_efi64_ih *)mbt)->pointer;
    312 			break;
    313 #else
    314 		case MULTIBOOT_TAG_TYPE_EFI32:
    315 			efi_systbl = (struct efi_systbl *)
    316 				((struct multiboot_tag_efi32 *)mbt)->pointer;
    317 			break;
    318 		case MULTIBOOT_TAG_TYPE_EFI32_IH:
    319 			efi_ih = (void *)
    320 			    ((struct multiboot_tag_efi32_ih *)mbt)->pointer;
    321 			break;
    322 #endif
    323 		case MULTIBOOT_TAG_TYPE_EFI_BS:
    324 #if notyet
    325 			has_bs = true;
    326 #endif
    327 			break;
    328 		default:
    329 			break;
    330 		}
    331 	}
    332 
    333 	/* Broken */
    334 	if (has_bs)
    335 		efi_exit_bs(efi_systbl, efi_ih);
    336 
    337 	if (mbt_elf)
    338 		multiboot2_copy_syms(mbt_elf,
    339 		    RELOC(struct multiboot_symbols *, &Multiboot_Symbols),
    340 		    RELOC(bool *, &has_syms),
    341 		    RELOC(int **, &esym),
    342 		    RELOC(void *, &end),
    343 		    KERNBASE);
    344 
    345 	return;
    346 }
    347 
    348 static struct btinfo_common *
    349 bootinfo_init(int type, int len)
    350 {
    351 	int i;
    352 	struct bootinfo *bip = (struct bootinfo *)&bootinfo;
    353 	vaddr_t data;
    354 
    355 	data = (vaddr_t)&bip->bi_data;
    356 	for (i = 0; i < bip->bi_nentries; i++) {
    357 		struct btinfo_common *tmp;
    358 
    359 		tmp = (struct btinfo_common *)data;
    360 		data += tmp->len;
    361 	}
    362 	if (data + len < (vaddr_t)&bip->bi_data + sizeof(bip->bi_data)) {
    363 		/* Initialize the common part */
    364 		struct btinfo_common *item = (struct btinfo_common *)data;
    365 		item->type = type;
    366 		item->len = len;
    367 		bip->bi_nentries++;
    368 		return item;
    369 	} else {
    370 		return NULL;
    371 	}
    372 }
    373 
    374 static void
    375 bootinfo_add(struct btinfo_common *item, int type, int len)
    376 {
    377 	struct btinfo_common *bip = bootinfo_init(type, len);
    378 	if (bip == NULL)
    379 		return;
    380 
    381 	/* Copy the data after the common part over */
    382 	memcpy(&bip[1], &item[1], len - sizeof(*item));
    383 }
    384 
    385 static void
    386 mbi_cmdline(struct multiboot_tag_string *mbt)
    387 {
    388 	char *cmdline = mbt->string;
    389 	struct btinfo_console bic;
    390 	struct btinfo_rootdevice bir;
    391 	char *cl;
    392 
    393 	if (optstr_get(cmdline, "console", bic.devname, sizeof(bic.devname))) {
    394 		if (strncmp(bic.devname, "com", sizeof(bic.devname)) == 0) {
    395 			char opt[10];
    396 
    397 			if (optstr_get(cmdline, "console_speed",
    398 				       opt, sizeof(opt)))
    399 				bic.speed = strtoul(opt, NULL, 10);
    400 			else
    401 				bic.speed = 0; /* Use default speed. */
    402 
    403 			if (optstr_get(cmdline, "console_addr",
    404 				       opt, sizeof(opt))) {
    405 				if (opt[0] == '0' && opt[1] == 'x')
    406 					bic.addr = strtoul(opt + 2, NULL, 16);
    407 				else
    408 					bic.addr = strtoul(opt, NULL, 10);
    409 			} else {
    410 				bic.addr = 0; /* Use default address. */
    411 			}
    412 
    413 			bootinfo_add((struct btinfo_common *)&bic,
    414 				     BTINFO_CONSOLE, sizeof(bic));
    415 
    416 		}
    417 
    418 		if (strncmp(bic.devname, "pc", sizeof(bic.devname)) == 0)
    419 			bootinfo_add((struct btinfo_common *)&bic,
    420 				     BTINFO_CONSOLE, sizeof(bic));
    421 	}
    422 
    423 	if (optstr_get(cmdline, "root", bir.devname, sizeof(bir.devname)))
    424 		bootinfo_add((struct btinfo_common *)&bir, BTINFO_ROOTDEVICE,
    425 		    sizeof(bir));
    426 
    427 	/*
    428 	 * Parse boot flags (-s and friends)
    429 	 */
    430 	cl = cmdline;
    431 
    432 	/* Skip kernel file name. */
    433 	while (*cl != '\0' && *cl != ' ')
    434 		cl++;
    435 	while (*cl == ' ')
    436 		cl++;
    437 
    438 	/* Check if there are flags and set 'howto' accordingly. */
    439 	if (*cl == '-') {
    440 		int howto = 0;
    441 
    442 		cl++;
    443 		while (*cl != '\0' && *cl != ' ') {
    444 			BOOT_FLAG(*cl, howto);
    445 			cl++;
    446 		}
    447 		if (*cl == ' ')
    448 			cl++;
    449 
    450 		boothowto = howto;
    451 	}
    452 
    453 	return;
    454 }
    455 
    456 static void
    457 mbi_modules(char *mbi, uint32_t mbi_size, int module_count)
    458 {
    459 	char *cp;
    460 	struct multiboot_tag_module *mbt;
    461 	size_t bim_len;
    462 	struct bi_modulelist_entry *bie;
    463 	struct btinfo_modulelist *bim;
    464 
    465 	bim_len = sizeof(*bim) + (module_count * sizeof(*bie));
    466 	bim = (struct btinfo_modulelist *)bootinfo_init(BTINFO_MODULELIST,
    467 	    bim_len);
    468 	if (bim == NULL)
    469 		return;
    470 
    471 	bim->num = module_count;
    472 	bim->endpa = end;
    473 
    474 	bie = (struct bi_modulelist_entry *)(bim + 1);
    475 
    476 	for (cp = mbi + (2 * sizeof(uint32_t));
    477 	     cp - mbi < mbi_size;
    478 	     cp += roundup(mbt->size, MULTIBOOT_INFO_ALIGN)) {
    479 		mbt = (struct multiboot_tag_module *)cp;
    480 		if (mbt->type != MULTIBOOT_TAG_TYPE_MODULE)
    481 			continue;
    482 
    483 		strncpy(bie->path, mbt->cmdline, sizeof(bie->path));
    484 		bie->type = BI_MODULE_ELF;
    485 		bie->len = mbt->mod_end - mbt->mod_start;
    486 		bie->base = mbt->mod_start;
    487 
    488 		bie++;
    489 	}
    490 }
    491 
    492 static void
    493 mbi_basic_meminfo(struct multiboot_tag_basic_meminfo *mbt)
    494 {
    495 	/* Make sure we don't override user-set variables. */
    496 	if (biosbasemem == 0) {
    497 		biosbasemem = mbt->mem_lower;
    498 #ifdef __i386__
    499 		biosmem_implicit = 1;
    500 #endif
    501 	}
    502 	if (biosextmem == 0) {
    503 		biosextmem = mbt->mem_upper;
    504 #ifdef __i386__
    505 		biosmem_implicit = 1;
    506 #endif
    507 	}
    508 
    509 	return;
    510 }
    511 
    512 static void
    513 mbi_bootdev(struct multiboot_tag_bootdev *mbt)
    514 {
    515 	struct btinfo_bootdisk bid;
    516 
    517 	bid.labelsector = -1;
    518 	bid.biosdev = mbt->biosdev;
    519 	bid.partition = mbt->slice;
    520 
    521 	bootinfo_add((struct btinfo_common *)&bid,
    522 	   BTINFO_BOOTDISK, sizeof(bid));
    523 }
    524 
    525 static void
    526 mbi_mmap(struct multiboot_tag_mmap *mbt)
    527 {
    528 	struct btinfo_memmap *bim;
    529 	int num;
    530 	char *cp;
    531 
    532 	if (mbt->entry_version != 0)
    533 		return;
    534 
    535 	/* Determine size */
    536 	num = 0;
    537 	for (cp = (char *)(mbt + 1);
    538 	     cp - (char *)mbt < mbt->size;
    539 	     cp += mbt->entry_size) {
    540 		num++;
    541 	}
    542 
    543 	bim = (struct btinfo_memmap *)bootinfo_init(BTINFO_MEMMAP,
    544 	    sizeof(num) + num * sizeof(struct bi_memmap_entry));
    545 	if (bim == NULL)
    546 		return;
    547 	bim->num = 0;
    548 
    549 	for (cp = (char *)(mbt + 1);
    550 	     cp - (char *)mbt < mbt->size;
    551 	     cp += mbt->entry_size) {
    552 		struct multiboot_mmap_entry *mbe;
    553 		struct bi_memmap_entry *bie;
    554 
    555 		mbe = (struct multiboot_mmap_entry *)cp;
    556 		bie = &bim->entry[bim->num];
    557 
    558 		bie->addr = mbe->addr;
    559 		bie->size = mbe->len;
    560 		switch (mbe->type) {
    561 		case MULTIBOOT_MEMORY_AVAILABLE:
    562 			bie->type = BIM_Memory;
    563 			break;
    564 		case MULTIBOOT_MEMORY_RESERVED:
    565 			bie->type = BIM_Reserved;
    566 			break;
    567 		case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE:
    568 			bie->type = BIM_ACPI;
    569 			break;
    570 		case MULTIBOOT_MEMORY_NVS:
    571 			bie->type = BIM_NVS;
    572 			break;
    573 		case MULTIBOOT_MEMORY_BADRAM:
    574 		default:
    575 			bie->type = BIM_Unusable;
    576 			break;
    577 		}
    578 
    579 		bim->num++;
    580 	}
    581 
    582 	KASSERT(bim->num == num);
    583 }
    584 
    585 static void
    586 mbi_vbe(struct multiboot_tag_vbe *mbt, struct btinfo_framebuffer *bif)
    587 {
    588 	bif->vbemode = mbt->vbe_mode;
    589 	return;
    590 }
    591 
    592 static void
    593 mbi_framebuffer(struct multiboot_tag_framebuffer *mbt,
    594      struct btinfo_framebuffer *bif)
    595 {
    596 	bif->physaddr = mbt->common.framebuffer_addr;
    597 	bif->width = mbt->common.framebuffer_width;
    598 	bif->height = mbt->common.framebuffer_height;
    599 	bif->depth = mbt->common.framebuffer_bpp;
    600 	bif->stride = mbt->common.framebuffer_pitch;
    601 
    602 	return;
    603 }
    604 
    605 static void
    606 mbi_efi32(struct multiboot_tag_efi32 *mbt)
    607 {
    608 	struct btinfo_efi bie;
    609 
    610 	bie.systblpa = mbt->pointer;
    611 	bie.flags = BI_EFI_32BIT;
    612 
    613 	bootinfo_add((struct btinfo_common *)&bie, BTINFO_EFI, sizeof(bie));
    614 }
    615 
    616 static void
    617 mbi_efi64(struct multiboot_tag_efi64 *mbt)
    618 {
    619 	struct btinfo_efi bie;
    620 
    621 	bie.systblpa = mbt->pointer;
    622 
    623 	bootinfo_add((struct btinfo_common *)&bie, BTINFO_EFI, sizeof(bie));
    624 }
    625 
    626 static void
    627 mbi_efi_mmap(struct multiboot_tag_efi_mmap *mbt)
    628 {
    629 	struct btinfo_efimemmap *bie;
    630 	size_t bie_len;
    631 
    632 	if (mbt->descr_vers != 0)
    633 		return;
    634 
    635 	bie_len = sizeof(*bie) + mbt->size - sizeof(*mbt);
    636 	bie = (struct btinfo_efimemmap *)bootinfo_init(BTINFO_EFIMEMMAP,
    637 	    bie_len);
    638 	if (bie == NULL)
    639 		return;
    640 
    641 	bie->num = (mbt->size - sizeof(*mbt)) / mbt->descr_size;
    642 	bie->version = mbt->descr_vers;
    643 	bie->size = mbt->descr_size;
    644 	memcpy(bie->memmap, mbt + 1, mbt->size - sizeof(*mbt));
    645 }
    646 
    647 void
    648 multiboot2_post_reloc(void)
    649 {
    650 	uint32_t mbi_size;
    651 	struct multiboot_tag *mbt;
    652 	char *mbi = multiboot_info;
    653 	char *cp;
    654 	int module_count = 0;
    655 	struct btinfo_framebuffer fbinfo;
    656 	bool has_fbinfo = false;
    657 
    658 	if (multiboot2_enabled == false)
    659 		goto out;
    660 
    661 	mbi_size = *(uint32_t *)multiboot_info;
    662 	if (mbi_size < 2 * sizeof(uint32_t))
    663 		goto out;
    664 
    665 	bootinfo.bi_nentries = 0;
    666 
    667 	memset(&fbinfo, 0, sizeof(fbinfo));
    668 
    669 	for (cp = mbi + (2 * sizeof(uint32_t));
    670 	     cp - mbi < mbi_size;
    671 	     cp += roundup(mbt->size, MULTIBOOT_INFO_ALIGN)) {
    672 		mbt = (struct multiboot_tag *)cp;
    673 		switch (mbt->type) {
    674 		case MULTIBOOT_TAG_TYPE_CMDLINE:
    675 			mbi_cmdline((void *)mbt);
    676 			break;
    677 		case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
    678 			break;
    679 		case MULTIBOOT_TAG_TYPE_MMAP:
    680 			mbi_mmap((void *)mbt);
    681 			break;
    682 		case MULTIBOOT_TAG_TYPE_MODULE:
    683 			module_count++;
    684 			break;
    685 		case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
    686 			mbi_basic_meminfo((void *)mbt);
    687 			break;
    688 		case MULTIBOOT_TAG_TYPE_BOOTDEV:
    689 			mbi_bootdev((void *)mbt);
    690 			break;
    691 		case MULTIBOOT_TAG_TYPE_VBE:
    692 			mbi_vbe((void *)mbt, &fbinfo);
    693 			break;
    694 		case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
    695 			mbi_framebuffer((void *)mbt, &fbinfo);
    696 			has_fbinfo = true;
    697 			break;
    698 		case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
    699 		case MULTIBOOT_TAG_TYPE_APM:
    700 			break;
    701 		case MULTIBOOT_TAG_TYPE_EFI32:
    702 			mbi_efi32((void *)mbt);
    703 			break;
    704 		case MULTIBOOT_TAG_TYPE_EFI64:
    705 			mbi_efi64((void *)mbt);
    706 			break;
    707 		case MULTIBOOT_TAG_TYPE_SMBIOS:
    708 		case MULTIBOOT_TAG_TYPE_ACPI_OLD:
    709 		case MULTIBOOT_TAG_TYPE_ACPI_NEW:
    710 		case MULTIBOOT_TAG_TYPE_NETWORK:
    711 			break;
    712 		case MULTIBOOT_TAG_TYPE_EFI_MMAP:
    713 			mbi_efi_mmap((void *)mbt);
    714 			break;
    715 		case MULTIBOOT_TAG_TYPE_EFI_BS:
    716 		case MULTIBOOT_TAG_TYPE_EFI32_IH:
    717 		case MULTIBOOT_TAG_TYPE_EFI64_IH:
    718 		case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
    719 		case MULTIBOOT_TAG_TYPE_END:
    720 		default:
    721 			break;
    722 		}
    723 	}
    724 
    725 	if (has_fbinfo)
    726 		bootinfo_add((struct btinfo_common *)&fbinfo,
    727 		    BTINFO_FRAMEBUFFER, sizeof(fbinfo));
    728 
    729 	if (module_count > 0)
    730 		mbi_modules(mbi, mbi_size, module_count);
    731 
    732 out:
    733 	return;
    734 }
    735 
    736 
    737 #ifdef DEBUG
    738 static void
    739 mbi_hexdump(char *addr, size_t len)
    740 {
    741 	int i,j;
    742 
    743 	for (i = 0; i < len; i += 16) {
    744 		printf("  %p ", addr + i);
    745 		for (j = 0; j < 16 && i + j < len; j++) {
    746 			char *cp = addr + i + j;
    747 			printf("%s%s%x",
    748 			       (i+j) % 4 ? "" : " ",
    749 			       (unsigned char)*cp < 0x10 ? "0" : "",
    750 			       (unsigned char)*cp);
    751 		}
    752 		printf("\n");
    753 	}
    754 
    755 	return;
    756 }
    757 #endif
    758 
    759 static const char *
    760 mbi_tag_name(uint32_t type)
    761 {
    762 	const char *tag_name;
    763 
    764 	switch (type) {
    765 	case MULTIBOOT_TAG_TYPE_END:
    766 		tag_name = "";
    767 		break;
    768 	case MULTIBOOT_TAG_TYPE_CMDLINE:
    769 		tag_name = "command line"; break;
    770 	case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
    771 		tag_name = "boot loader name"; break;
    772 	case MULTIBOOT_TAG_TYPE_MODULE:
    773 		tag_name = "module"; break;
    774 	case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO:
    775 		tag_name = "basic meminfo"; break;
    776 	case MULTIBOOT_TAG_TYPE_BOOTDEV:
    777 		tag_name = "boot device"; break;
    778 	case MULTIBOOT_TAG_TYPE_MMAP:
    779 		tag_name = "memory map"; break;
    780 	case MULTIBOOT_TAG_TYPE_VBE:
    781 		tag_name = "VESA BIOS Extensions"; break;
    782 	case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
    783 		tag_name = "framebuffer"; break;
    784 	case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
    785 		tag_name = "ELF sections"; break;
    786 	case MULTIBOOT_TAG_TYPE_APM:
    787 		tag_name = "APM"; break;
    788 	case MULTIBOOT_TAG_TYPE_EFI32:
    789 		tag_name = "EFI system table"; break;
    790 	case MULTIBOOT_TAG_TYPE_EFI64:
    791 		tag_name = "EFI system table"; break;
    792 	case MULTIBOOT_TAG_TYPE_SMBIOS:
    793 		tag_name = "SMBIOS"; break;
    794 	case MULTIBOOT_TAG_TYPE_ACPI_OLD:
    795 		tag_name = "ACPI 2"; break;
    796 	case MULTIBOOT_TAG_TYPE_ACPI_NEW:
    797 		tag_name = "ACPI 3"; break;
    798 	case MULTIBOOT_TAG_TYPE_NETWORK:
    799 		tag_name = "network"; break;
    800 	case MULTIBOOT_TAG_TYPE_EFI_MMAP:
    801 		tag_name = "EFI memory map"; break;
    802 	case MULTIBOOT_TAG_TYPE_EFI_BS:
    803 		tag_name = "EFI boot services available"; break;
    804 	case MULTIBOOT_TAG_TYPE_EFI32_IH:
    805 		tag_name = "EFI ImageHandle"; break;
    806 	case MULTIBOOT_TAG_TYPE_EFI64_IH:
    807 		tag_name = "EFI ImaheHandle"; break;
    808 	case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR:
    809 		tag_name = "load base"; break;
    810 	default:
    811 		tag_name = ""; break;
    812 	}
    813 
    814 	return tag_name;
    815 }
    816 
    817 void
    818 multiboot2_print_info(void)
    819 {
    820 	struct multiboot_tag *mbt;
    821 	char *cp;
    822 	uint32_t total_size;
    823 	uint32_t reserved;
    824 #ifdef DEBUG
    825 	int i = 0;
    826 #endif
    827 
    828 	if (multiboot2_enabled == false)
    829 		goto out;
    830 
    831 	total_size = *(uint32_t *)multiboot_info;
    832 	reserved = *(uint32_t *)multiboot_info + 1;
    833 	mbt = (struct multiboot_tag *)(uint32_t *)multiboot_info + 2;
    834 
    835 	for (cp = multiboot_info + sizeof(total_size) + sizeof(reserved);
    836 	     cp - multiboot_info < total_size;
    837 	     cp = cp + roundup(mbt->size, MULTIBOOT_TAG_ALIGN)) {
    838 		const char *tag_name;
    839 
    840 		mbt = (struct multiboot_tag *)cp;
    841 		tag_name = mbi_tag_name(mbt->type);
    842 
    843 #ifdef DEBUG
    844 		printf("multiboot2: tag[%d].type = %d(%s), .size = %d ",
    845 		    i++, mbt->type, tag_name, mbt->size);
    846 #else
    847 		if (*tag_name == '\0')
    848 			break;
    849 
    850 		printf("multiboot2: %s ", mbi_tag_name(mbt->type));
    851 #endif
    852 
    853 		switch (mbt->type) {
    854 		case MULTIBOOT_TAG_TYPE_CMDLINE:
    855 			printf("%s\n",
    856 			    ((struct multiboot_tag_string *)mbt)->string);
    857 			break;
    858 		case MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME:
    859 			printf("%s\n",
    860 			    ((struct multiboot_tag_string *)mbt)->string);
    861 			break;
    862 		case MULTIBOOT_TAG_TYPE_MODULE:
    863 			printf("0x%08x - 0x%08x %s\n",
    864 			    ((struct multiboot_tag_module *)mbt)->mod_start,
    865 			    ((struct multiboot_tag_module *)mbt)->mod_end,
    866 			    ((struct multiboot_tag_module *)mbt)->cmdline);
    867 			break;
    868 		case MULTIBOOT_TAG_TYPE_BASIC_MEMINFO: {
    869 			struct multiboot_tag_basic_meminfo *meminfo;
    870 
    871 			meminfo = (struct multiboot_tag_basic_meminfo *)mbt;
    872 			printf("ower = %uKB, upper = %uKB\n",
    873 			    meminfo->mem_lower, meminfo->mem_upper);
    874 			break;
    875 		}
    876 		case MULTIBOOT_TAG_TYPE_BOOTDEV:
    877 			printf ("biosdev = 0x%x, slice = %d, part = %d\n",
    878 			    ((struct multiboot_tag_bootdev *)mbt)->biosdev,
    879 			    ((struct multiboot_tag_bootdev *)mbt)->slice,
    880 			    ((struct multiboot_tag_bootdev *)mbt)->part);
    881 			break;
    882 		case MULTIBOOT_TAG_TYPE_MMAP: {
    883 			struct multiboot_tag_mmap *memmap;
    884 			multiboot_memory_map_t *mmap;
    885 			uint32_t entry_size;
    886 			uint32_t entry_version;
    887 
    888 			memmap = (struct multiboot_tag_mmap *)mbt;
    889 			entry_size = memmap->entry_size;
    890 			entry_version = memmap->entry_version;
    891 			printf ("entry version = %d\n", entry_version);
    892 
    893 			if (entry_version != 0)
    894 				break;
    895 
    896 			for (mmap = ((struct multiboot_tag_mmap *)mbt)->entries;
    897 			    (char *)mmap - (char *)mbt < mbt->size;
    898 			    mmap = (void *)((char *)mmap + entry_size))
    899 				printf("  0x%016"PRIx64" @ 0x%016"PRIx64" "
    900 				    "type 0x%x\n",
    901 				    (uint64_t)mmap->len, (uint64_t)mmap->addr,
    902 				    mmap->type);
    903 			break;
    904 		}
    905 		case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: {
    906 			struct multiboot_tag_framebuffer *fb = (void *)mbt;
    907 
    908 			printf ("%dx%dx%d @ 0x%"PRIx64"\n",
    909 			    fb->common.framebuffer_width,
    910 			    fb->common.framebuffer_height,
    911 			    fb->common.framebuffer_bpp,
    912 			    (uint64_t)fb->common.framebuffer_addr);
    913 #ifdef DEBUG
    914 			mbi_hexdump((char *)mbt, mbt->size);
    915 #endif
    916 			break;
    917 		}
    918 		case MULTIBOOT_TAG_TYPE_ELF_SECTIONS:
    919 			printf("num = %d, entsize = %d, shndx = %d\n",
    920 			    ((struct multiboot_tag_elf_sections *)mbt)->num,
    921 			    ((struct multiboot_tag_elf_sections *)mbt)->entsize,
    922 			    ((struct multiboot_tag_elf_sections *)mbt)->shndx);
    923 #ifdef DEBUG
    924 			mbi_hexdump((char *)mbt, mbt->size);
    925 #endif
    926 			break;
    927 		case MULTIBOOT_TAG_TYPE_APM:
    928 			printf("version = %d, cseg = 0x%x, offset = 0x%x, "
    929 			    "cseg_16 = 0x%x, dseg = 0x%x, flags = 0x%x, "
    930 			    "cseg_len = %d, cseg_16_len = %d, "
    931 			    "dseg_len = %d\n",
    932 			    ((struct multiboot_tag_apm *)mbt)->version,
    933 			    ((struct multiboot_tag_apm *)mbt)->cseg,
    934 			    ((struct multiboot_tag_apm *)mbt)->offset,
    935 			    ((struct multiboot_tag_apm *)mbt)->cseg_16,
    936 			    ((struct multiboot_tag_apm *)mbt)->dseg,
    937 			    ((struct multiboot_tag_apm *)mbt)->flags,
    938 			    ((struct multiboot_tag_apm *)mbt)->cseg_len,
    939 			    ((struct multiboot_tag_apm *)mbt)->cseg_16_len,
    940 			    ((struct multiboot_tag_apm *)mbt)->dseg_len);
    941 			break;
    942 		case MULTIBOOT_TAG_TYPE_EFI32:
    943 			printf("0x%x\n",
    944 			    ((struct multiboot_tag_efi32 *)mbt)->pointer);
    945 			break;
    946 		case MULTIBOOT_TAG_TYPE_EFI64:
    947 			printf("0x%"PRIx64"\n", (uint64_t)
    948 			    ((struct multiboot_tag_efi64 *)mbt)->pointer);
    949 			break;
    950 		case MULTIBOOT_TAG_TYPE_SMBIOS:
    951 			printf("major = %d, minor = %d\n",
    952 			    ((struct multiboot_tag_smbios *)mbt)->major,
    953 			    ((struct multiboot_tag_smbios *)mbt)->minor);
    954 #ifdef DEBUG
    955 			mbi_hexdump((char *)mbt, mbt->size);
    956 #endif
    957 			break;
    958 		case MULTIBOOT_TAG_TYPE_ACPI_OLD:
    959 			printf("\n");
    960 #ifdef DEBUG
    961 			mbi_hexdump((char *)mbt, mbt->size);
    962 #endif
    963 			break;
    964 		case MULTIBOOT_TAG_TYPE_ACPI_NEW:
    965 			printf("\n");
    966 #ifdef DEBUG
    967 			mbi_hexdump((char *)mbt, mbt->size);
    968 #endif
    969 			break;
    970 		case MULTIBOOT_TAG_TYPE_NETWORK:
    971 			printf("\n");
    972 #ifdef DEBUG
    973 			mbi_hexdump((char *)mbt, mbt->size);
    974 #endif
    975 			break;
    976 		case MULTIBOOT_TAG_TYPE_EFI_MMAP:
    977 			printf("\n");
    978 #ifdef DEBUG
    979 			mbi_hexdump((char *)mbt, mbt->size);
    980 #endif
    981 			break;
    982 		case MULTIBOOT_TAG_TYPE_EFI_BS:
    983 			printf("\n");
    984 			break;
    985 		case MULTIBOOT_TAG_TYPE_EFI32_IH:
    986 			printf("0x%"PRIx32"\n",
    987 			    ((struct multiboot_tag_efi32_ih *)mbt)->pointer);
    988 			break;
    989 		case MULTIBOOT_TAG_TYPE_EFI64_IH:
    990 			printf("0x%"PRIx64"\n", (uint64_t)
    991 			    ((struct multiboot_tag_efi64_ih *)mbt)->pointer);
    992 			break;
    993 		case MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR: {
    994 			struct multiboot_tag_load_base_addr *ld = (void *)mbt;
    995 			printf("0x%x\n", ld->load_base_addr);
    996 			break;
    997 		}
    998 		case MULTIBOOT_TAG_TYPE_END:
    999 			printf("\n");
   1000 			break;
   1001 		default:
   1002 			printf("\n");
   1003 #ifdef DEBUG
   1004 			mbi_hexdump((char *)mbt, mbt->size);
   1005 #endif
   1006 			break;
   1007 		}
   1008 	}
   1009 
   1010 out:
   1011 	return;
   1012 }
   1013 
   1014 
   1015 
   1016 
   1017 /*
   1018  * Sets up the initial kernel symbol table.  Returns true if this was
   1019  * passed in by Multiboot; false otherwise.
   1020  */
   1021 bool
   1022 multiboot2_ksyms_addsyms_elf(void)
   1023 {
   1024 	struct multiboot_symbols *ms = &Multiboot_Symbols;
   1025 	vaddr_t symstart = (vaddr_t)ms->s_symstart;
   1026 	vaddr_t strstart = (vaddr_t)ms->s_strstart;
   1027 	Elf_Ehdr ehdr;
   1028 
   1029 	if (!multiboot2_enabled || !has_syms)
   1030 		return false;
   1031 
   1032 	KASSERT(esym != 0);
   1033 
   1034 #ifdef __LP64__
   1035 	/* Adjust pointer as 64 bits */
   1036 	symstart &= 0xffffffff;
   1037 	symstart |= ((vaddr_t)KERNBASE_HI << 32);
   1038 	strstart &= 0xffffffff;
   1039 	strstart |= ((vaddr_t)KERNBASE_HI << 32);
   1040 #endif
   1041 
   1042 	memset(&ehdr, 0, sizeof(ehdr));
   1043 	memcpy(ehdr.e_ident, ELFMAG, SELFMAG);
   1044 	ehdr.e_ident[EI_CLASS] = ELFCLASS;
   1045 	ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
   1046 	ehdr.e_ident[EI_VERSION] = EV_CURRENT;
   1047 	ehdr.e_ident[EI_OSABI] = ELFOSABI_SYSV;
   1048 	ehdr.e_ident[EI_ABIVERSION] = 0;
   1049 	ehdr.e_type = ET_EXEC;
   1050 #ifdef __amd64__
   1051 	ehdr.e_machine = EM_X86_64;
   1052 #elif __i386__
   1053 	ehdr.e_machine = EM_386;
   1054 #else
   1055 	#error "Unknown ELF machine type"
   1056 #endif
   1057 	ehdr.e_version = 1;
   1058 	ehdr.e_entry = (Elf_Addr)&start;
   1059 	ehdr.e_ehsize = sizeof(ehdr);
   1060 
   1061 	ksyms_addsyms_explicit((void *)&ehdr,
   1062 	    (void *)symstart, ms->s_symsize,
   1063 	    (void *)strstart, ms->s_strsize);
   1064 
   1065 	return true;
   1066 }
   1067