diff --git a/sys/boot/alpha/libalpha/elf_freebsd.c b/sys/boot/alpha/libalpha/elf_freebsd.c index 74faee2a77e..a223652c863 100644 --- a/sys/boot/alpha/libalpha/elf_freebsd.c +++ b/sys/boot/alpha/libalpha/elf_freebsd.c @@ -90,16 +90,16 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *afp); +static int elf64_exec(struct preloaded_file *afp); int bi_load(struct bootinfo_v1 *, vm_offset_t *, struct preloaded_file *); -struct file_format alpha_elf = { elf_loadfile, elf_exec }; +struct file_format alpha_elf = { elf64_loadfile, elf64_exec }; vm_offset_t ffp_save, ptbr_save; static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { static struct bootinfo_v1 bootinfo_v1; struct file_metadata *md; diff --git a/sys/boot/arc/lib/elf_freebsd.c b/sys/boot/arc/lib/elf_freebsd.c index 994a78714bb..41cdedb2481 100644 --- a/sys/boot/arc/lib/elf_freebsd.c +++ b/sys/boot/arc/lib/elf_freebsd.c @@ -90,16 +90,16 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); int bi_load(struct bootinfo_v1 *, vm_offset_t *, struct preloaded_file *); -struct file_format alpha_elf = { elf_loadfile, elf_exec }; +struct file_format alpha_elf = { elf64_loadfile, elf64_exec }; vm_offset_t ffp_save, ptbr_save; static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { #if 0 static struct bootinfo_v1 bootinfo_v1; diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 3f6c9107812..c72d09ea7e4 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -1,9 +1,19 @@ # $FreeBSD$ SRCS+= bcache.c boot.c commands.c console.c devopen.c interp.c -SRCS+= interp_backslash.c interp_parse.c load_elf.c ls.c misc.c +SRCS+= interp_backslash.c interp_parse.c ls.c misc.c SRCS+= module.c panic.c +.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" +SRCS+= load_elf32.c load_elf64.c +.endif +.if ${MACHINE_ARCH} == "powerpc" +SRCS+= load_elf32.c +.endif +.if ${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "ia64" || ${MACHINE_ARCH} == "alpha" +SRCS+= load_elf64.c +.endif + .if defined(LOADER_NET_SUPPORT) SRCS+= dev_net.c .endif @@ -25,3 +35,6 @@ MAN+= ../forth/loader.4th.8 MAN+= loader.8 +.if ${MACHINE_ARCH} == "amd64" +CFLAGS+= -m32 +.endif diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h index d7a95a7e884..6e17be7ca38 100644 --- a/sys/boot/common/bootstrap.h +++ b/sys/boot/common/bootstrap.h @@ -210,7 +210,7 @@ struct preloaded_file struct file_format { /* Load function must return EFTYPE if it can't handle the module supplied */ - int (* l_load)(char *filename, vm_offset_t dest, struct preloaded_file **result); + int (* l_load)(char *filename, u_int64_t dest, struct preloaded_file **result); /* Only a loader that will load a kernel (first module) should have an exec handler */ int (* l_exec)(struct preloaded_file *mp); }; @@ -231,7 +231,9 @@ int file_addmodule(struct preloaded_file *fp, char *modname, int version, /* MI module loaders */ -int elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result); +#ifdef __elfN +int __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result); +#endif /* * Support for commands diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c index 63f5d6418e1..b28abb820cb 100644 --- a/sys/boot/common/load_elf.c +++ b/sys/boot/common/load_elf.c @@ -41,6 +41,12 @@ #define COPYOUT(s,d,l) archsw.arch_copyout((vm_offset_t)(s), d, l) +#if defined(__i386__) && __ELF_WORD_SIZE == 64 +#undef ELF_TARG_CLASS +#undef ELF_TARG_MACH +#define ELF_TARG_CLASS ELFCLASS64 +#define ELF_TARG_MACH EM_X86_64 +#endif typedef struct elf_file { Elf_Phdr *ph; @@ -59,20 +65,20 @@ typedef struct elf_file { caddr_t firstpage; size_t firstlen; int kernel; - vm_offset_t off; + u_int64_t off; } *elf_file_t; -static int elf_loadimage(struct preloaded_file *mp, elf_file_t ef, vm_offset_t loadaddr); -static int elf_lookup_symbol(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym); +static int __elfN(loadimage)(struct preloaded_file *mp, elf_file_t ef, u_int64_t loadaddr); +static int __elfN(lookup_symbol)(struct preloaded_file *mp, elf_file_t ef, const char* name, Elf_Sym* sym); #ifdef __sparc__ -static void elf_reloc_ptr(struct preloaded_file *mp, elf_file_t ef, +static void __elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, void *p, void *val, size_t len); #endif -static int elf_parse_modmetadata(struct preloaded_file *mp, elf_file_t ef); +static int __elfN(parse_modmetadata)(struct preloaded_file *mp, elf_file_t ef); static char *fake_modname(const char *name); -const char *elf_kerneltype = "elf kernel"; -const char *elf_moduletype = "elf module"; +const char *__elfN(kerneltype) = "elf kernel"; +const char *__elfN(moduletype) = "elf module"; /* * Attempt to load the file (file) as an ELF module. It will be stored at @@ -80,7 +86,7 @@ const char *elf_moduletype = "elf module"; * will be saved in (result). */ int -elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result) +__elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) { struct preloaded_file *fp, *kfp; struct elf_file ef; @@ -134,12 +140,12 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result) if (ehdr->e_type == ET_DYN) { /* Looks like a kld module */ if (kfp == NULL) { - printf("elf_loadfile: can't load module before kernel\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } - if (strcmp(elf_kerneltype, kfp->f_type)) { - printf("elf_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); + if (strcmp(__elfN(kerneltype), kfp->f_type)) { + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } @@ -155,16 +161,16 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result) } else if (ehdr->e_type == ET_EXEC) { /* Looks like a kernel */ if (kfp != NULL) { - printf("elf_loadfile: kernel already loaded\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); err = EPERM; goto oerr; } /* * Calculate destination address based on kernel entrypoint */ - dest = (vm_offset_t) ehdr->e_entry; + dest = ehdr->e_entry; if (dest == 0) { - printf("elf_loadfile: not a kernel (maybe static binary?)\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); err = EPERM; goto oerr; } @@ -180,23 +186,23 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result) */ fp = file_alloc(); if (fp == NULL) { - printf("elf_loadfile: cannot allocate module info\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } if (ef.kernel) setenv("kernelname", filename, 1); fp->f_name = strdup(filename); - fp->f_type = strdup(ef.kernel ? elf_kerneltype : elf_moduletype); + fp->f_type = strdup(ef.kernel ? __elfN(kerneltype) : __elfN(moduletype)); #ifdef ELF_VERBOSE if (ef.kernel) - printf("%s entry at %p\n", filename, (void *) dest); + printf("%s entry at 0x%jx\n", filename, (uintmax_t)dest); #else printf("%s ", filename); #endif - fp->f_size = elf_loadimage(fp, &ef, dest); + fp->f_size = __elfN(loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; @@ -224,7 +230,7 @@ elf_loadfile(char *filename, vm_offset_t dest, struct preloaded_file **result) * the Elf header, load the image at (off) */ static int -elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) +__elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) { int i; u_int j; @@ -238,12 +244,13 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) size_t resid, chunk; ssize_t result; vm_offset_t dest; - vm_offset_t ssym, esym; + Elf_Addr ssym, esym; Elf_Dyn *dp; + Elf_Addr adp; int ndp; int symstrindex; int symtabindex; - long size; + Elf_Size size; u_int fpcopy; dp = NULL; @@ -253,7 +260,11 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) ehdr = ef->ehdr; if (ef->kernel) { #ifdef __i386__ +#if __ELF_WORD_SIZE == 64 + off = - (off & 0xffffffffff000000ull);/* x86_64 relocates after locore */ +#else off = - (off & 0xff000000u); /* i386 relocates after locore */ +#endif #else off = 0; /* alpha is direct mapped for kernels */ #endif @@ -261,7 +272,7 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) ef->off = off; if ((ehdr->e_phoff + ehdr->e_phnum * sizeof(*phdr)) > ef->firstlen) { - printf("elf_loadimage: program header not within first page\n"); + printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: program header not within first page\n"); goto out; } phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); @@ -295,12 +306,12 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) if (phdr[i].p_filesz > fpcopy) { if (lseek(ef->fd, (off_t)(phdr[i].p_offset + fpcopy), SEEK_SET) == -1) { - printf("\nelf_loadexec: cannot seek\n"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: cannot seek\n"); goto out; } if (archsw.arch_readin(ef->fd, phdr[i].p_vaddr + off + fpcopy, phdr[i].p_filesz - fpcopy) != (ssize_t)(phdr[i].p_filesz - fpcopy)) { - printf("\nelf_loadexec: archsw.readin failed\n"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadexec: archsw.readin failed\n"); goto out; } } @@ -315,7 +326,7 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) /* no archsw.arch_bzero */ buf = malloc(PAGE_SIZE); if (buf == NULL) { - printf("\nelf_loadimage: malloc() failed\n"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: malloc() failed\n"); goto out; } bzero(buf, PAGE_SIZE); @@ -353,12 +364,12 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) if (shdr == NULL) goto nosyms; if (lseek(ef->fd, (off_t)ehdr->e_shoff, SEEK_SET) == -1) { - printf("\nelf_loadimage: cannot lseek() to section headers"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: cannot lseek() to section headers"); goto nosyms; } result = read(ef->fd, shdr, chunk); if (result < 0 || (size_t)result != chunk) { - printf("\nelf_loadimage: read section headers failed"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: read section headers failed"); goto nosyms; } symtabindex = -1; @@ -410,7 +421,7 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) size = shdr[i].sh_size; archsw.arch_copyin(&size, lastaddr, sizeof(size)); - lastaddr += sizeof(long); + lastaddr += sizeof(size); #ifdef ELF_VERBOSE printf("\n%s: 0x%lx@0x%lx -> 0x%lx-0x%lx", secname, @@ -419,25 +430,25 @@ elf_loadimage(struct preloaded_file *fp, elf_file_t ef, vm_offset_t off) #else if (i == symstrindex) printf("+"); - printf("0x%lx+0x%lx", (long)sizeof(size), size); + printf("0x%lx+0x%lx", (long)sizeof(size), (long)size); #endif if (lseek(ef->fd, (off_t)shdr[i].sh_offset, SEEK_SET) == -1) { - printf("\nelf_loadimage: could not seek for symbols - skipped!"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not seek for symbols - skipped!"); lastaddr = ssym; ssym = 0; goto nosyms; } result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size); if (result < 0 || (size_t)result != shdr[i].sh_size) { - printf("\nelf_loadimage: could not read symbols - skipped!"); + printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped!"); lastaddr = ssym; ssym = 0; goto nosyms; } /* Reset offsets relative to ssym */ lastaddr += shdr[i].sh_size; - lastaddr = roundup(lastaddr, sizeof(long)); + lastaddr = roundup(lastaddr, sizeof(size)); if (i == symtabindex) symtabindex = -1; else if (i == symstrindex) @@ -461,9 +472,8 @@ nosyms: for (i = 0; i < ehdr->e_phnum; i++) { if (phdr[i].p_type == PT_DYNAMIC) { php = phdr + i; - dp = (Elf_Dyn *)(php->p_vaddr); - file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(dp), &dp); - dp = NULL; + adp = php->p_vaddr; + file_addmetadata(fp, MODINFOMD_DYNAMIC, sizeof(adp), &adp); break; } } @@ -485,19 +495,19 @@ nosyms: break; switch (dp[i].d_tag) { case DT_HASH: - ef->hashtab = (Elf_Hashelt*)(dp[i].d_un.d_ptr + off); + ef->hashtab = (Elf_Hashelt*)(uintptr_t)(dp[i].d_un.d_ptr + off); break; case DT_STRTAB: - ef->strtab = (char *)(dp[i].d_un.d_ptr + off); + ef->strtab = (char *)(uintptr_t)(dp[i].d_un.d_ptr + off); break; case DT_STRSZ: ef->strsz = dp[i].d_un.d_val; break; case DT_SYMTAB: - ef->symtab = (Elf_Sym*)(dp[i].d_un.d_ptr + off); + ef->symtab = (Elf_Sym*)(uintptr_t)(dp[i].d_un.d_ptr + off); break; case DT_RELA: - ef->rela = (Elf_Rela *)(dp[i].d_un.d_ptr + off); + ef->rela = (Elf_Rela *)(uintptr_t)(dp[i].d_un.d_ptr + off); break; case DT_RELASZ: ef->relasz = dp[i].d_un.d_val; @@ -513,7 +523,7 @@ nosyms: COPYOUT(ef->hashtab + 1, &ef->nchains, sizeof(ef->nchains)); ef->buckets = ef->hashtab + 2; ef->chains = ef->buckets + ef->nbuckets; - if (elf_parse_modmetadata(fp, ef) == 0) + if (__elfN(parse_modmetadata)(fp, ef) == 0) goto out; if (ef->kernel) /* kernel must not depend on anything */ @@ -559,33 +569,34 @@ fake_modname(const char *name) } int -elf_parse_modmetadata(struct preloaded_file *fp, elf_file_t ef) +__elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) { struct mod_metadata md; struct mod_depend *mdepend; struct mod_version mver; Elf_Sym sym; - char *s, *v, **p, **p_stop; + char *s, **p, **p_stop; int modcnt, minfolen; + Elf_Addr v; - if (elf_lookup_symbol(fp, ef, "__start_set_modmetadata_set", &sym) != 0) + if (__elfN(lookup_symbol)(fp, ef, "__start_set_modmetadata_set", &sym) != 0) return ENOENT; - p = (char **)(sym.st_value + ef->off); - if (elf_lookup_symbol(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) + p = (char **)(uintptr_t)(sym.st_value + ef->off); + if (__elfN(lookup_symbol)(fp, ef, "__stop_set_modmetadata_set", &sym) != 0) return ENOENT; - p_stop = (char **)(sym.st_value + ef->off); + p_stop = (char **)(uintptr_t)(sym.st_value + ef->off); modcnt = 0; while (p < p_stop) { COPYOUT(p, &v, sizeof(v)); #ifdef __sparc64__ - elf_reloc_ptr(fp, ef, p, &v, sizeof(v)); + __elfN(reloc_ptr)(fp, ef, p, &v, sizeof(v)); #else v += ef->off; #endif COPYOUT(v, &md, sizeof(md)); #ifdef __sparc64__ - elf_reloc_ptr(fp, ef, v, &md, sizeof(md)); + __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); #else md.md_cval += ef->off; md.md_data += ef->off; @@ -639,9 +650,9 @@ elf_hash(const char *name) return h; } -static const char elf_bad_symtable[] = "elf_lookup_symbol: corrupt symbol table\n"; +static const char __elfN(bad_symtable)[] = "elf" __XSTRING(__ELF_WORD_SIZE) "_lookup_symbol: corrupt symbol table\n"; int -elf_lookup_symbol(struct preloaded_file *fp, elf_file_t ef, const char* name, +__elfN(lookup_symbol)(struct preloaded_file *fp, elf_file_t ef, const char* name, Elf_Sym *symp) { Elf_Hashelt symnum; @@ -654,13 +665,13 @@ elf_lookup_symbol(struct preloaded_file *fp, elf_file_t ef, const char* name, while (symnum != STN_UNDEF) { if (symnum >= ef->nchains) { - printf(elf_bad_symtable); + printf(__elfN(bad_symtable)); return ENOENT; } COPYOUT(ef->symtab + symnum, &sym, sizeof(sym)); if (sym.st_name == 0) { - printf(elf_bad_symtable); + printf(__elfN(bad_symtable)); return ENOENT; } @@ -688,7 +699,7 @@ elf_lookup_symbol(struct preloaded_file *fp, elf_file_t ef, const char* name, * the image in-place, because this is done by kern_linker later on. */ static void -elf_reloc_ptr(struct preloaded_file *mp, elf_file_t ef, +__elfN(reloc_ptr)(struct preloaded_file *mp, elf_file_t ef, void *p, void *val, size_t len) { Elf_Addr off = (Elf_Addr)p - ef->off, word; diff --git a/sys/boot/common/load_elf32.c b/sys/boot/common/load_elf32.c new file mode 100644 index 00000000000..59b6496b0a2 --- /dev/null +++ b/sys/boot/common/load_elf32.c @@ -0,0 +1,3 @@ +/* $FreeBSD$ */ +#define __ELF_WORD_SIZE 32 +#include "load_elf.c" diff --git a/sys/boot/common/load_elf64.c b/sys/boot/common/load_elf64.c new file mode 100644 index 00000000000..d5f99d90ee4 --- /dev/null +++ b/sys/boot/common/load_elf64.c @@ -0,0 +1,3 @@ +/* $FreeBSD$ */ +#define __ELF_WORD_SIZE 64 +#include "load_elf.c" diff --git a/sys/boot/efi/libefi/elf_freebsd.c b/sys/boot/efi/libefi/elf_freebsd.c index 7df9950bbce..27d2b6e0856 100644 --- a/sys/boot/efi/libefi/elf_freebsd.c +++ b/sys/boot/efi/libefi/elf_freebsd.c @@ -94,9 +94,9 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); -struct file_format ia64_elf = { elf_loadfile, elf_exec }; +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; static __inline u_int64_t disable_ic() @@ -136,7 +136,7 @@ enter_kernel(u_int64_t start, struct bootinfo *bi) } static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *hdr; diff --git a/sys/boot/i386/libi386/Makefile b/sys/boot/i386/libi386/Makefile index 19fa0bf3647..b7cb2cc852b 100644 --- a/sys/boot/i386/libi386/Makefile +++ b/sys/boot/i386/libi386/Makefile @@ -4,9 +4,11 @@ LIB= i386 INTERNALLIB= true SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \ - biospci.c bootinfo.c comconsole.c devicename.c elf_freebsd.c gatea20.c \ + biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \ + comconsole.c devicename.c elf32_freebsd.c \ + elf64_freebsd.c gatea20.c \ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \ - time.c vidconsole.c + time.c vidconsole.c amd64_tramp.S CFLAGS+= -ffreestanding BOOT_COMCONSOLE_PORT?= 0x3f8 diff --git a/sys/boot/i386/libi386/amd64_tramp.S b/sys/boot/i386/libi386/amd64_tramp.S new file mode 100644 index 00000000000..012512d8c8a --- /dev/null +++ b/sys/boot/i386/libi386/amd64_tramp.S @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2003 Peter Wemm + * 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. + * + * $FreeBSD$ + */ + +/* + * Quick and dirty trampoline to get into 64 bit (long) mode and running + * with paging enabled so that we enter the kernel at its linked address. + */ +#define MSR_EFER 0xc0000080 +#define EFER_LME 0x00000100 +#define CR4_PAE 0x00000020 +#define CR4_PSE 0x00000010 +#define CR0_PG 0x80000000 + +/* GRRR. Deal with BTX that links us for a non-zero location */ +#define VPBASE 0xa000 +#define VTOP(x) ((x) + VPBASE) + + .data + + .p2align 12,0x40 + + .globl PT4 +PT4: + .space 0x1000 + .globl PT3 +PT3: + .space 0x1000 + .globl PT2 +PT2: + .space 0x1000 + +gdtdesc: + .word gdtend - gdt + .long VTOP(gdt) # low + .long 0 # high + +gdt: + .long 0 # null descriptor + .long 0 + .long 0x00000000 # %cs + .long 0x00209800 + .long 0x00000000 # %ds + .long 0x00008000 +gdtend: + + .text + .code32 + + .globl amd64_tramp +amd64_tramp: + /* Be sure that interrupts are disabled */ + cli + + /* Turn on EFER.LME */ + movl $MSR_EFER, %ecx + rdmsr + orl $EFER_LME, %eax + wrmsr + + /* Turn on PAE */ + movl %cr4, %eax + orl $(CR4_PAE | CR4_PSE), %eax + movl %eax, %cr4 + + /* Set %cr3 for PT4 */ + movl $VTOP(PT4), %eax + movl %eax, %cr3 + + /* Turn on paging (implicitly sets EFER.LMA) */ + movl %cr0, %eax + orl $CR0_PG, %eax + movl %eax, %cr0 + + /* Now we're in compatability mode. set %cs for long mode */ + movl $VTOP(gdtdesc), %eax + movl VTOP(entry_hi), %esi + movl VTOP(entry_lo), %edi + lgdt (%eax) + ljmp $0x8, $VTOP(longmode) + + .code64 +longmode: + /* We're still running V=P, jump to entry point */ + movl %esi, %eax + salq $32, %rax + movl %edi, %eax + pushq %rax + ret diff --git a/sys/boot/i386/libi386/biossmap.c b/sys/boot/i386/libi386/biossmap.c new file mode 100644 index 00000000000..1548dd901e1 --- /dev/null +++ b/sys/boot/i386/libi386/biossmap.c @@ -0,0 +1,107 @@ +/*- + * Copyright (c) 1998 Michael Smith + * 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. + * + * $FreeBSD$ + */ + +/* + * Obtain memory configuration information from the BIOS + */ +#include +#include +#include +#include +#include "bootstrap.h" +#include "libi386.h" +#include "btxv86.h" + +#define SMAPSIG 0x534D4150 + +struct smap { + u_int64_t base; + u_int64_t length; + u_int32_t type; +} __packed; + +static struct smap smap; + +static struct smap *smapbase; +static int smaplen; + +void +bios_getsmap(void) +{ + int n; + + n = 0; + smaplen = 0; + /* Count up segments in system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct smap); + v86.edx = SMAPSIG; + v86.es = VTOPSEG(&smap); + v86.edi = VTOPOFF(&smap); + v86int(); + if ((v86.efl & 1) || (v86.eax != SMAPSIG)) + break; + n++; + } while (v86.ebx != 0); + if (n == 0) + return; + n += 10; /* spare room */ + smapbase = malloc(n * sizeof(*smapbase)); + + /* Save system memory map */ + v86.ebx = 0; + do { + v86.ctl = V86_FLAGS; + v86.addr = 0x15; /* int 0x15 function 0xe820*/ + v86.eax = 0xe820; + v86.ecx = sizeof(struct smap); + v86.edx = SMAPSIG; + v86.es = VTOPSEG(&smapbase[smaplen]); + v86.edi = VTOPOFF(&smapbase[smaplen]); + v86int(); + smaplen++; + if ((v86.efl & 1) || (v86.eax != SMAPSIG)) + break; + } while (v86.ebx != 0 && smaplen < n); +} +void +bios_addsmapdata(struct preloaded_file *kfp) +{ + int len; + + if (smapbase == 0 || smaplen == 0) + return; + len = smaplen * sizeof(*smapbase); + file_addmetadata(kfp, MODINFOMD_SMAP, len, smapbase); + /* Temporary compatability with older development kernels */ + file_addmetadata(kfp, 0x0009, len, smapbase); +} diff --git a/sys/boot/i386/libi386/bootinfo.c b/sys/boot/i386/libi386/bootinfo.c index fb269dfa43c..5de13a7a991 100644 --- a/sys/boot/i386/libi386/bootinfo.c +++ b/sys/boot/i386/libi386/bootinfo.c @@ -30,13 +30,10 @@ #include #include #include -#include #include "bootstrap.h" #include "libi386.h" #include "btxv86.h" -static struct bootinfo bi; - /* * Return a 'boothowto' value corresponding to the kernel arguments in * (kargs) and any relevant environment variables. @@ -58,8 +55,6 @@ static struct {NULL, 0} }; -vm_offset_t bi_copymodules(vm_offset_t addr); - int bi_getboothowto(char *kargs) { @@ -159,205 +154,3 @@ bi_copyenv(vm_offset_t addr) addr++; return(addr); } - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a) { \ - u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s) { \ - COPY32(t, a); \ - COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long));\ -} - -#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) -#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) -#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) - -#define MOD_VAR(t, a, s) { \ - COPY32(t, a); \ - COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) -#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) - -#define MOD_METADATA(a, mm) { \ - COPY32(MODINFO_METADATA | mm->md_type, a); \ - COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long));\ -} - -#define MOD_END(a) { \ - COPY32(MODINFO_END, a); \ - COPY32(0, a); \ -} - -vm_offset_t -bi_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - - /* start with the first module on the list, should be the kernel */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - - MOD_NAME(addr, fp->f_name); /* this field must come first */ - MOD_TYPE(addr, fp->f_type); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args); - MOD_ADDR(addr, fp->f_addr); - MOD_SIZE(addr, fp->f_size); - for (md = fp->f_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md); - } - MOD_END(addr); - return(addr); -} - -/* - * Load the information expected by an i386 kernel. - * - * - The 'boothowto' argument is constructed - * - The 'bootdev' argument is constructed - * - The 'bootinfo' struct is constructed, and copied into the kernel space. - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) -{ - struct preloaded_file *xp; - struct i386_devdesc *rootdev; - vm_offset_t addr; - char *rootdevname; - int bootdevnr, i; - u_int pad; - char *kernelname; - const char *kernelpath; - - *howtop = bi_getboothowto(args); - - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - i386_getdev((void **)(&rootdev), rootdevname, NULL); - if (rootdev == NULL) { /* bad $rootdev/$currdev */ - printf("can't determine root device\n"); - return(EINVAL); - } - - /* Try reading the /etc/fstab file to select the root device */ - getrootmount(i386_fmtdev((void *)rootdev)); - - /* Do legacy rootdev guessing */ - - /* XXX - use a default bootdev of 0. Is this ok??? */ - bootdevnr = 0; - - switch(rootdev->d_type) { - case DEVT_CD: - /* Pass in BIOS device number. */ - bi.bi_bios_dev = bc_unit2bios(rootdev->d_kind.bioscd.unit); - bootdevnr = bc_getdev(rootdev); - break; - - case DEVT_DISK: - /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit); - bootdevnr = bd_getdev(rootdev); - break; - - case DEVT_NET: - break; - - default: - printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); - } - if (bootdevnr == -1) { - printf("root device %s invalid\n", i386_fmtdev(rootdev)); - return (EINVAL); - } - free(rootdev); - *bootdevp = bootdevnr; - - /* legacy bootinfo structure */ - bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ - for (i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = bd_getbigeom(i); - bi.bi_size = sizeof(bi); - bi.bi_memsizes_valid = 1; - bi.bi_basemem = bios_basemem / 1024; - bi.bi_extmem = bios_extmem / 1024; - - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - - /* copy our environment */ - bi.bi_envp = addr; - addr = bi_copyenv(addr); - - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - /* copy module list and metadata */ - bi.bi_modulep = addr; - addr = bi_copymodules(addr); - - /* all done copying stuff in, save end of loaded object space */ - bi.bi_kernend = addr; - - *howtop |= RB_BOOTINFO; /* it's there now */ - - /* - * Get the kernel name, strip off any device prefix. - */ - kernelname = getenv("kernelname"); - i386_getdev(NULL, kernelname, &kernelpath); - bi.bi_kernelname = VTOP(kernelpath); - *bip = VTOP(&bi); - - return(0); -} diff --git a/sys/boot/i386/libi386/bootinfo32.c b/sys/boot/i386/libi386/bootinfo32.c index fb269dfa43c..a2fc2c8d036 100644 --- a/sys/boot/i386/libi386/bootinfo32.c +++ b/sys/boot/i386/libi386/bootinfo32.c @@ -35,130 +35,7 @@ #include "libi386.h" #include "btxv86.h" -static struct bootinfo bi; - -/* - * Return a 'boothowto' value corresponding to the kernel arguments in - * (kargs) and any relevant environment variables. - */ -static struct -{ - const char *ev; - int mask; -} howto_names[] = { - {"boot_askname", RB_ASKNAME}, - {"boot_cdrom", RB_CDROM}, - {"boot_userconfig", RB_CONFIG}, - {"boot_ddb", RB_KDB}, - {"boot_gdb", RB_GDB}, - {"boot_single", RB_SINGLE}, - {"boot_verbose", RB_VERBOSE}, - {"boot_multicons", RB_MULTIPLE}, - {"boot_serial", RB_SERIAL}, - {NULL, 0} -}; - -vm_offset_t bi_copymodules(vm_offset_t addr); - -int -bi_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'c': - howto |= RB_CONFIG; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (!strcmp(getenv("console"), "comconsole")) - howto |= RB_SERIAL; - if (!strcmp(getenv("console"), "nullconsole")) - howto |= RB_MUTE; - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as =, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - i386_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - i386_copyin("", addr, 1); - addr++; - } - i386_copyin("", addr, 1); - addr++; - return(addr); -} +static struct bootinfo bi; /* * Copy module-related data into the load area, where it can be @@ -176,65 +53,71 @@ bi_copyenv(vm_offset_t addr) * MOD_SIZE sizeof(size_t) module size * MOD_METADATA (variable) type-specific metadata */ -#define COPY32(v, a) { \ +#define COPY32(v, a, c) { \ u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ + if (c) \ + i386_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ } -#define MOD_STR(t, a, s) { \ - COPY32(t, a); \ - COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c); \ + if (c) \ + i386_copyin(s, a, strlen(s) + 1); \ a += roundup(strlen(s) + 1, sizeof(u_long));\ } -#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) -#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) -#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) -#define MOD_VAR(t, a, s) { \ - COPY32(t, a); \ - COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + i386_copyin(&s, a, sizeof(s)); \ a += roundup(sizeof(s), sizeof(u_long)); \ } -#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) -#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) -#define MOD_METADATA(a, mm) { \ - COPY32(MODINFO_METADATA | mm->md_type, a); \ - COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ +#define MOD_METADATA(a, mm, c) { \ + COPY32(MODINFO_METADATA | mm->md_type, a, c); \ + COPY32(mm->md_size, a, c); \ + if (c) \ + i386_copyin(mm->md_data, a, mm->md_size); \ a += roundup(mm->md_size, sizeof(u_long));\ } -#define MOD_END(a) { \ - COPY32(MODINFO_END, a); \ - COPY32(0, a); \ +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ } -vm_offset_t -bi_copymodules(vm_offset_t addr) +static vm_offset_t +bi_copymodules32(vm_offset_t addr) { struct preloaded_file *fp; struct file_metadata *md; + int c; + c = addr != 0; /* start with the first module on the list, should be the kernel */ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - MOD_NAME(addr, fp->f_name); /* this field must come first */ - MOD_TYPE(addr, fp->f_type); + MOD_NAME(addr, fp->f_name, c); /* this field must come first */ + MOD_TYPE(addr, fp->f_type, c); if (fp->f_args) - MOD_ARGS(addr, fp->f_args); - MOD_ADDR(addr, fp->f_addr); - MOD_SIZE(addr, fp->f_size); + MOD_ARGS(addr, fp->f_args, c); + MOD_ADDR(addr, fp->f_addr, c); + MOD_SIZE(addr, fp->f_size, c); for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md); + MOD_METADATA(addr, md, c); } - MOD_END(addr); + MOD_END(addr, c); return(addr); } @@ -248,18 +131,22 @@ bi_copymodules(vm_offset_t addr) * - Module metadata are formatted and placed in kernel space. */ int -bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) +bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp) { - struct preloaded_file *xp; + struct preloaded_file *xp, *kfp; struct i386_devdesc *rootdev; + struct file_metadata *md; vm_offset_t addr; + vm_offset_t kernend; + vm_offset_t envp; + vm_offset_t size; + vm_offset_t ssym, esym; char *rootdevname; - int bootdevnr, i; - u_int pad; + int bootdevnr, i, howto; char *kernelname; const char *kernelpath; - *howtop = bi_getboothowto(args); + howto = bi_getboothowto(args); /* * Allow the environment variable 'rootdev' to override the supplied device @@ -305,9 +192,60 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) return (EINVAL); } free(rootdev); - *bootdevp = bootdevnr; + + /* find the last module in the chain */ + addr = 0; + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; + } + /* pad to a page boundary */ + addr = roundup(addr, PAGE_SIZE); + + /* copy our environment */ + envp = addr; + addr = bi_copyenv(addr); + + /* pad to a page boundary */ + addr = roundup(addr, PAGE_SIZE); + + kfp = file_findfile(NULL, "elf64 kernel"); + if (kfp == NULL) + kfp = file_findfile(NULL, "elf32 kernel"); + if (kfp == NULL) + panic("can't find kernel file"); + kernend = 0; /* fill it in later */ + file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); + file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); + file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); + bios_addsmapdata(kfp); + + /* Figure out the size and location of the metadata */ + *modulep = addr; + size = bi_copymodules32(0); + kernend = roundup(addr + size, PAGE_SIZE); + *kernendp = kernend; + + /* patch MODINFOMD_KERNEND */ + md = file_findmetadata(kfp, MODINFOMD_KERNEND); + bcopy(&kernend, md->md_data, sizeof kernend); + + /* copy module list and metadata */ + (void)bi_copymodules32(addr); + + ssym = esym = 0; + md = file_findmetadata(kfp, MODINFOMD_SSYM); + if (md != NULL) + ssym = *((vm_offset_t *)&(md->md_data)); + md = file_findmetadata(kfp, MODINFOMD_ESYM); + if (md != NULL) + esym = *((vm_offset_t *)&(md->md_data)); + if (ssym == 0 || esym == 0) + ssym = esym = 0; /* sanity */ /* legacy bootinfo structure */ + kernelname = getenv("kernelname"); + i386_getdev(NULL, kernelname, &kernelpath); bi.bi_version = BOOTINFO_VERSION; bi.bi_kernelname = 0; /* XXX char * -> kernel name */ bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ @@ -318,45 +256,16 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) bi.bi_memsizes_valid = 1; bi.bi_basemem = bios_basemem / 1024; bi.bi_extmem = bios_extmem / 1024; - - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - - /* copy our environment */ - bi.bi_envp = addr; - addr = bi_copyenv(addr); - - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - /* copy module list and metadata */ - bi.bi_modulep = addr; - addr = bi_copymodules(addr); - - /* all done copying stuff in, save end of loaded object space */ - bi.bi_kernend = addr; - - *howtop |= RB_BOOTINFO; /* it's there now */ - - /* - * Get the kernel name, strip off any device prefix. - */ - kernelname = getenv("kernelname"); - i386_getdev(NULL, kernelname, &kernelpath); + bi.bi_envp = envp; + bi.bi_modulep = *modulep; + bi.bi_kernend = kernend; bi.bi_kernelname = VTOP(kernelpath); + bi.bi_symtab = ssym; /* XXX this is only the primary kernel symtab */ + bi.bi_esymtab = esym; + + /* legacy boot arguments */ + *howtop = howto | RB_BOOTINFO; + *bootdevp = bootdevnr; *bip = VTOP(&bi); return(0); diff --git a/sys/boot/i386/libi386/bootinfo64.c b/sys/boot/i386/libi386/bootinfo64.c index fb269dfa43c..5398a0c0a41 100644 --- a/sys/boot/i386/libi386/bootinfo64.c +++ b/sys/boot/i386/libi386/bootinfo64.c @@ -35,131 +35,6 @@ #include "libi386.h" #include "btxv86.h" -static struct bootinfo bi; - -/* - * Return a 'boothowto' value corresponding to the kernel arguments in - * (kargs) and any relevant environment variables. - */ -static struct -{ - const char *ev; - int mask; -} howto_names[] = { - {"boot_askname", RB_ASKNAME}, - {"boot_cdrom", RB_CDROM}, - {"boot_userconfig", RB_CONFIG}, - {"boot_ddb", RB_KDB}, - {"boot_gdb", RB_GDB}, - {"boot_single", RB_SINGLE}, - {"boot_verbose", RB_VERBOSE}, - {"boot_multicons", RB_MULTIPLE}, - {"boot_serial", RB_SERIAL}, - {NULL, 0} -}; - -vm_offset_t bi_copymodules(vm_offset_t addr); - -int -bi_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'c': - howto |= RB_CONFIG; - break; - case 'C': - howto |= RB_CDROM; - break; - case 'd': - howto |= RB_KDB; - break; - case 'D': - howto |= RB_MULTIPLE; - break; - case 'm': - howto |= RB_MUTE; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'p': - howto |= RB_PAUSE; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (!strcmp(getenv("console"), "comconsole")) - howto |= RB_SERIAL; - if (!strcmp(getenv("console"), "nullconsole")) - howto |= RB_MUTE; - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as =, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - i386_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - i386_copyin("", addr, 1); - addr++; - } - i386_copyin("", addr, 1); - addr++; - return(addr); -} - /* * Copy module-related data into the load area, where it can be * used as a directory for loaded modules. @@ -176,65 +51,74 @@ bi_copyenv(vm_offset_t addr) * MOD_SIZE sizeof(size_t) module size * MOD_METADATA (variable) type-specific metadata */ -#define COPY32(v, a) { \ +#define COPY32(v, a, c) { \ u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ + if (c) \ + i386_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ } -#define MOD_STR(t, a, s) { \ - COPY32(t, a); \ - COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long));\ +#define MOD_STR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(strlen(s) + 1, a, c); \ + if (c) \ + i386_copyin(s, a, strlen(s) + 1); \ + a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ } -#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) -#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) -#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) +#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c) +#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c) +#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c) -#define MOD_VAR(t, a, s) { \ - COPY32(t, a); \ - COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ +#define MOD_VAR(t, a, s, c) { \ + COPY32(t, a, c); \ + COPY32(sizeof(s), a, c); \ + if (c) \ + i386_copyin(&s, a, sizeof(s)); \ + a += roundup(sizeof(s), sizeof(u_int64_t)); \ } -#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) -#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) +#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c) +#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c) -#define MOD_METADATA(a, mm) { \ - COPY32(MODINFO_METADATA | mm->md_type, a); \ - COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long));\ +#define MOD_METADATA(a, mm, c) { \ + COPY32(MODINFO_METADATA | mm->md_type, a, c); \ + COPY32(mm->md_size, a, c); \ + if (c) \ + i386_copyin(mm->md_data, a, mm->md_size); \ + a += roundup(mm->md_size, sizeof(u_int64_t));\ } -#define MOD_END(a) { \ - COPY32(MODINFO_END, a); \ - COPY32(0, a); \ +#define MOD_END(a, c) { \ + COPY32(MODINFO_END, a, c); \ + COPY32(0, a, c); \ } -vm_offset_t -bi_copymodules(vm_offset_t addr) +static vm_offset_t +bi_copymodules64(vm_offset_t addr) { struct preloaded_file *fp; struct file_metadata *md; + int c; + u_int64_t v; + c = addr != 0; /* start with the first module on the list, should be the kernel */ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - MOD_NAME(addr, fp->f_name); /* this field must come first */ - MOD_TYPE(addr, fp->f_type); + MOD_NAME(addr, fp->f_name, c); /* this field must come first */ + MOD_TYPE(addr, fp->f_type, c); if (fp->f_args) - MOD_ARGS(addr, fp->f_args); - MOD_ADDR(addr, fp->f_addr); - MOD_SIZE(addr, fp->f_size); + MOD_ARGS(addr, fp->f_args, c); + v = fp->f_addr; + MOD_ADDR(addr, v, c); + v = fp->f_size; + MOD_SIZE(addr, v, c); for (md = fp->f_metadata; md != NULL; md = md->md_next) if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md); + MOD_METADATA(addr, md, c); } - MOD_END(addr); + MOD_END(addr, c); return(addr); } @@ -248,18 +132,21 @@ bi_copymodules(vm_offset_t addr) * - Module metadata are formatted and placed in kernel space. */ int -bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) +bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) { - struct preloaded_file *xp; + struct preloaded_file *xp, *kfp; struct i386_devdesc *rootdev; + struct file_metadata *md; vm_offset_t addr; + u_int64_t kernend; + u_int64_t envp; + vm_offset_t size; char *rootdevname; - int bootdevnr, i; - u_int pad; + int i, howto; char *kernelname; const char *kernelpath; - *howtop = bi_getboothowto(args); + howto = bi_getboothowto(args); /* * Allow the environment variable 'rootdev' to override the supplied device @@ -276,49 +163,6 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) /* Try reading the /etc/fstab file to select the root device */ getrootmount(i386_fmtdev((void *)rootdev)); - /* Do legacy rootdev guessing */ - - /* XXX - use a default bootdev of 0. Is this ok??? */ - bootdevnr = 0; - - switch(rootdev->d_type) { - case DEVT_CD: - /* Pass in BIOS device number. */ - bi.bi_bios_dev = bc_unit2bios(rootdev->d_kind.bioscd.unit); - bootdevnr = bc_getdev(rootdev); - break; - - case DEVT_DISK: - /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit); - bootdevnr = bd_getdev(rootdev); - break; - - case DEVT_NET: - break; - - default: - printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type); - } - if (bootdevnr == -1) { - printf("root device %s invalid\n", i386_fmtdev(rootdev)); - return (EINVAL); - } - free(rootdev); - *bootdevp = bootdevnr; - - /* legacy bootinfo structure */ - bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ - for (i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = bd_getbigeom(i); - bi.bi_size = sizeof(bi); - bi.bi_memsizes_valid = 1; - bi.bi_basemem = bios_basemem / 1024; - bi.bi_extmem = bios_extmem / 1024; - /* find the last module in the chain */ addr = 0; for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { @@ -326,38 +170,38 @@ bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) addr = xp->f_addr + xp->f_size; } /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } + addr = roundup(addr, PAGE_SIZE); /* copy our environment */ - bi.bi_envp = addr; + envp = addr; addr = bi_copyenv(addr); /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } + addr = roundup(addr, PAGE_SIZE); + + kfp = file_findfile(NULL, "elf64 kernel"); + if (kfp == NULL) + kfp = file_findfile(NULL, "elf32 kernel"); + if (kfp == NULL) + panic("can't find kernel file"); + kernend = 0; /* fill it in later */ + file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); + file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); + file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); + bios_addsmapdata(kfp); + + /* Figure out the size and location of the metadata */ + *modulep = addr; + size = bi_copymodules64(0); + kernend = roundup(addr + size, PAGE_SIZE); + *kernendp = kernend; + + /* patch MODINFOMD_KERNEND */ + md = file_findmetadata(kfp, MODINFOMD_KERNEND); + bcopy(&kernend, md->md_data, sizeof kernend); + /* copy module list and metadata */ - bi.bi_modulep = addr; - addr = bi_copymodules(addr); - - /* all done copying stuff in, save end of loaded object space */ - bi.bi_kernend = addr; - - *howtop |= RB_BOOTINFO; /* it's there now */ - - /* - * Get the kernel name, strip off any device prefix. - */ - kernelname = getenv("kernelname"); - i386_getdev(NULL, kernelname, &kernelpath); - bi.bi_kernelname = VTOP(kernelpath); - *bip = VTOP(&bi); + (void)bi_copymodules64(addr); return(0); } diff --git a/sys/boot/i386/libi386/elf32_freebsd.c b/sys/boot/i386/libi386/elf32_freebsd.c index 514183db144..3c9397b3a09 100644 --- a/sys/boot/i386/libi386/elf32_freebsd.c +++ b/sys/boot/i386/libi386/elf32_freebsd.c @@ -38,9 +38,9 @@ #include "libi386.h" #include "btxv86.h" -static int elf_exec(struct preloaded_file *amp); +static int elf32_exec(struct preloaded_file *amp); -struct file_format i386_elf = { elf_loadfile, elf_exec }; +struct file_format i386_elf = { elf32_loadfile, elf32_exec }; /* * There is an a.out kernel and one or more a.out modules loaded. @@ -48,41 +48,28 @@ struct file_format i386_elf = { elf_loadfile, elf_exec }; * preparations as are required, and do so. */ static int -elf_exec(struct preloaded_file *fp) +elf32_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *ehdr; - vm_offset_t entry, bootinfop; + vm_offset_t entry, bootinfop, modulep, kernend; int boothowto, err, bootdev; - struct bootinfo *bi; - vm_offset_t ssym, esym; if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ ehdr = (Elf_Ehdr *)&(md->md_data); - if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0) + err = bi_load32(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend); + if (err != 0) return(err); entry = ehdr->e_entry & 0xffffff; - ssym = esym = 0; - if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) - ssym = *((vm_offset_t *)&(md->md_data)); - if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) - esym = *((vm_offset_t *)&(md->md_data)); - if (ssym == 0 || esym == 0) - ssym = esym = 0; /* sanity */ - bi = (struct bootinfo *)PTOV(bootinfop); - bi->bi_symtab = ssym; /* XXX this is only the primary kernel symtab */ - bi->bi_esymtab = esym; - - #ifdef DEBUG printf("Start @ 0x%lx ...\n", entry); #endif dev_cleanup(); - __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop); + __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend); panic("exec returned"); } diff --git a/sys/boot/i386/libi386/elf64_freebsd.c b/sys/boot/i386/libi386/elf64_freebsd.c index 514183db144..d1033f29c7d 100644 --- a/sys/boot/i386/libi386/elf64_freebsd.c +++ b/sys/boot/i386/libi386/elf64_freebsd.c @@ -26,6 +26,7 @@ * $FreeBSD$ */ +#define __ELF_WORD_SIZE 64 #include #include #include @@ -38,9 +39,26 @@ #include "libi386.h" #include "btxv86.h" -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); -struct file_format i386_elf = { elf_loadfile, elf_exec }; +struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; + +#define PG_V 0x001 +#define PG_RW 0x002 +#define PG_U 0x004 +#define PG_PS 0x080 + +typedef u_int64_t p4_entry_t; +typedef u_int64_t p3_entry_t; +typedef u_int64_t p2_entry_t; +extern p4_entry_t PT4[]; +extern p3_entry_t PT3[]; +extern p2_entry_t PT2[]; + +u_int32_t entry_hi; +u_int32_t entry_lo; + +extern amd64_tramp(); /* * There is an a.out kernel and one or more a.out modules loaded. @@ -48,41 +66,52 @@ struct file_format i386_elf = { elf_loadfile, elf_exec }; * preparations as are required, and do so. */ static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *ehdr; - vm_offset_t entry, bootinfop; - int boothowto, err, bootdev; - struct bootinfo *bi; - vm_offset_t ssym, esym; + vm_offset_t modulep, kernend; + int err; + int i; if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ ehdr = (Elf_Ehdr *)&(md->md_data); - if ((err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop)) != 0) + err = bi_load64(fp->f_args, &modulep, &kernend); + if (err != 0) return(err); - entry = ehdr->e_entry & 0xffffff; - ssym = esym = 0; - if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) - ssym = *((vm_offset_t *)&(md->md_data)); - if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) - esym = *((vm_offset_t *)&(md->md_data)); - if (ssym == 0 || esym == 0) - ssym = esym = 0; /* sanity */ - bi = (struct bootinfo *)PTOV(bootinfop); - bi->bi_symtab = ssym; /* XXX this is only the primary kernel symtab */ - bi->bi_esymtab = esym; + bzero(PT4, PAGE_SIZE); + bzero(PT3, PAGE_SIZE); + bzero(PT2, PAGE_SIZE); + /* single PML4 entry */ + PT4[0] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); + PT4[0] |= PG_V | PG_RW | PG_U; + /* Direct map 1GB at address zero */ + PT3[0] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); + PT3[0] |= PG_V | PG_RW | PG_U; + + /* Direct map 1GB at KERNBASE (hardcoded for now) */ + PT3[1] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); + PT3[1] |= PG_V | PG_RW | PG_U; + + /* 512 PG_PS (2MB) page mappings for 1GB of direct mapping */ + for (i = 0; i < 512; i++) { + PT2[i] = i * (2 * 1024 * 1024); + PT2[i] |= PG_V | PG_RW | PG_PS | PG_U; + } + + entry_lo = ehdr->e_entry & 0xffffffff; + entry_hi = (ehdr->e_entry >> 32) & 0xffffffff; #ifdef DEBUG - printf("Start @ 0x%lx ...\n", entry); + printf("Start @ %#llx ...\n", ehdr->e_entry); #endif dev_cleanup(); - __exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop); + __exec((void *)VTOP(amd64_tramp), modulep, kernend); panic("exec returned"); } diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h index cabe735b7bc..f2696e0a360 100644 --- a/sys/boot/i386/libi386/libi386.h +++ b/sys/boot/i386/libi386/libi386.h @@ -84,6 +84,10 @@ ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t i386_copyout(const vm_offset_t src, void *dest, const size_t len); ssize_t i386_readin(const int fd, vm_offset_t dest, const size_t len); +struct preloaded_file; +void bios_addsmapdata(struct preloaded_file *); +void bios_getsmap(void); + void bios_getmem(void); extern u_int32_t bios_basemem; /* base memory in bytes */ extern u_int32_t bios_extmem; /* extended memory in bytes */ @@ -97,6 +101,8 @@ int i386_autoload(void); int bi_getboothowto(char *kargs); vm_offset_t bi_copyenv(vm_offset_t addr); -int bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip); +int bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, + vm_offset_t *modulep, vm_offset_t *kernend); +int bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernend); void pxe_enable(void *pxeinfo); diff --git a/sys/boot/i386/loader/conf.c b/sys/boot/i386/loader/conf.c index 78b5d59b72a..17d8d7d43db 100644 --- a/sys/boot/i386/loader/conf.c +++ b/sys/boot/i386/loader/conf.c @@ -82,9 +82,11 @@ struct fs_ops *file_system[] = { * rather than reading the file go first. */ extern struct file_format i386_elf; +extern struct file_format amd64_elf; struct file_format *file_formats[] = { &i386_elf, + &amd64_elf, NULL }; diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c index f3021311185..ff2ee103480 100644 --- a/sys/boot/i386/loader/main.c +++ b/sys/boot/i386/loader/main.c @@ -144,6 +144,8 @@ main(void) extract_currdev(); /* set $currdev and $loaddev */ setenv("LINES", "24", 1); /* optional */ + bios_getsmap(); + archsw.arch_autoload = i386_autoload; archsw.arch_getdev = i386_getdev; archsw.arch_copyin = i386_copyin; diff --git a/sys/boot/ia64/common/exec.c b/sys/boot/ia64/common/exec.c index 7df9950bbce..27d2b6e0856 100644 --- a/sys/boot/ia64/common/exec.c +++ b/sys/boot/ia64/common/exec.c @@ -94,9 +94,9 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); -struct file_format ia64_elf = { elf_loadfile, elf_exec }; +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; static __inline u_int64_t disable_ic() @@ -136,7 +136,7 @@ enter_kernel(u_int64_t start, struct bootinfo *bi) } static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *hdr; diff --git a/sys/boot/ia64/libski/elf_freebsd.c b/sys/boot/ia64/libski/elf_freebsd.c index e72a52d5a7b..c6599a77a2b 100644 --- a/sys/boot/ia64/libski/elf_freebsd.c +++ b/sys/boot/ia64/libski/elf_freebsd.c @@ -91,9 +91,9 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); -struct file_format ia64_elf = { elf_loadfile, elf_exec }; +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; #define PTE_MA_WB 0 #define PTE_MA_UC 4 @@ -154,7 +154,7 @@ enter_kernel(const char* filename, u_int64_t start, struct bootinfo *bi) } static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *hdr; diff --git a/sys/boot/ia64/ski/elf_freebsd.c b/sys/boot/ia64/ski/elf_freebsd.c index e72a52d5a7b..c6599a77a2b 100644 --- a/sys/boot/ia64/ski/elf_freebsd.c +++ b/sys/boot/ia64/ski/elf_freebsd.c @@ -91,9 +91,9 @@ #define _KERNEL -static int elf_exec(struct preloaded_file *amp); +static int elf64_exec(struct preloaded_file *amp); -struct file_format ia64_elf = { elf_loadfile, elf_exec }; +struct file_format ia64_elf = { elf64_loadfile, elf64_exec }; #define PTE_MA_WB 0 #define PTE_MA_UC 4 @@ -154,7 +154,7 @@ enter_kernel(const char* filename, u_int64_t start, struct bootinfo *bi) } static int -elf_exec(struct preloaded_file *fp) +elf64_exec(struct preloaded_file *fp) { struct file_metadata *md; Elf_Ehdr *hdr; diff --git a/sys/boot/ofw/libofw/elf_freebsd.c b/sys/boot/ofw/libofw/elf_freebsd.c index 95d4a908af6..7fa75860d80 100644 --- a/sys/boot/ofw/libofw/elf_freebsd.c +++ b/sys/boot/ofw/libofw/elf_freebsd.c @@ -42,13 +42,13 @@ extern char end[]; extern vm_offset_t reloc; /* From /conf.c */ int -ofw_elf_loadfile(char *filename, vm_offset_t dest, +__elfN(ofw_loadfile)(char *filename, vm_offset_t dest, struct preloaded_file **result) { int r; void *addr; - r = elf_loadfile(filename, dest, result); + r = __elfN(loadfile)(filename, dest, result); if (r != 0) return (r); @@ -56,7 +56,7 @@ ofw_elf_loadfile(char *filename, vm_offset_t dest, } int -ofw_elf_exec(struct preloaded_file *fp) +__elfN(ofw_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp; @@ -83,6 +83,6 @@ ofw_elf_exec(struct preloaded_file *fp) struct file_format ofw_elf = { - ofw_elf_loadfile, - ofw_elf_exec + __elfN(ofw_loadfile), + __elfN(ofw_exec) };