diff --git a/stand/common/modinfo.h b/stand/common/modinfo.h index e4739df0b68f..967367beeeb0 100644 --- a/stand/common/modinfo.h +++ b/stand/common/modinfo.h @@ -1,12 +1,15 @@ /*- * Copyright (c) 2022, Netflix, Inc. * * SPDX-License-Identifier: BSD-2-Clause */ #ifndef COMMON_MODINFO_H #define COMMON_MODINFO_H +int md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); +int md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); + vm_offset_t md_copymodules(vm_offset_t addr, bool kern64); vm_offset_t md_copyenv(vm_offset_t addr); #endif /* COMMON_MODINFO_H */ diff --git a/stand/efi/loader/arch/arm/exec.c b/stand/efi/loader/arch/arm/exec.c index a110f3d07cbc..2fecb2ea043a 100644 --- a/stand/efi/loader/arch/arm/exec.c +++ b/stand/efi/loader/arch/arm/exec.c @@ -1,106 +1,105 @@ /*- * Copyright (c) 2001 Benno Rice * Copyright (c) 2007 Semihalf, Rafal Jaworowski * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include "bootstrap.h" #include "loader_efi.h" -extern vm_offset_t md_load(char *, vm_offset_t *); extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool); static int __elfN(arm_load)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); return (0); } static int __elfN(arm_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t modulep, kernend; Elf_Ehdr *e; int error; void (*entry)(void *); if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); e = (Elf_Ehdr *)&fmp->md_data; efi_time_fini(); entry = efi_translate(e->e_entry); printf("Kernel entry at %p...\n", entry); printf("Kernel args: %s\n", fp->f_args); if ((error = bi_load(fp->f_args, &modulep, &kernend, true)) != 0) { efi_time_init(); return (error); } /* At this point we've called ExitBootServices, so we can't call * printf or any other function that uses Boot Services */ dev_cleanup(); (*entry)((void *)modulep); panic("exec returned"); } static struct file_format arm_elf = { __elfN(arm_load), __elfN(arm_exec) }; struct file_format *file_formats[] = { &arm_elf, NULL }; diff --git a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c b/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c index 5851d71fdc13..3341771be09a 100644 --- a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c +++ b/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c @@ -1,182 +1,181 @@ /*- * Copyright (c) 2001 Benno Rice * 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 __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include #include #include #include #include #include #include "bootstrap.h" #include "syscall_nr.h" #include "host_syscall.h" +#include "modinfo.h" extern char end[]; extern void *kerneltramp; extern size_t szkerneltramp; struct trampoline_data { uint32_t kernel_entry; uint32_t dtb; uint32_t phys_mem_offset; uint32_t of_entry; uint32_t mdp; uint32_t mdp_size; }; -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - int ppc64_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); return (0); } int ppc64_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp, dtb; Elf_Ehdr *e; int error; uint32_t *trampoline; uint64_t entry; uint64_t trampolinebase; struct trampoline_data *trampoline_data; int nseg; void *kseg; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; /* * Figure out where to put it. * * Linux does not allow to do kexec_load into * any part of memory. Ask arch_loadaddr to * resolve the first available chunk of physical * memory where loading is possible (load_addr). * * Memory organization is shown below. * It is assumed, that text segment offset of * kernel ELF (KERNPHYSADDR) is non-zero, * which is true for PPC/PPC64 architectures, * where default is 0x100000. * * load_addr: trampoline code * load_addr + KERNPHYSADDR: kernel text segment */ trampolinebase = archsw.arch_loadaddr(LOAD_RAW, NULL, 0); printf("Load address at %#jx\n", (uintmax_t)trampolinebase); printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); /* Set up loader trampoline */ trampoline = malloc(szkerneltramp); memcpy(trampoline, &kerneltramp, szkerneltramp); /* Parse function descriptor for ELFv1 kernels */ if ((e->e_flags & 3) == 2) entry = e->e_entry; else { archsw.arch_copyout(e->e_entry + elf64_relocation_offset, &entry, 8); entry = be64toh(entry); } /* * Placeholder for trampoline data is at trampolinebase + 0x08 * CAUTION: all data must be Big Endian */ trampoline_data = (void*)&trampoline[2]; trampoline_data->kernel_entry = htobe32(entry + elf64_relocation_offset); trampoline_data->phys_mem_offset = htobe32(0); trampoline_data->of_entry = htobe32(0); if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0) return (error); trampoline_data->dtb = htobe32(dtb); trampoline_data->mdp = htobe32(mdp); trampoline_data->mdp_size = htobe32(0xfb5d104d); printf("Kernel entry at %#jx (%#x) ...\n", entry, be32toh(trampoline_data->kernel_entry)); printf("DTB at %#x, mdp at %#x\n", be32toh(trampoline_data->dtb), be32toh(trampoline_data->mdp)); dev_cleanup(); archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp); free(trampoline); if (archsw.arch_kexec_kseg_get == NULL) panic("architecture did not provide kexec segment mapping"); archsw.arch_kexec_kseg_get(&nseg, &kseg); error = host_kexec_load(trampolinebase, nseg, kseg, HOST_KEXEC_ARCH_PPC64); if (error != 0) panic("kexec_load returned error: %d", error); error = host_reboot(HOST_REBOOT_MAGIC1, HOST_REBOOT_MAGIC2, HOST_REBOOT_CMD_KEXEC, (uintptr_t)NULL); if (error != 0) panic("reboot returned error: %d", error); while (1) {} } struct file_format ppc_elf64 = { ppc64_elf_loadfile, ppc64_elf_exec }; /* * Sort formats so that those that can detect based on arguments rather than * reading the file first. */ struct file_format *file_formats[] = { &ppc_elf64, NULL }; diff --git a/stand/libofw/libofw.h b/stand/libofw/libofw.h index dc520d741290..2d6ea9a5bf24 100644 --- a/stand/libofw/libofw.h +++ b/stand/libofw/libofw.h @@ -1,91 +1,87 @@ /*- * Copyright (C) 2000 Benno Rice. * 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 Benno Rice ``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 TOOLS GMBH 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 "openfirm.h" #include #define DEVT_OFDISK 1001 struct ofw_devdesc { struct devdesc dd; union { struct { ihandle_t d_handle; char d_path[256]; }; struct { uint64_t pool_guid; uint64_t root_guid; }; }; }; extern int ofw_getdev(void **vdev, const char *devspec, const char **path); extern ev_sethook_t ofw_setcurrdev; extern struct devsw ofwdisk; extern struct devsw ofw_netdev; extern struct netif_driver ofwnet; int ofwn_getunit(const char *); ssize_t ofw_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len); ssize_t ofw_readin(readin_handle_t fd, vm_offset_t dest, const size_t len); extern int ofw_boot(void); extern int ofw_autoload(void); void ofw_memmap(int); phandle_t ofw_path_to_handle(const char *ofwpath, const char *want_type, const char **path); int ofw_common_parsedev(struct devdesc **dev, const char *devspec, const char **path, const char *ofwtype); struct preloaded_file; struct file_format; -/* MD code implementing MI interfaces */ -vm_offset_t md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb); -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); - extern void reboot(void); struct ofw_reg { cell_t base; cell_t size; }; struct ofw_reg2 { cell_t base_hi; cell_t base_lo; cell_t size; }; extern int (*openfirmware)(void *); diff --git a/stand/powerpc/ofw/elf_freebsd.c b/stand/powerpc/ofw/elf_freebsd.c index 89811e965d6e..ee173d55e25c 100644 --- a/stand/powerpc/ofw/elf_freebsd.c +++ b/stand/powerpc/ofw/elf_freebsd.c @@ -1,106 +1,107 @@ /*- * Copyright (c) 2001 Benno Rice * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #if defined(__powerpc__) #include #endif #include #include "bootstrap.h" #include "libofw.h" #include "openfirm.h" +#include "modinfo.h" extern char end[]; extern vm_offset_t reloc; /* From /conf.c */ int __elfN(ofw_loadfile)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); #if defined(__powerpc__) /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); #endif return (0); } int __elfN(ofw_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; intptr_t entry; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; entry = e->e_entry; if ((error = md_load(fp->f_args, &mdp, &dtbp)) != 0) return (error); printf("Kernel entry at 0x%x ...\n", entry); dev_cleanup(); if (dtbp != 0) { OF_quiesce(); ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, (void *)mdp, 0xfb5d104d); } else { OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, (void *)mdp, 0xfb5d104d); } panic("exec returned"); } struct file_format ofw_elf = { __elfN(ofw_loadfile), __elfN(ofw_exec) }; diff --git a/stand/powerpc/ofw/ppc64_elf_freebsd.c b/stand/powerpc/ofw/ppc64_elf_freebsd.c index 38c664228c12..ece3dbc6d822 100644 --- a/stand/powerpc/ofw/ppc64_elf_freebsd.c +++ b/stand/powerpc/ofw/ppc64_elf_freebsd.c @@ -1,110 +1,111 @@ /*- * Copyright (c) 2001 Benno Rice * 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 __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include #include #include #include #include #include #include "bootstrap.h" #include "libofw.h" #include "openfirm.h" +#include "modinfo.h" extern char end[]; extern vm_offset_t reloc; /* From /conf.c */ int ppc64_ofw_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); return (0); } int ppc64_ofw_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; intptr_t entry; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; /* Handle function descriptor for ELFv1 kernels */ if ((e->e_flags & 3) == 2) entry = e->e_entry; else entry = *(uint64_t *)(intptr_t)e->e_entry; if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0) return (error); printf("Kernel entry at 0x%x ...\n", entry); dev_cleanup(); if (dtbp != 0) { OF_quiesce(); ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, (void *)mdp, 0xfb5d104d); } else { OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, (void *)mdp, 0xfb5d104d); } panic("exec returned"); } struct file_format ofw_elf64 = { ppc64_ofw_elf_loadfile, ppc64_ofw_elf_exec }; diff --git a/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c b/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c index 57b2e791fbba..feabcde3bf4a 100644 --- a/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c +++ b/stand/uboot/arch/powerpc/ppc64_elf_freebsd.c @@ -1,101 +1,98 @@ /*- * Copyright (c) 2001 Benno Rice * 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 __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include #include #include #include #include #include #include "bootstrap.h" #include "libuboot.h" - -vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); -extern char end[]; -extern vm_offset_t reloc; /* From /conf.c */ +#include "modinfo.h" int ppc64_uboot_elf_loadfile(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); return (0); } int ppc64_uboot_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; void (*entry)(void *); if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; /* Handle function descriptor for ELFv1 kernels */ if ((e->e_flags & 3) == 2) entry = (void (*)(void*))(intptr_t)e->e_entry; else entry = *(void (*)(void*))(uint64_t *)(intptr_t)e->e_entry; if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0) return (error); dev_cleanup(); printf("Kernel args: %s\n", fp->f_args); (*entry)((void *)mdp); panic("exec returned"); } struct file_format uboot_elf64 = { ppc64_uboot_elf_loadfile, ppc64_uboot_elf_exec }; diff --git a/stand/uboot/elf_freebsd.c b/stand/uboot/elf_freebsd.c index 802d6e96dee6..0541edd92c64 100644 --- a/stand/uboot/elf_freebsd.c +++ b/stand/uboot/elf_freebsd.c @@ -1,96 +1,95 @@ /*- * Copyright (c) 2001 Benno Rice * Copyright (c) 2007 Semihalf, Rafal Jaworowski * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include "bootstrap.h" #include "libuboot.h" - -extern vm_offset_t md_load(char *, vm_offset_t *, vm_offset_t *); +#include "modinfo.h" int __elfN(uboot_load)(char *filename, uint64_t dest, struct preloaded_file **result) { int r; r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); #if defined(__powerpc__) /* * No need to sync the icache for modules: this will * be done by the kernel after relocation. */ if (!strcmp((*result)->f_type, "elf kernel")) __syncicache((void *) (*result)->f_addr, (*result)->f_size); #endif return (0); } int __elfN(uboot_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp; Elf_Ehdr *e; int error; void (*entry)(void *); if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return (EFTYPE); e = (Elf_Ehdr *)&fmp->md_data; if ((error = md_load(fp->f_args, &mdp, NULL)) != 0) return (error); entry = (void *)e->e_entry; printf("Kernel entry at %p...\n", entry); dev_cleanup(); printf("Kernel args: %s\n", fp->f_args); (*entry)((void *)mdp); panic("exec returned"); } struct file_format uboot_elf = { __elfN(uboot_load), __elfN(uboot_exec) };