xref: /csrg-svn/sys/hp300/stand/mkboot.c (revision 63825)
141488Smckusick /*
2*63825Sbostic  * Copyright (c) 1990, 1993
3*63825Sbostic  *	The Regents of the University of California.  All rights reserved.
441488Smckusick  *
541488Smckusick  * %sccs.include.redist.c%
641488Smckusick  *
7*63825Sbostic  *	@(#)mkboot.c	8.1 (Berkeley) 07/15/93
841488Smckusick  */
941488Smckusick 
1041488Smckusick #ifndef lint
1163811Shibler static char copyright[] =
1263811Shibler "@(#) Copyright (c) 1990, 1993\n\
1363811Shibler 	The Regents of the University of California.  All rights reserved.\n";
1441488Smckusick #endif /* not lint */
1541488Smckusick 
1641488Smckusick #ifndef lint
1745790Sbostic static char sccsid[] = "@(#)mkboot.c	7.2 (Berkeley) 12/16/90";
1841488Smckusick #endif /* not lint */
1941488Smckusick 
2056510Sbostic #include <sys/param.h>
2156510Sbostic #include <sys/exec.h>
2256510Sbostic #include <sys/file.h>
2354073Shibler 
2456510Sbostic #include <hp300/stand/volhdr.h>
2556510Sbostic 
2641488Smckusick #include <stdio.h>
2741488Smckusick #include <ctype.h>
2841488Smckusick 
2957299Shibler #define LIF_NUMDIR	8
3057299Shibler 
3157299Shibler #define LIF_VOLSTART	0
3257299Shibler #define LIF_VOLSIZE	sizeof(struct lifvol)
3357299Shibler #define LIF_DIRSTART	512
3457299Shibler #define LIF_DIRSIZE	(LIF_NUMDIR * sizeof(struct lifdir))
3557299Shibler #define LIF_FILESTART	8192
3657299Shibler 
3757299Shibler #define btolifs(b)	(((b) + (SECTSIZE - 1)) / SECTSIZE)
3857299Shibler #define lifstob(s)	((s) * SECTSIZE)
3957299Shibler 
4041488Smckusick int lpflag;
4141488Smckusick int loadpoint;
4241488Smckusick struct load ld;
4341488Smckusick struct lifvol lifv;
4457299Shibler struct lifdir lifd[LIF_NUMDIR];
4541488Smckusick struct exec ex;
4641488Smckusick char buf[10240];
4741488Smckusick 
4857299Shibler /*
4957299Shibler  * Old Format:
5057299Shibler  *	sector 0:	LIF volume header (40 bytes)
5157299Shibler  *	sector 1:	<unused>
5257299Shibler  *	sector 2:	LIF directory (8 x 32 == 256 bytes)
5357299Shibler  *	sector 3-:	LIF file 0, LIF file 1, etc.
5457299Shibler  * where sectors are 256 bytes.
5557299Shibler  *
5657299Shibler  * New Format:
5757299Shibler  *	sector 0:	LIF volume header (40 bytes)
5857299Shibler  *	sector 1:	<unused>
5957299Shibler  *	sector 2:	LIF directory (8 x 32 == 256 bytes)
6057299Shibler  *	sector 3:	<unused>
6157299Shibler  *	sector 4-31:	disklabel (~300 bytes right now)
6257299Shibler  *	sector 32-:	LIF file 0, LIF file 1, etc.
6357299Shibler  */
main(argc,argv)6441488Smckusick main(argc, argv)
6541488Smckusick 	char **argv;
6641488Smckusick {
6741488Smckusick 	int ac;
6841488Smckusick 	char **av;
6963811Shibler 	int from1, from2, from3, to;
7041488Smckusick 	register int n;
7163811Shibler 	char *n1, *n2, *n3, *lifname();
7241488Smckusick 
7341488Smckusick 	ac = --argc;
7441488Smckusick 	av = ++argv;
7541488Smckusick 	if (ac == 0)
7641488Smckusick 		usage();
7741488Smckusick 	if (!strcmp(av[0], "-l")) {
7841488Smckusick 		av++;
7941488Smckusick 		ac--;
8041488Smckusick 		if (ac == 0)
8141488Smckusick 			usage();
8241488Smckusick 		sscanf(av[0], "0x%x", &loadpoint);
8341488Smckusick 		lpflag++;
8441488Smckusick 		av++;
8541488Smckusick 		ac--;
8641488Smckusick 	}
8741488Smckusick 	if (ac == 0)
8841488Smckusick 		usage();
8941488Smckusick 	from1 = open(av[0], O_RDONLY, 0);
9041488Smckusick 	if (from1 < 0) {
9141488Smckusick 		perror("open");
9241488Smckusick 		exit(1);
9341488Smckusick 	}
9441488Smckusick 	n1 = av[0];
9541488Smckusick 	av++;
9641488Smckusick 	ac--;
9741488Smckusick 	if (ac == 0)
9841488Smckusick 		usage();
9963811Shibler 	if (ac > 1) {
10041488Smckusick 		from2 = open(av[0], O_RDONLY, 0);
10141488Smckusick 		if (from2 < 0) {
10241488Smckusick 			perror("open");
10341488Smckusick 			exit(1);
10441488Smckusick 		}
10541488Smckusick 		n2 = av[0];
10641488Smckusick 		av++;
10741488Smckusick 		ac--;
10863811Shibler 		if (ac > 1) {
10963811Shibler 			from3 = open(av[0], O_RDONLY, 0);
11063811Shibler 			if (from3 < 0) {
11163811Shibler 				perror("open");
11263811Shibler 				exit(1);
11363811Shibler 			}
11463811Shibler 			n3 = av[0];
11563811Shibler 			av++;
11663811Shibler 			ac--;
11763811Shibler 		} else
11863811Shibler 			from3 = -1;
11941488Smckusick 	} else
12063811Shibler 		from2 = from3 = -1;
12141488Smckusick 	to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
12241488Smckusick 	if (to < 0) {
12341488Smckusick 		perror("open");
12441488Smckusick 		exit(1);
12541488Smckusick 	}
12641488Smckusick 	/* clear possibly unused directory entries */
12741488Smckusick 	strncpy(lifd[1].dir_name, "          ", 10);
12841488Smckusick 	lifd[1].dir_type = -1;
12941488Smckusick 	lifd[1].dir_addr = 0;
13041488Smckusick 	lifd[1].dir_length = 0;
13141488Smckusick 	lifd[1].dir_flag = 0xFF;
13241488Smckusick 	lifd[1].dir_exec = 0;
13341488Smckusick 	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
13441488Smckusick 	/* record volume info */
13541488Smckusick 	lifv.vol_id = VOL_ID;
13641488Smckusick 	strncpy(lifv.vol_label, "BOOT43", 6);
13757299Shibler 	lifv.vol_addr = btolifs(LIF_DIRSTART);
13841488Smckusick 	lifv.vol_oct = VOL_OCT;
13957299Shibler 	lifv.vol_dirsize = btolifs(LIF_DIRSIZE);
14041488Smckusick 	lifv.vol_version = 1;
14141488Smckusick 	/* output bootfile one */
14257299Shibler 	lseek(to, LIF_FILESTART, 0);
14341488Smckusick 	putfile(from1, to);
14457299Shibler 	n = btolifs(ld.count + sizeof(ld));
14541488Smckusick 	strcpy(lifd[0].dir_name, lifname(n1));
14641488Smckusick 	lifd[0].dir_type = DIR_TYPE;
14757299Shibler 	lifd[0].dir_addr = btolifs(LIF_FILESTART);
14841488Smckusick 	lifd[0].dir_length = n;
14954073Shibler 	bcddate(from1, lifd[0].dir_toc);
15041488Smckusick 	lifd[0].dir_flag = DIR_FLAG;
15141488Smckusick 	lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
15241488Smckusick 	lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length;
15341488Smckusick 	/* if there is an optional second boot program, output it */
15441488Smckusick 	if (from2 >= 0) {
15557299Shibler 		lseek(to, LIF_FILESTART+lifstob(n), 0);
15641488Smckusick 		putfile(from2, to);
15757299Shibler 		n = btolifs(ld.count + sizeof(ld));
15841488Smckusick 		strcpy(lifd[1].dir_name, lifname(n2));
15941488Smckusick 		lifd[1].dir_type = DIR_TYPE;
16057299Shibler 		lifd[1].dir_addr = lifv.vol_length;
16141488Smckusick 		lifd[1].dir_length = n;
16254073Shibler 		bcddate(from2, lifd[1].dir_toc);
16341488Smckusick 		lifd[1].dir_flag = DIR_FLAG;
16441488Smckusick 		lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
16541488Smckusick 		lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length;
16641488Smckusick 	}
16763811Shibler 	/* ditto for three */
16863811Shibler 	if (from3 >= 0) {
16963811Shibler 		lseek(to, LIF_FILESTART+lifstob(lifd[0].dir_length+n), 0);
17063811Shibler 		putfile(from3, to);
17163811Shibler 		n = btolifs(ld.count + sizeof(ld));
17263811Shibler 		strcpy(lifd[2].dir_name, lifname(n3));
17363811Shibler 		lifd[2].dir_type = DIR_TYPE;
17463811Shibler 		lifd[2].dir_addr = lifv.vol_length;
17563811Shibler 		lifd[2].dir_length = n;
17663811Shibler 		bcddate(from3, lifd[2].dir_toc);
17763811Shibler 		lifd[2].dir_flag = DIR_FLAG;
17863811Shibler 		lifd[2].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
17963811Shibler 		lifv.vol_length = lifd[2].dir_addr + lifd[2].dir_length;
18063811Shibler 	}
18141488Smckusick 	/* output volume/directory header info */
18257299Shibler 	lseek(to, LIF_VOLSTART, 0);
18357299Shibler 	write(to, &lifv, LIF_VOLSIZE);
18457299Shibler 	lseek(to, LIF_DIRSTART, 0);
18557299Shibler 	write(to, lifd, LIF_DIRSIZE);
18641488Smckusick 	exit(0);
18741488Smckusick }
18841488Smckusick 
putfile(from,to)18941488Smckusick putfile(from, to)
19041488Smckusick {
19141488Smckusick 	register int n, tcnt, dcnt;
19241488Smckusick 
19341488Smckusick 	n = read(from, &ex, sizeof(ex));
19441488Smckusick 	if (n != sizeof(ex)) {
19541488Smckusick 		fprintf(stderr, "error reading file header\n");
19641488Smckusick 		exit(1);
19741488Smckusick 	}
19841488Smckusick 	if (ex.a_magic == OMAGIC) {
19941488Smckusick 		tcnt = ex.a_text;
20041488Smckusick 		dcnt = ex.a_data;
20141488Smckusick 	}
20241488Smckusick 	else if (ex.a_magic == NMAGIC) {
20341488Smckusick 		tcnt = (ex.a_text + PGOFSET) & ~PGOFSET;
20441488Smckusick 		dcnt = ex.a_data;
20541488Smckusick 	}
20641488Smckusick 	else {
20741488Smckusick 		fprintf(stderr, "bad magic number\n");
20841488Smckusick 		exit(1);
20941488Smckusick 	}
21041488Smckusick 	ld.address = lpflag ? loadpoint : ex.a_entry;
21141488Smckusick 	ld.count = tcnt + dcnt;
21241488Smckusick 	write(to, &ld, sizeof(ld));
21341488Smckusick 	while (tcnt) {
21441488Smckusick 		n = sizeof(buf);
21541488Smckusick 		if (n > tcnt)
21641488Smckusick 			n = tcnt;
21741488Smckusick 		n = read(from, buf, n);
21841488Smckusick 		if (n < 0) {
21941488Smckusick 			perror("read");
22041488Smckusick 			exit(1);
22141488Smckusick 		}
22241488Smckusick 		if (n == 0) {
22341488Smckusick 			fprintf(stderr, "short read\n");
22441488Smckusick 			exit(1);
22541488Smckusick 		}
22641488Smckusick 		if (write(to, buf, n) < 0) {
22741488Smckusick 			perror("write");
22841488Smckusick 			exit(1);
22941488Smckusick 		}
23041488Smckusick 		tcnt -= n;
23141488Smckusick 	}
23241488Smckusick 	while (dcnt) {
23341488Smckusick 		n = sizeof(buf);
23441488Smckusick 		if (n > dcnt)
23541488Smckusick 			n = dcnt;
23641488Smckusick 		n = read(from, buf, n);
23741488Smckusick 		if (n < 0) {
23841488Smckusick 			perror("read");
23941488Smckusick 			exit(1);
24041488Smckusick 		}
24141488Smckusick 		if (n == 0) {
24241488Smckusick 			fprintf(stderr, "short read\n");
24341488Smckusick 			exit(1);
24441488Smckusick 		}
24541488Smckusick 		if (write(to, buf, n) < 0) {
24641488Smckusick 			perror("write");
24741488Smckusick 			exit(1);
24841488Smckusick 		}
24941488Smckusick 		dcnt -= n;
25041488Smckusick 	}
25141488Smckusick }
25241488Smckusick 
usage()25341488Smckusick usage()
25441488Smckusick {
25541488Smckusick 	fprintf(stderr,
25641488Smckusick 		"usage:  mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n");
25741488Smckusick 	exit(1);
25841488Smckusick }
25941488Smckusick 
26041488Smckusick char *
lifname(str)26141488Smckusick lifname(str)
26241488Smckusick  char *str;
26341488Smckusick {
26441488Smckusick 	static char lname[10] = "SYS_XXXXX";
26541488Smckusick 	register int i;
26641488Smckusick 
26741488Smckusick 	for (i = 4; i < 9; i++) {
26841488Smckusick 		if (islower(*str))
26941488Smckusick 			lname[i] = toupper(*str);
27041488Smckusick 		else if (isalnum(*str) || *str == '_')
27141488Smckusick 			lname[i] = *str;
27241488Smckusick 		else
27341488Smckusick 			break;
27441488Smckusick 		str++;
27541488Smckusick 	}
27641488Smckusick 	for ( ; i < 10; i++)
27741488Smckusick 		lname[i] = '\0';
27841488Smckusick 	return(lname);
27941488Smckusick }
28054073Shibler 
28156510Sbostic #include <sys/stat.h>
28256510Sbostic #include <time.h>	/* XXX */
28354073Shibler 
bcddate(fd,toc)28454073Shibler bcddate(fd, toc)
28554073Shibler 	int fd;
28654073Shibler 	char *toc;
28754073Shibler {
28854073Shibler 	struct stat statb;
28954073Shibler 	struct tm *tm;
29054073Shibler 
29154073Shibler 	fstat(fd, &statb);
29254073Shibler 	tm = localtime(&statb.st_ctime);
29354073Shibler 	*toc = ((tm->tm_mon+1) / 10) << 4;
29454073Shibler 	*toc++ |= (tm->tm_mon+1) % 10;
29554073Shibler 	*toc = (tm->tm_mday / 10) << 4;
29654073Shibler 	*toc++ |= tm->tm_mday % 10;
29754073Shibler 	*toc = (tm->tm_year / 10) << 4;
29854073Shibler 	*toc++ |= tm->tm_year % 10;
29954073Shibler 	*toc = (tm->tm_hour / 10) << 4;
30054073Shibler 	*toc++ |= tm->tm_hour % 10;
30154073Shibler 	*toc = (tm->tm_min / 10) << 4;
30254073Shibler 	*toc++ |= tm->tm_min % 10;
30354073Shibler 	*toc = (tm->tm_sec / 10) << 4;
30454073Shibler 	*toc |= tm->tm_sec % 10;
30554073Shibler }
306