You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mkQNXnbi.c 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <unistd.h>
  51. #include <sys/types.h>
  52. // max. size of QNX OS boot image is 512K
  53. #define MAXSIZE (512*1024)
  54. typedef unsigned short ushort_t;
  55. typedef unsigned long ulong_t;
  56. // global header of tagged image:
  57. struct initial_t
  58. {
  59. ulong_t magic;
  60. ulong_t length;
  61. ulong_t location;
  62. ulong_t start;
  63. };
  64. // header of each image:
  65. struct header_t
  66. {
  67. ulong_t flags;
  68. ulong_t loadaddr;
  69. ulong_t imgsize;
  70. ulong_t memsize;
  71. };
  72. // global header of the QNX EtherBoot image:
  73. struct qnx_loader_t
  74. {
  75. struct initial_t setup;
  76. struct header_t qnx;
  77. };
  78. // global header:
  79. union
  80. {
  81. struct qnx_loader_t h;
  82. char filler[512];
  83. } header;
  84. char buffer[MAXSIZE];
  85. int usage( char* const* argv )
  86. {
  87. fprintf( stderr, "%s - make a tagged boot image for EtherBoot\n", *argv );
  88. fprintf( stderr, "\nuse:\n" );
  89. fprintf( stderr, "%s [ -<option> ]*\n", *argv );
  90. fprintf( stderr, "\noptions:\n" );
  91. fprintf( stderr, " i <input file> : QNX boot file (default: stdin)\n" );
  92. fprintf( stderr, " o <output file> : tagged image file (default: stdout)\n" );
  93. fprintf( stderr, " v : be verbose\n" );
  94. return EXIT_FAILURE;
  95. }
  96. #ifdef __USAGE
  97. %C - make a tagged boot image for EtherBoot
  98. use:
  99. %C [ -<option> ]*
  100. options:
  101. i <input file> : QNX boot file (default: stdin)
  102. o <output file> : tagged image file (default: stdout)
  103. v : be verbose
  104. #endif
  105. int main( int argc, char* const* argv )
  106. {
  107. int ch, l;
  108. int verbose = 0;
  109. while ( ( ch = getopt( argc, argv, "hi:o:v" ) ) != EOF )
  110. switch ( ch )
  111. {
  112. case 'i':
  113. if ( !freopen( optarg, "r", stdin ) )
  114. {
  115. perror( "can't open input file" );
  116. return EXIT_FAILURE;
  117. }
  118. break;
  119. case 'o':
  120. if ( !freopen( optarg, "w", stdout ) )
  121. {
  122. perror( "can't create output file" );
  123. return EXIT_FAILURE;
  124. }
  125. break;
  126. case 'v':
  127. verbose++;
  128. break;
  129. case 'h':
  130. default:
  131. return usage( argv );
  132. }
  133. if ( optind != argc )
  134. return usage( argv );
  135. memset( &header, 0, sizeof header );
  136. header.h.setup.magic = 0x1b031336; // magic number
  137. header.h.setup.length = 4;
  138. header.h.setup.location = 0x93e00000; // just below the EtherBoot rom
  139. header.h.setup.start = 0; // filled in dynamically
  140. header.h.qnx.flags = 0x04000004; // single image only
  141. header.h.qnx.loadaddr = 0; // filled in dynamically
  142. header.h.qnx.imgsize = 0; // filled in dynamically
  143. header.h.qnx.memsize = 0; // filled in dynamically
  144. // read the QNX image from stdin:
  145. for ( ; ( l = fread( buffer + header.h.qnx.imgsize, 1, 1024, stdin ) ) > 0;
  146. header.h.qnx.imgsize += l
  147. )
  148. ;
  149. header.h.qnx.memsize = header.h.qnx.imgsize;
  150. // fill in the real load-address of the QNX boot image:
  151. header.h.setup.start = *(ushort_t*)&buffer[10] << 16;
  152. header.h.qnx.loadaddr = *(ushort_t*)&buffer[10] << 4;
  153. // write the tagged image file to stdout:
  154. fwrite( &header, 1, 512, stdout );
  155. fwrite( buffer, 1, header.h.qnx.imgsize, stdout );
  156. if ( verbose )
  157. {
  158. // print diagnostic information:
  159. fprintf( stderr, "QNX image size: %d bytes (%dK), load addr: 0x%05X\n",
  160. header.h.qnx.imgsize,
  161. header.h.qnx.imgsize / 1024,
  162. header.h.qnx.loadaddr
  163. );
  164. }
  165. return EXIT_SUCCESS;
  166. }