152132Smckusick /* 252132Smckusick * Copyright (c) 1992 Regents of the University of California. 352132Smckusick * All rights reserved. 452132Smckusick * 552132Smckusick * This code is derived from software contributed to Berkeley by 652132Smckusick * Ralph Campbell. 752132Smckusick * 852132Smckusick * %sccs.include.redist.c% 952132Smckusick * 10*52765Sralph * @(#)boot.c 7.2 (Berkeley) 03/01/92 1152132Smckusick */ 1252132Smckusick 13*52765Sralph #include "param.h" 1452132Smckusick #include "reboot.h" 1552132Smckusick #include "exec.h" 1652132Smckusick 1752132Smckusick #ifndef TEST 1852132Smckusick #define DEF_MONFUNCS 1952132Smckusick #include "../include/machMon.h" 2052132Smckusick #endif 2152132Smckusick 2252132Smckusick char line[1024]; 2352132Smckusick 2452132Smckusick /* 2552132Smckusick * This gets arguments from the PROM, calls other routines to open 2652132Smckusick * and load the program to boot, and then transfers execution to that 2752132Smckusick * new program. 28*52765Sralph * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100. 29*52765Sralph * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000. 30*52765Sralph * The argument "-a" means vmunix should do an automatic reboot. 3152132Smckusick */ 3252132Smckusick void 3352132Smckusick main(argc, argv, argenv) 3452132Smckusick int argc; 3552132Smckusick char **argv; 3652132Smckusick char **argenv; 3752132Smckusick { 3852132Smckusick register char *cp; 3952132Smckusick int howto, entry; 40*52765Sralph char *boot = "boot"; 4152132Smckusick 4252132Smckusick #ifdef JUSTASK 43*52765Sralph howto = RB_ASKNAME; 4452132Smckusick #else 45*52765Sralph if (argc > 0 && strcmp(argv[0], boot) == 0) { 46*52765Sralph argc--; 47*52765Sralph argv++; 48*52765Sralph argv[0] = getenv(boot); 49*52765Sralph printf("boot '%s'\n", argv[0]); /* XXX */ 50*52765Sralph } 51*52765Sralph howto = 0; 5252132Smckusick for (cp = argv[0]; *cp; cp++) { 5352132Smckusick if (*cp == ')' && cp[1]) { 5452132Smckusick cp = argv[0]; 5552132Smckusick goto fnd; 5652132Smckusick } 5752132Smckusick } 5852132Smckusick howto |= RB_ASKNAME; 5952132Smckusick fnd: 6052132Smckusick ; 6152132Smckusick #endif 6252132Smckusick for (;;) { 6352132Smckusick if (howto & RB_ASKNAME) { 6452132Smckusick printf("Boot: "); 6552132Smckusick gets(line); 6652132Smckusick if (line[0] == '\0') 6752132Smckusick continue; 6852132Smckusick cp = line; 69*52765Sralph argv[0] = cp; 70*52765Sralph argc = 1; 7152132Smckusick } else 7252132Smckusick printf("Boot: %s\n", cp); 7352132Smckusick entry = loadfile(cp); 7452132Smckusick if (entry != -1) 7552132Smckusick break; 76*52765Sralph howto = RB_ASKNAME; 7752132Smckusick } 7852132Smckusick #ifndef TEST 7952132Smckusick Boot_Transfer(argc, argv, argenv, entry); 8052132Smckusick #endif 8152132Smckusick } 8252132Smckusick 8352132Smckusick /* 8452132Smckusick * Open 'filename', read in program and return the entry point or -1 if error. 8552132Smckusick */ 8652132Smckusick loadfile(fname) 8752132Smckusick register char *fname; 8852132Smckusick { 8952132Smckusick register struct devices *dp; 9052132Smckusick register int fd, i, n; 9152132Smckusick struct exec aout; 9252132Smckusick 9352132Smckusick if ((fd = Open(fname, 0)) < 0) 9452132Smckusick goto err; 9552132Smckusick 9652132Smckusick /* read the COFF header */ 9752132Smckusick i = Read(fd, (char *)&aout, sizeof(aout)); 9852132Smckusick if (i != sizeof(aout)) { 9952132Smckusick printf("No a.out header\n"); 10052132Smckusick goto cerr; 10152132Smckusick } else if (aout.a_magic != OMAGIC) { 10252132Smckusick printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic, 10352132Smckusick aout.a_text, aout.a_data, aout.a_bss); 10452132Smckusick goto cerr; 10552132Smckusick } 10652132Smckusick 10752132Smckusick /* read the code and initialized data */ 10852132Smckusick printf("Size: %d+%d", aout.a_text, aout.a_data); 10952132Smckusick if (Lseek(fd, N_TXTOFF(aout), 0) < 0) { 11052132Smckusick printf("\nSeek error\n"); 11152132Smckusick goto cerr; 11252132Smckusick } 11352132Smckusick i = aout.a_text + aout.a_data; 11452132Smckusick #ifndef TEST 11552132Smckusick n = Read(fd, (char *)aout.ex_aout.codeStart, i); 11652132Smckusick #else 11752132Smckusick n = i; 11852132Smckusick #endif 11952132Smckusick (void) Close(fd); 12052132Smckusick if (n < 0) { 12152132Smckusick printf("\nRead error\n"); 12252132Smckusick goto err; 12352132Smckusick } else if (n != i) { 12452132Smckusick printf("\nShort read (%d)\n", n); 12552132Smckusick goto err; 12652132Smckusick } 12752132Smckusick 12852132Smckusick /* kernel will zero out its own bss */ 12952132Smckusick n = aout.a_bss; 13052132Smckusick printf("+%d\n", n); 13152132Smckusick 13252132Smckusick return ((int)aout.a_entry); 13352132Smckusick 13452132Smckusick cerr: 13552132Smckusick (void) Close(fd); 13652132Smckusick err: 13752132Smckusick return (-1); 13852132Smckusick } 139