1*41488Smckusick /* 2*41488Smckusick * Copyright (c) 1990 The Regents of the University of California. 3*41488Smckusick * All rights reserved. 4*41488Smckusick * 5*41488Smckusick * %sccs.include.redist.c% 6*41488Smckusick * 7*41488Smckusick * @(#)mkboot.c 7.1 (Berkeley) 05/08/90 8*41488Smckusick */ 9*41488Smckusick 10*41488Smckusick #ifndef lint 11*41488Smckusick char copyright[] = 12*41488Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 13*41488Smckusick All rights reserved.\n"; 14*41488Smckusick #endif /* not lint */ 15*41488Smckusick 16*41488Smckusick #ifndef lint 17*41488Smckusick static char sccsid[] = "@(#)mkboot.c 7.1 (Berkeley) 05/08/90"; 18*41488Smckusick #endif /* not lint */ 19*41488Smckusick 20*41488Smckusick #include "machine/machparam.h" 21*41488Smckusick #include "volhdr.h" 22*41488Smckusick #include <sys/exec.h> 23*41488Smckusick #include <sys/file.h> 24*41488Smckusick #include <stdio.h> 25*41488Smckusick #include <ctype.h> 26*41488Smckusick 27*41488Smckusick int lpflag; 28*41488Smckusick int loadpoint; 29*41488Smckusick struct load ld; 30*41488Smckusick struct lifvol lifv; 31*41488Smckusick struct lifdir lifd[8]; 32*41488Smckusick struct exec ex; 33*41488Smckusick char buf[10240]; 34*41488Smckusick 35*41488Smckusick main(argc, argv) 36*41488Smckusick char **argv; 37*41488Smckusick { 38*41488Smckusick int ac; 39*41488Smckusick char **av; 40*41488Smckusick int from1, from2, to; 41*41488Smckusick register int n; 42*41488Smckusick char *n1, *n2, *lifname(); 43*41488Smckusick 44*41488Smckusick ac = --argc; 45*41488Smckusick av = ++argv; 46*41488Smckusick if (ac == 0) 47*41488Smckusick usage(); 48*41488Smckusick if (!strcmp(av[0], "-l")) { 49*41488Smckusick av++; 50*41488Smckusick ac--; 51*41488Smckusick if (ac == 0) 52*41488Smckusick usage(); 53*41488Smckusick sscanf(av[0], "0x%x", &loadpoint); 54*41488Smckusick lpflag++; 55*41488Smckusick av++; 56*41488Smckusick ac--; 57*41488Smckusick } 58*41488Smckusick if (ac == 0) 59*41488Smckusick usage(); 60*41488Smckusick from1 = open(av[0], O_RDONLY, 0); 61*41488Smckusick if (from1 < 0) { 62*41488Smckusick perror("open"); 63*41488Smckusick exit(1); 64*41488Smckusick } 65*41488Smckusick n1 = av[0]; 66*41488Smckusick av++; 67*41488Smckusick ac--; 68*41488Smckusick if (ac == 0) 69*41488Smckusick usage(); 70*41488Smckusick if (ac == 2) { 71*41488Smckusick from2 = open(av[0], O_RDONLY, 0); 72*41488Smckusick if (from2 < 0) { 73*41488Smckusick perror("open"); 74*41488Smckusick exit(1); 75*41488Smckusick } 76*41488Smckusick n2 = av[0]; 77*41488Smckusick av++; 78*41488Smckusick ac--; 79*41488Smckusick } else 80*41488Smckusick from2 = -1; 81*41488Smckusick to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644); 82*41488Smckusick if (to < 0) { 83*41488Smckusick perror("open"); 84*41488Smckusick exit(1); 85*41488Smckusick } 86*41488Smckusick /* clear possibly unused directory entries */ 87*41488Smckusick strncpy(lifd[1].dir_name, " ", 10); 88*41488Smckusick lifd[1].dir_type = -1; 89*41488Smckusick lifd[1].dir_addr = 0; 90*41488Smckusick lifd[1].dir_length = 0; 91*41488Smckusick lifd[1].dir_flag = 0xFF; 92*41488Smckusick lifd[1].dir_exec = 0; 93*41488Smckusick lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1]; 94*41488Smckusick /* record volume info */ 95*41488Smckusick lifv.vol_id = VOL_ID; 96*41488Smckusick strncpy(lifv.vol_label, "BOOT43", 6); 97*41488Smckusick lifv.vol_addr = 2; 98*41488Smckusick lifv.vol_oct = VOL_OCT; 99*41488Smckusick lifv.vol_dirsize = 1; 100*41488Smckusick lifv.vol_version = 1; 101*41488Smckusick /* output bootfile one */ 102*41488Smckusick lseek(to, 3 * SECTSIZE, 0); 103*41488Smckusick putfile(from1, to); 104*41488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 105*41488Smckusick strcpy(lifd[0].dir_name, lifname(n1)); 106*41488Smckusick lifd[0].dir_type = DIR_TYPE; 107*41488Smckusick lifd[0].dir_addr = 3; 108*41488Smckusick lifd[0].dir_length = n; 109*41488Smckusick lifd[0].dir_flag = DIR_FLAG; 110*41488Smckusick lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 111*41488Smckusick lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length; 112*41488Smckusick /* if there is an optional second boot program, output it */ 113*41488Smckusick if (from2 >= 0) { 114*41488Smckusick lseek(to, (3 + n) * SECTSIZE, 0); 115*41488Smckusick putfile(from2, to); 116*41488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 117*41488Smckusick strcpy(lifd[1].dir_name, lifname(n2)); 118*41488Smckusick lifd[1].dir_type = DIR_TYPE; 119*41488Smckusick lifd[1].dir_addr = 3 + lifd[0].dir_length; 120*41488Smckusick lifd[1].dir_length = n; 121*41488Smckusick lifd[1].dir_flag = DIR_FLAG; 122*41488Smckusick lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 123*41488Smckusick lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length; 124*41488Smckusick } 125*41488Smckusick /* output volume/directory header info */ 126*41488Smckusick lseek(to, 0 * SECTSIZE, 0); 127*41488Smckusick write(to, &lifv, sizeof(lifv)); 128*41488Smckusick lseek(to, 2 * SECTSIZE, 0); 129*41488Smckusick write(to, lifd, sizeof(lifd)); 130*41488Smckusick exit(0); 131*41488Smckusick } 132*41488Smckusick 133*41488Smckusick putfile(from, to) 134*41488Smckusick { 135*41488Smckusick register int n, tcnt, dcnt; 136*41488Smckusick 137*41488Smckusick n = read(from, &ex, sizeof(ex)); 138*41488Smckusick if (n != sizeof(ex)) { 139*41488Smckusick fprintf(stderr, "error reading file header\n"); 140*41488Smckusick exit(1); 141*41488Smckusick } 142*41488Smckusick if (ex.a_magic == OMAGIC) { 143*41488Smckusick tcnt = ex.a_text; 144*41488Smckusick dcnt = ex.a_data; 145*41488Smckusick } 146*41488Smckusick else if (ex.a_magic == NMAGIC) { 147*41488Smckusick tcnt = (ex.a_text + PGOFSET) & ~PGOFSET; 148*41488Smckusick dcnt = ex.a_data; 149*41488Smckusick } 150*41488Smckusick else { 151*41488Smckusick fprintf(stderr, "bad magic number\n"); 152*41488Smckusick exit(1); 153*41488Smckusick } 154*41488Smckusick ld.address = lpflag ? loadpoint : ex.a_entry; 155*41488Smckusick ld.count = tcnt + dcnt; 156*41488Smckusick write(to, &ld, sizeof(ld)); 157*41488Smckusick while (tcnt) { 158*41488Smckusick n = sizeof(buf); 159*41488Smckusick if (n > tcnt) 160*41488Smckusick n = tcnt; 161*41488Smckusick n = read(from, buf, n); 162*41488Smckusick if (n < 0) { 163*41488Smckusick perror("read"); 164*41488Smckusick exit(1); 165*41488Smckusick } 166*41488Smckusick if (n == 0) { 167*41488Smckusick fprintf(stderr, "short read\n"); 168*41488Smckusick exit(1); 169*41488Smckusick } 170*41488Smckusick if (write(to, buf, n) < 0) { 171*41488Smckusick perror("write"); 172*41488Smckusick exit(1); 173*41488Smckusick } 174*41488Smckusick tcnt -= n; 175*41488Smckusick } 176*41488Smckusick while (dcnt) { 177*41488Smckusick n = sizeof(buf); 178*41488Smckusick if (n > dcnt) 179*41488Smckusick n = dcnt; 180*41488Smckusick n = read(from, buf, n); 181*41488Smckusick if (n < 0) { 182*41488Smckusick perror("read"); 183*41488Smckusick exit(1); 184*41488Smckusick } 185*41488Smckusick if (n == 0) { 186*41488Smckusick fprintf(stderr, "short read\n"); 187*41488Smckusick exit(1); 188*41488Smckusick } 189*41488Smckusick if (write(to, buf, n) < 0) { 190*41488Smckusick perror("write"); 191*41488Smckusick exit(1); 192*41488Smckusick } 193*41488Smckusick dcnt -= n; 194*41488Smckusick } 195*41488Smckusick } 196*41488Smckusick 197*41488Smckusick usage() 198*41488Smckusick { 199*41488Smckusick fprintf(stderr, 200*41488Smckusick "usage: mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n"); 201*41488Smckusick exit(1); 202*41488Smckusick } 203*41488Smckusick 204*41488Smckusick char * 205*41488Smckusick lifname(str) 206*41488Smckusick char *str; 207*41488Smckusick { 208*41488Smckusick static char lname[10] = "SYS_XXXXX"; 209*41488Smckusick register int i; 210*41488Smckusick 211*41488Smckusick for (i = 4; i < 9; i++) { 212*41488Smckusick if (islower(*str)) 213*41488Smckusick lname[i] = toupper(*str); 214*41488Smckusick else if (isalnum(*str) || *str == '_') 215*41488Smckusick lname[i] = *str; 216*41488Smckusick else 217*41488Smckusick break; 218*41488Smckusick str++; 219*41488Smckusick } 220*41488Smckusick for ( ; i < 10; i++) 221*41488Smckusick lname[i] = '\0'; 222*41488Smckusick return(lname); 223*41488Smckusick } 224