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