1 /* $OpenBSD: exec.c,v 1.8 2016/06/21 15:39:51 kettenis Exp $ */ 2 3 /* 4 * Copyright (c) 2006, 2016 Mark Kettenis 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/reboot.h> 21 #include <dev/cons.h> 22 23 #include <lib/libkern/libkern.h> 24 #include <lib/libsa/loadfile.h> 25 #include <sys/exec_elf.h> 26 27 #include <efi.h> 28 #include <stand/boot/cmd.h> 29 30 #include "efiboot.h" 31 #include "libsa.h" 32 33 typedef void (*startfuncp)(void *, void *, void *) __attribute__ ((noreturn)); 34 35 void 36 run_loadfile(u_long *marks, int howto) 37 { 38 Elf_Ehdr *elf = (Elf_Ehdr *)marks[MARK_SYM]; 39 Elf_Shdr *shp = (Elf_Shdr *)(marks[MARK_SYM] + elf->e_shoff); 40 u_long esym = marks[MARK_END] & 0x0fffffff; 41 u_long offset = 0; 42 char args[256]; 43 char *cp; 44 void *fdt; 45 uint32_t board_id; 46 int i; 47 48 /* 49 * Tell locore.S where the symbol table ends by setting 50 * 'esym', which should be the first word in the .data 51 * section. 52 */ 53 for (i = 0; i < elf->e_shnum; i++) { 54 /* XXX Assume .data is the first writable segment. */ 55 if (shp[i].sh_flags & SHF_WRITE) { 56 /* XXX We have to store the virtual address. */ 57 esym |= shp[i].sh_addr & 0xf0000000; 58 *(u_long *)(LOADADDR(shp[i].sh_addr)) = esym; 59 break; 60 } 61 } 62 63 snprintf(args, sizeof(args) - 8, "%s:%s", cmd.bootdev, cmd.image); 64 cp = args + strlen(args); 65 66 *cp++ = ' '; 67 *cp = '-'; 68 if (howto & RB_ASKNAME) 69 *++cp = 'a'; 70 if (howto & RB_CONFIG) 71 *++cp = 'c'; 72 if (howto & RB_SINGLE) 73 *++cp = 's'; 74 if (howto & RB_KDB) 75 *++cp = 'd'; 76 if (*cp == '-') 77 *--cp = 0; 78 else 79 *++cp = 0; 80 81 fdt = efi_makebootargs(args, &board_id); 82 83 efi_cleanup(); 84 85 (*(startfuncp)(marks[MARK_ENTRY]))(NULL, (void *)board_id, fdt); 86 87 /* NOTREACHED */ 88 } 89