1 1.1 nonaka /* $NetBSD: loadfile_zboot.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */ 2 1.1 nonaka 3 1.1 nonaka /* 4 1.1 nonaka * Copyright (c) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org> 5 1.1 nonaka * All rights reserved. 6 1.1 nonaka * 7 1.1 nonaka * Redistribution and use in source and binary forms, with or without 8 1.1 nonaka * modification, are permitted provided that the following conditions 9 1.1 nonaka * are met: 10 1.1 nonaka * 1. Redistributions of source code must retain the above copyright 11 1.1 nonaka * notice, this list of conditions and the following disclaimer. 12 1.1 nonaka * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 nonaka * notice, this list of conditions and the following disclaimer in the 14 1.1 nonaka * documentation and/or other materials provided with the distribution. 15 1.1 nonaka * 16 1.1 nonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 nonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 nonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 nonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 nonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 nonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 nonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 nonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 nonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 nonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 nonaka */ 27 1.1 nonaka 28 1.1 nonaka #include <sys/types.h> 29 1.1 nonaka #include <sys/bootblock.h> 30 1.1 nonaka 31 1.1 nonaka #include "boot.h" 32 1.1 nonaka #include "bootinfo.h" 33 1.1 nonaka #include "disk.h" 34 1.1 nonaka #include "unixdev.h" 35 1.1 nonaka #include "pathnames.h" 36 1.1 nonaka 37 1.1 nonaka #include <lib/libsa/loadfile.h> 38 1.1 nonaka 39 1.1 nonaka #include "compat_linux.h" 40 1.1 nonaka 41 1.1 nonaka static int fdloadfile_zboot(int fd, u_long *marks, int flags); 42 1.1 nonaka static int zboot_exec(int fd, u_long *marks, int flags); 43 1.1 nonaka 44 1.1 nonaka int 45 1.1 nonaka loadfile_zboot(const char *fname, u_long *marks, int flags) 46 1.1 nonaka { 47 1.1 nonaka int fd, error; 48 1.1 nonaka 49 1.1 nonaka /* Open the file. */ 50 1.1 nonaka if ((fd = open(fname, 0)) < 0) { 51 1.1 nonaka WARN(("open %s", fname ? fname : "<default>")); 52 1.1 nonaka return -1; 53 1.1 nonaka } 54 1.1 nonaka 55 1.1 nonaka /* Load it; save the value of errno across the close() call */ 56 1.1 nonaka if ((error = fdloadfile_zboot(fd, marks, flags)) != 0) { 57 1.1 nonaka (void)close(fd); 58 1.1 nonaka errno = error; 59 1.1 nonaka return -1; 60 1.1 nonaka } 61 1.1 nonaka 62 1.1 nonaka return fd; 63 1.1 nonaka } 64 1.1 nonaka 65 1.1 nonaka static int 66 1.1 nonaka fdloadfile_zboot(int fd, u_long *marks, int flags) 67 1.1 nonaka { 68 1.1 nonaka Elf32_Ehdr elf32; 69 1.1 nonaka ssize_t nr; 70 1.1 nonaka int rval; 71 1.1 nonaka 72 1.1 nonaka /* Read the exec header. */ 73 1.1 nonaka if (lseek(fd, 0, SEEK_SET) == (off_t)-1) 74 1.1 nonaka goto err; 75 1.1 nonaka nr = read(fd, &elf32, sizeof(elf32)); 76 1.1 nonaka if (nr == -1) { 77 1.1 nonaka WARN(("read header failed")); 78 1.1 nonaka goto err; 79 1.1 nonaka } 80 1.1 nonaka if (nr != sizeof(elf32)) { 81 1.1 nonaka WARN(("read header short")); 82 1.1 nonaka errno = EFTYPE; 83 1.1 nonaka goto err; 84 1.1 nonaka } 85 1.1 nonaka 86 1.1 nonaka if (memcmp(elf32.e_ident, ELFMAG, SELFMAG) == 0 && 87 1.1 nonaka elf32.e_ident[EI_CLASS] == ELFCLASS32) { 88 1.1 nonaka rval = zboot_exec(fd, marks, flags); 89 1.1 nonaka } else { 90 1.1 nonaka rval = 1; 91 1.1 nonaka errno = EFTYPE; 92 1.1 nonaka } 93 1.1 nonaka 94 1.1 nonaka if (rval == 0) 95 1.1 nonaka return 0; 96 1.1 nonaka err: 97 1.1 nonaka return errno; 98 1.1 nonaka } 99 1.1 nonaka 100 1.1 nonaka static int 101 1.1 nonaka zboot_exec(int fd, u_long *marks, int flags) 102 1.1 nonaka { 103 1.1 nonaka static char bibuf[BOOTINFO_MAXSIZE]; 104 1.1 nonaka char buf[512]; 105 1.1 nonaka struct btinfo_common *help; 106 1.1 nonaka char *p; 107 1.1 nonaka int tofd; 108 1.1 nonaka int sz; 109 1.1 nonaka int i; 110 1.1 nonaka 111 1.1 nonaka /* 112 1.1 nonaka * set bootargs 113 1.1 nonaka */ 114 1.1 nonaka p = bibuf; 115 1.1 nonaka memcpy(p, &bootinfo->nentries, sizeof(bootinfo->nentries)); 116 1.1 nonaka p += sizeof(bootinfo->nentries); 117 1.1 nonaka for (i = 0; i < bootinfo->nentries; i++) { 118 1.1 nonaka help = (struct btinfo_common *)(bootinfo->entry[i]); 119 1.1 nonaka if ((p - bibuf) + help->len > BOOTINFO_MAXSIZE) 120 1.1 nonaka break; 121 1.1 nonaka 122 1.1 nonaka memcpy(p, help, help->len); 123 1.1 nonaka p += help->len; 124 1.1 nonaka } 125 1.1 nonaka 126 1.1 nonaka tofd = uopen(_PATH_ZBOOT, LINUX_O_WRONLY); 127 1.1 nonaka if (tofd == -1) { 128 1.1 nonaka printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno); 129 1.1 nonaka return 1; 130 1.1 nonaka } 131 1.1 nonaka 132 1.1 nonaka if (uwrite(tofd, bibuf, p - bibuf) != p - bibuf) 133 1.1 nonaka printf("setbootargs: argument write error\n"); 134 1.1 nonaka 135 1.1 nonaka /* Commit boot arguments. */ 136 1.1 nonaka uclose(tofd); 137 1.1 nonaka 138 1.1 nonaka /* 139 1.1 nonaka * load kernel 140 1.1 nonaka */ 141 1.1 nonaka tofd = uopen(_PATH_ZBOOT, LINUX_O_WRONLY); 142 1.1 nonaka if (tofd == -1) { 143 1.1 nonaka printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno); 144 1.1 nonaka return 1; 145 1.1 nonaka } 146 1.1 nonaka 147 1.1 nonaka if (lseek(fd, 0, SEEK_SET) != 0) { 148 1.1 nonaka printf("%s: seek error\n", _PATH_ZBOOT); 149 1.1 nonaka goto err; 150 1.1 nonaka } 151 1.1 nonaka 152 1.1 nonaka while ((sz = read(fd, buf, sizeof(buf))) == sizeof(buf)) { 153 1.1 nonaka if ((sz = uwrite(tofd, buf, sz)) != sizeof(buf)) { 154 1.1 nonaka printf("%s: write error\n", _PATH_ZBOOT); 155 1.1 nonaka goto err; 156 1.1 nonaka } 157 1.1 nonaka } 158 1.1 nonaka 159 1.1 nonaka if (sz < 0) { 160 1.1 nonaka printf("zboot_exec: read error\n"); 161 1.1 nonaka goto err; 162 1.1 nonaka } 163 1.1 nonaka 164 1.1 nonaka if (sz >= 0 && uwrite(tofd, buf, sz) != sz) { 165 1.1 nonaka printf("zboot_exec: write error\n"); 166 1.1 nonaka goto err; 167 1.1 nonaka } 168 1.1 nonaka 169 1.1 nonaka uclose(tofd); 170 1.1 nonaka /*NOTREACHED*/ 171 1.1 nonaka return 0; 172 1.1 nonaka 173 1.1 nonaka err: 174 1.1 nonaka uclose(tofd); 175 1.1 nonaka return 1; 176 1.1 nonaka } 177