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