Hi!
From: KIYOHARA Takashi <kiyoh...@kk.iij4u.or.jp> Date: Fri, 01 Feb 2019 13:53:09 +0900 (JST) > known problems: > - Shuld support to multiboot2 instead of multiboot. My ThinkPad X1 gen6 boots XEN3_DOM0 kernel. This implement was tested only efiboot/bootx64/bootx64.efi by me. Please test for command 'multiboot2', if you have interesting this. e.g. boot/biosboot, efiboot/bootia32/bootia32.efi. Thanks -- kiyohara
? arch/i386/stand/efiboot/bootia32/multiboot32.S ? arch/i386/stand/efiboot/bootx64/multiboot64.S ? sys/multiboot2.h Index: arch/i386/stand/boot/boot2.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/boot/boot2.c,v retrieving revision 1.70 diff -u -r1.70 boot2.c --- arch/i386/stand/boot/boot2.c 14 Nov 2017 09:55:41 -0000 1.70 +++ arch/i386/stand/boot/boot2.c 15 Mar 2019 06:10:28 -0000 @@ -129,6 +129,7 @@ #endif void command_modules(char *); void command_multiboot(char *); +void command_multiboot2(char *); const struct bootblk_command commands[] = { { "help", command_help }, @@ -147,6 +148,7 @@ { "modules", command_modules }, { "load", module_add }, { "multiboot", command_multiboot }, + { "multiboot2", command_multiboot2 }, { "vesa", command_vesa }, { "splash", splash_add }, { "rndseed", rnd_add }, @@ -416,6 +418,7 @@ "modules {on|off|enabled|disabled}\n" "load {path_to_module}\n" "multiboot [xdNx:][filename] [<args>]\n" + "multiboot2 [xdNx:][filename] [<args>]\n" "splash {path_to_image_file}\n" "userconf {command}\n" "rndseed {path_to_rndseed_file}\n" @@ -581,3 +584,16 @@ printf("boot returned\n"); } +void +command_multiboot2(char *arg) +{ + char *filename; + + filename = arg; + if (exec_multiboot2(filename, gettrailer(arg)) < 0) + printf("multiboot2: %s: %s\n", sprint_bootsel(filename), + strerror(errno)); + else + printf("boot returned\n"); +} + Index: arch/i386/stand/efiboot/boot.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/boot.c,v retrieving revision 1.10 diff -u -r1.10 boot.c --- arch/i386/stand/efiboot/boot.c 11 Apr 2018 10:32:09 -0000 1.10 +++ arch/i386/stand/efiboot/boot.c 15 Mar 2019 06:10:28 -0000 @@ -75,7 +75,7 @@ void command_menu(char *); #endif void command_modules(char *); -void command_multiboot(char *); +void command_multiboot2(char *); void command_text(char *); void command_version(char *); @@ -99,7 +99,7 @@ { "menu", command_menu }, #endif { "modules", command_modules }, - { "multiboot", command_multiboot }, + { "multiboot2", command_multiboot2 }, { "rndseed", rnd_add }, { "splash", splash_add }, { "text", command_text }, @@ -377,7 +377,7 @@ "menu (reenters boot menu, if defined in boot.cfg)\n" #endif "modules {on|off|enabled|disabled}\n" - "multiboot [xdNx:][filename] [<args>]\n" + "multiboot2 [xdNx:][filename] [<args>]\n" "rndseed {path_to_rndseed_file}\n" "splash {path_to_image_file}\n" "text [{modenum|list}]\n" @@ -569,13 +569,13 @@ } void -command_multiboot(char *arg) +command_multiboot2(char *arg) { char *filename; filename = arg; - if (exec_multiboot(filename, gettrailer(arg)) < 0) - printf("multiboot: %s: %s\n", sprint_bootsel(filename), + if (exec_multiboot2(filename, gettrailer(arg)) < 0) + printf("multiboot2: %s: %s\n", sprint_bootsel(filename), strerror(errno)); else printf("boot returned\n"); Index: arch/i386/stand/efiboot/bootia32/Makefile =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootia32/Makefile,v retrieving revision 1.2 diff -u -r1.2 Makefile --- arch/i386/stand/efiboot/bootia32/Makefile 21 Feb 2017 10:53:37 -0000 1.2 +++ arch/i386/stand/efiboot/bootia32/Makefile 15 Mar 2019 06:10:28 -0000 @@ -3,7 +3,7 @@ PROG= bootia32.efi OBJFMT= pei-i386 -EXTRA_SOURCES= efibootia32.c startprog32.S +EXTRA_SOURCES= efibootia32.c startprog32.S multiboot32.S CPUFLAGS= -march=i686 -mtune=i686 GNUEFIARCH= ia32 Index: arch/i386/stand/efiboot/bootia32/efibootia32.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootia32/efibootia32.c,v retrieving revision 1.4 diff -u -r1.4 efibootia32.c --- arch/i386/stand/efiboot/bootia32/efibootia32.c 27 Mar 2018 14:15:05 -0000 1.4 +++ arch/i386/stand/efiboot/bootia32/efibootia32.c 15 Mar 2019 06:10:28 -0000 @@ -29,6 +29,7 @@ #include "efiboot.h" #include <sys/bootblock.h> +#include <sys/multiboot2.h> void startprog32_start(physaddr_t, uint32_t, uint32_t *, physaddr_t, physaddr_t, physaddr_t, u_long, void *); @@ -36,12 +37,19 @@ physaddr_t, physaddr_t, u_long, void *); extern u_int startprog32_size; +void multiboot2_32_start(physaddr_t, uint32_t, uint32_t *, physaddr_t, + physaddr_t, physaddr_t, u_long, void *); +extern void (*multiboot2_32)(physaddr_t, uint32_t, uint32_t *, physaddr_t, + physaddr_t, physaddr_t, u_long, void *); +extern u_int multiboot2_32_size; + void efi_md_init(void) { EFI_STATUS status; EFI_PHYSICAL_ADDRESS addr = EFI_ALLOCATE_MAX_ADDRESS; - u_int sz = EFI_SIZE_TO_PAGES(startprog32_size); + u_int sz = EFI_SIZE_TO_PAGES(startprog32_size) + + + EFI_SIZE_TO_PAGES(multiboot2_32_size); status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, EfiLoaderData, sz, &addr); @@ -50,6 +58,9 @@ __func__, sz, (uintmax_t)status); startprog32 = (void *)(u_long)addr; CopyMem(startprog32, startprog32_start, startprog32_size); + multiboot2_32 = (void *)(u_long)addr + + (EFI_SIZE_TO_PAGES(startprog32_size) << EFI_PAGE_SHIFT); + CopyMem(multiboot2_32, multiboot2_32_start, multiboot2_32_size); } /* ARGSUSED */ @@ -65,7 +76,21 @@ /* ARGSUSED */ void -multiboot(physaddr_t entry, physaddr_t header, physaddr_t sp) +multiboot(int ver, physaddr_t entry, physaddr_t info, physaddr_t sp) { - panic("%s: not implemented", __func__); + struct multiboot2_info *mb2i = (void *)info; + const uint32_t argc = mb2i->total_size / sizeof(uint32_t); + uint32_t *newsp = (void *)((char *)multiboot2_32 + multiboot2_32_size); + + if (ver != 2) + panic("%s: ver.1 not implemented", __func__); + + /* Copy the Multiboot information structure to new stack pointer */ + newsp -= mb2i->total_size; + memcpy(newsp, (void *)info, mb2i->total_size); + + (*multiboot2_32)(entry, argc, newsp, + (physaddr_t)multiboot2_32 + multiboot2_32_size, + efi_kernel_start, efi_kernel_start + efi_loadaddr, + efi_kernel_size, multiboot2_32); } Index: arch/i386/stand/efiboot/bootx64/Makefile =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootx64/Makefile,v retrieving revision 1.1 diff -u -r1.1 Makefile --- arch/i386/stand/efiboot/bootx64/Makefile 24 Jan 2017 11:09:14 -0000 1.1 +++ arch/i386/stand/efiboot/bootx64/Makefile 15 Mar 2019 06:10:28 -0000 @@ -4,7 +4,7 @@ OBJFMT= pei-x86-64 NEWVERSWHAT= "EFI Boot (x64)" -EXTRA_SOURCES= efibootx64.c startprog64.S +EXTRA_SOURCES= efibootx64.c startprog64.S multiboot64.S COPTS+= -mno-red-zone CPPFLAGS+= -DEFI_FUNCTION_WRAPPER Index: arch/i386/stand/efiboot/bootx64/efibootx64.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/bootx64/efibootx64.c,v retrieving revision 1.4 diff -u -r1.4 efibootx64.c --- arch/i386/stand/efiboot/bootx64/efibootx64.c 27 Mar 2018 14:15:05 -0000 1.4 +++ arch/i386/stand/efiboot/bootx64/efibootx64.c 15 Mar 2019 06:10:28 -0000 @@ -29,6 +29,7 @@ #include "efiboot.h" #include <sys/bootblock.h> +#include <sys/multiboot2.h> void startprog64_start(physaddr_t, physaddr_t, physaddr_t, u_long, void *, physaddr_t); @@ -36,12 +37,19 @@ void *, physaddr_t); extern u_int startprog64_size; +void multiboot2_64_start(physaddr_t, physaddr_t, physaddr_t, u_long, + void *, physaddr_t); +extern void (*multiboot2_64)(physaddr_t, physaddr_t, physaddr_t, u_long, + void *, physaddr_t); +extern u_int multiboot2_64_size; + void efi_md_init(void) { EFI_STATUS status; EFI_PHYSICAL_ADDRESS addr = EFI_ALLOCATE_MAX_ADDRESS; - u_int sz = EFI_SIZE_TO_PAGES(startprog64_size); + u_int sz = EFI_SIZE_TO_PAGES(startprog64_size) + + EFI_SIZE_TO_PAGES(multiboot2_64_size); status = uefi_call_wrapper(BS->AllocatePages, 4, AllocateMaxAddress, EfiLoaderData, sz, &addr); @@ -50,6 +58,9 @@ __func__, sz, (uintmax_t)status); startprog64 = (void *)addr; CopyMem(startprog64, startprog64_start, startprog64_size); + multiboot2_64 = (void *)addr + + (EFI_SIZE_TO_PAGES(startprog64_size) << EFI_PAGE_SHIFT); + CopyMem(multiboot2_64, multiboot2_64_start, multiboot2_64_size); } /* ARGSUSED */ @@ -70,7 +81,18 @@ /* ARGSUSED */ void -multiboot(physaddr_t entry, physaddr_t header, physaddr_t sp) +multiboot(int ver, physaddr_t entry, physaddr_t info, physaddr_t sp) { - panic("%s: not implemented", __func__); + struct multiboot2_info *mb2i = (void *)info; + uint32_t *newsp = (void *)((char *)multiboot2_64 + multiboot2_64_size); + + if (ver != 2) + panic("%s: ver.1 not supported", __func__); + + /* Copy the Multiboot information structure to new stack pointer */ + newsp -= mb2i->total_size; + memcpy(newsp, (void *)info, mb2i->total_size); + + (*multiboot2_64)(efi_kernel_start, efi_kernel_start + efi_loadaddr, + (physaddr_t)newsp, efi_kernel_size, multiboot2_64, entry); } Index: arch/i386/stand/lib/exec.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/lib/exec.c,v retrieving revision 1.69 diff -u -r1.69 exec.c --- arch/i386/stand/lib/exec.c 7 Oct 2017 10:26:38 -0000 1.69 +++ arch/i386/stand/lib/exec.c 15 Mar 2019 06:10:28 -0000 @@ -97,6 +97,7 @@ #include <sys/reboot.h> #include <i386/multiboot.h> +#include <sys/multiboot2.h> #include <lib/libsa/stand.h> #include <lib/libkern/libkern.h> @@ -123,6 +124,7 @@ #define MODULE_WARNING_SEC 5 extern struct btinfo_console btinfo_console; +extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[]; boot_module_t *boot_modules; bool boot_modules_enabled = true; @@ -901,7 +903,7 @@ btinfo_symtab.esym = marks[MARK_END]; #endif - multiboot(marks[MARK_ENTRY], vtophys(mbi), + multiboot(1, marks[MARK_ENTRY], vtophys(mbi), x86_trunc_page(mbi->mi_mem_lower * 1024)); panic("exec returned"); @@ -910,6 +912,102 @@ return -1; } +int +exec_multiboot2(const char *file, char *args) +{ + struct multiboot2_info *mb2i; + struct multiboot2_info_basic_tag *mb2i_bt; + struct multiboot2_info_basic_memory_information *mb2i_bmi; + struct multiboot2_info_boot_command_line *mb2i_bcl; + struct multiboot2_info_modules *mb2i_mod; + struct multiboot2_info_boot_loader_name *mb2i_bln; + struct bi_modulelist_entry *bim; + int i, len; + u_long marks[MARK_MAX]; + u_long extmem; + u_long basemem; + + mb2i = (void *)roundup2((intptr_t)alloc(PAGE_SIZE), 8); + mb2i->total_size = sizeof(*mb2i); + mb2i->reserved = 0; + + if (common_load_kernel(file, &basemem, &extmem, 0, 0, marks)) + goto out; + mb2i_bmi = (void *)mb2i + mb2i->total_size; + mb2i_bmi->basic_tag.type = MULTIBOOT2_INFO_BASIC_MEMORY_INFORMATION; + mb2i_bmi->basic_tag.size = sizeof(*mb2i_bmi); + mb2i_bmi->mem_lower = basemem; + mb2i_bmi->mem_upper = extmem; + mb2i->total_size += sizeof(*mb2i_bmi); + + if (args) { + len = strlen(file) + 1 + strlen(args) + 1; + + mb2i_bcl = (void *)mb2i + mb2i->total_size; + mb2i_bcl->basic_tag.type = MULTIBOOT2_INFO_BOOT_COMMAND_LINE; + mb2i_bcl->basic_tag.size = sizeof(*mb2i_bcl) + len; + snprintf(mb2i_bcl->string, len, "%s %s", file, args); + mb2i->total_size += sizeof(*mb2i_bcl) + len; + /* each tag to start at 8-bytes aligned address. */ + mb2i->total_size = roundup2(mb2i->total_size, 8); + } + + /* pull in any modules if necessary */ + if (boot_modules_enabled) { + module_init(file); + + bim = (struct bi_modulelist_entry *) + (((char *) btinfo_modulelist) + + sizeof(struct btinfo_modulelist)); + for (i = 0; + btinfo_modulelist != NULL && i < btinfo_modulelist->num; + i++) { + len = strlen(bim->path) + 1; + mb2i_mod = (void *)mb2i + mb2i->total_size; + mb2i_mod->basic_tag.type = MULTIBOOT2_INFO_MODULES; + mb2i_mod->basic_tag.size = sizeof(*mb2i_mod) + len; + mb2i_mod->mod_start = bim->base; + mb2i_mod->mod_end = bim->base + bim->len; + strcpy(mb2i_mod->string, bim->path); + mb2i->total_size += sizeof(*mb2i_mod) + len; + /* each tag to start at 8-bytes aligned address. */ + mb2i->total_size = roundup2(mb2i->total_size, 8); + bim++; + } + } + + mb2i_bln = (void *)mb2i + mb2i->total_size; + mb2i_bln->basic_tag.type = MULTIBOOT2_INFO_BOOT_LOADER_NAME; + mb2i_bln->basic_tag.size = sizeof(*mb2i_bln); + mb2i->total_size += sizeof(*mb2i_bln); + len = snprintf(mb2i_bln->string, + PAGE_SIZE - mb2i->total_size - sizeof(*mb2i_bt), + "%s, Revision %s (from NetBSD %s)", + bootprog_name, bootprog_rev, bootprog_kernrev); + mb2i_bln->basic_tag.size += (len + sizeof('\0')); + mb2i->total_size += (len + sizeof('\0')); + /* each tag to start at 8-bytes aligned address. */ + mb2i->total_size = roundup2(mb2i->total_size, 8); + + mb2i_bt = (void *)mb2i + mb2i->total_size; + mb2i_bt->type = MULTIBOOT2_INFO_TERMINATE; + mb2i_bt->size = sizeof(*mb2i_bt); + mb2i->total_size += sizeof(*mb2i_bt); + +#ifdef DEBUG + printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY], + marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]); +#endif + + multiboot(2, marks[MARK_ENTRY], vtophys(mb2i), + x86_trunc_page(mb2i_bmi->mem_lower * 1024)); + panic("exec returned"); + +out: + dealloc(mb2i, 0); + return -1; +} + void x86_progress(const char *fmt, ...) { Index: arch/i386/stand/lib/libi386.h =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/lib/libi386.h,v retrieving revision 1.42 diff -u -r1.42 libi386.h --- arch/i386/stand/lib/libi386.h 12 Mar 2017 05:33:48 -0000 1.42 +++ arch/i386/stand/lib/libi386.h 15 Mar 2019 06:10:28 -0000 @@ -39,10 +39,11 @@ ssize_t pread(int, void *, size_t); void startprog(physaddr_t, uint32_t, uint32_t *, physaddr_t); -void multiboot(physaddr_t, physaddr_t, physaddr_t); +void multiboot(int, physaddr_t, physaddr_t, physaddr_t); int exec_netbsd(const char *, physaddr_t, int, int, void (*)(void)); int exec_multiboot(const char *, char *); +int exec_multiboot2(const char *, char *); int count_netbsd(const char *, u_long *); void delay(int); Index: arch/i386/stand/lib/multiboot.S =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/lib/multiboot.S,v retrieving revision 1.2 diff -u -r1.2 multiboot.S --- arch/i386/stand/lib/multiboot.S 4 Dec 2016 08:21:08 -0000 1.2 +++ arch/i386/stand/lib/multiboot.S 15 Mar 2019 06:10:28 -0000 @@ -78,7 +78,9 @@ */ #include <machine/asm.h> -#define MULTIBOOT_INFO_MAGIC 0x2BADB002 +#define _LOCORE +#include <machine/multiboot.h> +#include <sys/multiboot2.h> /* * Starts program in protected mode / flat space with given stackframe. @@ -87,7 +89,7 @@ */ /* - * multiboot(phyaddr, header, stack) + * multiboot(ver, phyaddr, header, stack) * start the program on protected mode where phyaddr is the entry point */ ENTRY(multiboot) @@ -97,12 +99,12 @@ /* Prepare a new stack */ movl $flatdataseg,%eax movw %ax,%es /* for arg copy */ - movl 16(%ebp),%ebx /* stack */ + movl 20(%ebp),%ebx /* stack */ subl $4,%ebx movl %ebx,%edi - movl 12(%ebp),%ebx /* header */ - movl 8(%ebp),%ecx /* entry */ + movl 16(%ebp),%ebx /* header */ + movl 12(%ebp),%ecx /* entry */ /* Set new stack pointer */ movw %ax,%ss @@ -118,7 +120,15 @@ mov %ax,%ds mov %ax,%es + movl 8(%ebp),%eax /* ver */ + cmpl $2,%eax + je 2f +1: movl $MULTIBOOT_INFO_MAGIC,%eax + jmp 0f +2: + movl $MULTIBOOT2_INFO_MAGIC,%eax +0: /* Jump to phyaddr, with the new code segment */ lret --- arch/i386/stand/efiboot/bootia32/multiboot32.S.orig 1970-01-01 09:00:00.000000000 +0900 +++ arch/i386/stand/efiboot/bootia32/multiboot32.S 2019-03-14 19:21:51.642545202 +0900 @@ -0,0 +1,248 @@ +/* $NetBSD: startprog32.S,v 1.2 2017/02/24 12:24:25 nonaka Exp $ */ +/* NetBSD: startprog.S,v 1.4 2016/12/04 08:21:08 maxv Exp */ + +/* + * Ported to boot 386BSD by Julian Elischer (jul...@tfs.com) Sept 1992 + * + * Mach Operating System + * Copyright (c) 1992, 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or software.distribut...@cs.cmu.edu + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Copyright 1988, 1989, 1990, 1991, 1992 + * by Intel Corporation, Santa Clara, California. + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies and that both the copyright notice and this permission notice + * appear in supporting documentation, and that the name of Intel + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, + * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <machine/asm.h> +#include <machine/specialreg.h> + +#define _LOCORE +#include <sys/multiboot2.h> + +#define CODE_SEGMENT 0x08 +#define DATA_SEGMENT 0x10 + + .align 16 + .globl _C_LABEL(multiboot2_32) +_C_LABEL(multiboot2_32): + .quad 0 + + .globl _C_LABEL(multiboot2_32_size) +_C_LABEL(multiboot2_32_size): + .long multiboot2_32_end - _C_LABEL(multiboot2_32_start) + + .text + .p2align 4,,15 + +/* + * multiboot2_32(entry,argc,argv,stack,kern_start,kern_load,kern_size,loadaddr) + */ +ENTRY(multiboot2_32_start) +start: + pushl %ebp + movl %esp, %ebp + + /* + * 8(%ebp): kernel entry address + * 12(%ebp): argc + * 16(%ebp): argv + * 20(%ebp): stack address + * 24(%ebp): kernel start address + * 28(%ebp): loaded kernel address + * 32(%ebp): loaded kernel size + * 36(%ebp): loaded start address + */ + + cli + + movl 8(%ebp), %ebx /* %ebx: entry address */ + movl 36(%ebp), %edx /* %edx: loaded start address */ + + /* Prepare a new stack */ + movl 20(%ebp), %eax /* stack */ + subl $4, %eax + movl %eax, %edi + + /* Push some number of args onto the stack */ + movl 12(%ebp), %ecx /* argc */ + movl %ecx, %eax + decl %eax + shl $2, %eax + addl 16(%ebp), %eax /* ptr to last arg */ + movl %eax, %esi + + std /* backwards */ + rep + movsl /* copy %ds:(%esi) -> %es:(%edi) */ + cld + mov %edi, %esp /* set new stack pointer */ + + /* Copy kernel */ + movl 24(%ebp), %edi /* dest */ + movl 28(%ebp), %esi /* src */ + movl 32(%ebp), %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 1f + movw (%esi), %ax + movw %ax, (%edi) + je .Lcopy_done + movb 2(%esi), %al + movb %al, 2(%edi) + jmp .Lcopy_done +1: 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 1f + je 2f + movb 2(%esi), %al + movb %al, 2(%edi) +2: movw (%esi), %ax + movw %ax, (%edi) + jmp .Lback_aligned +1: 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 (start32a - start)(%edx), %eax + movl %eax, (start32r - start)(%edx) + + /* Setup GDT */ + lea (gdt - start)(%edx), %eax + movl %eax, (gdtrr - start)(%edx) + lgdt (gdtr - start)(%edx) + + /* Jump to set %cs */ + ljmp *(start32r - start)(%edx) + + .align 4 +start32a: + 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 start32b + + .align 4 +start32b: + movl %ebx, (start32r - start)(%edx) + movl $MULTIBOOT2_INFO_MAGIC,%eax + movl %ebp,%ebx + ljmp *(start32r - start)(%edx) + + .align 16 +start32r: + .long 0 + .long CODE_SEGMENT + .align 16 +gdt: + .long 0, 0 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 +gdtr: + .word gdtr - gdt +gdtrr: + .quad +start32end: + /* Space for the stack */ + .align 16 + .space 8192 +multiboot2_32_end: --- arch/i386/stand/efiboot/bootx64/multiboot64.S.orig 1970-01-01 09:00:00.000000000 +0900 +++ arch/i386/stand/efiboot/bootx64/multiboot64.S 2019-03-12 19:07:49.945778117 +0900 @@ -0,0 +1,269 @@ +/* $NetBSD: startprog64.S,v 1.3 2017/02/11 10:23:39 nonaka Exp $ */ +/* NetBSD: startprog.S,v 1.3 2003/02/01 14:48:18 dsl Exp */ + +/* starts program in protected mode / flat space + with given stackframe + needs global variables flatcodeseg and flatdataseg + (gdt offsets) + derived from: NetBSD:sys/arch/i386/boot/asm.S + */ + +/* + * Ported to boot 386BSD by Julian Elischer (jul...@tfs.com) Sept 1992 + * + * Mach Operating System + * Copyright (c) 1992, 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or software.distribut...@cs.cmu.edu + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + Copyright 1988, 1989, 1990, 1991, 1992 + by Intel Corporation, Santa Clara, California. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Intel +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include <machine/asm.h> +#include <machine/specialreg.h> + +#define _LOCORE +#include <sys/multiboot2.h> + +#define CODE_SEGMENT 0x08 +#define DATA_SEGMENT 0x10 + + .align 16 + .globl _C_LABEL(multiboot2_64) +_C_LABEL(multiboot2_64): + .quad 0 + + .globl _C_LABEL(multiboot2_64_size) +_C_LABEL(multiboot2_64_size): + .long multiboot2_64_end - _C_LABEL(multiboot2_64_start) + + .text + .p2align 4,,15 + +/* + * multiboot2_64(kern_start,kern_load,stack,kern_size,loadaddr,entry) + */ +ENTRY(multiboot2_64_start) +start: + /* + * This function is to call the loaded kernel's start() with + * 32bit segment mode from x64 mode. + * %rdi: kernel start address + * %rsi: loaded kernel address + * %rdx: stack address + * %rcx: loaded kernel size + * %r8 : loaded start address + * %r9 : kernel entry address + */ + + cld /* LynxOS depends on it */ + + cli + + /* Copy kernel */ + mov %rcx, %r12 /* original kernel size */ + movq %rdi, %r11 /* for misaligned check */ + +#if !defined(NO_OVERLAP) + movq %rdi, %r13 + subq %rsi, %r13 +#endif + + shrq $3, %rcx /* count for copy by words */ + jz 8f /* j if less than 8 bytes */ + + lea -8(%rdi, %r12), %r14 /* target address of last 8 */ + mov -8(%rsi, %r12), %r15 /* get last word */ +#if !defined(NO_OVERLAP) + cmpq %r12, %r13 /* overlapping? */ + jb 10f +#endif + +/* + * Non-overlaping, copy forwards. + * Newer Intel cpus (Nehalem) will do 16byte read/write transfers + * if %ecx is more than 76. + * AMD might do something similar some day. + */ + and $7, %r11 /* destination misaligned ? */ + jnz 2f + rep + movsq + mov %r15, (%r14) /* write last word */ + jmp .Lcopy_done + +/* + * Destination misaligned + * AMD say it is better to align the destination (not the source). + * This will also re-align copies if the source and dest are both + * misaligned by the same amount) + * (I think Nehalem will use its accelerated copy if the source + * and destination have the same alignment.) + */ +2: + lea -9(%r11, %r12), %rcx /* post re-alignment count */ + neg %r11 /* now -1 .. -7 */ + mov (%rsi), %r12 /* get first word */ + mov %rdi, %r13 /* target for first word */ + lea 8(%rsi, %r11), %rsi + lea 8(%rdi, %r11), %rdi + shr $3, %rcx + rep + movsq + mov %r12, (%r13) /* write first word */ + mov %r15, (%r14) /* write last word */ + jmp .Lcopy_done + +#if !defined(NO_OVERLAP) +/* Must copy backwards. + * Reverse copy is probably easy to code faster than 'rep movds' + * since that requires (IIRC) an extra clock every 3 iterations (AMD). + * However I don't suppose anything cares that much! + * The big cost is the std/cld pair - reputedly 50+ cycles on Netburst P4. + * The copy is aligned with the buffer start (more likely to + * be a multiple of 8 than the end). + */ +10: + lea -8(%rsi, %rcx, 8), %rsi + lea -8(%rdi, %rcx, 8), %rdi + std + rep + movsq + cld + mov %r15, (%r14) /* write last bytes */ + jmp .Lcopy_done +#endif + +/* Less than 8 bytes to copy, copy by bytes */ +/* Intel Nehalem optimise 'rep movsb' for <= 7 bytes (9-15 clocks). + * For longer transfers it is 50+ ! + */ +8: mov %r12, %rcx + +#if !defined(NO_OVERLAP) + cmpq %r12, %r13 /* overlapping? */ + jb 81f +#endif + + /* nope, copy forwards. */ + rep + movsb + jmp .Lcopy_done + +#if !defined(NO_OVERLAP) +/* Must copy backwards */ +81: + lea -1(%rsi, %rcx), %rsi + lea -1(%rdi, %rcx), %rdi + std + rep + movsb + cld +#endif + /* End of copy kernel */ +.Lcopy_done: + + mov %r8, %rdi /* %rdi: loaded start address */ + mov %r9, %rsi /* %rsi: kernel entry address */ + + /* Prepare jump address */ + lea (start32a - start)(%rdi), %rax + movl %eax, (start32r - start)(%rdi) + + /* Setup GDT */ + lea (gdt - start)(%rdi), %rax + mov %rax, (gdtrr - start)(%rdi) + lgdt (gdtr - start)(%rdi) + + /* Jump to set %cs */ + ljmp *(start32r - start)(%rdi) + + .align 4 + .code32 +start32a: + movl $DATA_SEGMENT, %eax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + movl %edx, %esp + movl %edx, %ebx + + /* Disable Paging in CR0 */ + movl %cr0, %eax + andl $(~CR0_PG), %eax + orl $CR0_PE, %eax + movl %eax, %cr0 + + /* Disable PAE in CR4 */ + movl %cr4, %eax + andl $(~CR4_PAE), %eax + movl %eax, %cr4 + + jmp start32b + + .align 4 +start32b: + movl $MULTIBOOT2_INFO_MAGIC,%eax + call *%esi + + .align 16 +start32r: + .long 0 + .long CODE_SEGMENT + .align 16 +gdt: + .long 0, 0 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9f, 0xcf, 0x00 + .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 +gdtr: + .word gdtr - gdt +gdtrr: + .quad +start32end: + /* Space for the stack */ + .align 16 + .space 8192 +multiboot2_64_end: --- sys/multiboot2.h.orig 1970-01-01 09:00:00.000000000 +0900 +++ sys/multiboot2.h 2019-03-12 15:38:54.294088203 +0900 @@ -0,0 +1,313 @@ +/* $NetBSD: multiboot.h,v 1.10 2018/11/13 11:01:54 mlelstv Exp $ */ + +/*- + * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Julio M. Merino Vidal. + * + * 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. + */ + +/* --------------------------------------------------------------------- */ + +/* + * Multiboot2 header structure. + */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 +#define MULTIBOOT2_HEADER_ARCHITECTURE_I386 0x00000000 /* protected mode */ +#define MULTIBOOT2_HEADER_ARCHITECTURE_MIPS 0x00000004 + +#define MULTIBOOT2_HEADER_TAG_TYPE_TERMINATE 0 +#define MULTIBOOT2_HEADER_TAG_TYPE_INFORMATION_REQUEST 1 +#define MULTIBOOT2_HEADER_TAG_TYPE_ADDRESS 2 +#define MULTIBOOT2_HEADER_TAG_TYPE_ENTRY_ADDRESS 3 +#define MULTIBOOT2_HEADER_TAG_TYPE_ENTRY_ADDRESS_EFI_I386 8 +#define MULTIBOOT2_HEADER_TAG_TYPE_ENTRY_ADDRESS_EFI_AMD64 9 +#define MULTIBOOT2_HEADER_TAG_TYPE_FLAGS 4 +#define MULTIBOOT2_HEADER_TAG_TYPE_FRAMEBUFFER 5 +#define MULTIBOOT2_HEADER_TAG_TYPE_MODULE_ALIGNMENT 6 +#define MULTIBOOT2_HEADER_TAG_TYPE_EFI_BOOT_SERVICE 7 +#define MULTIBOOT2_HEADER_TAG_TYPE_RELOCATABLE_HEADER 10 + +#if !defined(_LOCORE) +struct multiboot2_header { + uint32_t mh_magic; + uint32_t mh_architecture; + uint32_t mh_header_length; + uint32_t mh_checksum; +}; + +struct multiboot2_header_general_tag { + uint16_t type; /* 0 is terminater */ + uint16_t flags; + uint32_t size; +}; +struct multiboot2_header_information_request_tag { + struct multiboot2_header_general_tag gt; + + uint32_t mbi_tag_types[0]; +}; +struct address_tag { + struct multiboot2_header_general_tag gt; + + uint32_t header_addr; + uint32_t load_addr; + uint32_t load_end_addr; + uint32_t bss_end_addr; +}; +struct entry_address_tag { + struct multiboot2_header_general_tag gt; + /* 3:entry_addr, 8:EFI i386, 9:EFI amd64 */ + + uint32_t entry_addr; +}; +struct flags_tag { + struct multiboot2_header_general_tag gt; + + uint32_t console_flags; +}; +struct framebuffer_tag { + struct multiboot2_header_general_tag gt; + + uint32_t width; + uint32_t height; + uint32_t depth; +}; +struct module_alignment_tag { + struct multiboot2_header_general_tag gt; +}; +struct efi_boot_service_tag { + struct multiboot2_header_general_tag gt; +}; +struct relocatable_header_tag { + struct multiboot2_header_general_tag gt; + + uint32_t min_addr; + uint32_t max_addr; + uint32_t align; + uint32_t preference; +}; + +#endif /* !defined(_LOCORE) */ + +/* + * Symbols defined in locore.S. + */ +#if !defined(_LOCORE) && defined(_KERNEL) +extern struct multiboot2_header *Multiboot2_Header; +#endif /* !defined(_LOCORE) && defined(_KERNEL) */ + +/* --------------------------------------------------------------------- */ + +/* + * Multiboot information structure. + */ +#define MULTIBOOT2_INFO_MAGIC 0x36d76289 +#define MULTIBOOT2_INFO_TERMINATE 0 +#define MULTIBOOT2_INFO_BOOT_COMMAND_LINE 1 +#define MULTIBOOT2_INFO_BOOT_LOADER_NAME 2 +#define MULTIBOOT2_INFO_MODULES 3 +#define MULTIBOOT2_INFO_BASIC_MEMORY_INFORMATION 4 +#define MULTIBOOT2_INFO_BIOS_BOOT_DEVICE 5 +#define MULTIBOOT2_INFO_MEMORY_MAP 6 +#define MULTIBOOT2_INFO_VBE_INFO 7 +#define MULTIBOOT2_INFO_FRAMEBUFFER_INFO 8 +#define MULTIBOOT2_INFO_ELF_SYMBOLS 9 +#define MULTIBOOT2_INFO_APM_TABLE 10 +#define MULTIBOOT2_INFO_EFI_32BIT_SYSTEM_TABLE_POINTER 11 +#define MULTIBOOT2_INFO_EFI_64BIT_SYSTEM_TABLE_POINTER 12 +#define MULTIBOOT2_INFO_SMBIOS_TABLES 13 +#define MULTIBOOT2_INFO_ACPI_OLD_RSDP 14 +#define MULTIBOOT2_INFO_ACPI_NEW_RSDP 15 +#define MULTIBOOT2_INFO_NETWORKING_INFORMATION 16 +#define MULTIBOOT2_INFO_EFI_MEMORY_MAP 17 +#define MULTIBOOT2_INFO_EFI_BOOT_SERVICE_NOT_TERMINATED 18 +#define MULTIBOOT2_INFO_EFI_32BIT_IMAGE_HANDLE_POINTER 19 +#define MULTIBOOT2_INFO_EFI_64BIT_IMAGE_HANDLE_POINTER 20 +#define MULTIBOOT2_INFO_IMAGE_LOAD_BASE_PHYSICAL_ADDRESS 21 + +#if !defined(_LOCORE) +struct multiboot2_info { + uint32_t total_size; + uint32_t reserved; /* always set to 0 */ +}; + +struct multiboot2_info_basic_tag { + uint32_t type; /* 0 is terminater */ + uint32_t size; +}; +struct multiboot2_info_basic_memory_information { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t mem_lower; + uint32_t mem_upper; +}; +struct multiboot2_info_bios_boot_device { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t biosdev; + uint32_t partition; + uint32_t sub_partition; +}; +struct multiboot2_info_boot_command_line { + struct multiboot2_info_basic_tag basic_tag; + + char string[0]; +}; +struct multiboot2_info_modules { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t mod_start; + uint32_t mod_end; + char string[0]; +}; +struct multiboot2_info_elf_symbols { + struct multiboot2_info_basic_tag basic_tag; + + uint16_t num; + uint16_t entsize; + uint16_t shndx; + uint16_t reserved; +}; +struct multiboot2_info_memory_map { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t entry_size; + uint32_t entry_version; + union entry_ver { + struct _0 { + uint64_t base_addr; + uint64_t length; + uint64_t type; + uint64_t reserved; + } _0; + } entries[0]; +}; +struct multiboot2_info_boot_loader_name { + struct multiboot2_info_basic_tag basic_tag; + + char string[0]; +}; +struct multiboot2_info_apm_table { + struct multiboot2_info_basic_tag basic_tag; + + uint16_t version; + uint16_t cseg; + uint32_t offset; + uint16_t cseg_16; + uint16_t dseg; + uint16_t flags; + uint16_t cseg_len; + uint16_t cseg_16_len; + uint16_t dseg_len; +}; +struct multiboot2_info_vbe_info { + struct multiboot2_info_basic_tag basic_tag; + + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + uint8_t vbe_control_info[512]; + uint8_t vbe_mode_info[256]; +}; +struct multiboot2_info_framebuffer_info { + struct multiboot2_info_basic_tag basic_tag; + + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; + uint8_t reserved; + union { + struct { + uint32_t framebuffer_palette_num_colors; + struct framebuffer_palette { + uint8_t red_value; + uint8_t green_value; + uint8_t blue_value; + } framebuffer_palette[0]; + } type_0; + struct { + uint8_t framebuffer_red_field_position; + uint8_t framebuffer_red_mask_size; + uint8_t framebuffer_green_field_position; + uint8_t framebuffer_green_mask_size; + uint8_t framebuffer_blue_field_position; + uint8_t framebuffer_blue_mask_size; + } type_1; + } coloer_info; +}; +struct multiboot2_info_efi_system_table_pointer { + struct multiboot2_info_basic_tag basic_tag; + /* 11:32bit EFI, 12:64bit EFI */ + + vaddr_t pointer; +}; +struct multiboot2_info_smbios_tables { + struct multiboot2_info_basic_tag basic_tag; + + uint8_t major; + uint8_t minor; + uint8_t reserved[6]; + + /* smbios tables */ +}; +struct multiboot2_info_efi_memory_map { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t descriptor_size; + uint32_t descriptor_version; + + /* EFI memory map */ +}; +struct multiboot2_info_efi_image_handle_pointer { + struct multiboot2_info_basic_tag basic_tag; + /* 19:32bit image, 20:64bit image */ + + vaddr_t pointer; +}; +struct multiboot2_info_image_load_base_physical_address { + struct multiboot2_info_basic_tag basic_tag; + + uint32_t load_base_addr; +}; + +#endif /* !defined(_LOCORE) */ + +/* --------------------------------------------------------------------- */ + +/* + * Prototypes for public functions defined in multiboot.c. + */ +#if !defined(_LOCORE) && defined(_KERNEL) +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) */ + +/* --------------------------------------------------------------------- */
Index: i386/stand/lib/pread.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/stand/lib/pread.c,v retrieving revision 1.7 diff -u -r1.7 pread.c --- i386/stand/lib/pread.c 14 Dec 2008 17:03:43 -0000 1.7 +++ i386/stand/lib/pread.c 30 Jan 2019 12:36:02 -0000 @@ -43,7 +43,7 @@ ssize_t pread(int fd, void *dest, size_t size) { - int rsize; + size_t rsize; if (!buf) buf = alloc(BUFSIZE);