Home | History | Annotate | Line # | Download | only in mkboot
mkboot.c revision 1.2.2.1
      1  1.2.2.1  nathanw /*	$NetBSD: mkboot.c,v 1.2.2.1 2001/06/21 19:22:13 nathanw Exp $
      2      1.1  thorpej 
      3      1.1  thorpej /*
      4      1.1  thorpej  * Copyright (c) 1990, 1993
      5      1.1  thorpej  *	The Regents of the University of California.  All rights reserved.
      6      1.1  thorpej  *
      7      1.1  thorpej  * Redistribution and use in source and binary forms, with or without
      8      1.1  thorpej  * modification, are permitted provided that the following conditions
      9      1.1  thorpej  * are met:
     10      1.1  thorpej  * 1. Redistributions of source code must retain the above copyright
     11      1.1  thorpej  *    notice, this list of conditions and the following disclaimer.
     12      1.1  thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  thorpej  *    notice, this list of conditions and the following disclaimer in the
     14      1.1  thorpej  *    documentation and/or other materials provided with the distribution.
     15      1.1  thorpej  * 3. All advertising materials mentioning features or use of this software
     16      1.1  thorpej  *    must display the following acknowledgement:
     17      1.1  thorpej  *	This product includes software developed by the University of
     18      1.1  thorpej  *	California, Berkeley and its contributors.
     19      1.1  thorpej  * 4. Neither the name of the University nor the names of its contributors
     20      1.1  thorpej  *    may be used to endorse or promote products derived from this software
     21      1.1  thorpej  *    without specific prior written permission.
     22      1.1  thorpej  *
     23      1.1  thorpej  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24      1.1  thorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25      1.1  thorpej  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26      1.1  thorpej  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27      1.1  thorpej  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28      1.1  thorpej  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29      1.1  thorpej  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30      1.1  thorpej  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31      1.1  thorpej  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32      1.1  thorpej  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33      1.1  thorpej  * SUCH DAMAGE.
     34      1.1  thorpej  *
     35      1.1  thorpej  *	@(#)mkboot.c	8.1 (Berkeley) 7/15/93
     36      1.1  thorpej  */
     37      1.1  thorpej 
     38      1.2   simonb #include <sys/cdefs.h>
     39      1.2   simonb 
     40      1.1  thorpej #ifndef lint
     41      1.2   simonb __COPYRIGHT(
     42      1.1  thorpej "@(#) Copyright (c) 1990, 1993\n\
     43      1.2   simonb 	The Regents of the University of California.  All rights reserved.\n");
     44      1.1  thorpej #endif /* not lint */
     45      1.1  thorpej 
     46      1.1  thorpej #ifndef lint
     47      1.1  thorpej #ifdef notdef
     48      1.1  thorpej static char sccsid[] = "@(#)mkboot.c	7.2 (Berkeley) 12/16/90";
     49      1.1  thorpej #endif
     50  1.2.2.1  nathanw __RCSID("$NetBSD: mkboot.c,v 1.2.2.1 2001/06/21 19:22:13 nathanw Exp $");
     51      1.1  thorpej #endif /* not lint */
     52      1.1  thorpej 
     53      1.1  thorpej #include <sys/param.h>
     54      1.1  thorpej #include <sys/file.h>
     55      1.2   simonb #include <sys/stat.h>
     56  1.2.2.1  nathanw #include <sys/endian.h>
     57      1.2   simonb 
     58      1.2   simonb #include <ctype.h>
     59      1.2   simonb #include <stdio.h>
     60      1.2   simonb #include <stdlib.h>
     61      1.2   simonb #include <string.h>
     62      1.2   simonb #include <unistd.h>
     63      1.1  thorpej 
     64      1.1  thorpej #include "volhdr.h"
     65      1.1  thorpej 
     66      1.1  thorpej #define LIF_NUMDIR	8
     67      1.1  thorpej 
     68      1.1  thorpej #define LIF_VOLSTART	0
     69      1.1  thorpej #define LIF_VOLSIZE	sizeof(struct lifvol)
     70      1.1  thorpej #define LIF_DIRSTART	512
     71      1.1  thorpej #define LIF_DIRSIZE	(LIF_NUMDIR * sizeof(struct lifdir))
     72      1.1  thorpej #define LIF_FILESTART	8192
     73      1.1  thorpej 
     74      1.1  thorpej #define btolifs(b)	(((b) + (SECTSIZE - 1)) / SECTSIZE)
     75      1.1  thorpej #define lifstob(s)	((s) * SECTSIZE)
     76      1.1  thorpej 
     77      1.2   simonb int	lpflag;
     78      1.2   simonb int	loadpoint;
     79  1.2.2.1  nathanw struct  load ld;
     80      1.2   simonb struct	lifvol lifv;
     81      1.2   simonb struct	lifdir lifd[LIF_NUMDIR];
     82      1.2   simonb 
     83      1.2   simonb int	 main(int, char **);
     84      1.2   simonb void	 bcddate(char *, char *);
     85      1.2   simonb char	*lifname(char *);
     86  1.2.2.1  nathanw int	 putfile(char *, int);
     87      1.2   simonb void	 usage(void);
     88      1.1  thorpej 
     89      1.1  thorpej /*
     90      1.1  thorpej  * Old Format:
     91      1.1  thorpej  *	sector 0:	LIF volume header (40 bytes)
     92      1.1  thorpej  *	sector 1:	<unused>
     93      1.1  thorpej  *	sector 2:	LIF directory (8 x 32 == 256 bytes)
     94      1.1  thorpej  *	sector 3-:	LIF file 0, LIF file 1, etc.
     95      1.1  thorpej  * where sectors are 256 bytes.
     96      1.1  thorpej  *
     97      1.1  thorpej  * New Format:
     98      1.1  thorpej  *	sector 0:	LIF volume header (40 bytes)
     99      1.1  thorpej  *	sector 1:	<unused>
    100      1.1  thorpej  *	sector 2:	LIF directory (8 x 32 == 256 bytes)
    101      1.1  thorpej  *	sector 3:	<unused>
    102      1.1  thorpej  *	sector 4-31:	disklabel (~300 bytes right now)
    103      1.1  thorpej  *	sector 32-:	LIF file 0, LIF file 1, etc.
    104      1.1  thorpej  */
    105      1.2   simonb int
    106      1.2   simonb main(int argc, char **argv)
    107      1.1  thorpej {
    108      1.2   simonb 	char *n1, *n2, *n3;
    109      1.2   simonb 	int n, to;
    110  1.2.2.1  nathanw 	int count;
    111      1.2   simonb 
    112      1.2   simonb 	--argc;
    113      1.2   simonb 	++argv;
    114      1.2   simonb 	if (argc == 0)
    115      1.1  thorpej 		usage();
    116      1.2   simonb 	if (!strcmp(argv[0], "-l")) {
    117      1.2   simonb 		argv++;
    118      1.2   simonb 		argc--;
    119      1.2   simonb 		if (argc == 0)
    120      1.1  thorpej 			usage();
    121      1.2   simonb 		sscanf(argv[0], "0x%x", &loadpoint);
    122      1.1  thorpej 		lpflag++;
    123      1.2   simonb 		argv++;
    124      1.2   simonb 		argc--;
    125      1.1  thorpej 	}
    126  1.2.2.1  nathanw 	if (!lpflag || argc == 0)
    127      1.1  thorpej 		usage();
    128      1.2   simonb 	n1 = argv[0];
    129      1.2   simonb 	argv++;
    130      1.2   simonb 	argc--;
    131      1.2   simonb 	if (argc == 0)
    132      1.1  thorpej 		usage();
    133      1.2   simonb 	if (argc > 1) {
    134      1.2   simonb 		n2 = argv[0];
    135      1.2   simonb 		argv++;
    136      1.2   simonb 		argc--;
    137      1.2   simonb 		if (argc > 1) {
    138      1.2   simonb 			n3 = argv[0];
    139      1.2   simonb 			argv++;
    140      1.2   simonb 			argc--;
    141      1.1  thorpej 		} else
    142      1.2   simonb 			n3 = NULL;
    143      1.1  thorpej 	} else
    144      1.2   simonb 		n2 = n3 = NULL;
    145  1.2.2.1  nathanw 
    146      1.2   simonb 	to = open(argv[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
    147      1.1  thorpej 	if (to < 0) {
    148      1.1  thorpej 		perror("open");
    149      1.1  thorpej 		exit(1);
    150      1.1  thorpej 	}
    151      1.1  thorpej 	/* clear possibly unused directory entries */
    152  1.2.2.1  nathanw 	strncpy(lifd[1].dir_name, "          ", 10);
    153  1.2.2.1  nathanw 	lifd[1].dir_type = htobe16(-1);
    154  1.2.2.1  nathanw 	lifd[1].dir_addr = htobe32(0);
    155  1.2.2.1  nathanw 	lifd[1].dir_length = htobe32(0);
    156  1.2.2.1  nathanw 	lifd[1].dir_flag = htobe16(0xFF);
    157  1.2.2.1  nathanw 	lifd[1].dir_exec = htobe32(0);
    158      1.1  thorpej 	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
    159      1.1  thorpej 	/* record volume info */
    160  1.2.2.1  nathanw 	lifv.vol_id = htobe16(VOL_ID);
    161      1.1  thorpej 	strncpy(lifv.vol_label, "BOOT43", 6);
    162  1.2.2.1  nathanw 	lifv.vol_addr = htobe32(btolifs(LIF_DIRSTART));
    163  1.2.2.1  nathanw 	lifv.vol_oct = htobe16(VOL_OCT);
    164  1.2.2.1  nathanw 	lifv.vol_dirsize = htobe32(btolifs(LIF_DIRSIZE));
    165  1.2.2.1  nathanw 	lifv.vol_version = htobe16(1);
    166      1.1  thorpej 	/* output bootfile one */
    167      1.2   simonb 	lseek(to, LIF_FILESTART, SEEK_SET);
    168  1.2.2.1  nathanw 	count = putfile(n1, to);
    169  1.2.2.1  nathanw 	n = btolifs(count);
    170      1.1  thorpej 	strcpy(lifd[0].dir_name, lifname(n1));
    171  1.2.2.1  nathanw 	lifd[0].dir_type = htobe16(DIR_TYPE);
    172  1.2.2.1  nathanw 	lifd[0].dir_addr = htobe32(btolifs(LIF_FILESTART));
    173  1.2.2.1  nathanw 	lifd[0].dir_length = htobe32(n);
    174      1.2   simonb 	bcddate(n1, lifd[0].dir_toc);
    175  1.2.2.1  nathanw 	lifd[0].dir_flag = htobe16(DIR_FLAG);
    176  1.2.2.1  nathanw 	lifd[0].dir_exec = htobe32(loadpoint);
    177  1.2.2.1  nathanw 	lifv.vol_length = htobe32(be32toh(lifd[0].dir_addr) +
    178  1.2.2.1  nathanw 				  be32toh(lifd[0].dir_length));
    179      1.1  thorpej 	/* if there is an optional second boot program, output it */
    180      1.2   simonb 	if (n2) {
    181      1.2   simonb 		lseek(to, LIF_FILESTART+lifstob(n), SEEK_SET);
    182  1.2.2.1  nathanw 		count = putfile(n2, to);
    183  1.2.2.1  nathanw 		n = btolifs(count);
    184      1.1  thorpej 		strcpy(lifd[1].dir_name, lifname(n2));
    185  1.2.2.1  nathanw 		lifd[1].dir_type = htobe16(DIR_TYPE);
    186  1.2.2.1  nathanw 		lifd[1].dir_addr = htobe32(lifv.vol_length);
    187  1.2.2.1  nathanw 		lifd[1].dir_length = htobe32(n);
    188      1.2   simonb 		bcddate(n2, lifd[1].dir_toc);
    189  1.2.2.1  nathanw 		lifd[1].dir_flag = htobe32(DIR_FLAG);
    190  1.2.2.1  nathanw 		lifd[1].dir_exec = htobe32(loadpoint);
    191  1.2.2.1  nathanw 		lifv.vol_length = htobe32(be32toh(lifd[1].dir_addr) +
    192  1.2.2.1  nathanw 					  be32toh(lifd[1].dir_length));
    193      1.1  thorpej 	}
    194      1.1  thorpej 	/* ditto for three */
    195      1.2   simonb 	if (n3) {
    196  1.2.2.1  nathanw 		lseek(to, LIF_FILESTART+lifstob(lifd[0].dir_length+n),
    197  1.2.2.1  nathanw 		      SEEK_SET);
    198  1.2.2.1  nathanw 		count = putfile(n3, to);
    199  1.2.2.1  nathanw 		n = btolifs(count);
    200      1.1  thorpej 		strcpy(lifd[2].dir_name, lifname(n3));
    201  1.2.2.1  nathanw 		lifd[2].dir_type = htobe16(DIR_TYPE);
    202  1.2.2.1  nathanw 		lifd[2].dir_addr = htobe32(lifv.vol_length);
    203  1.2.2.1  nathanw 		lifd[2].dir_length = htobe32(n);
    204      1.2   simonb 		bcddate(n3, lifd[2].dir_toc);
    205  1.2.2.1  nathanw 		lifd[2].dir_flag = htobe32(DIR_FLAG);
    206  1.2.2.1  nathanw 		lifd[2].dir_exec = htobe32(loadpoint);
    207  1.2.2.1  nathanw 		lifv.vol_length = htobe32(be32toh(lifd[2].dir_addr) +
    208  1.2.2.1  nathanw 					  be32toh(lifd[2].dir_length));
    209      1.1  thorpej 	}
    210      1.1  thorpej 	/* output volume/directory header info */
    211      1.2   simonb 	lseek(to, LIF_VOLSTART, SEEK_SET);
    212      1.1  thorpej 	write(to, &lifv, LIF_VOLSIZE);
    213      1.2   simonb 	lseek(to, LIF_DIRSTART, SEEK_SET);
    214      1.1  thorpej 	write(to, lifd, LIF_DIRSIZE);
    215      1.1  thorpej 	exit(0);
    216      1.1  thorpej }
    217      1.1  thorpej 
    218  1.2.2.1  nathanw int
    219      1.1  thorpej putfile(from, to)
    220      1.2   simonb 	char *from;
    221      1.2   simonb 	int to;
    222      1.1  thorpej {
    223      1.2   simonb 	int fd;
    224  1.2.2.1  nathanw 	struct stat statb;
    225  1.2.2.1  nathanw 	int nr;
    226  1.2.2.1  nathanw 	void *bp;
    227  1.2.2.1  nathanw 
    228  1.2.2.1  nathanw 	if ((fd = open(from, 0)) < 0) {
    229  1.2.2.1  nathanw 	  printf("error: unable to open file %s\n", from);
    230  1.2.2.1  nathanw 	  exit(1);
    231  1.2.2.1  nathanw 	}
    232  1.2.2.1  nathanw 	fstat(fd, &statb);
    233  1.2.2.1  nathanw 	ld.address = htobe32(loadpoint);
    234  1.2.2.1  nathanw 	ld.count = htobe32(statb.st_size);
    235  1.2.2.1  nathanw 	bp = malloc(statb.st_size);
    236  1.2.2.1  nathanw 	if ((nr = read(fd, bp, statb.st_size)) < 0) {
    237  1.2.2.1  nathanw 	  printf("error: reading from file %s\n", from);
    238  1.2.2.1  nathanw 	  exit(1);
    239  1.2.2.1  nathanw 	}
    240      1.2   simonb 	(void)close(fd);
    241      1.1  thorpej 	write(to, &ld, sizeof(ld));
    242  1.2.2.1  nathanw 	write(to, bp, statb.st_size);
    243  1.2.2.1  nathanw 	free(bp);
    244  1.2.2.1  nathanw 	return (statb.st_size + sizeof(ld));
    245      1.1  thorpej }
    246      1.1  thorpej 
    247      1.2   simonb void
    248      1.2   simonb usage(void)
    249      1.1  thorpej {
    250      1.2   simonb 
    251      1.1  thorpej 	fprintf(stderr,
    252  1.2.2.1  nathanw 		"usage:	 mkboot -l loadpoint prog1 [ prog2 ] outfile\n");
    253      1.1  thorpej 	exit(1);
    254      1.1  thorpej }
    255      1.1  thorpej 
    256      1.1  thorpej char *
    257      1.2   simonb lifname(char *str)
    258      1.1  thorpej {
    259      1.1  thorpej 	static char lname[10] = "SYS_XXXXX";
    260      1.2   simonb 	char *cp;
    261      1.2   simonb 	int i;
    262      1.1  thorpej 
    263      1.2   simonb 	if ((cp = strrchr(str, '/')) != NULL)
    264      1.2   simonb 		str = ++cp;
    265      1.1  thorpej 	for (i = 4; i < 9; i++) {
    266      1.1  thorpej 		if (islower(*str))
    267      1.1  thorpej 			lname[i] = toupper(*str);
    268      1.1  thorpej 		else if (isalnum(*str) || *str == '_')
    269      1.1  thorpej 			lname[i] = *str;
    270      1.1  thorpej 		else
    271      1.1  thorpej 			break;
    272      1.1  thorpej 		str++;
    273      1.1  thorpej 	}
    274      1.1  thorpej 	for ( ; i < 10; i++)
    275      1.1  thorpej 		lname[i] = '\0';
    276      1.1  thorpej 	return(lname);
    277      1.1  thorpej }
    278      1.1  thorpej 
    279      1.2   simonb void
    280      1.2   simonb bcddate(char *name, char *toc)
    281      1.1  thorpej {
    282      1.1  thorpej 	struct stat statb;
    283      1.1  thorpej 	struct tm *tm;
    284      1.1  thorpej 
    285      1.2   simonb 	stat(name, &statb);
    286      1.1  thorpej 	tm = localtime(&statb.st_ctime);
    287      1.1  thorpej 	*toc = ((tm->tm_mon+1) / 10) << 4;
    288      1.1  thorpej 	*toc++ |= (tm->tm_mon+1) % 10;
    289      1.1  thorpej 	*toc = (tm->tm_mday / 10) << 4;
    290      1.1  thorpej 	*toc++ |= tm->tm_mday % 10;
    291      1.1  thorpej 	*toc = (tm->tm_year / 10) << 4;
    292      1.1  thorpej 	*toc++ |= tm->tm_year % 10;
    293      1.1  thorpej 	*toc = (tm->tm_hour / 10) << 4;
    294      1.1  thorpej 	*toc++ |= tm->tm_hour % 10;
    295      1.1  thorpej 	*toc = (tm->tm_min / 10) << 4;
    296      1.1  thorpej 	*toc++ |= tm->tm_min % 10;
    297      1.1  thorpej 	*toc = (tm->tm_sec / 10) << 4;
    298      1.1  thorpej 	*toc |= tm->tm_sec % 10;
    299      1.1  thorpej }
    300