152132Smckusick /*
2*63226Sbostic * Copyright (c) 1992, 1993
3*63226Sbostic * The Regents of the University of California. 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
12*63226Sbostic static char copyright[] =
13*63226Sbostic "@(#) Copyright (c) 1992, 1993\n\
14*63226Sbostic The Regents of the University of California. All rights reserved.\n";
1552132Smckusick #endif not lint
1652132Smckusick
1752132Smckusick #ifndef lint
18*63226Sbostic static char sccsid[] = "@(#)mkboot.c 8.1 (Berkeley) 06/10/93";
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 */
main(argc,argv)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 */
7658007Sralph if (!GetHeader(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
9656639Sralph printf("load %x, start %x, len %d, nsectors %d\n", loadAddr, execAddr,
9756639Sralph length, nsectors);
9856639Sralph
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
usage()12352132Smckusick usage()
12452132Smckusick {
12553207Sralph printf("Usage: mkboot bootprog xxboot bootxx\n");
12652132Smckusick printf("where:\n");
12756639Sralph printf("\t\"bootprog\" is a -N format file\n");
12856639Sralph printf("\t\"xxboot\" is the file name for the first boot block\n");
12956639Sralph printf("\t\"bootxx\" is the file name for the remaining boot blocks.\n");
13052132Smckusick exit(1);
13152132Smckusick }
13252132Smckusick
13352132Smckusick /*
13452132Smckusick *----------------------------------------------------------------------
13552132Smckusick *
13658007Sralph * GetHeader -
13752132Smckusick *
13858007Sralph * Check if the header is an a.out file.
13952132Smckusick *
14052132Smckusick * Results:
14152132Smckusick * Return true if all went ok.
14252132Smckusick *
14352132Smckusick * Side effects:
14458007Sralph * bootFID is left ready to read the text & data sections.
14558007Sralph * length is set to the size of the text + data sections.
14652132Smckusick *
14752132Smckusick *----------------------------------------------------------------------
14852132Smckusick */
GetHeader(bootFID,loadAddr,execAddr,length)14958007Sralph GetHeader(bootFID, loadAddr, execAddr, length)
15052132Smckusick int bootFID; /* Handle on the boot program */
15152132Smckusick long *loadAddr; /* Address to start loading boot program. */
15252132Smckusick long *execAddr; /* Address to start executing boot program. */
15352132Smckusick long *length; /* Length of the boot program. */
15452132Smckusick {
15552132Smckusick struct exec aout;
15652132Smckusick int bytesRead;
15752132Smckusick
15852132Smckusick if (lseek(bootFID, 0, 0) < 0) {
15952132Smckusick perror(bootfname);
16052132Smckusick return 0;
16152132Smckusick }
16252132Smckusick bytesRead = read(bootFID, (char *)&aout, sizeof(aout));
16358007Sralph if (bytesRead != sizeof(aout) || aout.a_magic != OMAGIC)
16452132Smckusick return 0;
16558007Sralph *loadAddr = aout.a_entry;
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 }
17258007Sralph printf("Input file is a.out format\n");
17352132Smckusick return 1;
17452132Smckusick }
175