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 */
main(argc,argv)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
usage()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 */
GetHeader(bootFID,loadAddr,execAddr,length)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