141488Smckusick /* 241488Smckusick * Copyright (c) 1990 The Regents of the University of California. 341488Smckusick * All rights reserved. 441488Smckusick * 541488Smckusick * %sccs.include.redist.c% 641488Smckusick * 7*45790Sbostic * @(#)mkboot.c 7.2 (Berkeley) 12/16/90 841488Smckusick */ 941488Smckusick 1041488Smckusick #ifndef lint 1141488Smckusick char copyright[] = 1241488Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 1341488Smckusick All rights reserved.\n"; 1441488Smckusick #endif /* not lint */ 1541488Smckusick 1641488Smckusick #ifndef lint 17*45790Sbostic static char sccsid[] = "@(#)mkboot.c 7.2 (Berkeley) 12/16/90"; 1841488Smckusick #endif /* not lint */ 1941488Smckusick 20*45790Sbostic #include "../include/param.h" 2141488Smckusick #include "volhdr.h" 2241488Smckusick #include <sys/exec.h> 2341488Smckusick #include <sys/file.h> 2441488Smckusick #include <stdio.h> 2541488Smckusick #include <ctype.h> 2641488Smckusick 2741488Smckusick int lpflag; 2841488Smckusick int loadpoint; 2941488Smckusick struct load ld; 3041488Smckusick struct lifvol lifv; 3141488Smckusick struct lifdir lifd[8]; 3241488Smckusick struct exec ex; 3341488Smckusick char buf[10240]; 3441488Smckusick 3541488Smckusick main(argc, argv) 3641488Smckusick char **argv; 3741488Smckusick { 3841488Smckusick int ac; 3941488Smckusick char **av; 4041488Smckusick int from1, from2, to; 4141488Smckusick register int n; 4241488Smckusick char *n1, *n2, *lifname(); 4341488Smckusick 4441488Smckusick ac = --argc; 4541488Smckusick av = ++argv; 4641488Smckusick if (ac == 0) 4741488Smckusick usage(); 4841488Smckusick if (!strcmp(av[0], "-l")) { 4941488Smckusick av++; 5041488Smckusick ac--; 5141488Smckusick if (ac == 0) 5241488Smckusick usage(); 5341488Smckusick sscanf(av[0], "0x%x", &loadpoint); 5441488Smckusick lpflag++; 5541488Smckusick av++; 5641488Smckusick ac--; 5741488Smckusick } 5841488Smckusick if (ac == 0) 5941488Smckusick usage(); 6041488Smckusick from1 = open(av[0], O_RDONLY, 0); 6141488Smckusick if (from1 < 0) { 6241488Smckusick perror("open"); 6341488Smckusick exit(1); 6441488Smckusick } 6541488Smckusick n1 = av[0]; 6641488Smckusick av++; 6741488Smckusick ac--; 6841488Smckusick if (ac == 0) 6941488Smckusick usage(); 7041488Smckusick if (ac == 2) { 7141488Smckusick from2 = open(av[0], O_RDONLY, 0); 7241488Smckusick if (from2 < 0) { 7341488Smckusick perror("open"); 7441488Smckusick exit(1); 7541488Smckusick } 7641488Smckusick n2 = av[0]; 7741488Smckusick av++; 7841488Smckusick ac--; 7941488Smckusick } else 8041488Smckusick from2 = -1; 8141488Smckusick to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644); 8241488Smckusick if (to < 0) { 8341488Smckusick perror("open"); 8441488Smckusick exit(1); 8541488Smckusick } 8641488Smckusick /* clear possibly unused directory entries */ 8741488Smckusick strncpy(lifd[1].dir_name, " ", 10); 8841488Smckusick lifd[1].dir_type = -1; 8941488Smckusick lifd[1].dir_addr = 0; 9041488Smckusick lifd[1].dir_length = 0; 9141488Smckusick lifd[1].dir_flag = 0xFF; 9241488Smckusick lifd[1].dir_exec = 0; 9341488Smckusick lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1]; 9441488Smckusick /* record volume info */ 9541488Smckusick lifv.vol_id = VOL_ID; 9641488Smckusick strncpy(lifv.vol_label, "BOOT43", 6); 9741488Smckusick lifv.vol_addr = 2; 9841488Smckusick lifv.vol_oct = VOL_OCT; 9941488Smckusick lifv.vol_dirsize = 1; 10041488Smckusick lifv.vol_version = 1; 10141488Smckusick /* output bootfile one */ 10241488Smckusick lseek(to, 3 * SECTSIZE, 0); 10341488Smckusick putfile(from1, to); 10441488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 10541488Smckusick strcpy(lifd[0].dir_name, lifname(n1)); 10641488Smckusick lifd[0].dir_type = DIR_TYPE; 10741488Smckusick lifd[0].dir_addr = 3; 10841488Smckusick lifd[0].dir_length = n; 10941488Smckusick lifd[0].dir_flag = DIR_FLAG; 11041488Smckusick lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 11141488Smckusick lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length; 11241488Smckusick /* if there is an optional second boot program, output it */ 11341488Smckusick if (from2 >= 0) { 11441488Smckusick lseek(to, (3 + n) * SECTSIZE, 0); 11541488Smckusick putfile(from2, to); 11641488Smckusick n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE; 11741488Smckusick strcpy(lifd[1].dir_name, lifname(n2)); 11841488Smckusick lifd[1].dir_type = DIR_TYPE; 11941488Smckusick lifd[1].dir_addr = 3 + lifd[0].dir_length; 12041488Smckusick lifd[1].dir_length = n; 12141488Smckusick lifd[1].dir_flag = DIR_FLAG; 12241488Smckusick lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry; 12341488Smckusick lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length; 12441488Smckusick } 12541488Smckusick /* output volume/directory header info */ 12641488Smckusick lseek(to, 0 * SECTSIZE, 0); 12741488Smckusick write(to, &lifv, sizeof(lifv)); 12841488Smckusick lseek(to, 2 * SECTSIZE, 0); 12941488Smckusick write(to, lifd, sizeof(lifd)); 13041488Smckusick exit(0); 13141488Smckusick } 13241488Smckusick 13341488Smckusick putfile(from, to) 13441488Smckusick { 13541488Smckusick register int n, tcnt, dcnt; 13641488Smckusick 13741488Smckusick n = read(from, &ex, sizeof(ex)); 13841488Smckusick if (n != sizeof(ex)) { 13941488Smckusick fprintf(stderr, "error reading file header\n"); 14041488Smckusick exit(1); 14141488Smckusick } 14241488Smckusick if (ex.a_magic == OMAGIC) { 14341488Smckusick tcnt = ex.a_text; 14441488Smckusick dcnt = ex.a_data; 14541488Smckusick } 14641488Smckusick else if (ex.a_magic == NMAGIC) { 14741488Smckusick tcnt = (ex.a_text + PGOFSET) & ~PGOFSET; 14841488Smckusick dcnt = ex.a_data; 14941488Smckusick } 15041488Smckusick else { 15141488Smckusick fprintf(stderr, "bad magic number\n"); 15241488Smckusick exit(1); 15341488Smckusick } 15441488Smckusick ld.address = lpflag ? loadpoint : ex.a_entry; 15541488Smckusick ld.count = tcnt + dcnt; 15641488Smckusick write(to, &ld, sizeof(ld)); 15741488Smckusick while (tcnt) { 15841488Smckusick n = sizeof(buf); 15941488Smckusick if (n > tcnt) 16041488Smckusick n = tcnt; 16141488Smckusick n = read(from, buf, n); 16241488Smckusick if (n < 0) { 16341488Smckusick perror("read"); 16441488Smckusick exit(1); 16541488Smckusick } 16641488Smckusick if (n == 0) { 16741488Smckusick fprintf(stderr, "short read\n"); 16841488Smckusick exit(1); 16941488Smckusick } 17041488Smckusick if (write(to, buf, n) < 0) { 17141488Smckusick perror("write"); 17241488Smckusick exit(1); 17341488Smckusick } 17441488Smckusick tcnt -= n; 17541488Smckusick } 17641488Smckusick while (dcnt) { 17741488Smckusick n = sizeof(buf); 17841488Smckusick if (n > dcnt) 17941488Smckusick n = dcnt; 18041488Smckusick n = read(from, buf, n); 18141488Smckusick if (n < 0) { 18241488Smckusick perror("read"); 18341488Smckusick exit(1); 18441488Smckusick } 18541488Smckusick if (n == 0) { 18641488Smckusick fprintf(stderr, "short read\n"); 18741488Smckusick exit(1); 18841488Smckusick } 18941488Smckusick if (write(to, buf, n) < 0) { 19041488Smckusick perror("write"); 19141488Smckusick exit(1); 19241488Smckusick } 19341488Smckusick dcnt -= n; 19441488Smckusick } 19541488Smckusick } 19641488Smckusick 19741488Smckusick usage() 19841488Smckusick { 19941488Smckusick fprintf(stderr, 20041488Smckusick "usage: mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n"); 20141488Smckusick exit(1); 20241488Smckusick } 20341488Smckusick 20441488Smckusick char * 20541488Smckusick lifname(str) 20641488Smckusick char *str; 20741488Smckusick { 20841488Smckusick static char lname[10] = "SYS_XXXXX"; 20941488Smckusick register int i; 21041488Smckusick 21141488Smckusick for (i = 4; i < 9; i++) { 21241488Smckusick if (islower(*str)) 21341488Smckusick lname[i] = toupper(*str); 21441488Smckusick else if (isalnum(*str) || *str == '_') 21541488Smckusick lname[i] = *str; 21641488Smckusick else 21741488Smckusick break; 21841488Smckusick str++; 21941488Smckusick } 22041488Smckusick for ( ; i < 10; i++) 22141488Smckusick lname[i] = '\0'; 22241488Smckusick return(lname); 22341488Smckusick } 224