1 /* $NetBSD: mkbootimage.c,v 1.6 2002/05/14 06:34:20 lukem Exp $ */
4 * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Christopher G. Demetriou
17 * for the NetBSD Project.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/param.h> /* XXX for roundup, howmany */
35 #include <sys/bootblock.h>
36 #include <sys/disklabel.h>
45 static void usage(void);
51 "usage: %s [-n] [-v] inputfile [outputfile]\n", getprogname());
56 main(int argc
, char **argv
)
59 struct alpha_boot_block
*bb
;
60 const char *infile
, *outfile
;
64 int c
, verbose
, nowrite
, infd
, outfd
;
66 verbose
= nowrite
= 0;
68 while ((c
= getopt(argc
, argv
, "nv")) != -1) {
71 /* Do not actually write the boot file */
86 if (argc
!= 1 && argc
!= 2)
90 outfile
= argv
[1]; /* NULL if argc == 1 */
93 fprintf(stderr
, "input file: %s\n", infile
);
94 fprintf(stderr
, "output file: %s\n",
95 outfile
!= NULL
? outfile
: "<stdout>");
97 if (sizeof (struct alpha_boot_block
) != ALPHA_BOOT_BLOCK_BLOCKSIZE
)
99 "alpha_boot_block structure badly sized (build error)");
101 /* Open the input file and check it out */
102 if ((infd
= open(infile
, O_RDONLY
)) == -1)
103 err(EXIT_FAILURE
, "open %s", infile
);
104 if (fstat(infd
, &insb
) == -1)
105 err(EXIT_FAILURE
, "fstat %s", infile
);
106 if (!S_ISREG(insb
.st_mode
))
107 errx(EXIT_FAILURE
, "%s must be a regular file", infile
);
110 * Allocate a buffer, with space to round up the input file
111 * to the next block size boundary, and with space for the boot
114 outbufsize
= roundup(insb
.st_size
, ALPHA_BOOT_BLOCK_BLOCKSIZE
);
115 outbufsize
+= sizeof (struct alpha_boot_block
);
117 outbuf
= malloc(outbufsize
);
119 err(EXIT_FAILURE
, "allocating output buffer");
120 memset(outbuf
, 0, outbufsize
);
122 /* read the file into the buffer, leaving room for the boot block */
123 rv
= read(infd
, outbuf
+ sizeof (struct alpha_boot_block
),
126 err(EXIT_FAILURE
, "read %s", infile
);
127 else if (rv
!= insb
.st_size
)
128 errx(EXIT_FAILURE
, "read %s: short read", infile
);
131 /* fill in the boot block fields, and checksum the boot block */
132 bb
= (struct alpha_boot_block
*)outbuf
;
133 bb
->bb_secsize
= howmany(insb
.st_size
, ALPHA_BOOT_BLOCK_BLOCKSIZE
);
136 ALPHA_BOOT_BLOCK_CKSUM(bb
, &bb
->bb_cksum
);
139 fprintf(stderr
, "starting sector: %qu\n",
140 (unsigned long long)bb
->bb_secstart
);
141 fprintf(stderr
, "sector count: %qu\n",
142 (unsigned long long)bb
->bb_secsize
);
143 fprintf(stderr
, "checksum: %#qx\n",
144 (unsigned long long)bb
->bb_cksum
);
150 /* set up the output file descriptor */
151 if (outfile
== NULL
) {
152 outfd
= STDOUT_FILENO
;
153 outfile
= "<stdout>";
154 } else if ((outfd
= open(outfile
, O_WRONLY
|O_CREAT
, 0666)) == -1)
155 err(EXIT_FAILURE
, "open %s", outfile
);
158 rv
= write(outfd
, outbuf
, outbufsize
);
160 err(EXIT_FAILURE
, "write %s", outfile
);
161 else if (rv
!= outbufsize
)
162 errx(EXIT_FAILURE
, "write %s: short write", outfile
);