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