152132Smckusick /* 252132Smckusick * Copyright (c) 1992 Regents of the University of California. 352132Smckusick * All rights reserved. 452132Smckusick * 552132Smckusick * This code is derived from software contributed to Berkeley by 652132Smckusick * Ralph Campbell. 752132Smckusick * 852132Smckusick * %sccs.include.redist.c% 952132Smckusick */ 1052132Smckusick 1152132Smckusick #ifndef lint 1252132Smckusick char copyright[] = 1352132Smckusick "@(#) Copyright (c) 1992 Regents of the University of California.\n\ 1452132Smckusick All rights reserved.\n"; 1552132Smckusick #endif not lint 1652132Smckusick 1752132Smckusick #ifndef lint 18*56639Sralph static char sccsid[] = "@(#)mkboot.c 7.5 (Berkeley) 10/24/92"; 1952132Smckusick #endif not lint 2052132Smckusick 2156526Sbostic #include <sys/param.h> 2256526Sbostic #include <sys/exec.h> 2356526Sbostic #include <sys/disklabel.h> 2452132Smckusick #include <stdio.h> 2552132Smckusick 2656526Sbostic #include <pmax/stand/dec_boot.h> 2753207Sralph 2853207Sralph struct Dec_DiskBoot decBootInfo; 2952132Smckusick char block[DEV_BSIZE]; 3053207Sralph char *bootfname, *xxboot, *bootxx; 3152132Smckusick 3252132Smckusick /* 3353207Sralph * This program takes a boot program and splits it into xxboot and bootxx 3453207Sralph * files for the disklabel program. The disklabel program should be used to 3553207Sralph * label and install the boot program onto a new disk. 3653207Sralph * 3753207Sralph * mkboot bootprog xxboot bootxx 3852132Smckusick */ 3952132Smckusick main(argc, argv) 4052132Smckusick int argc; 4152132Smckusick char *argv[]; 4252132Smckusick { 4352132Smckusick register int i, n; 4453207Sralph int ifd, ofd1, ofd2; 4552132Smckusick int nsectors; 4652132Smckusick long loadAddr; 4752132Smckusick long execAddr; 4852132Smckusick long length; 4952132Smckusick 5053207Sralph if (argc != 4) 5152132Smckusick usage(); 5252132Smckusick bootfname = argv[1]; 5353207Sralph xxboot = argv[2]; 5453207Sralph bootxx = argv[3]; 5552132Smckusick ifd = open(bootfname, 0, 0); 5652132Smckusick if (ifd < 0) { 5752132Smckusick perror(bootfname); 5852132Smckusick exit(1); 5952132Smckusick } 6053207Sralph ofd1 = creat(xxboot, 0666); 6153207Sralph if (ofd1 < 0) { 6253207Sralph xxboot_err: 6353207Sralph perror(xxboot); 6452132Smckusick exit(1); 6552132Smckusick } 6653207Sralph ofd2 = creat(bootxx, 0666); 6753207Sralph if (ofd2 < 0) { 6853207Sralph bootxx_err: 6953207Sralph perror(bootxx); 7053207Sralph exit(1); 7153207Sralph } 7252132Smckusick 7352132Smckusick /* 7452132Smckusick * Check for exec header and skip to code segment. 7552132Smckusick */ 7652132Smckusick if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) { 7752132Smckusick fprintf(stderr, "Need impure text format (OMAGIC) file\n"); 7852132Smckusick exit(1); 7952132Smckusick } 8052132Smckusick 8152132Smckusick /* 8252132Smckusick * Write the boot information block. 8352132Smckusick */ 8452132Smckusick decBootInfo.magic = DEC_BOOT_MAGIC; 8552132Smckusick decBootInfo.mode = 0; 8652132Smckusick decBootInfo.loadAddr = loadAddr; 8752132Smckusick decBootInfo.execAddr = execAddr; 8852132Smckusick decBootInfo.map[0].numBlocks = nsectors = 8952132Smckusick (length + DEV_BSIZE - 1) >> DEV_BSHIFT; 9052132Smckusick decBootInfo.map[0].startBlock = 1; 9152132Smckusick decBootInfo.map[1].numBlocks = 0; 9253207Sralph if (write(ofd1, (char *)&decBootInfo, sizeof(decBootInfo)) != 9353207Sralph sizeof(decBootInfo) || close(ofd1) != 0) 9453207Sralph goto xxboot_err; 9552132Smckusick 96*56639Sralph printf("load %x, start %x, len %d, nsectors %d\n", loadAddr, execAddr, 97*56639Sralph length, nsectors); 98*56639Sralph 9952132Smckusick /* 10053207Sralph * Write the boot code to the bootxx file. 10152132Smckusick */ 10252132Smckusick for (i = 0; i < nsectors && length > 0; i++) { 10353207Sralph if (length < DEV_BSIZE) { 10453207Sralph n = length; 10553207Sralph bzero(block, DEV_BSIZE); 10653207Sralph } else 10753207Sralph n = DEV_BSIZE; 10852132Smckusick if (read(ifd, block, n) != n) { 10952132Smckusick perror(bootfname); 11052132Smckusick break; 11152132Smckusick } 11252132Smckusick length -= n; 11353207Sralph if (write(ofd2, block, DEV_BSIZE) != DEV_BSIZE) { 11453207Sralph perror(bootxx); 11552132Smckusick break; 11652132Smckusick } 11752132Smckusick } 11852132Smckusick if (length > 0) 11952132Smckusick printf("Warning: didn't reach end of boot program!\n"); 12052132Smckusick exit(0); 12152132Smckusick } 12252132Smckusick 12352132Smckusick usage() 12452132Smckusick { 12553207Sralph printf("Usage: mkboot bootprog xxboot bootxx\n"); 12652132Smckusick printf("where:\n"); 127*56639Sralph printf("\t\"bootprog\" is a -N format file\n"); 128*56639Sralph printf("\t\"xxboot\" is the file name for the first boot block\n"); 129*56639Sralph printf("\t\"bootxx\" is the file name for the remaining boot blocks.\n"); 13052132Smckusick exit(1); 13152132Smckusick } 13252132Smckusick 13352132Smckusick /* 13452132Smckusick *---------------------------------------------------------------------- 13552132Smckusick * 13652132Smckusick * DecHeader - 13752132Smckusick * 13852868Sralph * Check if the header is a DEC (COFF) file. 13952132Smckusick * 14052132Smckusick * Results: 14152132Smckusick * Return true if all went ok. 14252132Smckusick * 14352132Smckusick * Side effects: 14452132Smckusick * None. 14552132Smckusick * 14652132Smckusick *---------------------------------------------------------------------- 14752132Smckusick */ 14852132Smckusick DecHeader(bootFID, loadAddr, execAddr, length) 14952132Smckusick int bootFID; /* Handle on the boot program */ 15052132Smckusick long *loadAddr; /* Address to start loading boot program. */ 15152132Smckusick long *execAddr; /* Address to start executing boot program. */ 15252132Smckusick long *length; /* Length of the boot program. */ 15352132Smckusick { 15452132Smckusick struct exec aout; 15552132Smckusick int bytesRead; 15652132Smckusick 15752132Smckusick if (lseek(bootFID, 0, 0) < 0) { 15852132Smckusick perror(bootfname); 15952132Smckusick return 0; 16052132Smckusick } 16152132Smckusick bytesRead = read(bootFID, (char *)&aout, sizeof(aout)); 16252132Smckusick if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC || 16352132Smckusick aout.a_magic != OMAGIC) 16452132Smckusick return 0; 16552132Smckusick *loadAddr = aout.ex_aout.codeStart; 16652132Smckusick *execAddr = aout.a_entry; 16752132Smckusick *length = aout.a_text + aout.a_data; 16852132Smckusick if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) { 16952132Smckusick perror(bootfname); 17052132Smckusick return 0; 17152132Smckusick } 17252868Sralph printf("Input file is COFF format\n"); 17352132Smckusick return 1; 17452132Smckusick } 175