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*56526Sbostic static char sccsid[] = "@(#)mkboot.c 7.4 (Berkeley) 10/11/92"; 1952132Smckusick #endif not lint 2052132Smckusick 21*56526Sbostic #include <sys/param.h> 22*56526Sbostic #include <sys/exec.h> 23*56526Sbostic #include <sys/disklabel.h> 2452132Smckusick #include <stdio.h> 2552132Smckusick 26*56526Sbostic #include <pmax/stand/dec_boot.h> 2753207Sralph 2852132Smckusick /* this is the size of the standard ULTRIX boot */ 2952132Smckusick #define MAXBOOTSIZE (15 * DEV_BSIZE) 3052132Smckusick 3153207Sralph struct Dec_DiskBoot decBootInfo; 3252132Smckusick char block[DEV_BSIZE]; 3353207Sralph char *bootfname, *xxboot, *bootxx; 3452132Smckusick 3552132Smckusick /* 3653207Sralph * This program takes a boot program and splits it into xxboot and bootxx 3753207Sralph * files for the disklabel program. The disklabel program should be used to 3853207Sralph * label and install the boot program onto a new disk. 3953207Sralph * 4053207Sralph * mkboot bootprog xxboot bootxx 4152132Smckusick */ 4252132Smckusick main(argc, argv) 4352132Smckusick int argc; 4452132Smckusick char *argv[]; 4552132Smckusick { 4652132Smckusick register int i, n; 4753207Sralph int ifd, ofd1, ofd2; 4852132Smckusick int nsectors; 4952132Smckusick long loadAddr; 5052132Smckusick long execAddr; 5152132Smckusick long length; 5252132Smckusick 5353207Sralph if (argc != 4) 5452132Smckusick usage(); 5552132Smckusick bootfname = argv[1]; 5653207Sralph xxboot = argv[2]; 5753207Sralph bootxx = argv[3]; 5852132Smckusick ifd = open(bootfname, 0, 0); 5952132Smckusick if (ifd < 0) { 6052132Smckusick perror(bootfname); 6152132Smckusick exit(1); 6252132Smckusick } 6353207Sralph ofd1 = creat(xxboot, 0666); 6453207Sralph if (ofd1 < 0) { 6553207Sralph xxboot_err: 6653207Sralph perror(xxboot); 6752132Smckusick exit(1); 6852132Smckusick } 6953207Sralph ofd2 = creat(bootxx, 0666); 7053207Sralph if (ofd2 < 0) { 7153207Sralph bootxx_err: 7253207Sralph perror(bootxx); 7353207Sralph exit(1); 7453207Sralph } 7552132Smckusick 7652132Smckusick /* 7752132Smckusick * Check for exec header and skip to code segment. 7852132Smckusick */ 7952132Smckusick if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) { 8052132Smckusick fprintf(stderr, "Need impure text format (OMAGIC) file\n"); 8152132Smckusick exit(1); 8252132Smckusick } 8352132Smckusick if (length > MAXBOOTSIZE) { 8452132Smckusick fprintf(stderr, "boot program is too big (%d > %d)\n", 8552132Smckusick length, MAXBOOTSIZE); 8652132Smckusick exit(1); 8752132Smckusick } 8852132Smckusick 8952132Smckusick /* 9052132Smckusick * Write the boot information block. 9152132Smckusick */ 9252132Smckusick decBootInfo.magic = DEC_BOOT_MAGIC; 9352132Smckusick decBootInfo.mode = 0; 9452132Smckusick decBootInfo.loadAddr = loadAddr; 9552132Smckusick decBootInfo.execAddr = execAddr; 9652132Smckusick decBootInfo.map[0].numBlocks = nsectors = 9752132Smckusick (length + DEV_BSIZE - 1) >> DEV_BSHIFT; 9852132Smckusick decBootInfo.map[0].startBlock = 1; 9952132Smckusick decBootInfo.map[1].numBlocks = 0; 10053207Sralph if (write(ofd1, (char *)&decBootInfo, sizeof(decBootInfo)) != 10153207Sralph sizeof(decBootInfo) || close(ofd1) != 0) 10253207Sralph goto xxboot_err; 10352132Smckusick 10452132Smckusick /* 10553207Sralph * Write the boot code to the bootxx file. 10652132Smckusick */ 10752132Smckusick for (i = 0; i < nsectors && length > 0; i++) { 10853207Sralph if (length < DEV_BSIZE) { 10953207Sralph n = length; 11053207Sralph bzero(block, DEV_BSIZE); 11153207Sralph } else 11253207Sralph n = DEV_BSIZE; 11352132Smckusick if (read(ifd, block, n) != n) { 11452132Smckusick perror(bootfname); 11552132Smckusick break; 11652132Smckusick } 11752132Smckusick length -= n; 11853207Sralph if (write(ofd2, block, DEV_BSIZE) != DEV_BSIZE) { 11953207Sralph perror(bootxx); 12052132Smckusick break; 12152132Smckusick } 12252132Smckusick } 12352132Smckusick if (length > 0) 12452132Smckusick printf("Warning: didn't reach end of boot program!\n"); 12552132Smckusick exit(0); 12652132Smckusick } 12752132Smckusick 12852132Smckusick usage() 12952132Smckusick { 13053207Sralph printf("Usage: mkboot bootprog xxboot bootxx\n"); 13152132Smckusick printf("where:\n"); 13252132Smckusick printf("\t\"bootprog\" is a -N format file < %d bytes long\n", 13352132Smckusick MAXBOOTSIZE); 13453207Sralph printf("\t\"xxboot\" is the name of the first boot block\n"); 13553207Sralph printf("\t\"bootxx\" is the name of the remaining boot blocks.\n"); 13652132Smckusick exit(1); 13752132Smckusick } 13852132Smckusick 13952132Smckusick /* 14052132Smckusick *---------------------------------------------------------------------- 14152132Smckusick * 14252132Smckusick * DecHeader - 14352132Smckusick * 14452868Sralph * Check if the header is a DEC (COFF) file. 14552132Smckusick * 14652132Smckusick * Results: 14752132Smckusick * Return true if all went ok. 14852132Smckusick * 14952132Smckusick * Side effects: 15052132Smckusick * None. 15152132Smckusick * 15252132Smckusick *---------------------------------------------------------------------- 15352132Smckusick */ 15452132Smckusick DecHeader(bootFID, loadAddr, execAddr, length) 15552132Smckusick int bootFID; /* Handle on the boot program */ 15652132Smckusick long *loadAddr; /* Address to start loading boot program. */ 15752132Smckusick long *execAddr; /* Address to start executing boot program. */ 15852132Smckusick long *length; /* Length of the boot program. */ 15952132Smckusick { 16052132Smckusick struct exec aout; 16152132Smckusick int bytesRead; 16252132Smckusick 16352132Smckusick if (lseek(bootFID, 0, 0) < 0) { 16452132Smckusick perror(bootfname); 16552132Smckusick return 0; 16652132Smckusick } 16752132Smckusick bytesRead = read(bootFID, (char *)&aout, sizeof(aout)); 16852132Smckusick if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC || 16952132Smckusick aout.a_magic != OMAGIC) 17052132Smckusick return 0; 17152132Smckusick *loadAddr = aout.ex_aout.codeStart; 17252132Smckusick *execAddr = aout.a_entry; 17352132Smckusick *length = aout.a_text + aout.a_data; 17452132Smckusick if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) { 17552132Smckusick perror(bootfname); 17652132Smckusick return 0; 17752132Smckusick } 17852868Sralph printf("Input file is COFF format\n"); 17952132Smckusick printf("load %x, start %x, len %d\n", *loadAddr, *execAddr, *length); 18052132Smckusick return 1; 18152132Smckusick } 182