xref: /csrg-svn/sys/pmax/stand/mkboot.c (revision 52132)
1*52132Smckusick /*
2*52132Smckusick  * Copyright (c) 1992 Regents of the University of California.
3*52132Smckusick  * All rights reserved.
4*52132Smckusick  *
5*52132Smckusick  * This code is derived from software contributed to Berkeley by
6*52132Smckusick  * Ralph Campbell.
7*52132Smckusick  *
8*52132Smckusick  * %sccs.include.redist.c%
9*52132Smckusick  */
10*52132Smckusick 
11*52132Smckusick #ifndef lint
12*52132Smckusick char copyright[] =
13*52132Smckusick "@(#) Copyright (c) 1992 Regents of the University of California.\n\
14*52132Smckusick  All rights reserved.\n";
15*52132Smckusick #endif not lint
16*52132Smckusick 
17*52132Smckusick #ifndef lint
18*52132Smckusick static char sccsid[] = "@(#)mkboot.c	7.1 (Berkeley) 01/07/92";
19*52132Smckusick #endif not lint
20*52132Smckusick 
21*52132Smckusick #include <stdio.h>
22*52132Smckusick #include "types.h"
23*52132Smckusick #include "exec.h"
24*52132Smckusick #include "../include/param.h"
25*52132Smckusick #include "../dev/devDiskLabel.h"
26*52132Smckusick 
27*52132Smckusick /* this is the size of the standard ULTRIX boot */
28*52132Smckusick #define MAXBOOTSIZE (15 * DEV_BSIZE)
29*52132Smckusick 
30*52132Smckusick char	block[DEV_BSIZE];
31*52132Smckusick char	*dev, *bootfname;
32*52132Smckusick 
33*52132Smckusick /*
34*52132Smckusick  * installboot bootprog device
35*52132Smckusick  */
36*52132Smckusick main(argc, argv)
37*52132Smckusick 	int argc;
38*52132Smckusick 	char *argv[];
39*52132Smckusick {
40*52132Smckusick 	register int i, n;
41*52132Smckusick 	int ifd, ofd;
42*52132Smckusick 	Dec_DiskBoot decBootInfo;
43*52132Smckusick 	int nsectors;
44*52132Smckusick 	long loadAddr;
45*52132Smckusick 	long execAddr;
46*52132Smckusick 	long length;
47*52132Smckusick 
48*52132Smckusick 	if (argc != 3)
49*52132Smckusick 		usage();
50*52132Smckusick 	dev = argv[2];
51*52132Smckusick 	i = strlen(dev);
52*52132Smckusick 	bootfname = argv[1];
53*52132Smckusick 	ifd = open(bootfname, 0, 0);
54*52132Smckusick 	if (ifd < 0) {
55*52132Smckusick 		perror(bootfname);
56*52132Smckusick 		exit(1);
57*52132Smckusick 	}
58*52132Smckusick 	ofd = open(dev, 2, 0);
59*52132Smckusick 	if (ofd < 0) {
60*52132Smckusick 	deverr:
61*52132Smckusick 		perror(dev);
62*52132Smckusick 		exit(1);
63*52132Smckusick 	}
64*52132Smckusick 
65*52132Smckusick 	/*
66*52132Smckusick 	 * Check for exec header and skip to code segment.
67*52132Smckusick 	 */
68*52132Smckusick 	if (!DecHeader(ifd, &loadAddr, &execAddr, &length)) {
69*52132Smckusick 		fprintf(stderr, "Need impure text format (OMAGIC) file\n");
70*52132Smckusick 		exit(1);
71*52132Smckusick 	}
72*52132Smckusick 	if (length > MAXBOOTSIZE) {
73*52132Smckusick 		fprintf(stderr, "boot program is too big (%d > %d)\n",
74*52132Smckusick 			length, MAXBOOTSIZE);
75*52132Smckusick 		exit(1);
76*52132Smckusick 	}
77*52132Smckusick 
78*52132Smckusick 	/*
79*52132Smckusick 	 * Write the boot information block.
80*52132Smckusick 	 */
81*52132Smckusick 	decBootInfo.magic = DEC_BOOT_MAGIC;
82*52132Smckusick 	decBootInfo.mode = 0;
83*52132Smckusick 	decBootInfo.loadAddr = loadAddr;
84*52132Smckusick 	decBootInfo.execAddr = execAddr;
85*52132Smckusick 	decBootInfo.map[0].numBlocks = nsectors =
86*52132Smckusick 		(length + DEV_BSIZE - 1) >> DEV_BSHIFT;
87*52132Smckusick 	decBootInfo.map[0].startBlock = 1;
88*52132Smckusick 	decBootInfo.map[1].numBlocks = 0;
89*52132Smckusick 	if (lseek(ofd, (long)(DEC_BOOT_SECTOR * DEV_BSIZE), 0) < 0 ||
90*52132Smckusick 	    write(ofd, (char *)&decBootInfo, sizeof(decBootInfo)) !=
91*52132Smckusick 	    sizeof(decBootInfo)) {
92*52132Smckusick 		perror(dev);
93*52132Smckusick 		fprintf(stderr, "Sector write %d failed: ", DEC_BOOT_SECTOR);
94*52132Smckusick 		exit(1);
95*52132Smckusick 	}
96*52132Smckusick 	if (lseek(ofd, (long)(1 * DEV_BSIZE), 0) < 0)
97*52132Smckusick 		goto deverr;
98*52132Smckusick 
99*52132Smckusick 	/*
100*52132Smckusick 	 * Write the remaining code to the correct place on the disk.
101*52132Smckusick 	 */
102*52132Smckusick 	for (i = 0; i < nsectors && length > 0; i++) {
103*52132Smckusick 		bzero(block, DEV_BSIZE);
104*52132Smckusick 		n = length < DEV_BSIZE ? length : DEV_BSIZE;
105*52132Smckusick 		if (read(ifd, block, n) != n) {
106*52132Smckusick 			perror(bootfname);
107*52132Smckusick 			break;
108*52132Smckusick 		}
109*52132Smckusick 		length -= n;
110*52132Smckusick 		if (write(ofd, block, DEV_BSIZE) != DEV_BSIZE) {
111*52132Smckusick 			perror(dev);
112*52132Smckusick 			break;
113*52132Smckusick 		}
114*52132Smckusick 	}
115*52132Smckusick 	printf("Wrote %d sectors\n", i);
116*52132Smckusick 	if (length > 0)
117*52132Smckusick 		printf("Warning: didn't reach end of boot program!\n");
118*52132Smckusick 	exit(0);
119*52132Smckusick }
120*52132Smckusick 
121*52132Smckusick usage()
122*52132Smckusick {
123*52132Smckusick 	printf("Usage: installboot bootprog device\n");
124*52132Smckusick 	printf("where:\n");
125*52132Smckusick 	printf("\t\"bootprog\" is a -N format file < %d bytes long\n",
126*52132Smckusick 	       MAXBOOTSIZE);
127*52132Smckusick 	printf("\t\"device\" should be the 'a' partition of a bootable disk\n");
128*52132Smckusick 	printf("WARNING!!  If the 'c' partition contains a file system, %s\n",
129*52132Smckusick 	       "DON'T RUN THIS!!");
130*52132Smckusick 	exit(1);
131*52132Smckusick }
132*52132Smckusick 
133*52132Smckusick /*
134*52132Smckusick  *----------------------------------------------------------------------
135*52132Smckusick  *
136*52132Smckusick  * DecHeader -
137*52132Smckusick  *
138*52132Smckusick  *	Check if the header is a dec (coff) file.
139*52132Smckusick  *
140*52132Smckusick  * Results:
141*52132Smckusick  *	Return true if all went ok.
142*52132Smckusick  *
143*52132Smckusick  * Side effects:
144*52132Smckusick  *	None.
145*52132Smckusick  *
146*52132Smckusick  *----------------------------------------------------------------------
147*52132Smckusick  */
148*52132Smckusick DecHeader(bootFID, loadAddr, execAddr, length)
149*52132Smckusick 	int bootFID;	/* Handle on the boot program */
150*52132Smckusick 	long *loadAddr;	/* Address to start loading boot program. */
151*52132Smckusick 	long *execAddr;	/* Address to start executing boot program. */
152*52132Smckusick 	long *length;	/* Length of the boot program. */
153*52132Smckusick {
154*52132Smckusick 	struct exec aout;
155*52132Smckusick 	int bytesRead;
156*52132Smckusick 
157*52132Smckusick 	if (lseek(bootFID, 0, 0) < 0) {
158*52132Smckusick 		perror(bootfname);
159*52132Smckusick 		return 0;
160*52132Smckusick 	}
161*52132Smckusick 	bytesRead = read(bootFID, (char *)&aout, sizeof(aout));
162*52132Smckusick 	if (bytesRead != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC ||
163*52132Smckusick 	    aout.a_magic != OMAGIC)
164*52132Smckusick 		return 0;
165*52132Smckusick 	*loadAddr = aout.ex_aout.codeStart;
166*52132Smckusick 	*execAddr = aout.a_entry;
167*52132Smckusick 	*length = aout.a_text + aout.a_data;
168*52132Smckusick 	if (lseek(bootFID, N_TXTOFF(aout), 0) < 0) {
169*52132Smckusick 		perror(bootfname);
170*52132Smckusick 		return 0;
171*52132Smckusick 	}
172*52132Smckusick 	printf("Input file is coff format\n");
173*52132Smckusick 	printf("load %x, start %x, len %d\n", *loadAddr, *execAddr, *length);
174*52132Smckusick 	return 1;
175*52132Smckusick }
176