diff options
-rw-r--r-- | share/mk/src.opts.mk | 4 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/Makefile.inc | 8 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/amd64_tramp.S | 76 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/conf.c | 104 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/elf64_freebsd.c | 345 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/host_syscall.S | 29 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/ldscript.amd64 | 72 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/multiboot2.h | 1 | ||||
-rw-r--r-- | stand/kboot/arch/amd64/syscall_nr.h | 15 |
9 files changed, 652 insertions, 2 deletions
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index c580b9aafc0e..a7e414fd0432 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -301,8 +301,8 @@ BROKEN_OPTIONS+=EFI .if ${__T:Mpowerpc*} == "" BROKEN_OPTIONS+=LOADER_OFW .endif -# KBOOT is only for powerpc64 (powerpc64le broken) -.if ${__T} != "powerpc64" +# KBOOT is only for powerpc64 (powerpc64le broken) and kinda for amd64 +.if ${__T} != "powerpc64" && ${__T} != "amd64" BROKEN_OPTIONS+=LOADER_KBOOT .endif # UBOOT is only for arm, and big-endian powerpc diff --git a/stand/kboot/arch/amd64/Makefile.inc b/stand/kboot/arch/amd64/Makefile.inc new file mode 100644 index 000000000000..fb954e798599 --- /dev/null +++ b/stand/kboot/arch/amd64/Makefile.inc @@ -0,0 +1,8 @@ +SRCS+= conf.c host_syscall.S amd64_tramp.S elf64_freebsd.c + +CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include +# load address. set in linker script +RELOC?= 0x0 +CFLAGS+= -DRELOC=${RELOC} + +LDFLAGS= -nostdlib -static -T ${.CURDIR}/arch/${MACHINE_ARCH}/ldscript.amd64 diff --git a/stand/kboot/arch/amd64/amd64_tramp.S b/stand/kboot/arch/amd64/amd64_tramp.S new file mode 100644 index 000000000000..877705407f92 --- /dev/null +++ b/stand/kboot/arch/amd64/amd64_tramp.S @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Benno Rice under sponsorship from + * the FreeBSD Foundation. + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include <machine/asmacros.h> + +#define ASM_FILE +#include "multiboot2.h" + + .text + .globl amd64_tramp + +/* + * void amd64_tramp(uint64_t stack, void *copy_finish, uint64_t kernend, + * uint64_t modulep, uint64_t pagetable, uint64_t entry) + */ +amd64_tramp: + cli /* Make sure we don't get interrupted. */ + movq %rdi,%rsp /* Switch to our temporary stack. */ + + movq %rdx,%r12 /* Stash the kernel values for later. */ + movq %rcx,%r13 + movq %r8,%r14 + movq %r9,%r15 + + callq *%rsi /* Call copy_finish so we're all ready to go. */ + + pushq %r12 /* Push kernend. */ + salq $32,%r13 /* Shift modulep and push it. */ + pushq %r13 + pushq %r15 /* Push the entry address. */ + movq %r14,%cr3 /* Switch page tables. */ + ret /* "Return" to kernel entry. */ + + ALIGN_TEXT +amd64_tramp_end: + +/* void multiboot2_exec(uint64_t entry, uint64_t multiboot_info, uint64_t stack) */ + .globl multiboot2_exec +multiboot2_exec: + movq %rdx,%rsp + pushq %rdi + movq %rsi,%rbx + movq $MULTIBOOT2_BOOTLOADER_MAGIC,%rax + ret + + .data + .globl amd64_tramp_size +amd64_tramp_size: + .long amd64_tramp_end-amd64_tramp diff --git a/stand/kboot/arch/amd64/conf.c b/stand/kboot/arch/amd64/conf.c new file mode 100644 index 000000000000..b840d008a347 --- /dev/null +++ b/stand/kboot/arch/amd64/conf.c @@ -0,0 +1,104 @@ +/*- + * Copyright (C) 1999 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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> +__FBSDID("$FreeBSD$"); + +#include <stand.h> +#include "bootstrap.h" + +#if defined(LOADER_NET_SUPPORT) +#include "dev_net.h" +#endif + +extern struct devsw hostdisk; + +/* + * We could use linker sets for some or all of these, but + * then we would have to control what ended up linked into + * the bootstrap. So it's easier to conditionalise things + * here. + * + * XXX rename these arrays to be consistent and less namespace-hostile + */ + +/* Exported for libsa */ +struct devsw *devsw[] = { +#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) + &hostdisk, +#endif +#if defined(LOADER_NET_SUPPORT) + &netdev, +#endif + NULL +}; + +struct fs_ops *file_system[] = { +#if defined(LOADER_UFS_SUPPORT) + &ufs_fsops, +#endif +#if defined(LOADER_CD9660_SUPPORT) + &cd9660_fsops, +#endif +#if defined(LOADER_EXT2FS_SUPPORT) + &ext2fs_fsops, +#endif +#if defined(LOADER_NFS_SUPPORT) + &nfs_fsops, +#endif +#if defined(LOADER_TFTP_SUPPORT) + &tftp_fsops, +#endif +#if defined(LOADER_GZIP_SUPPORT) + &gzipfs_fsops, +#endif +#if defined(LOADER_BZIP2_SUPPORT) + &bzipfs_fsops, +#endif + &dosfs_fsops, + NULL +}; + +extern struct netif_driver kbootnet; + +struct netif_driver *netif_drivers[] = { +#if 0 /* XXX */ +#if defined(LOADER_NET_SUPPORT) + &kbootnet, +#endif +#endif + NULL, +}; + +/* + * Consoles + */ +extern struct console hostconsole; + +struct console *consoles[] = { + &hostconsole, + NULL +}; diff --git a/stand/kboot/arch/amd64/elf64_freebsd.c b/stand/kboot/arch/amd64/elf64_freebsd.c new file mode 100644 index 000000000000..a45a0db32e44 --- /dev/null +++ b/stand/kboot/arch/amd64/elf64_freebsd.c @@ -0,0 +1,345 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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> +__FBSDID("$FreeBSD$"); + +#define __ELF_WORD_SIZE 64 +#include <sys/param.h> +#include <sys/exec.h> +#include <sys/linker.h> +#include <string.h> +#include <machine/elf.h> +#include <stand.h> +#include <vm/vm.h> +#include <vm/pmap.h> + +#ifdef EFI +#include <efi.h> +#include <efilib.h> +#endif + +#include "bootstrap.h" + +#include "platform/acfreebsd.h" +#include "acconfig.h" +#define ACPI_SYSTEM_XFACE +#include "actypes.h" +#include "actbl.h" + +#ifdef EFI +#include "loader_efi.h" +#endif + +#ifdef EFI +static EFI_GUID acpi_guid = ACPI_TABLE_GUID; +static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID; +#endif + +#ifdef EFI +#define LOADER_PAGE_SIZE EFI_PAGE_SIZE +#else +#define LOADER_PAGE_SIZE 8192 +#endif + +extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp, + bool exit_bs); + +static int elf64_exec(struct preloaded_file *amp); +static int elf64_obj_exec(struct preloaded_file *amp); + +static struct file_format amd64_elf = { + .l_load = elf64_loadfile, + .l_exec = elf64_exec, +}; +static struct file_format amd64_elf_obj = { + .l_load = elf64_obj_loadfile, + .l_exec = elf64_obj_exec, +}; + +#if 0 +extern struct file_format multiboot2; +extern struct file_format multiboot2_obj; +#endif + +struct file_format *file_formats[] = { +#if 0 + &multiboot2, + &multiboot2_obj, +#endif + &amd64_elf, + &amd64_elf_obj, + NULL +}; + +#ifdef EFI +static pml4_entry_t *PT4; +static pdp_entry_t *PT3; +static pdp_entry_t *PT3_l, *PT3_u; +static pd_entry_t *PT2; +static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; + +extern EFI_PHYSICAL_ADDRESS staging; + +static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend, + uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry); +#endif + +extern uintptr_t amd64_tramp; +extern uint32_t amd64_tramp_size; + +/* + * There is an ELF kernel and one or more ELF modules loaded. + * We wish to start executing the kernel image, so make such + * preparations as are required, and do so. + */ +static int +elf64_exec(struct preloaded_file *fp) +{ +#ifdef EFI + struct file_metadata *md; + Elf_Ehdr *ehdr; + vm_offset_t modulep, kernend, trampcode, trampstack; + int err, i; + ACPI_TABLE_RSDP *rsdp; + char buf[24]; + int revision; + bool copy_auto; + +#ifdef EFI + copy_auto = copy_staging == COPY_STAGING_AUTO; + if (copy_auto) + copy_staging = fp->f_kernphys_relocatable ? + COPY_STAGING_DISABLE : COPY_STAGING_ENABLE; +#else + copy_auto = COPY_STAGING_DISABLE; /* XXX */ +#endif + + /* + * Report the RSDP to the kernel. While this can be found with + * a BIOS boot, the RSDP may be elsewhere when booted from UEFI. + * The old code used the 'hints' method to communite this to + * the kernel. However, while convenient, the 'hints' method + * is fragile and does not work when static hints are compiled + * into the kernel. Instead, move to setting different tunables + * that start with acpi. The old 'hints' can be removed before + * we branch for FreeBSD 12. + */ + +#ifdef EFI + rsdp = efi_get_table(&acpi20_guid); + if (rsdp == NULL) { + rsdp = efi_get_table(&acpi_guid); + } +#else + rsdp = NULL; +#warning "write me" +#endif + if (rsdp != NULL) { + sprintf(buf, "0x%016llx", (unsigned long long)rsdp); + setenv("hint.acpi.0.rsdp", buf, 1); + setenv("acpi.rsdp", buf, 1); + revision = rsdp->Revision; + if (revision == 0) + revision = 1; + sprintf(buf, "%d", revision); + setenv("hint.acpi.0.revision", buf, 1); + setenv("acpi.revision", buf, 1); + strncpy(buf, rsdp->OemId, sizeof(rsdp->OemId)); + buf[sizeof(rsdp->OemId)] = '\0'; + setenv("hint.acpi.0.oem", buf, 1); + setenv("acpi.oem", buf, 1); + sprintf(buf, "0x%016x", rsdp->RsdtPhysicalAddress); + setenv("hint.acpi.0.rsdt", buf, 1); + setenv("acpi.rsdt", buf, 1); + if (revision >= 2) { + /* XXX extended checksum? */ + sprintf(buf, "0x%016llx", + (unsigned long long)rsdp->XsdtPhysicalAddress); + setenv("hint.acpi.0.xsdt", buf, 1); + setenv("acpi.xsdt", buf, 1); + sprintf(buf, "%d", rsdp->Length); + setenv("hint.acpi.0.xsdt_length", buf, 1); + setenv("acpi.xsdt_length", buf, 1); + } + } + + if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) + return (EFTYPE); + ehdr = (Elf_Ehdr *)&(md->md_data); + + trampcode = copy_staging == COPY_STAGING_ENABLE ? + (vm_offset_t)0x0000000040000000 /* 1G */ : + (vm_offset_t)0x0000000100000000; /* 4G */; +#ifdef EFI + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1, + (EFI_PHYSICAL_ADDRESS *)&trampcode); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline\n"); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } +#else +#warning "Write me" +#endif + bzero((void *)trampcode, LOADER_PAGE_SIZE); + trampstack = trampcode + LOADER_PAGE_SIZE - 8; + bcopy((void *)&amd64_tramp, (void *)trampcode, amd64_tramp_size); + trampoline = (void *)trampcode; + + if (copy_staging == COPY_STAGING_ENABLE) { + PT4 = (pml4_entry_t *)0x0000000040000000; +#ifdef EFI + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3, + (EFI_PHYSICAL_ADDRESS *)&PT4); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages(trampcode, 1); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } +#else +#warning "Write me" +#endif + bzero(PT4, 3 * LOADER_PAGE_SIZE); + PT3 = &PT4[512]; + PT2 = &PT3[512]; + + /* + * This is kinda brutal, but every single 1GB VM + * memory segment points to the same first 1GB of + * physical memory. But it is more than adequate. + */ + for (i = 0; i < NPTEPG; i++) { + /* + * Each slot of the L4 pages points to the + * same L3 page. + */ + PT4[i] = (pml4_entry_t)PT3; + PT4[i] |= PG_V | PG_RW; + + /* + * Each slot of the L3 pages points to the + * same L2 page. + */ + PT3[i] = (pdp_entry_t)PT2; + PT3[i] |= PG_V | PG_RW; + + /* + * The L2 page slots are mapped with 2MB pages for 1GB. + */ + PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024); + PT2[i] |= PG_V | PG_RW | PG_PS; + } + } else { + PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */ +#ifdef EFI + err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9, + (EFI_PHYSICAL_ADDRESS *)&PT4); + if (EFI_ERROR(err)) { + printf("Unable to allocate trampoline page table\n"); + BS->FreePages(trampcode, 9); + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (ENOMEM); + } +#else +#warning "Write me" +#endif + + bzero(PT4, 9 * LOADER_PAGE_SIZE); + + PT3_l = &PT4[NPML4EPG * 1]; + PT3_u = &PT4[NPML4EPG * 2]; + PT2_l0 = &PT4[NPML4EPG * 3]; + PT2_l1 = &PT4[NPML4EPG * 4]; + PT2_l2 = &PT4[NPML4EPG * 5]; + PT2_l3 = &PT4[NPML4EPG * 6]; + PT2_u0 = &PT4[NPML4EPG * 7]; + PT2_u1 = &PT4[NPML4EPG * 8]; + + /* 1:1 mapping of lower 4G */ + PT4[0] = (pml4_entry_t)PT3_l | PG_V | PG_RW; + PT3_l[0] = (pdp_entry_t)PT2_l0 | PG_V | PG_RW; + PT3_l[1] = (pdp_entry_t)PT2_l1 | PG_V | PG_RW; + PT3_l[2] = (pdp_entry_t)PT2_l2 | PG_V | PG_RW; + PT3_l[3] = (pdp_entry_t)PT2_l3 | PG_V | PG_RW; + for (i = 0; i < 4 * NPDEPG; i++) { + PT2_l0[i] = ((pd_entry_t)i << PDRSHIFT) | PG_V | + PG_RW | PG_PS; + } + + /* mapping of kernel 2G below top */ + PT4[NPML4EPG - 1] = (pml4_entry_t)PT3_u | PG_V | PG_RW; + PT3_u[NPDPEPG - 2] = (pdp_entry_t)PT2_u0 | PG_V | PG_RW; + PT3_u[NPDPEPG - 1] = (pdp_entry_t)PT2_u1 | PG_V | PG_RW; + /* compat mapping of phys @0 */ + PT2_u0[0] = PG_PS | PG_V | PG_RW; + /* this maps past staging area */ + for (i = 1; i < 2 * NPDEPG; i++) { + PT2_u0[i] = ((pd_entry_t)staging + + ((pd_entry_t)i - 1) * NBPDR) | + PG_V | PG_RW | PG_PS; + } + } + + printf("staging %#lx (%scopying) tramp %p PT4 %p\n", + staging, copy_staging == COPY_STAGING_ENABLE ? "" : "not ", + trampoline, PT4); + printf("Start @ 0x%lx ...\n", ehdr->e_entry); + +#ifdef EFI + efi_time_fini(); +#endif + err = bi_load(fp->f_args, &modulep, &kernend, true); + if (err != 0) { +#ifdef EFI + efi_time_init(); +#endif + if (copy_auto) + copy_staging = COPY_STAGING_AUTO; + return (err); + } + + dev_cleanup(); + + trampoline(trampstack, copy_staging == COPY_STAGING_ENABLE ? + efi_copy_finish : efi_copy_finish_nop, kernend, modulep, + PT4, ehdr->e_entry); +#endif + + panic("exec returned"); +} + +static int +elf64_obj_exec(struct preloaded_file *fp) +{ + + return (EFTYPE); +} diff --git a/stand/kboot/arch/amd64/host_syscall.S b/stand/kboot/arch/amd64/host_syscall.S new file mode 100644 index 000000000000..5bf0fca0cec1 --- /dev/null +++ b/stand/kboot/arch/amd64/host_syscall.S @@ -0,0 +1,29 @@ +#include <machine/asm.h> + +/* + * Emulate the Linux system call interface. The system call number is set in + * %rax, and %rdi, %rsi, %rdx, %r10, %r8, %r9 have the 6 system call + * arguments. errno is returned as a negative value, but we use it more as a + * flag something went wrong rather than using its value. + * + * Note: For system calls, we use %r10 instead of %rcx for the 4th argument. + * See section A.2.1 for the Linux calling conventions of the ABI spec + * https://web.archive.org/web/20160801075146/http://www.x86-64.org/documentation/abi.pdf + * In addition to the below, %r11 and %rcx are destroyed, negative + * values are ERRNO for %rax between -1 and -4095 otherwise the system + * call is successful. Unlike other Unix systems, carry isn't used to + * signal an error in the system call. We expose the raw system call + * result, rather than do the POSIX converion to -1 and setting errno. + */ +ENTRY(host_syscall) + movq %rdi, %rax /* SYS_ number in %rax */ + movq %rsi, %rdi /* arg2 -> 1 */ + movq %rdx, %rsi /* arg3 -> 2 */ + movq %rcx, %rdx /* arg4 -> 3 */ + movq %r8, %r10 /* arg5 -> 4 */ + movq %r9, %r8 /* arg6 -> 5 */ + movq 8(%rsp),%r9 /* arg7 -> 6 from stack. */ + syscall + ret +/* Note: We're exposing the raw return value to the caller */ +END(host_syscall) diff --git a/stand/kboot/arch/amd64/ldscript.amd64 b/stand/kboot/arch/amd64/ldscript.amd64 new file mode 100644 index 000000000000..bbfe47cd4ef5 --- /dev/null +++ b/stand/kboot/arch/amd64/ldscript.amd64 @@ -0,0 +1,72 @@ +/* $FreeBSD$ */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x401000; + ImageBase = .; + .hash : { *(.hash) } /* this MUST come first! */ + . = ALIGN(4096); + .eh_frame : + { + *(.eh_frame) + } + . = ALIGN(4096); + .text : { + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.plt) + } =0xCCCCCCCC + . = ALIGN(4096); + .data : { + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) + *(.opd) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.plabel) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + } + . = ALIGN(4096); + set_Xcommand_set : { + __start_set_Xcommand_set = .; + *(set_Xcommand_set) + __stop_set_Xcommand_set = .; + } + set_Xficl_compile_set : { + __start_set_Xficl_compile_set = .; + *(set_Xficl_compile_set) + __stop_set_Xficl_compile_set = .; + } + . = ALIGN(4096); + __gp = .; + .sdata : { + *(.got.plt .got) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela.dyn : { + *(.rela.data*) + *(.rela.got) + *(.rela.stab) + *(.relaset_*) + } + . = ALIGN(4096); + .reloc : { *(.reloc) } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } +} diff --git a/stand/kboot/arch/amd64/multiboot2.h b/stand/kboot/arch/amd64/multiboot2.h new file mode 100644 index 000000000000..bf673da66c2c --- /dev/null +++ b/stand/kboot/arch/amd64/multiboot2.h @@ -0,0 +1 @@ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 diff --git a/stand/kboot/arch/amd64/syscall_nr.h b/stand/kboot/arch/amd64/syscall_nr.h new file mode 100644 index 000000000000..193368364bf3 --- /dev/null +++ b/stand/kboot/arch/amd64/syscall_nr.h @@ -0,0 +1,15 @@ +#define SYS_read 0 +#define SYS_write 1 +#define SYS_open 2 +#define SYS_close 3 +#define SYS_gettimeofday 96 +#define SYS_reboot 169 +#define SYS_mmap 9 +#define SYS_uname 63 +#define SYS_lseek 8 +#define SYS_getdents 78 +#define SYS_select 23 +#define __NR_kexec_load 246 + +#define KEXEC_ARCH_X86_64 62 +#define KEXEC_ARCH KEXEC_ARCH_X86_64 |