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