[Timers] Do not enable serial console by default; this change should not
[people/dverkamp/gpxe.git] / contrib / mkQNXnbi / mkQNXnbi.c
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)
12 //
13 //
14 //      Author:         Anders Larsen
15 //
16 //
17 //      Copyright:      (C) 1999 by
18 //
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
27 //
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.
32 //
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.
37 //
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.
41 //
42 //-----------------------------------------------------------------------------
43 //
44 //      Change Log:
45 //        V0.2: Sun 1999-12-13 Anders Larsen <al@alarsen.net>
46 //*****************************************************************************
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <unistd.h>
52 #include <sys/types.h>
53
54
55 // max. size of QNX OS boot image is 512K
56 #define MAXSIZE (512*1024)
57
58 typedef unsigned short ushort_t;
59 typedef unsigned long  ulong_t;
60
61
62 // global header of tagged image:
63 struct initial_t
64 {
65   ulong_t magic;
66   ulong_t length;
67   ulong_t location;
68   ulong_t start;
69 };
70
71
72 // header of each image:
73 struct header_t
74 {
75   ulong_t flags;
76   ulong_t loadaddr;
77   ulong_t imgsize;
78   ulong_t memsize;
79 };
80
81
82 // global header of the QNX EtherBoot image:
83 struct qnx_loader_t
84 {
85   struct initial_t setup;
86   struct header_t  qnx;
87 };
88
89
90 // global header:
91 union
92 {
93   struct qnx_loader_t h;
94   char                filler[512];
95 } header;
96
97
98 char buffer[MAXSIZE];
99
100
101 int usage( char* const* argv )
102 {
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;
111 }
112
113 #ifdef __USAGE
114 %C - make a tagged boot image for EtherBoot
115
116 use:
117 %C [ -<option> ]* 
118
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
124
125
126 int main( int argc, char* const* argv )
127 {
128   int ch, l;
129   int verbose = 0;
130
131   while ( ( ch = getopt( argc, argv, "hi:o:v" ) ) != EOF )
132     switch ( ch )
133     {
134       case 'i':
135         if ( !freopen( optarg, "r", stdin ) )
136         {
137           perror( "can't open input file" );
138           return EXIT_FAILURE;
139         }
140         break;
141
142       case 'o':
143         if ( !freopen( optarg, "w", stdout ) )
144         {
145           perror( "can't create output file" );
146           return EXIT_FAILURE;
147         }
148         break;
149
150       case 'v':
151         verbose++;
152         break;
153
154       case 'h':
155       default:
156         return usage( argv );
157     }
158   if ( optind != argc )
159     return usage( argv );
160
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
170
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
174       )
175     ;
176   header.h.qnx.memsize = header.h.qnx.imgsize;
177
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;
181
182   // write the tagged image file to stdout:
183   fwrite( &header, 1, 512, stdout );
184   fwrite( buffer, 1, header.h.qnx.imgsize, stdout );
185
186   if ( verbose )
187   {
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
193            );
194   }
195   return EXIT_SUCCESS;
196 }