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