1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)boot.c 7.5 (Berkeley) 10/24/92 11 */ 12 13 #include <sys/param.h> 14 #include <sys/exec.h> 15 16 char line[1024]; 17 18 /* 19 * This gets arguments from the PROM, calls other routines to open 20 * and load the program to boot, and then transfers execution to that 21 * new program. 22 * Argv[0] should be something like "rz(0,0,0)vmunix" on a DECstation 3100. 23 * Argv[0,1] should be something like "boot 5/rz0/vmunix" on a DECstation 5000. 24 * The argument "-a" means vmunix should do an automatic reboot. 25 */ 26 void 27 main(argc, argv) 28 int argc; 29 char **argv; 30 { 31 register char *cp; 32 int ask, entry; 33 char *boot = "boot"; 34 35 #ifdef JUSTASK 36 ask = 1; 37 #else 38 ask = 0; 39 #ifdef DS3100 40 for (cp = argv[0]; *cp; cp++) { 41 if (*cp == ')' && cp[1]) { 42 cp = argv[0]; 43 goto fnd; 44 } 45 } 46 #endif 47 #ifdef DS5000 48 if (argc > 1) { 49 argc--; 50 argv++; 51 /* look for second '/' as in '5/rz0/vmunix' */ 52 for (cp = argv[0]; *cp; cp++) { 53 if (*cp == '/') { 54 while (*++cp) { 55 if (*cp == '/' && cp[1]) { 56 cp = argv[0]; 57 goto fnd; 58 } 59 } 60 } 61 } 62 } 63 #endif 64 ask = 1; 65 fnd: 66 ; 67 #endif /* JUSTASK */ 68 for (;;) { 69 if (ask) { 70 printf("Boot: "); 71 gets(line); 72 if (line[0] == '\0') 73 continue; 74 cp = line; 75 argv[0] = cp; 76 argc = 1; 77 } else 78 printf("Boot: %s\n", cp); 79 entry = loadfile(cp); 80 if (entry != -1) 81 break; 82 ask = 1; 83 } 84 printf("Starting at 0x%x\n\n", entry); 85 ((void (*)())entry)(argc, argv); 86 } 87 88 /* 89 * Open 'filename', read in program and return the entry point or -1 if error. 90 */ 91 loadfile(fname) 92 register char *fname; 93 { 94 register struct devices *dp; 95 register int fd, i, n; 96 struct exec aout; 97 98 if ((fd = open(fname, 0)) < 0) { 99 printf("Can't open '%s'\n", fname); 100 goto err; 101 } 102 103 /* read the COFF header */ 104 i = read(fd, (char *)&aout, sizeof(aout)); 105 if (i != sizeof(aout)) { 106 printf("No a.out header\n"); 107 goto cerr; 108 } else if (aout.a_magic != OMAGIC) { 109 printf("A.out? magic 0%o size %d+%d+%d\n", aout.a_magic, 110 aout.a_text, aout.a_data, aout.a_bss); 111 goto cerr; 112 } 113 114 /* read the code and initialized data */ 115 printf("Size: %d+%d", aout.a_text, aout.a_data); 116 if (lseek(fd, (off_t)N_TXTOFF(aout), 0) < 0) { 117 printf("\nSeek error\n"); 118 goto cerr; 119 } 120 i = aout.a_text + aout.a_data; 121 #ifndef TEST 122 n = read(fd, (char *)aout.ex_aout.codeStart, i); 123 #else 124 n = i; 125 #endif 126 (void) close(fd); 127 if (n < 0) { 128 printf("\nRead error\n"); 129 goto err; 130 } else if (n != i) { 131 printf("\nShort read (%d)\n", n); 132 goto err; 133 } 134 135 /* kernel will zero out its own bss */ 136 n = aout.a_bss; 137 printf("+%d\n", n); 138 139 return ((int)aout.a_entry); 140 141 cerr: 142 (void) close(fd); 143 err: 144 return (-1); 145 } 146