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 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1992 Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif not lint 16 17 #ifndef lint 18 static char sccsid[] = "@(#)mkboot.c 7.3 (Berkeley) 04/19/92"; 19 #endif not lint 20 21 #include <stdio.h> 22 #include "param.h" 23 #include "exec.h" 24 #include "disklabel.h" 25 26 #include "dec_boot.h" 27 28 /* this is the size of the standard ULTRIX boot */ 29 #define MAXBOOTSIZE (15 * DEV_BSIZE) 30 31 struct Dec_DiskBoot decBootInfo; 32 char block[DEV_BSIZE]; 33 char *bootfname, *xxboot, *bootxx; 34 35 /* 36 * This program takes a boot program and splits it into xxboot and bootxx 37 * files for the disklabel program. The disklabel program should be used to 38 * label and install the boot program onto a new disk. 39 * 40 * mkboot bootprog xxboot bootxx 41 */ 42 main(argc, argv) 43 int argc; 44 char *argv[]; 45 { 46 register int i, n; 47 int ifd, ofd1, ofd2; 48 int nsectors; 49 long loadAddr; 50 long execAddr; 51 long length; 52 53 if (argc != 4) 54 usage(); 55 bootfname = argv[1]; 56 xxboot = argv[2]; 57 bootxx = argv[3]; 58 ifd = open(bootfname, 0, 0); 59 if (ifd < 0) { 60 perror(bootfname); 61 exit(1); 62 } 63 ofd1 = creat(xxboot, 0666); 64 if (ofd1 < 0) { 65 xxboot_err: 66 perror(xxboot); 67 exit(1); 68 } 69 ofd2 = creat(bootxx, 0666); 70 if (ofd2 < 0) { 71 bootxx_err: 72 perror(bootxx); 73 exit(1); 74 } 75 76 /* 77 * Check for exec header and skip to code segment. 78 */ 79 if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) { 80 fprintf(stderr, "Need impure text format (OMAGIC) file\n"); 81 exit(1); 82 } 83 if (length > MAXBOOTSIZE) { 84 fprintf(stderr, "boot program is too big (%d > %d)\n", 85 length, MAXBOOTSIZE); 86 exit(1); 87 } 88 89 /* 90 * Write the boot information block. 91 */ 92 decBootInfo.magic = DEC_BOOT_MAGIC; 93 decBootInfo.mode = 0; 94 decBootInfo.loadAddr = loadAddr; 95 decBootInfo.execAddr = execAddr; 96 decBootInfo.map[0].numBlocks = nsectors = 97 (length + DEV_BSIZE - 1) >> DEV_BSHIFT; 98 decBootInfo.map[0].startBlock = 1; 99 decBootInfo.map[1].numBlocks = 0; 100 if (write(ofd1, (char *)&decBootInfo, sizeof(decBootInfo)) != 101 sizeof(decBootInfo) || close(ofd1) != 0) 102 goto xxboot_err; 103 104 /* 105 * Write the boot code to the bootxx file. 106 */ 107 for (i = 0; i < nsectors && length > 0; i++) { 108 if (length < DEV_BSIZE) { 109 n = length; 110 bzero(block, DEV_BSIZE); 111 } else 112 n = DEV_BSIZE; 113 if (read(ifd, block, n) != n) { 114 perror(bootfname); 115 break; 116 } 117 length -= n; 118 if (write(ofd2, block, DEV_BSIZE) != DEV_BSIZE) { 119 perror(bootxx); 120 break; 121 } 122 } 123 if (length > 0) 124 printf("Warning: didn't reach end of boot program!\n"); 125 exit(0); 126 } 127 128 usage() 129 { 130 printf("Usage: mkboot bootprog xxboot bootxx\n"); 131 printf("where:\n"); 132 printf("\t\"bootprog\" is a -N format file < %d bytes long\n", 133 MAXBOOTSIZE); 134 printf("\t\"xxboot\" is the name of the first boot block\n"); 135 printf("\t\"bootxx\" is the name of the remaining boot blocks.\n"); 136 exit(1); 137 } 138 139 /* 140 *---------------------------------------------------------------------- 141 * 142 * DecHeader - 143 * 144 * Check if the header is a DEC (COFF) file. 145 * 146 * Results: 147 * Return true if all went ok. 148 * 149 * Side effects: 150 * None. 151 * 152 *---------------------------------------------------------------------- 153 */ 154 DecHeader(bootFID, loadAddr, execAddr, length) 155 int bootFID; /* Handle on the boot program */ 156 long *loadAddr; /* Address to start loading boot program. */ 157 long *execAddr; /* Address to start executing boot program. */ 158 long *length; /* Length of the boot program. */ 159 { 160 struct exec aout; 161 int bytesRead; 162 163 if (lseek(bootFID, 0, 0) < 0) { 164 perror(bootfname); 165 return 0; 166 } 167 bytesRead = read(bootFID, (char *)&aout, sizeof(aout)); 168 if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC || 169 aout.a_magic != OMAGIC) 170 return 0; 171 *loadAddr = aout.ex_aout.codeStart; 172 *execAddr = aout.a_entry; 173 *length = aout.a_text + aout.a_data; 174 if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) { 175 perror(bootfname); 176 return 0; 177 } 178 printf("Input file is COFF format\n"); 179 printf("load %x, start %x, len %d\n", *loadAddr, *execAddr, *length); 180 return 1; 181 } 182