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