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.1 (Berkeley) 01/07/92"; 19 #endif not lint 20 21 #include <stdio.h> 22 #include "types.h" 23 #include "exec.h" 24 #include "../include/param.h" 25 #include "../dev/devDiskLabel.h" 26 27 /* this is the size of the standard ULTRIX boot */ 28 #define MAXBOOTSIZE (15 * DEV_BSIZE) 29 30 char block[DEV_BSIZE]; 31 char *dev, *bootfname; 32 33 /* 34 * installboot bootprog device 35 */ 36 main(argc, argv) 37 int argc; 38 char *argv[]; 39 { 40 register int i, n; 41 int ifd, ofd; 42 Dec_DiskBoot decBootInfo; 43 int nsectors; 44 long loadAddr; 45 long execAddr; 46 long length; 47 48 if (argc != 3) 49 usage(); 50 dev = argv[2]; 51 i = strlen(dev); 52 bootfname = argv[1]; 53 ifd = open(bootfname, 0, 0); 54 if (ifd < 0) { 55 perror(bootfname); 56 exit(1); 57 } 58 ofd = open(dev, 2, 0); 59 if (ofd < 0) { 60 deverr: 61 perror(dev); 62 exit(1); 63 } 64 65 /* 66 * Check for exec header and skip to code segment. 67 */ 68 if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) { 69 fprintf(stderr, "Need impure text format (OMAGIC) file\n"); 70 exit(1); 71 } 72 if (length > MAXBOOTSIZE) { 73 fprintf(stderr, "boot program is too big (%d > %d)\n", 74 length, MAXBOOTSIZE); 75 exit(1); 76 } 77 78 /* 79 * Write the boot information block. 80 */ 81 decBootInfo.magic = DEC_BOOT_MAGIC; 82 decBootInfo.mode = 0; 83 decBootInfo.loadAddr = loadAddr; 84 decBootInfo.execAddr = execAddr; 85 decBootInfo.map[0].numBlocks = nsectors = 86 (length + DEV_BSIZE - 1) >> DEV_BSHIFT; 87 decBootInfo.map[0].startBlock = 1; 88 decBootInfo.map[1].numBlocks = 0; 89 if (lseek(ofd, (long)(DEC_BOOT_SECTOR * DEV_BSIZE), 0) < 0 || 90 write(ofd, (char *)&decBootInfo, sizeof(decBootInfo)) != 91 sizeof(decBootInfo)) { 92 perror(dev); 93 fprintf(stderr, "Sector write %d failed: ", DEC_BOOT_SECTOR); 94 exit(1); 95 } 96 if (lseek(ofd, (long)(1 * DEV_BSIZE), 0) < 0) 97 goto deverr; 98 99 /* 100 * Write the remaining code to the correct place on the disk. 101 */ 102 for (i = 0; i < nsectors && length > 0; i++) { 103 bzero(block, DEV_BSIZE); 104 n = length < DEV_BSIZE ? length : DEV_BSIZE; 105 if (read(ifd, block, n) != n) { 106 perror(bootfname); 107 break; 108 } 109 length -= n; 110 if (write(ofd, block, DEV_BSIZE) != DEV_BSIZE) { 111 perror(dev); 112 break; 113 } 114 } 115 printf("Wrote %d sectors\n", i); 116 if (length > 0) 117 printf("Warning: didn't reach end of boot program!\n"); 118 exit(0); 119 } 120 121 usage() 122 { 123 printf("Usage: installboot bootprog device\n"); 124 printf("where:\n"); 125 printf("\t\"bootprog\" is a -N format file < %d bytes long\n", 126 MAXBOOTSIZE); 127 printf("\t\"device\" should be the 'a' partition of a bootable disk\n"); 128 printf("WARNING!! If the 'c' partition contains a file system, %s\n", 129 "DON'T RUN THIS!!"); 130 exit(1); 131 } 132 133 /* 134 *---------------------------------------------------------------------- 135 * 136 * DecHeader - 137 * 138 * Check if the header is a dec (coff) file. 139 * 140 * Results: 141 * Return true if all went ok. 142 * 143 * Side effects: 144 * None. 145 * 146 *---------------------------------------------------------------------- 147 */ 148 DecHeader(bootFID, loadAddr, execAddr, length) 149 int bootFID; /* Handle on the boot program */ 150 long *loadAddr; /* Address to start loading boot program. */ 151 long *execAddr; /* Address to start executing boot program. */ 152 long *length; /* Length of the boot program. */ 153 { 154 struct exec aout; 155 int bytesRead; 156 157 if (lseek(bootFID, 0, 0) < 0) { 158 perror(bootfname); 159 return 0; 160 } 161 bytesRead = read(bootFID, (char *)&aout, sizeof(aout)); 162 if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC || 163 aout.a_magic != OMAGIC) 164 return 0; 165 *loadAddr = aout.ex_aout.codeStart; 166 *execAddr = aout.a_entry; 167 *length = aout.a_text + aout.a_data; 168 if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) { 169 perror(bootfname); 170 return 0; 171 } 172 printf("Input file is coff format\n"); 173 printf("load %x, start %x, len %d\n", *loadAddr, *execAddr, *length); 174 return 1; 175 } 176