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