1223695Sdfr/*- 2223695Sdfr * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3223695Sdfr * All rights reserved. 4223695Sdfr * 5223695Sdfr * Redistribution and use in source and binary forms, with or without 6223695Sdfr * modification, are permitted provided that the following conditions 7223695Sdfr * are met: 8223695Sdfr * 1. Redistributions of source code must retain the above copyright 9223695Sdfr * notice, this list of conditions and the following disclaimer. 10223695Sdfr * 2. Redistributions in binary form must reproduce the above copyright 11223695Sdfr * notice, this list of conditions and the following disclaimer in the 12223695Sdfr * documentation and/or other materials provided with the distribution. 13223695Sdfr * 14223695Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15223695Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16223695Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17223695Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18223695Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19223695Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20223695Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21223695Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22223695Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23223695Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24223695Sdfr * SUCH DAMAGE. 25223695Sdfr */ 26223695Sdfr 27223695Sdfr#include <sys/cdefs.h> 28223695Sdfr__FBSDID("$FreeBSD: stable/11/stand/userboot/userboot/elf32_freebsd.c 261504 2014-02-05 04:39:03Z jhb $"); 29223695Sdfr 30223695Sdfr#include <sys/param.h> 31223695Sdfr#include <sys/exec.h> 32223695Sdfr#include <sys/linker.h> 33223695Sdfr#include <string.h> 34247047Skib#define _MACHINE_ELF_WANT_32BIT 35223695Sdfr#include <i386/include/bootinfo.h> 36223695Sdfr#include <i386/include/elf.h> 37223695Sdfr#include <stand.h> 38223695Sdfr 39223695Sdfr#include "bootstrap.h" 40223695Sdfr#include "libuserboot.h" 41223695Sdfr 42223695Sdfrstatic int elf32_exec(struct preloaded_file *amp); 43223695Sdfrstatic int elf32_obj_exec(struct preloaded_file *amp); 44223695Sdfr 45223695Sdfrstruct file_format i386_elf = { elf32_loadfile, elf32_exec }; 46223695Sdfrstruct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec }; 47223695Sdfr 48261504Sjhb#define GUEST_STACK 0x1000 /* Initial stack base */ 49261504Sjhb#define GUEST_GDT 0x3000 /* Address of initial GDT */ 50261504Sjhb 51223695Sdfr/* 52223695Sdfr * There is an ELF kernel and one or more ELF modules loaded. 53223695Sdfr * We wish to start executing the kernel image, so make such 54223695Sdfr * preparations as are required, and do so. 55223695Sdfr */ 56223695Sdfrstatic int 57223695Sdfrelf32_exec(struct preloaded_file *fp) 58223695Sdfr{ 59223695Sdfr struct file_metadata *md; 60223695Sdfr Elf_Ehdr *ehdr; 61223695Sdfr vm_offset_t entry, bootinfop, modulep, kernend; 62223695Sdfr int boothowto, err, bootdev; 63261504Sjhb uint32_t stack[1024], *sp; 64223695Sdfr 65223695Sdfr 66223695Sdfr if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) 67223695Sdfr return(EFTYPE); 68223695Sdfr ehdr = (Elf_Ehdr *)&(md->md_data); 69223695Sdfr 70223695Sdfr err = bi_load32(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend); 71223695Sdfr if (err != 0) 72223695Sdfr return(err); 73223695Sdfr entry = ehdr->e_entry & 0xffffff; 74223695Sdfr 75223695Sdfr#ifdef DEBUG 76223695Sdfr printf("Start @ 0x%lx ...\n", entry); 77223695Sdfr#endif 78223695Sdfr 79223695Sdfr dev_cleanup(); 80223695Sdfr 81223695Sdfr /* 82223695Sdfr * Build a scratch stack at physical 0x1000 83223695Sdfr */ 84261504Sjhb memset(stack, 0, sizeof(stack)); 85261504Sjhb sp = (uint32_t *)((char *)stack + sizeof(stack)); 86261504Sjhb *--sp = kernend; 87261504Sjhb *--sp = modulep; 88261504Sjhb *--sp = bootinfop; 89261504Sjhb *--sp = 0; 90261504Sjhb *--sp = 0; 91261504Sjhb *--sp = 0; 92261504Sjhb *--sp = bootdev; 93261504Sjhb *--sp = boothowto; 94261504Sjhb 95261504Sjhb /* 96261504Sjhb * Fake return address to mimic "new" boot blocks. For more 97261504Sjhb * details see recover_bootinfo in locore.S. 98261504Sjhb */ 99261504Sjhb *--sp = 0xbeefface; 100261504Sjhb CALLBACK(copyin, stack, GUEST_STACK, sizeof(stack)); 101261504Sjhb CALLBACK(setreg, 4, (char *)sp - (char *)stack + GUEST_STACK); 102261504Sjhb 103261504Sjhb CALLBACK(setgdt, GUEST_GDT, 8 * 4 - 1); 104261504Sjhb 105223695Sdfr CALLBACK(exec, entry); 106223695Sdfr 107223695Sdfr panic("exec returned"); 108223695Sdfr} 109223695Sdfr 110223695Sdfrstatic int 111223695Sdfrelf32_obj_exec(struct preloaded_file *fp) 112223695Sdfr{ 113223695Sdfr return (EFTYPE); 114223695Sdfr} 115