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*59846Sralph * @(#)boot.c 7.9 (Berkeley) 05/09/93 1152132Smckusick */ 1252132Smckusick 1356526Sbostic #include <sys/param.h> 1456526Sbostic #include <sys/exec.h> 15*59846Sralph #include <pmax/stand/dec_prom.h> 1652132Smckusick 1752132Smckusick char line[1024]; 1852132Smckusick 1952132Smckusick /* 2052132Smckusick * This gets arguments from the PROM, calls other routines to open 2152132Smckusick * and load the program to boot, and then transfers execution to that 2252132Smckusick * new program. 2352765Sralph * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100. 2452765Sralph * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000. 2552765Sralph * The argument "-a" means vmunix should do an automatic reboot. 2652132Smckusick */ 2752132Smckusick void 2856638Sralph main(argc, argv) 2952132Smckusick int argc; 3052132Smckusick char **argv; 3152132Smckusick { 3252132Smckusick register char *cp; 3356638Sralph int ask, entry; 3452132Smckusick 3552132Smckusick #ifdef JUSTASK 3656638Sralph ask = 1; 3752132Smckusick #else 3858981Sralph /* check for DS5000 boot */ 3958981Sralph if (strcmp(argv[0], "boot") == 0) { 4056638Sralph argc--; 4156638Sralph argv++; 4256638Sralph } 4358981Sralph cp = *argv; 4458981Sralph ask = 0; 4556638Sralph #endif /* JUSTASK */ 4652132Smckusick for (;;) { 4756638Sralph if (ask) { 4852132Smckusick printf("Boot: "); 4952132Smckusick gets(line); 5052132Smckusick if (line[0] == '\0') 5152132Smckusick continue; 5252132Smckusick cp = line; 5352765Sralph argv[0] = cp; 5452765Sralph argc = 1; 5552132Smckusick } else 5652132Smckusick printf("Boot: %s\n", cp); 5752132Smckusick entry = loadfile(cp); 5852132Smckusick if (entry != -1) 5952132Smckusick break; 6056638Sralph ask = 1; 6152132Smckusick } 6256638Sralph printf("Starting at 0x%x\n\n", entry); 63*59846Sralph if (callv == &callvec) 64*59846Sralph ((void (*)())entry)(argc, argv, 0, 0); 65*59846Sralph else 66*59846Sralph ((void (*)())entry)(argc, argv, DEC_PROM_MAGIC, callv); 6752132Smckusick } 6852132Smckusick 6952132Smckusick /* 7052132Smckusick * Open 'filename', read in program and return the entry point or -1 if error. 7152132Smckusick */ 7252132Smckusick loadfile(fname) 7352132Smckusick register char *fname; 7452132Smckusick { 7552132Smckusick register struct devices *dp; 7652132Smckusick register int fd, i, n; 7752132Smckusick struct exec aout; 7852132Smckusick 7956638Sralph if ((fd = open(fname, 0)) < 0) { 8052132Smckusick goto err; 8156638Sralph } 8252132Smckusick 8358007Sralph /* read the exec header */ 8456638Sralph i = read(fd, (char *)&aout, sizeof(aout)); 8552132Smckusick if (i != sizeof(aout)) { 8652132Smckusick goto cerr; 8752132Smckusick } else if (aout.a_magic != OMAGIC) { 8852132Smckusick goto cerr; 8952132Smckusick } 9052132Smckusick 9152132Smckusick /* read the code and initialized data */ 9252132Smckusick printf("Size: %d+%d", aout.a_text, aout.a_data); 9356638Sralph if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) { 9452132Smckusick goto cerr; 9552132Smckusick } 9652132Smckusick i = aout.a_text + aout.a_data; 9758007Sralph n = read(fd, (char *)aout.a_entry, i); 9858835Sralph #ifndef SMALL 9958835Sralph (void) close(fd); 10052132Smckusick #endif 10152132Smckusick if (n < 0) { 10252132Smckusick goto err; 10352132Smckusick } else if (n != i) { 10452132Smckusick goto err; 10552132Smckusick } 10652132Smckusick 10752132Smckusick /* kernel will zero out its own bss */ 10852132Smckusick n = aout.a_bss; 10952132Smckusick printf("+%d\n", n); 11052132Smckusick 11152132Smckusick return ((int)aout.a_entry); 11252132Smckusick 11352132Smckusick cerr: 11458835Sralph #ifndef SMALL 11556638Sralph (void) close(fd); 11658835Sralph #endif 11752132Smckusick err: 11858835Sralph printf("Can't boot '%s'\n", fname); 11952132Smckusick return (-1); 12052132Smckusick } 121