xref: /csrg-svn/sys/pmax/stand/mkboot.c (revision 52868)
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*52868Sralph static char sccsid[] = "@(#)mkboot.c	7.2 (Berkeley) 03/07/92";
1952132Smckusick #endif not lint
2052132Smckusick 
2152132Smckusick #include <stdio.h>
22*52868Sralph #include "sys/param.h"
23*52868Sralph #include "sys/exec.h"
2452132Smckusick #include "../dev/devDiskLabel.h"
2552132Smckusick 
2652132Smckusick /* this is the size of the standard ULTRIX boot */
2752132Smckusick #define MAXBOOTSIZE (15 * DEV_BSIZE)
2852132Smckusick 
2952132Smckusick char	block[DEV_BSIZE];
3052132Smckusick char	*dev, *bootfname;
3152132Smckusick 
3252132Smckusick /*
3352132Smckusick  * installboot bootprog device
3452132Smckusick  */
3552132Smckusick main(argc, argv)
3652132Smckusick 	int argc;
3752132Smckusick 	char *argv[];
3852132Smckusick {
3952132Smckusick 	register int i, n;
4052132Smckusick 	int ifd, ofd;
4152132Smckusick 	Dec_DiskBoot decBootInfo;
4252132Smckusick 	int nsectors;
4352132Smckusick 	long loadAddr;
4452132Smckusick 	long execAddr;
4552132Smckusick 	long length;
4652132Smckusick 
4752132Smckusick 	if (argc != 3)
4852132Smckusick 		usage();
4952132Smckusick 	dev = argv[2];
5052132Smckusick 	i = strlen(dev);
5152132Smckusick 	bootfname = argv[1];
5252132Smckusick 	ifd = open(bootfname, 0, 0);
5352132Smckusick 	if (ifd < 0) {
5452132Smckusick 		perror(bootfname);
5552132Smckusick 		exit(1);
5652132Smckusick 	}
5752132Smckusick 	ofd = open(dev, 2, 0);
5852132Smckusick 	if (ofd < 0) {
5952132Smckusick 	deverr:
6052132Smckusick 		perror(dev);
6152132Smckusick 		exit(1);
6252132Smckusick 	}
6352132Smckusick 
6452132Smckusick 	/*
6552132Smckusick 	 * Check for exec header and skip to code segment.
6652132Smckusick 	 */
6752132Smckusick 	if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) {
6852132Smckusick 		fprintf(stderr, "Need impure text format (OMAGIC) file\n");
6952132Smckusick 		exit(1);
7052132Smckusick 	}
7152132Smckusick 	if (length > MAXBOOTSIZE) {
7252132Smckusick 		fprintf(stderr, "boot program is too big (%d > %d)\n",
7352132Smckusick 			length, MAXBOOTSIZE);
7452132Smckusick 		exit(1);
7552132Smckusick 	}
7652132Smckusick 
7752132Smckusick 	/*
7852132Smckusick 	 * Write the boot information block.
7952132Smckusick 	 */
8052132Smckusick 	decBootInfo.magic = DEC_BOOT_MAGIC;
8152132Smckusick 	decBootInfo.mode = 0;
8252132Smckusick 	decBootInfo.loadAddr = loadAddr;
8352132Smckusick 	decBootInfo.execAddr = execAddr;
8452132Smckusick 	decBootInfo.map[0].numBlocks = nsectors =
8552132Smckusick 		(length + DEV_BSIZE - 1) >> DEV_BSHIFT;
8652132Smckusick 	decBootInfo.map[0].startBlock = 1;
8752132Smckusick 	decBootInfo.map[1].numBlocks = 0;
8852132Smckusick 	if (lseek(ofd, (long)(DEC_BOOT_SECTOR * DEV_BSIZE), 0) < 0 ||
8952132Smckusick 	    write(ofd, (char *)&decBootInfo, sizeof(decBootInfo)) !=
9052132Smckusick 	    sizeof(decBootInfo)) {
9152132Smckusick 		perror(dev);
9252132Smckusick 		fprintf(stderr, "Sector write %d failed: ", DEC_BOOT_SECTOR);
9352132Smckusick 		exit(1);
9452132Smckusick 	}
9552132Smckusick 	if (lseek(ofd, (long)(1 * DEV_BSIZE), 0) < 0)
9652132Smckusick 		goto deverr;
9752132Smckusick 
9852132Smckusick 	/*
9952132Smckusick 	 * Write the remaining code to the correct place on the disk.
10052132Smckusick 	 */
10152132Smckusick 	for (i = 0; i < nsectors && length > 0; i++) {
10252132Smckusick 		bzero(block, DEV_BSIZE);
10352132Smckusick 		n = length < DEV_BSIZE ? length : DEV_BSIZE;
10452132Smckusick 		if (read(ifd, block, n) != n) {
10552132Smckusick 			perror(bootfname);
10652132Smckusick 			break;
10752132Smckusick 		}
10852132Smckusick 		length -= n;
10952132Smckusick 		if (write(ofd, block, DEV_BSIZE) != DEV_BSIZE) {
11052132Smckusick 			perror(dev);
11152132Smckusick 			break;
11252132Smckusick 		}
11352132Smckusick 	}
11452132Smckusick 	printf("Wrote %d sectors\n", i);
11552132Smckusick 	if (length > 0)
11652132Smckusick 		printf("Warning: didn't reach end of boot program!\n");
11752132Smckusick 	exit(0);
11852132Smckusick }
11952132Smckusick 
12052132Smckusick usage()
12152132Smckusick {
12252132Smckusick 	printf("Usage: installboot bootprog device\n");
12352132Smckusick 	printf("where:\n");
12452132Smckusick 	printf("\t\"bootprog\" is a -N format file < %d bytes long\n",
12552132Smckusick 	       MAXBOOTSIZE);
12652132Smckusick 	printf("\t\"device\" should be the 'a' partition of a bootable disk\n");
12752132Smckusick 	printf("WARNING!!  If the 'c' partition contains a file system, %s\n",
12852132Smckusick 	       "DON'T RUN THIS!!");
12952132Smckusick 	exit(1);
13052132Smckusick }
13152132Smckusick 
13252132Smckusick /*
13352132Smckusick  *----------------------------------------------------------------------
13452132Smckusick  *
13552132Smckusick  * DecHeader -
13652132Smckusick  *
137*52868Sralph  *	Check if the header is a DEC (COFF) file.
13852132Smckusick  *
13952132Smckusick  * Results:
14052132Smckusick  *	Return true if all went ok.
14152132Smckusick  *
14252132Smckusick  * Side effects:
14352132Smckusick  *	None.
14452132Smckusick  *
14552132Smckusick  *----------------------------------------------------------------------
14652132Smckusick  */
14752132Smckusick DecHeader(bootFID, loadAddr, execAddr, length)
14852132Smckusick 	int bootFID;	/* Handle on the boot program */
14952132Smckusick 	long *loadAddr;	/* Address to start loading boot program. */
15052132Smckusick 	long *execAddr;	/* Address to start executing boot program. */
15152132Smckusick 	long *length;	/* Length of the boot program. */
15252132Smckusick {
15352132Smckusick 	struct exec aout;
15452132Smckusick 	int bytesRead;
15552132Smckusick 
15652132Smckusick 	if (lseek(bootFID, 0, 0) < 0) {
15752132Smckusick 		perror(bootfname);
15852132Smckusick 		return 0;
15952132Smckusick 	}
16052132Smckusick 	bytesRead = read(bootFID, (char *)&aout, sizeof(aout));
16152132Smckusick 	if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC ||
16252132Smckusick 	    aout.a_magic != OMAGIC)
16352132Smckusick 		return 0;
16452132Smckusick 	*loadAddr = aout.ex_aout.codeStart;
16552132Smckusick 	*execAddr = aout.a_entry;
16652132Smckusick 	*length = aout.a_text + aout.a_data;
16752132Smckusick 	if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) {
16852132Smckusick 		perror(bootfname);
16952132Smckusick 		return 0;
17052132Smckusick 	}
171*52868Sralph 	printf("Input file is COFF format\n");
17252132Smckusick 	printf("load %x, start %x, len %d\n", *loadAddr, *execAddr, *length);
17352132Smckusick 	return 1;
17452132Smckusick }
175