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