Path: blob/main/stand/i386/libi386/elf64_freebsd.c
34860 views
/*-1* Copyright (c) 1998 Michael Smith <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#define __ELF_WORD_SIZE 6427#include <sys/param.h>28#include <sys/exec.h>29#include <sys/linker.h>30#include <vm/vm.h>31#include <vm/pmap.h>32#include <string.h>33#include <machine/bootinfo.h>34#include <machine/pmap_pae.h>35#include <machine/elf.h>36#include <stand.h>3738#include "bootstrap.h"39#include "libi386.h"40#include "btxv86.h"4142static int elf64_exec(struct preloaded_file *amp);43static int elf64_obj_exec(struct preloaded_file *amp);4445struct file_format amd64_elf = { elf64_loadfile, elf64_exec };46struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };4748/*49* i386's pmap_pae.h doesn't provide this, so50* just typedef our own.51*/52typedef pdpt_entry_t pml4_entry_t;5354extern pml4_entry_t PT4[];55extern pdpt_entry_t PT3[];56extern pd_entry_t PT2[];5758uint32_t entry_hi;59uint32_t entry_lo;6061extern void amd64_tramp();6263/*64* There is an ELF kernel and one or more ELF modules loaded.65* We wish to start executing the kernel image, so make such66* preparations as are required, and do so.67*/68static int69elf64_exec(struct preloaded_file *fp)70{71struct file_metadata *md;72Elf_Ehdr *ehdr;73vm_offset_t modulep, kernend;74int err;75int i;7677if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)78return(EFTYPE);79ehdr = (Elf_Ehdr *)&(md->md_data);8081err = bi_load64(fp->f_args, &modulep, &kernend, 1);82if (err != 0)83return(err);8485bzero(PT4, PAGE_SIZE);86bzero(PT3, PAGE_SIZE);87bzero(PT2, PAGE_SIZE);8889/*90* This is kinda brutal, but every single 1GB VM memory segment points to91* the same first 1GB of physical memory. But it is more than adequate.92*/93for (i = 0; i < 512; i++) {94/* Each slot of the level 4 pages points to the same level 3 page */95PT4[i] = (pml4_entry_t)VTOP((uintptr_t)&PT3[0]);96PT4[i] |= PG_V | PG_RW;9798/* Each slot of the level 3 pages points to the same level 2 page */99PT3[i] = (pdpt_entry_t)VTOP((uintptr_t)&PT2[0]);100PT3[i] |= PG_V | PG_RW;101102/* The level 2 page slots are mapped with 2MB pages for 1GB. */103PT2[i] = i * (2 * 1024 * 1024);104PT2[i] |= PG_V | PG_RW | PG_PS;105}106107entry_lo = ehdr->e_entry & 0xffffffff;108entry_hi = (ehdr->e_entry >> 32) & 0xffffffff;109#ifdef DEBUG110printf("Start @ %#llx ...\n", ehdr->e_entry);111#endif112113dev_cleanup();114__exec((void *)VTOP(amd64_tramp), modulep, kernend);115116panic("exec returned");117}118119static int120elf64_obj_exec(struct preloaded_file *fp)121{122return (EFTYPE);123}124125126