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