xref: /csrg-svn/sys/pmax/stand/mkboot.c (revision 56639)
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