| //***************************************************************************** |
| // |
| // Purpose: Make a boot-image for EtherBoot |
| // |
| // |
| // Compiler: This source can be compiled with gcc and Watcom C |
| // |
| // |
| // Note: The QNX boot image can be build with any reasonable |
| // start address, e.g. 0x1000 (default) or 0x10000 |
| // (widespread Boot-Rom address) |
| // |
| // |
| // Author: Anders Larsen |
| // |
| // |
| // Copyright: (C) 1999 by |
| // |
| // Anders Larsen |
| // systems engineer |
| // Gutleuthausstr. 3 |
| // D-69469 Weinheim |
| // Germany |
| // phone: +49-6201-961717 |
| // fax: +49-6201-961718 |
| // e-mail: al@alarsen.net |
| // |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 2 of the License, or |
| // (at your option) any later version. |
| // |
| // This program is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| // |
| // You should have received a copy of the GNU General Public License |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| // |
| //----------------------------------------------------------------------------- |
| // |
| // Change Log: |
| // V0.2: Sun 1999-12-13 Anders Larsen <al@alarsen.net> |
| //***************************************************************************** |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| |
| |
| // max. size of QNX OS boot image is 512K |
| #define MAXSIZE (512*1024) |
| |
| typedef unsigned short ushort_t; |
| typedef unsigned long ulong_t; |
| |
| |
| // global header of tagged image: |
| struct initial_t |
| { |
| ulong_t magic; |
| ulong_t length; |
| ulong_t location; |
| ulong_t start; |
| }; |
| |
| |
| // header of each image: |
| struct header_t |
| { |
| ulong_t flags; |
| ulong_t loadaddr; |
| ulong_t imgsize; |
| ulong_t memsize; |
| }; |
| |
| |
| // global header of the QNX EtherBoot image: |
| struct qnx_loader_t |
| { |
| struct initial_t setup; |
| struct header_t qnx; |
| }; |
| |
| |
| // global header: |
| union |
| { |
| struct qnx_loader_t h; |
| char filler[512]; |
| } header; |
| |
| |
| char buffer[MAXSIZE]; |
| |
| |
| int usage( char* const* argv ) |
| { |
| fprintf( stderr, "%s - make a tagged boot image for EtherBoot\n", *argv ); |
| fprintf( stderr, "\nuse:\n" ); |
| fprintf( stderr, "%s [ -<option> ]*\n", *argv ); |
| fprintf( stderr, "\noptions:\n" ); |
| fprintf( stderr, " i <input file> : QNX boot file (default: stdin)\n" ); |
| fprintf( stderr, " o <output file> : tagged image file (default: stdout)\n" ); |
| fprintf( stderr, " v : be verbose\n" ); |
| return EXIT_FAILURE; |
| } |
| |
| #ifdef __USAGE |
| %C - make a tagged boot image for EtherBoot |
| |
| use: |
| %C [ -<option> ]* |
| |
| options: |
| i <input file> : QNX boot file (default: stdin) |
| o <output file> : tagged image file (default: stdout) |
| v : be verbose |
| #endif |
| |
| |
| int main( int argc, char* const* argv ) |
| { |
| int ch, l; |
| int verbose = 0; |
| |
| while ( ( ch = getopt( argc, argv, "hi:o:v" ) ) != EOF ) |
| switch ( ch ) |
| { |
| case 'i': |
| if ( !freopen( optarg, "r", stdin ) ) |
| { |
| perror( "can't open input file" ); |
| return EXIT_FAILURE; |
| } |
| break; |
| |
| case 'o': |
| if ( !freopen( optarg, "w", stdout ) ) |
| { |
| perror( "can't create output file" ); |
| return EXIT_FAILURE; |
| } |
| break; |
| |
| case 'v': |
| verbose++; |
| break; |
| |
| case 'h': |
| default: |
| return usage( argv ); |
| } |
| if ( optind != argc ) |
| return usage( argv ); |
| |
| memset( &header, 0, sizeof header ); |
| header.h.setup.magic = 0x1b031336; // magic number |
| header.h.setup.length = 4; |
| header.h.setup.location = 0x93e00000; // just below the EtherBoot rom |
| header.h.setup.start = 0; // filled in dynamically |
| header.h.qnx.flags = 0x04000004; // single image only |
| header.h.qnx.loadaddr = 0; // filled in dynamically |
| header.h.qnx.imgsize = 0; // filled in dynamically |
| header.h.qnx.memsize = 0; // filled in dynamically |
| |
| // read the QNX image from stdin: |
| for ( ; ( l = fread( buffer + header.h.qnx.imgsize, 1, 1024, stdin ) ) > 0; |
| header.h.qnx.imgsize += l |
| ) |
| ; |
| header.h.qnx.memsize = header.h.qnx.imgsize; |
| |
| // fill in the real load-address of the QNX boot image: |
| header.h.setup.start = *(ushort_t*)&buffer[10] << 16; |
| header.h.qnx.loadaddr = *(ushort_t*)&buffer[10] << 4; |
| |
| // write the tagged image file to stdout: |
| fwrite( &header, 1, 512, stdout ); |
| fwrite( buffer, 1, header.h.qnx.imgsize, stdout ); |
| |
| if ( verbose ) |
| { |
| // print diagnostic information: |
| fprintf( stderr, "QNX image size: %d bytes (%dK), load addr: 0x%05X\n", |
| header.h.qnx.imgsize, |
| header.h.qnx.imgsize / 1024, |
| header.h.qnx.loadaddr |
| ); |
| } |
| return EXIT_SUCCESS; |
| } |