xref: /csrg-svn/sys/pmax/stand/mkboottape.c (revision 53090)
1*53090Sbostic /*-
2*53090Sbostic  * Copyright (c) 1992 The Regents of the University of California.
3*53090Sbostic  * All rights reserved.
4*53090Sbostic  *
5*53090Sbostic  * This code is derived from software contributed to Berkeley by
6*53090Sbostic  * Ralph Campbell.
7*53090Sbostic  *
8*53090Sbostic  * %sccs.include.redist.c%
9*53090Sbostic  *
10*53090Sbostic  *	@(#)mkboottape.c	7.1 (Berkeley) 03/30/92
11*53090Sbostic  */
12*53090Sbostic 
13*53090Sbostic #include <stdio.h>
14*53090Sbostic #include <sys/param.h>
15*53090Sbostic #include <sys/exec.h>
16*53090Sbostic #include "../dev/devDiskLabel.h"
17*53090Sbostic 
18*53090Sbostic char	block[DEV_BSIZE];
19*53090Sbostic char	*tapedev, *rootdev, *bootfname;
20*53090Sbostic 
21*53090Sbostic /*
22*53090Sbostic  * This program takes a kernel and the name of the special device file that
23*53090Sbostic  * has the mini-root file system stored on it and creates a boot tape.
24*53090Sbostic  * The -b option makes a bootfile that can load the kernel and mini-root
25*53090Sbostic  * over the network using the 'boot 6/tftp/filename -m' PROM command.
26*53090Sbostic  *
27*53090Sbostic  * usage: mkboottape [-b] tapedev vmunix minirootdev size
28*53090Sbostic  */
29*53090Sbostic main(argc, argv)
30*53090Sbostic 	int argc;
31*53090Sbostic 	char *argv[];
32*53090Sbostic {
33*53090Sbostic 	register int i, n;
34*53090Sbostic 	int ifd, ofd, rfd;
35*53090Sbostic 	Dec_DiskBoot decBootInfo;
36*53090Sbostic 	ProcSectionHeader shdr;
37*53090Sbostic 	struct exec aout;
38*53090Sbostic 	int nsectors;
39*53090Sbostic 	long loadAddr;
40*53090Sbostic 	long execAddr;
41*53090Sbostic 	long textoff;
42*53090Sbostic 	long length;
43*53090Sbostic 	long rootsize;
44*53090Sbostic 	int makebootfile = 0;
45*53090Sbostic 
46*53090Sbostic 	if (argc > 1 && strcmp(argv[1], "-b") == 0) {
47*53090Sbostic 		argc--;
48*53090Sbostic 		argv++;
49*53090Sbostic 		makebootfile = 1;
50*53090Sbostic 	}
51*53090Sbostic 	if (argc != 5)
52*53090Sbostic 		usage();
53*53090Sbostic 	tapedev = argv[1];
54*53090Sbostic 	bootfname = argv[2];
55*53090Sbostic 	rootdev = argv[3];
56*53090Sbostic 	rootsize = atoi(argv[4]);
57*53090Sbostic 	ifd = open(bootfname, 0, 0);
58*53090Sbostic 	if (ifd < 0) {
59*53090Sbostic 	bootferr:
60*53090Sbostic 		perror(bootfname);
61*53090Sbostic 		exit(1);
62*53090Sbostic 	}
63*53090Sbostic 	rfd = open(rootdev, 0, 0);
64*53090Sbostic 	if (rfd < 0) {
65*53090Sbostic 		perror(rootdev);
66*53090Sbostic 		exit(1);
67*53090Sbostic 	}
68*53090Sbostic 	if (makebootfile)
69*53090Sbostic 		ofd = creat(tapedev, 0666);
70*53090Sbostic 	else
71*53090Sbostic 		ofd = open(tapedev, 2, 0);
72*53090Sbostic 	if (ofd < 0) {
73*53090Sbostic 	deverr:
74*53090Sbostic 		perror(tapedev);
75*53090Sbostic 		exit(1);
76*53090Sbostic 	}
77*53090Sbostic 
78*53090Sbostic 	/*
79*53090Sbostic 	 * Check for exec header and skip to code segment.
80*53090Sbostic 	 */
81*53090Sbostic 	i = read(ifd, (char *)&aout, sizeof(aout));
82*53090Sbostic 	if (i != sizeof(aout) || aout.ex_fhdr.magic != COFF_MAGIC ||
83*53090Sbostic 	    aout.a_magic != OMAGIC) {
84*53090Sbostic 		fprintf(stderr, "Need impure text format (OMAGIC) file\n");
85*53090Sbostic 		exit(1);
86*53090Sbostic 	}
87*53090Sbostic 	loadAddr = aout.ex_aout.codeStart;
88*53090Sbostic 	execAddr = aout.a_entry;
89*53090Sbostic 	length = aout.a_text + aout.a_data;
90*53090Sbostic 	textoff = N_TXTOFF(aout);
91*53090Sbostic 	printf("Input file is COFF format\n");
92*53090Sbostic 	printf("load %x, start %x, len %d\n", loadAddr, execAddr, length);
93*53090Sbostic 
94*53090Sbostic 	/*
95*53090Sbostic 	 * Compute size of boot program rounded to page size + mini-root size.
96*53090Sbostic 	 */
97*53090Sbostic 	nsectors = (((length + aout.a_bss + NBPG - 1) & ~(NBPG - 1)) >>
98*53090Sbostic 		DEV_BSHIFT) + rootsize;
99*53090Sbostic 
100*53090Sbostic 	if (makebootfile) {
101*53090Sbostic 		/*
102*53090Sbostic 		 * Write modified ECOFF header.
103*53090Sbostic 		 */
104*53090Sbostic 		aout.ex_fhdr.numSections = 1;
105*53090Sbostic 		aout.ex_fhdr.numSyms = 0;
106*53090Sbostic 		aout.ex_fhdr.symPtr = 0;
107*53090Sbostic 		aout.a_text = nsectors << DEV_BSHIFT;
108*53090Sbostic 		aout.a_data = 0;
109*53090Sbostic 		aout.a_bss = 0;
110*53090Sbostic 		aout.ex_aout.heapStart = aout.ex_aout.bssStart =
111*53090Sbostic 			aout.ex_aout.codeStart + aout.a_text;
112*53090Sbostic 		if (write(ofd, (char *)&aout, sizeof(aout)) != sizeof(aout))
113*53090Sbostic 			goto deverr;
114*53090Sbostic 		strncpy(shdr.name, ".text", sizeof(shdr.name));
115*53090Sbostic 		shdr.physAddr = shdr.virtAddr = loadAddr;
116*53090Sbostic 		shdr.size = aout.a_text;
117*53090Sbostic 		shdr.sectionPtr = n = (sizeof(aout) + sizeof(shdr) + 15) & ~15;
118*53090Sbostic 		shdr.relocPtr = 0;
119*53090Sbostic 		shdr.lnnoPtr = 0;
120*53090Sbostic 		shdr.numReloc = 0;
121*53090Sbostic 		shdr.numLnno = 0;
122*53090Sbostic 		shdr.flags = 0x20;
123*53090Sbostic 		if (write(ofd, (char *)&shdr, sizeof(shdr)) != sizeof(shdr))
124*53090Sbostic 			goto deverr;
125*53090Sbostic 		n -= sizeof(aout) + sizeof(shdr);
126*53090Sbostic 		if (write(ofd, block, n) != n)
127*53090Sbostic 			goto deverr;
128*53090Sbostic 	} else {
129*53090Sbostic 		/*
130*53090Sbostic 		 * Write the boot information block.
131*53090Sbostic 		 */
132*53090Sbostic 		decBootInfo.magic = DEC_BOOT_MAGIC;
133*53090Sbostic 		decBootInfo.mode = 0;
134*53090Sbostic 		decBootInfo.loadAddr = loadAddr;
135*53090Sbostic 		decBootInfo.execAddr = execAddr;
136*53090Sbostic 		decBootInfo.map[0].numBlocks = nsectors;
137*53090Sbostic 		decBootInfo.map[0].startBlock = 1;
138*53090Sbostic 		decBootInfo.map[1].numBlocks = 0;
139*53090Sbostic 		if (write(ofd, (char *)&decBootInfo, sizeof(decBootInfo)) !=
140*53090Sbostic 		    sizeof(decBootInfo))
141*53090Sbostic 			goto deverr;
142*53090Sbostic 	}
143*53090Sbostic 	/* seek to start of text */
144*53090Sbostic 	if (lseek(ifd, textoff, 0) < 0)
145*53090Sbostic 		goto bootferr;
146*53090Sbostic 
147*53090Sbostic 	/*
148*53090Sbostic 	 * Write the remaining code to the correct place on the tape.
149*53090Sbostic 	 */
150*53090Sbostic 	i = length;
151*53090Sbostic 	while (i > 0) {
152*53090Sbostic 		n = DEV_BSIZE;
153*53090Sbostic 		if (n > i)
154*53090Sbostic 			n = i;
155*53090Sbostic 		if (read(ifd, block, n) != n)
156*53090Sbostic 			goto bootferr;
157*53090Sbostic 		if (write(ofd, block, n) != n)
158*53090Sbostic 			goto deverr;
159*53090Sbostic 		i -= n;
160*53090Sbostic 	}
161*53090Sbostic 
162*53090Sbostic 	/*
163*53090Sbostic 	 * Pad the boot file with zeros to the start of the mini-root.
164*53090Sbostic 	 */
165*53090Sbostic 	bzero(block, DEV_BSIZE);
166*53090Sbostic 	i = ((nsectors - rootsize) << DEV_BSHIFT) - length;
167*53090Sbostic 	while (i > 0) {
168*53090Sbostic 		n = DEV_BSIZE;
169*53090Sbostic 		if (n > i)
170*53090Sbostic 			n = i;
171*53090Sbostic 		if (write(ofd, block, n) != n)
172*53090Sbostic 			goto deverr;
173*53090Sbostic 		i -= n;
174*53090Sbostic 	}
175*53090Sbostic 
176*53090Sbostic 	/*
177*53090Sbostic 	 * Write the mini-root to tape.
178*53090Sbostic 	 */
179*53090Sbostic 	i = rootsize;
180*53090Sbostic 	while (i > 0) {
181*53090Sbostic 		if (read(rfd, block, DEV_BSIZE) != DEV_BSIZE) {
182*53090Sbostic 			perror(rootdev);
183*53090Sbostic 			break;
184*53090Sbostic 		}
185*53090Sbostic 		if (write(ofd, block, DEV_BSIZE) != DEV_BSIZE)
186*53090Sbostic 			goto deverr;
187*53090Sbostic 		i--;
188*53090Sbostic 	}
189*53090Sbostic 
190*53090Sbostic 	printf("Wrote %d sectors\n", nsectors);
191*53090Sbostic 	exit(0);
192*53090Sbostic }
193*53090Sbostic 
194*53090Sbostic usage()
195*53090Sbostic {
196*53090Sbostic 	printf("Usage: mkboottape [-b] tapedev vmunix minirootdev size\n");
197*53090Sbostic 	printf("where:\n");
198*53090Sbostic 	printf("\t\"tapedev\" is the tape drive device\n");
199*53090Sbostic 	printf("\t\"vmunix\" is a -N format file\n");
200*53090Sbostic 	printf("\t\"minitrootdev\" is the character device of a mini-root file system disk\n");
201*53090Sbostic 	printf("\t\"size\" is the number of 512 byte blocks in the file system\n");
202*53090Sbostic 	exit(1);
203*53090Sbostic }
204