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*56638Sralph * @(#)boot.c 7.5 (Berkeley) 10/24/92 1152132Smckusick */ 1252132Smckusick 1356526Sbostic #include <sys/param.h> 1456526Sbostic #include <sys/exec.h> 1552132Smckusick 1652132Smckusick char line[1024]; 1752132Smckusick 1852132Smckusick /* 1952132Smckusick * This gets arguments from the PROM, calls other routines to open 2052132Smckusick * and load the program to boot, and then transfers execution to that 2152132Smckusick * new program. 2252765Sralph * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100. 2352765Sralph * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000. 2452765Sralph * The argument "-a" means vmunix should do an automatic reboot. 2552132Smckusick */ 2652132Smckusick void 27*56638Sralph main(argc, argv) 2852132Smckusick int argc; 2952132Smckusick char **argv; 3052132Smckusick { 3152132Smckusick register char *cp; 32*56638Sralph int ask, entry; 3352765Sralph char *boot = "boot"; 3452132Smckusick 3552132Smckusick #ifdef JUSTASK 36*56638Sralph ask = 1; 3752132Smckusick #else 38*56638Sralph ask = 0; 39*56638Sralph #ifdef DS3100 4052132Smckusick for (cp = argv[0]; *cp; cp++) { 4152132Smckusick if (*cp == ')' && cp[1]) { 4252132Smckusick cp = argv[0]; 4352132Smckusick goto fnd; 4452132Smckusick } 4552132Smckusick } 46*56638Sralph #endif 47*56638Sralph #ifdef DS5000 48*56638Sralph if (argc > 1) { 49*56638Sralph argc--; 50*56638Sralph argv++; 51*56638Sralph /* look for second '/' as in '5/rz0/vmunix' */ 52*56638Sralph for (cp = argv[0]; *cp; cp++) { 53*56638Sralph if (*cp == '/') { 54*56638Sralph while (*++cp) { 55*56638Sralph if (*cp == '/' && cp[1]) { 56*56638Sralph cp = argv[0]; 57*56638Sralph goto fnd; 58*56638Sralph } 59*56638Sralph } 60*56638Sralph } 61*56638Sralph } 62*56638Sralph } 63*56638Sralph #endif 64*56638Sralph ask = 1; 6552132Smckusick fnd: 6652132Smckusick ; 67*56638Sralph #endif /* JUSTASK */ 6852132Smckusick for (;;) { 69*56638Sralph if (ask) { 7052132Smckusick printf("Boot: "); 7152132Smckusick gets(line); 7252132Smckusick if (line[0] == '\0') 7352132Smckusick continue; 7452132Smckusick cp = line; 7552765Sralph argv[0] = cp; 7652765Sralph argc = 1; 7752132Smckusick } else 7852132Smckusick printf("Boot: %s\n", cp); 7952132Smckusick entry = loadfile(cp); 8052132Smckusick if (entry != -1) 8152132Smckusick break; 82*56638Sralph ask = 1; 8352132Smckusick } 84*56638Sralph printf("Starting at 0x%x\n\n", entry); 85*56638Sralph ((void (*)())entry)(argc, argv); 8652132Smckusick } 8752132Smckusick 8852132Smckusick /* 8952132Smckusick * Open 'filename', read in program and return the entry point or -1 if error. 9052132Smckusick */ 9152132Smckusick loadfile(fname) 9252132Smckusick register char *fname; 9352132Smckusick { 9452132Smckusick register struct devices *dp; 9552132Smckusick register int fd, i, n; 9652132Smckusick struct exec aout; 9752132Smckusick 98*56638Sralph if ((fd = open(fname, 0)) < 0) { 99*56638Sralph printf("Can't open '%s'\n", fname); 10052132Smckusick goto err; 101*56638Sralph } 10252132Smckusick 10352132Smckusick /* read the COFF header */ 104*56638Sralph i = read(fd, (char *)&aout, sizeof(aout)); 10552132Smckusick if (i != sizeof(aout)) { 10652132Smckusick printf("No a.out header\n"); 10752132Smckusick goto cerr; 10852132Smckusick } else if (aout.a_magic != OMAGIC) { 10952132Smckusick printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic, 11052132Smckusick aout.a_text, aout.a_data, aout.a_bss); 11152132Smckusick goto cerr; 11252132Smckusick } 11352132Smckusick 11452132Smckusick /* read the code and initialized data */ 11552132Smckusick printf("Size: %d+%d", aout.a_text, aout.a_data); 116*56638Sralph if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) { 11752132Smckusick printf("\nSeek error\n"); 11852132Smckusick goto cerr; 11952132Smckusick } 12052132Smckusick i = aout.a_text + aout.a_data; 12152132Smckusick #ifndef TEST 122*56638Sralph n = read(fd, (char *)aout.ex_aout.codeStart, i); 12352132Smckusick #else 12452132Smckusick n = i; 12552132Smckusick #endif 126*56638Sralph (void) close(fd); 12752132Smckusick if (n < 0) { 12852132Smckusick printf("\nRead error\n"); 12952132Smckusick goto err; 13052132Smckusick } else if (n != i) { 13152132Smckusick printf("\nShort read (%d)\n", n); 13252132Smckusick goto err; 13352132Smckusick } 13452132Smckusick 13552132Smckusick /* kernel will zero out its own bss */ 13652132Smckusick n = aout.a_bss; 13752132Smckusick printf("+%d\n", n); 13852132Smckusick 13952132Smckusick return ((int)aout.a_entry); 14052132Smckusick 14152132Smckusick cerr: 142*56638Sralph (void) close(fd); 14352132Smckusick err: 14452132Smckusick return (-1); 14552132Smckusick } 146