1 /* $NetBSD: boot.c,v 1.3 1995/06/28 00:58:48 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Ralph Campbell. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)boot.c 8.1 (Berkeley) 6/10/93 39 */ 40 41 #include <lib/libsa/stand.h> 42 43 #include <sys/param.h> 44 #include <sys/exec.h> 45 46 #include <machine/prom.h> 47 48 #include "../../include/coff.h" 49 #define _KERNEL 50 #include "../../include/pte.h" 51 52 static int aout_exec __P((int, struct exec *, u_int64_t *)); 53 static int coff_exec __P((int, struct exechdr *, u_int64_t *)); 54 static int loadfile __P((char *, u_int64_t *)); 55 56 char line[64] = "/netbsd"; 57 58 char boot_file[128]; 59 char boot_dev[128]; 60 char boot_flags[128]; 61 char boot_console[8]; 62 63 extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; 64 65 #define KERNEL_ARGC 4 66 char *kernel_argv[KERNEL_ARGC+1] = { 67 boot_file, 68 boot_flags, 69 boot_console, 70 boot_dev, 71 NULL 72 }; 73 74 vm_offset_t ffp_save, ptbr_save; 75 76 void 77 main(argc, argv, envp) 78 int argc; 79 char **argv; 80 char **envp; 81 { 82 u_int64_t entry; 83 int ask; 84 prom_return_t ret; 85 86 #ifdef notdef 87 { 88 extern char *_EDATA, *_end; 89 bzero(_EDATA, _end - _EDATA); 90 } 91 #endif 92 93 /* Init prom callback vector. */ 94 init_prom_calls(); 95 96 /* print a banner */ 97 printf("\n\n"); 98 printf("%s, Revision %s\n", bootprog_name, bootprog_rev); 99 printf("(%s, %s)\n", bootprog_maker, bootprog_date); 100 printf("\n"); 101 102 /* switch to OSF pal code. */ 103 OSFpal(); 104 105 printf("\n"); 106 107 prom_getenv(PROM_E_BOOTED_DEV, boot_dev, sizeof(boot_dev)); 108 prom_getenv(PROM_E_BOOTED_FILE, boot_file, sizeof(boot_file)); 109 prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags)); 110 prom_getenv(PROM_E_TTY_DEV, boot_console, sizeof(boot_console)); 111 112 printf("boot_dev = \"%s\"\n", boot_dev); 113 printf("boot_file = \"%s\"\n", boot_file); 114 printf("boot_flags = \"%s\"\n", boot_flags); 115 printf("boot_console = \"%s\"\n", boot_console); 116 117 if (boot_file[0] == '\0') 118 bcopy(line, boot_file, strlen(line)+1); 119 120 #ifdef JUSTASK 121 ask = 1; 122 #else 123 ask = 0; 124 #endif 125 for (;;) { 126 if (ask) { 127 (void)printf("Boot: "); 128 gets(line); 129 if (line[0] == '\0') 130 continue; 131 if (!strcmp(line, "halt")) 132 halt(); 133 /* XXX TURN LINE INTO BOOT FILE/FLAGS */ 134 bcopy(line, boot_file, strlen(line)+1); 135 } else 136 (void)printf("Boot: %s %s\n", boot_file, boot_flags); 137 138 if (!loadfile(boot_file, &entry)) { 139 140 printf("calling %lx with %lx, %lx, %lx, %lx, %lx\n", entry, 141 ffp_save, ptbr_save, KERNEL_ARGC, kernel_argv, NULL); 142 (*(void (*)())entry)(ffp_save, ptbr_save, KERNEL_ARGC, 143 kernel_argv, NULL); 144 } 145 146 ask = 1; 147 } 148 /* NOTREACHED */ 149 } 150 151 /* 152 * Open 'filename', read in program and return the entry point or -1 if error. 153 */ 154 static int 155 loadfile(fname, entryp) 156 char *fname; 157 u_int64_t *entryp; 158 { 159 struct devices *dp; 160 union { 161 struct exec aout; 162 struct exechdr coff; 163 } hdr; 164 ssize_t nr; 165 int fd, rval; 166 167 /* Open the file. */ 168 rval = 1; 169 if ((fd = open(fname, 0)) < 0) { 170 (void)printf("open error: %d\n", errno); 171 goto err; 172 } 173 174 /* Read the exec header. */ 175 if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { 176 (void)printf("read error: %d\n", errno); 177 goto err; 178 } 179 180 /* Exec a.out or COFF. */ 181 rval = N_COFFBADMAG(hdr.coff.a) ? 182 aout_exec(fd, &hdr.aout, entryp) : 183 coff_exec(fd, &hdr.coff, entryp); 184 185 err: 186 #ifndef SMALL 187 if (fd >= 0) 188 (void)close(fd); 189 #endif 190 if (rval) 191 (void)printf("can't boot '%s'\n", fname); 192 return (rval); 193 } 194 195 static int 196 aout_exec(fd, aout, entryp) 197 int fd; 198 struct exec *aout; 199 u_int64_t *entryp; 200 { 201 size_t sz; 202 203 /* Check the magic number. */ 204 if (N_GETMAGIC(*aout) != OMAGIC) { 205 (void)printf("bad magic: %o\n", N_GETMAGIC(*aout)); 206 return (1); 207 } 208 209 /* Read in text, data. */ 210 (void)printf("%lu+%lu", aout->a_text, aout->a_data); 211 if (lseek(fd, (off_t)N_TXTOFF(*aout), SEEK_SET) < 0) { 212 (void)printf("lseek: %d\n", errno); 213 return (1); 214 } 215 sz = aout->a_text + aout->a_data; 216 if (read(fd, (void *)aout->a_entry, sz) != sz) { 217 (void)printf("read text/data: %d\n", errno); 218 return (1); 219 } 220 221 /* Zero out bss. */ 222 if (aout->a_bss != 0) { 223 (void)printf("+%lu", aout->a_bss); 224 bzero(aout->a_entry + sz, aout->a_bss); 225 } 226 227 ffp_save = aout->a_entry + aout->a_text + aout->a_data + aout->a_bss; 228 ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT; 229 ffp_save += 2; /* XXX OSF/1 does this, no idea why. */ 230 231 (void)printf("\n"); 232 *entryp = aout->a_entry; 233 return (0); 234 } 235 236 static int 237 coff_exec(fd, coff, entryp) 238 int fd; 239 struct exechdr *coff; 240 u_int64_t *entryp; 241 { 242 243 /* Read in text. */ 244 (void)printf("%lu", coff->a.tsize); 245 (void)lseek(fd, N_COFFTXTOFF(coff->f, coff->a), 0); 246 if (read(fd, (void *)coff->a.text_start, coff->a.tsize) != 247 coff->a.tsize) { 248 (void)printf("read text: %d\n", errno); 249 return (1); 250 } 251 252 /* Read in data. */ 253 if (coff->a.dsize != 0) { 254 (void)printf("+%lu", coff->a.dsize); 255 if (read(fd, (void *)coff->a.data_start, coff->a.dsize) != 256 coff->a.dsize) { 257 (void)printf("read data: %d\n", errno); 258 return (1); 259 } 260 } 261 262 263 /* Zero out bss. */ 264 if (coff->a.bsize != 0) { 265 (void)printf("+%lu", coff->a.bsize); 266 bzero(coff->a.bss_start, coff->a.bsize); 267 } 268 269 ffp_save = coff->a.text_start + coff->a.tsize; 270 if (ffp_save < coff->a.data_start + coff->a.dsize) 271 ffp_save = coff->a.data_start + coff->a.dsize; 272 if (ffp_save < coff->a.bss_start + coff->a.bsize) 273 ffp_save = coff->a.bss_start + coff->a.bsize; 274 ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT; 275 ffp_save += 2; /* XXX OSF/1 does this, no idea why. */ 276 277 (void)printf("\n"); 278 *entryp = coff->a.entry; 279 return (0); 280 } 281