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