xref: /csrg-svn/sys/hp300/stand/mkboot.c (revision 41488)
1*41488Smckusick /*
2*41488Smckusick  * Copyright (c) 1990 The Regents of the University of California.
3*41488Smckusick  * All rights reserved.
4*41488Smckusick  *
5*41488Smckusick  * %sccs.include.redist.c%
6*41488Smckusick  *
7*41488Smckusick  *	@(#)mkboot.c	7.1 (Berkeley) 05/08/90
8*41488Smckusick  */
9*41488Smckusick 
10*41488Smckusick #ifndef lint
11*41488Smckusick char copyright[] =
12*41488Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
13*41488Smckusick  All rights reserved.\n";
14*41488Smckusick #endif /* not lint */
15*41488Smckusick 
16*41488Smckusick #ifndef lint
17*41488Smckusick static char sccsid[] = "@(#)mkboot.c	7.1 (Berkeley) 05/08/90";
18*41488Smckusick #endif /* not lint */
19*41488Smckusick 
20*41488Smckusick #include "machine/machparam.h"
21*41488Smckusick #include "volhdr.h"
22*41488Smckusick #include <sys/exec.h>
23*41488Smckusick #include <sys/file.h>
24*41488Smckusick #include <stdio.h>
25*41488Smckusick #include <ctype.h>
26*41488Smckusick 
27*41488Smckusick int lpflag;
28*41488Smckusick int loadpoint;
29*41488Smckusick struct load ld;
30*41488Smckusick struct lifvol lifv;
31*41488Smckusick struct lifdir lifd[8];
32*41488Smckusick struct exec ex;
33*41488Smckusick char buf[10240];
34*41488Smckusick 
35*41488Smckusick main(argc, argv)
36*41488Smckusick 	char **argv;
37*41488Smckusick {
38*41488Smckusick 	int ac;
39*41488Smckusick 	char **av;
40*41488Smckusick 	int from1, from2, to;
41*41488Smckusick 	register int n;
42*41488Smckusick 	char *n1, *n2, *lifname();
43*41488Smckusick 
44*41488Smckusick 	ac = --argc;
45*41488Smckusick 	av = ++argv;
46*41488Smckusick 	if (ac == 0)
47*41488Smckusick 		usage();
48*41488Smckusick 	if (!strcmp(av[0], "-l")) {
49*41488Smckusick 		av++;
50*41488Smckusick 		ac--;
51*41488Smckusick 		if (ac == 0)
52*41488Smckusick 			usage();
53*41488Smckusick 		sscanf(av[0], "0x%x", &loadpoint);
54*41488Smckusick 		lpflag++;
55*41488Smckusick 		av++;
56*41488Smckusick 		ac--;
57*41488Smckusick 	}
58*41488Smckusick 	if (ac == 0)
59*41488Smckusick 		usage();
60*41488Smckusick 	from1 = open(av[0], O_RDONLY, 0);
61*41488Smckusick 	if (from1 < 0) {
62*41488Smckusick 		perror("open");
63*41488Smckusick 		exit(1);
64*41488Smckusick 	}
65*41488Smckusick 	n1 = av[0];
66*41488Smckusick 	av++;
67*41488Smckusick 	ac--;
68*41488Smckusick 	if (ac == 0)
69*41488Smckusick 		usage();
70*41488Smckusick 	if (ac == 2) {
71*41488Smckusick 		from2 = open(av[0], O_RDONLY, 0);
72*41488Smckusick 		if (from2 < 0) {
73*41488Smckusick 			perror("open");
74*41488Smckusick 			exit(1);
75*41488Smckusick 		}
76*41488Smckusick 		n2 = av[0];
77*41488Smckusick 		av++;
78*41488Smckusick 		ac--;
79*41488Smckusick 	} else
80*41488Smckusick 		from2 = -1;
81*41488Smckusick 	to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
82*41488Smckusick 	if (to < 0) {
83*41488Smckusick 		perror("open");
84*41488Smckusick 		exit(1);
85*41488Smckusick 	}
86*41488Smckusick 	/* clear possibly unused directory entries */
87*41488Smckusick 	strncpy(lifd[1].dir_name, "          ", 10);
88*41488Smckusick 	lifd[1].dir_type = -1;
89*41488Smckusick 	lifd[1].dir_addr = 0;
90*41488Smckusick 	lifd[1].dir_length = 0;
91*41488Smckusick 	lifd[1].dir_flag = 0xFF;
92*41488Smckusick 	lifd[1].dir_exec = 0;
93*41488Smckusick 	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
94*41488Smckusick 	/* record volume info */
95*41488Smckusick 	lifv.vol_id = VOL_ID;
96*41488Smckusick 	strncpy(lifv.vol_label, "BOOT43", 6);
97*41488Smckusick 	lifv.vol_addr = 2;
98*41488Smckusick 	lifv.vol_oct = VOL_OCT;
99*41488Smckusick 	lifv.vol_dirsize = 1;
100*41488Smckusick 	lifv.vol_version = 1;
101*41488Smckusick 	/* output bootfile one */
102*41488Smckusick 	lseek(to, 3 * SECTSIZE, 0);
103*41488Smckusick 	putfile(from1, to);
104*41488Smckusick 	n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
105*41488Smckusick 	strcpy(lifd[0].dir_name, lifname(n1));
106*41488Smckusick 	lifd[0].dir_type = DIR_TYPE;
107*41488Smckusick 	lifd[0].dir_addr = 3;
108*41488Smckusick 	lifd[0].dir_length = n;
109*41488Smckusick 	lifd[0].dir_flag = DIR_FLAG;
110*41488Smckusick 	lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
111*41488Smckusick 	lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length;
112*41488Smckusick 	/* if there is an optional second boot program, output it */
113*41488Smckusick 	if (from2 >= 0) {
114*41488Smckusick 		lseek(to, (3 + n) * SECTSIZE, 0);
115*41488Smckusick 		putfile(from2, to);
116*41488Smckusick 		n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
117*41488Smckusick 		strcpy(lifd[1].dir_name, lifname(n2));
118*41488Smckusick 		lifd[1].dir_type = DIR_TYPE;
119*41488Smckusick 		lifd[1].dir_addr = 3 + lifd[0].dir_length;
120*41488Smckusick 		lifd[1].dir_length = n;
121*41488Smckusick 		lifd[1].dir_flag = DIR_FLAG;
122*41488Smckusick 		lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
123*41488Smckusick 		lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length;
124*41488Smckusick 	}
125*41488Smckusick 	/* output volume/directory header info */
126*41488Smckusick 	lseek(to, 0 * SECTSIZE, 0);
127*41488Smckusick 	write(to, &lifv, sizeof(lifv));
128*41488Smckusick 	lseek(to, 2 * SECTSIZE, 0);
129*41488Smckusick 	write(to, lifd, sizeof(lifd));
130*41488Smckusick 	exit(0);
131*41488Smckusick }
132*41488Smckusick 
133*41488Smckusick putfile(from, to)
134*41488Smckusick {
135*41488Smckusick 	register int n, tcnt, dcnt;
136*41488Smckusick 
137*41488Smckusick 	n = read(from, &ex, sizeof(ex));
138*41488Smckusick 	if (n != sizeof(ex)) {
139*41488Smckusick 		fprintf(stderr, "error reading file header\n");
140*41488Smckusick 		exit(1);
141*41488Smckusick 	}
142*41488Smckusick 	if (ex.a_magic == OMAGIC) {
143*41488Smckusick 		tcnt = ex.a_text;
144*41488Smckusick 		dcnt = ex.a_data;
145*41488Smckusick 	}
146*41488Smckusick 	else if (ex.a_magic == NMAGIC) {
147*41488Smckusick 		tcnt = (ex.a_text + PGOFSET) & ~PGOFSET;
148*41488Smckusick 		dcnt = ex.a_data;
149*41488Smckusick 	}
150*41488Smckusick 	else {
151*41488Smckusick 		fprintf(stderr, "bad magic number\n");
152*41488Smckusick 		exit(1);
153*41488Smckusick 	}
154*41488Smckusick 	ld.address = lpflag ? loadpoint : ex.a_entry;
155*41488Smckusick 	ld.count = tcnt + dcnt;
156*41488Smckusick 	write(to, &ld, sizeof(ld));
157*41488Smckusick 	while (tcnt) {
158*41488Smckusick 		n = sizeof(buf);
159*41488Smckusick 		if (n > tcnt)
160*41488Smckusick 			n = tcnt;
161*41488Smckusick 		n = read(from, buf, n);
162*41488Smckusick 		if (n < 0) {
163*41488Smckusick 			perror("read");
164*41488Smckusick 			exit(1);
165*41488Smckusick 		}
166*41488Smckusick 		if (n == 0) {
167*41488Smckusick 			fprintf(stderr, "short read\n");
168*41488Smckusick 			exit(1);
169*41488Smckusick 		}
170*41488Smckusick 		if (write(to, buf, n) < 0) {
171*41488Smckusick 			perror("write");
172*41488Smckusick 			exit(1);
173*41488Smckusick 		}
174*41488Smckusick 		tcnt -= n;
175*41488Smckusick 	}
176*41488Smckusick 	while (dcnt) {
177*41488Smckusick 		n = sizeof(buf);
178*41488Smckusick 		if (n > dcnt)
179*41488Smckusick 			n = dcnt;
180*41488Smckusick 		n = read(from, buf, n);
181*41488Smckusick 		if (n < 0) {
182*41488Smckusick 			perror("read");
183*41488Smckusick 			exit(1);
184*41488Smckusick 		}
185*41488Smckusick 		if (n == 0) {
186*41488Smckusick 			fprintf(stderr, "short read\n");
187*41488Smckusick 			exit(1);
188*41488Smckusick 		}
189*41488Smckusick 		if (write(to, buf, n) < 0) {
190*41488Smckusick 			perror("write");
191*41488Smckusick 			exit(1);
192*41488Smckusick 		}
193*41488Smckusick 		dcnt -= n;
194*41488Smckusick 	}
195*41488Smckusick }
196*41488Smckusick 
197*41488Smckusick usage()
198*41488Smckusick {
199*41488Smckusick 	fprintf(stderr,
200*41488Smckusick 		"usage:  mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n");
201*41488Smckusick 	exit(1);
202*41488Smckusick }
203*41488Smckusick 
204*41488Smckusick char *
205*41488Smckusick lifname(str)
206*41488Smckusick  char *str;
207*41488Smckusick {
208*41488Smckusick 	static char lname[10] = "SYS_XXXXX";
209*41488Smckusick 	register int i;
210*41488Smckusick 
211*41488Smckusick 	for (i = 4; i < 9; i++) {
212*41488Smckusick 		if (islower(*str))
213*41488Smckusick 			lname[i] = toupper(*str);
214*41488Smckusick 		else if (isalnum(*str) || *str == '_')
215*41488Smckusick 			lname[i] = *str;
216*41488Smckusick 		else
217*41488Smckusick 			break;
218*41488Smckusick 		str++;
219*41488Smckusick 	}
220*41488Smckusick 	for ( ; i < 10; i++)
221*41488Smckusick 		lname[i] = '\0';
222*41488Smckusick 	return(lname);
223*41488Smckusick }
224