[release] Update version to 0.9.5 for release
[gpxe.git] / contrib / mkQNXnbi / mkQNXnbi.c
blob2ec2dc4b1bfc54ac74f27d93dec167831747c253
1 //*****************************************************************************
2 //
3 // Purpose: Make a boot-image for EtherBoot
4 //
5 //
6 // Compiler: This source can be compiled with gcc and Watcom C
7 //
8 //
9 // Note: The QNX boot image can be build with any reasonable
10 // start address, e.g. 0x1000 (default) or 0x10000
11 // (widespread Boot-Rom address)
14 // Author: Anders Larsen
17 // Copyright: (C) 1999 by
19 // Anders Larsen
20 // systems engineer
21 // Gutleuthausstr. 3
22 // D-69469 Weinheim
23 // Germany
24 // phone: +49-6201-961717
25 // fax: +49-6201-961718
26 // e-mail: al@alarsen.net
28 // This program is free software; you can redistribute it and/or modify
29 // it under the terms of the GNU General Public License as published by
30 // the Free Software Foundation; either version 2 of the License, or
31 // (at your option) any later version.
33 // This program is distributed in the hope that it will be useful,
34 // but WITHOUT ANY WARRANTY; without even the implied warranty of
35 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 // GNU General Public License for more details.
38 // You should have received a copy of the GNU General Public License
39 // along with this program; if not, write to the Free Software
40 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42 //-----------------------------------------------------------------------------
44 // Change Log:
45 // V0.2: Sun 1999-12-13 Anders Larsen <al@alarsen.net>
46 //*****************************************************************************
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include <sys/types.h>
55 // max. size of QNX OS boot image is 512K
56 #define MAXSIZE (512*1024)
58 typedef unsigned short ushort_t;
59 typedef unsigned long ulong_t;
62 // global header of tagged image:
63 struct initial_t
65 ulong_t magic;
66 ulong_t length;
67 ulong_t location;
68 ulong_t start;
72 // header of each image:
73 struct header_t
75 ulong_t flags;
76 ulong_t loadaddr;
77 ulong_t imgsize;
78 ulong_t memsize;
82 // global header of the QNX EtherBoot image:
83 struct qnx_loader_t
85 struct initial_t setup;
86 struct header_t qnx;
90 // global header:
91 union
93 struct qnx_loader_t h;
94 char filler[512];
95 } header;
98 char buffer[MAXSIZE];
101 int usage( char* const* argv )
103 fprintf( stderr, "%s - make a tagged boot image for EtherBoot\n", *argv );
104 fprintf( stderr, "\nuse:\n" );
105 fprintf( stderr, "%s [ -<option> ]*\n", *argv );
106 fprintf( stderr, "\noptions:\n" );
107 fprintf( stderr, " i <input file> : QNX boot file (default: stdin)\n" );
108 fprintf( stderr, " o <output file> : tagged image file (default: stdout)\n" );
109 fprintf( stderr, " v : be verbose\n" );
110 return EXIT_FAILURE;
113 #ifdef __USAGE
114 %C - make a tagged boot image for EtherBoot
116 use:
117 %C [ -<option> ]*
119 options:
120 i <input file> : QNX boot file (default: stdin)
121 o <output file> : tagged image file (default: stdout)
122 v : be verbose
123 #endif
126 int main( int argc, char* const* argv )
128 int ch, l;
129 int verbose = 0;
131 while ( ( ch = getopt( argc, argv, "hi:o:v" ) ) != EOF )
132 switch ( ch )
134 case 'i':
135 if ( !freopen( optarg, "r", stdin ) )
137 perror( "can't open input file" );
138 return EXIT_FAILURE;
140 break;
142 case 'o':
143 if ( !freopen( optarg, "w", stdout ) )
145 perror( "can't create output file" );
146 return EXIT_FAILURE;
148 break;
150 case 'v':
151 verbose++;
152 break;
154 case 'h':
155 default:
156 return usage( argv );
158 if ( optind != argc )
159 return usage( argv );
161 memset( &header, 0, sizeof header );
162 header.h.setup.magic = 0x1b031336; // magic number
163 header.h.setup.length = 4;
164 header.h.setup.location = 0x93e00000; // just below the EtherBoot rom
165 header.h.setup.start = 0; // filled in dynamically
166 header.h.qnx.flags = 0x04000004; // single image only
167 header.h.qnx.loadaddr = 0; // filled in dynamically
168 header.h.qnx.imgsize = 0; // filled in dynamically
169 header.h.qnx.memsize = 0; // filled in dynamically
171 // read the QNX image from stdin:
172 for ( ; ( l = fread( buffer + header.h.qnx.imgsize, 1, 1024, stdin ) ) > 0;
173 header.h.qnx.imgsize += l
176 header.h.qnx.memsize = header.h.qnx.imgsize;
178 // fill in the real load-address of the QNX boot image:
179 header.h.setup.start = *(ushort_t*)&buffer[10] << 16;
180 header.h.qnx.loadaddr = *(ushort_t*)&buffer[10] << 4;
182 // write the tagged image file to stdout:
183 fwrite( &header, 1, 512, stdout );
184 fwrite( buffer, 1, header.h.qnx.imgsize, stdout );
186 if ( verbose )
188 // print diagnostic information:
189 fprintf( stderr, "QNX image size: %d bytes (%dK), load addr: 0x%05X\n",
190 header.h.qnx.imgsize,
191 header.h.qnx.imgsize / 1024,
192 header.h.qnx.loadaddr
195 return EXIT_SUCCESS;