diff options
Diffstat (limited to 'util/BuildImage.c')
-rw-r--r-- | util/BuildImage.c | 380 |
1 files changed, 193 insertions, 187 deletions
diff --git a/util/BuildImage.c b/util/BuildImage.c index 2124c9d..42430ce 100644 --- a/util/BuildImage.c +++ b/util/BuildImage.c @@ -14,27 +14,27 @@ ** */ -#define _POSIX_C_SOURCE 200809L +#define _POSIX_C_SOURCE 200809L +#include <errno.h> #include <stdio.h> #include <stdlib.h> -#include <unistd.h> #include <string.h> -#include <errno.h> +#include <unistd.h> -#define TRUE 1 -#define FALSE 0 +#define TRUE 1 +#define FALSE 0 -#define DRIVE_FLOPPY 0x00 -#define DRIVE_USB 0x80 +#define DRIVE_FLOPPY 0x00 +#define DRIVE_USB 0x80 -#define SECT_SIZE 512 +#define SECT_SIZE 512 -char *progname; /* invocation name of this program */ -char *bootstrap_filename; /* path of file holding bootstrap program */ -char *output_filename; /* path of disk image file */ -FILE *out; /* output stream for disk image file */ -short drive = DRIVE_USB; /* boot drive */ +char *progname; /* invocation name of this program */ +char *bootstrap_filename; /* path of file holding bootstrap program */ +char *output_filename; /* path of disk image file */ +FILE *out; /* output stream for disk image file */ +short drive = DRIVE_USB; /* boot drive */ /* ** Array into which program information will be stored, starting at the @@ -46,9 +46,9 @@ short drive = DRIVE_USB; /* boot drive */ ** can be loaded. */ -#define N_INFO ( SECT_SIZE / sizeof( short ) ) +#define N_INFO (SECT_SIZE / sizeof(short)) -short info[ N_INFO ]; +short info[N_INFO]; int n_info = N_INFO; /** @@ -60,43 +60,46 @@ int n_info = N_INFO; ** ** does not return */ -void quit( char *msg, int call_perror ) { - if( msg != NULL ){ +void quit(char *msg, int call_perror) +{ + if (msg != NULL) { // preserve the error code in case we need it int err_num = errno; - fprintf( stderr, "%s: ", progname ); + fprintf(stderr, "%s: ", progname); errno = err_num; - if( call_perror ){ - perror( msg ); + if (call_perror) { + perror(msg); } else { - fprintf( stderr, "%s\n", msg ); + fprintf(stderr, "%s\n", msg); } } - if( output_filename != NULL ){ - unlink( output_filename ); + if (output_filename != NULL) { + unlink(output_filename); } - exit( EXIT_FAILURE ); + exit(EXIT_FAILURE); // NOTREACHED } -const char usage_error_msg[] = - "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } ...\n\n" - "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n" - "\tThere must be at least one program file and load point.\n\n" - "\tLoad points may be specified either as 32-bit quantities in hex,\n" - "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n" - "\tor as an explicit segment:offset pair whose digits are always\n" - "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n" - "\tboth equivalent to the previous examples).\n\n"; +const char usage_error_msg[] = + "\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } " + "...\n\n" + "\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n" + "\tThere must be at least one program file and load point.\n\n" + "\tLoad points may be specified either as 32-bit quantities in hex,\n" + "\tdecimal or octal (e.g. 0x10c00, 68608, 0206000 are all equivalent),\n" + "\tor as an explicit segment:offset pair whose digits are always\n" + "\tinterpreted as hexadecimal values (e.g. 10c0:0000, 1000:0c00 are\n" + "\tboth equivalent to the previous examples).\n\n"; /** ** print a usage message and then call quit() ** ** does not return */ -void usage_error( void ){ - fprintf( stderr, usage_error_msg, progname ); - quit( NULL, FALSE ); +void usage_error(void) +{ + fprintf(stderr, usage_error_msg, progname); + quit(NULL, FALSE); // NOTREACHED } @@ -107,29 +110,30 @@ void usage_error( void ){ ** @param in open FILE to be read ** @return the number of sectors copied from the file */ -int copy_file( FILE *in ){ +int copy_file(FILE *in) +{ int n_sectors = 0; - char buf[ SECT_SIZE ]; + char buf[SECT_SIZE]; int n_bytes; int i; /* - ** Copy the file to the output, being careful that the - ** last sector is padded with null bytes out to the - ** sector size. - */ + ** Copy the file to the output, being careful that the + ** last sector is padded with null bytes out to the + ** sector size. + */ n_sectors = 0; - while( (n_bytes = fread( buf, 1, sizeof( buf ), in )) > 0 ){ + while ((n_bytes = fread(buf, 1, sizeof(buf), in)) > 0) { // pad this sector out to block size - if( n_bytes < sizeof( buf ) ){ + if (n_bytes < sizeof(buf)) { int i; - for( i = n_bytes; i < sizeof( buf ); i += 1 ){ - buf[ i ] = '\0'; + for (i = n_bytes; i < sizeof(buf); i += 1) { + buf[i] = '\0'; } } - if( fwrite( buf, 1, sizeof( buf ), out ) != sizeof( buf ) ){ - quit( "Write failed or was wrong size", FALSE ); + if (fwrite(buf, 1, sizeof(buf), out) != sizeof(buf)) { + quit("Write failed or was wrong size", FALSE); } n_sectors += 1; } @@ -143,85 +147,85 @@ int copy_file( FILE *in ){ ** @param name path to the file to be copied ** @param addr string containing the load address */ -void process_file( char *name, char *addr ){ +void process_file(char *name, char *addr) +{ long address; short segment, offset; int n_bytes; /* - ** Open the input file. - */ - FILE *in = fopen( name, "rb" ); - if( in == NULL ){ - quit( name, TRUE ); + ** Open the input file. + */ + FILE *in = fopen(name, "rb"); + if (in == NULL) { + quit(name, TRUE); } /* - ** Copy the file to the output, being careful that the - ** last block is padded with null bytes. - */ - int n_sectors = copy_file( in ); - fclose( in ); + ** Copy the file to the output, being careful that the + ** last block is padded with null bytes. + */ + int n_sectors = copy_file(in); + fclose(in); /* - ** Decode the address they gave us. We'll accept two forms: - ** "nnnn:nnnn" for a segment:offset value (assumed to be hex), - ** "nnnnnnn" for a decimal, hex, or octal value - */ + ** Decode the address they gave us. We'll accept two forms: + ** "nnnn:nnnn" for a segment:offset value (assumed to be hex), + ** "nnnnnnn" for a decimal, hex, or octal value + */ int valid_address = FALSE; - char *cp = strchr( addr, ':' ); - if( cp != NULL ){ + char *cp = strchr(addr, ':'); + if (cp != NULL) { // must be in nnnn:nnnn form exactly - if( strlen( addr ) == 9 && cp == addr + 4 ){ + if (strlen(addr) == 9 && cp == addr + 4) { char *ep1, *ep2; int a1, a2; - segment = strtol( addr, &ep1, 16 ); - offset = strtol( addr + 5, &ep2, 16 ); - address = ( segment << 4 ) + offset; + segment = strtol(addr, &ep1, 16); + offset = strtol(addr + 5, &ep2, 16); + address = (segment << 4) + offset; valid_address = *ep1 == '\0' && *ep2 == '\0'; } else { - fprintf( stderr, "Bad address format - '%s'\n", addr ); - quit( NULL, FALSE ); + fprintf(stderr, "Bad address format - '%s'\n", addr); + quit(NULL, FALSE); } } else { // just a number, possibly hex or octal char *ep; - address = strtol( addr, &ep, 0 ); - segment = (short)( address >> 4 ); - offset = (short)( address & 0xf ); + address = strtol(addr, &ep, 0); + segment = (short)(address >> 4); + offset = (short)(address & 0xf); valid_address = *ep == '\0' && address <= 0x0009ffff; } - if( !valid_address ){ - fprintf( stderr, "%s: Invalid address: %s\n", progname, addr ); - quit( NULL, FALSE ); + if (!valid_address) { + fprintf(stderr, "%s: Invalid address: %s\n", progname, addr); + quit(NULL, FALSE); } /* - ** Make sure the program will fit! - */ - if( address + n_sectors * SECT_SIZE > 0x0009ffff ){ - fprintf( stderr, "Program %s too large to start at 0x%08x\n", - name, (unsigned int) address ); - quit( NULL, FALSE ); + ** Make sure the program will fit! + */ + if (address + n_sectors * SECT_SIZE > 0x0009ffff) { + fprintf(stderr, "Program %s too large to start at 0x%08x\n", name, + (unsigned int)address); + quit(NULL, FALSE); } - if( n_info < 3 ){ - quit( "Too many programs!", FALSE ); + if (n_info < 3) { + quit("Too many programs!", FALSE); } - /* - ** Looks good: report and store the information. - */ - fprintf( stderr, " %s: %d sectors, loaded at 0x%x\n", - name, n_sectors, (unsigned int) address ); + ** Looks good: report and store the information. + */ + fprintf(stderr, " %s: %d sectors, loaded at 0x%x\n", name, n_sectors, + (unsigned int)address); - info[ --n_info ] = n_sectors; - info[ --n_info ] = segment; - info[ --n_info ] = offset; + info[--n_info] = n_sectors; + info[--n_info] = segment; + info[--n_info] = offset; } /* @@ -237,64 +241,65 @@ extern char *optarg; ** @param ac the count of entries in av ** @param av the argument vector */ -void process_args( int ac, char **av ) { +void process_args(int ac, char **av) +{ int c; - - while( (c=getopt(ac,av,":d:o:b:")) != EOF ) { - - switch( c ) { - case ':': /* missing arg value */ - fprintf( stderr, "missing operand after -%c\n", optopt ); + while ((c = getopt(ac, av, ":d:o:b:")) != EOF) { + switch (c) { + case ':': /* missing arg value */ + fprintf(stderr, "missing operand after -%c\n", optopt); /* FALL THROUGH */ - case '?': /* error */ + case '?': /* error */ usage_error(); /* NOTREACHED */ - case 'b': /* -b bootstrap_file */ + case 'b': /* -b bootstrap_file */ bootstrap_filename = optarg; break; - case 'd': /* -d drive */ - switch( *optarg ) { - case 'f': drive = DRIVE_FLOPPY; break; - case 'u': drive = DRIVE_USB; break; - default: usage_error(); + case 'd': /* -d drive */ + switch (*optarg) { + case 'f': + drive = DRIVE_FLOPPY; + break; + case 'u': + drive = DRIVE_USB; + break; + default: + usage_error(); } break; - case 'o': /* -o output_file */ + case 'o': /* -o output_file */ output_filename = optarg; break; - + default: usage_error(); - } - } - if( !bootstrap_filename ) { - fprintf( stderr, "%s: no bootstrap file specified\n", progname ); - exit( 2 ); + if (!bootstrap_filename) { + fprintf(stderr, "%s: no bootstrap file specified\n", progname); + exit(2); } - if( !output_filename ) { - fprintf( stderr, "%s: no disk image file specified\n", progname ); - exit( 2 ); + if (!output_filename) { + fprintf(stderr, "%s: no disk image file specified\n", progname); + exit(2); } /* - ** Must have at least two remaining arguments (file to load, - ** address at which it should be loaded), and must have an - ** even number of remaining arguments. - */ + ** Must have at least two remaining arguments (file to load, + ** address at which it should be loaded), and must have an + ** even number of remaining arguments. + */ int remain = ac - optind; - if( remain < 2 || (remain & 1) != 0 ) { + if (remain < 2 || (remain & 1) != 0) { usage_error(); } - } /** @@ -307,109 +312,110 @@ void process_args( int ac, char **av ) { ** @param av command-line argument vector ** @return EXIT_SUCCESS or EXIT_FAILURE */ -int main( int ac, char **av ) { - FILE *bootimage; - int bootimage_size; - int n_bytes, n_words; - short existing_data[ N_INFO ]; - int i; - +int main(int ac, char **av) +{ + FILE *bootimage; + int bootimage_size; + int n_bytes, n_words; + short existing_data[N_INFO]; + int i; + /* - ** Save the program name for error messages - */ - progname = strrchr( av[ 0 ], '/' ); - if( progname != NULL ){ + ** Save the program name for error messages + */ + progname = strrchr(av[0], '/'); + if (progname != NULL) { progname++; } else { - progname = av[ 0 ]; + progname = av[0]; } /* - ** Process arguments - */ - process_args( ac, av ); + ** Process arguments + */ + process_args(ac, av); /* - ** Open the output file - */ + ** Open the output file + */ - out = fopen( output_filename, "wb+" ); - if( out == NULL ){ - quit( output_filename, TRUE ); + out = fopen(output_filename, "wb+"); + if (out == NULL) { + quit(output_filename, TRUE); } /* - ** Open the bootstrap file and copy it to the output image. - */ - bootimage = fopen( bootstrap_filename, "rb" ); - if( bootimage == NULL ){ - quit( bootstrap_filename, TRUE ); + ** Open the bootstrap file and copy it to the output image. + */ + bootimage = fopen(bootstrap_filename, "rb"); + if (bootimage == NULL) { + quit(bootstrap_filename, TRUE); } /* - ** Remember the size of the bootstrap for later, as we - ** need to patch some things into it - */ - int n_sectors = copy_file( bootimage ); - fclose( bootimage ); + ** Remember the size of the bootstrap for later, as we + ** need to patch some things into it + */ + int n_sectors = copy_file(bootimage); + fclose(bootimage); bootimage_size = n_sectors * SECT_SIZE; - fprintf( stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors ); + fprintf(stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors); /* - ** Process the programs one by one - */ + ** Process the programs one by one + */ ac -= optind; av += optind; - while( ac >= 2 ){ - process_file( av[ 0 ], av[ 1 ] ); - ac -= 2; av += 2; + while (ac >= 2) { + process_file(av[0], av[1]); + ac -= 2; + av += 2; } /* - ** Check for oddball leftover argument - */ - if( ac > 0 ){ + ** Check for oddball leftover argument + */ + if (ac > 0) { usage_error(); } /* - ** Seek to where the array of module data must begin and read - ** what's already there. - */ - n_words = ( N_INFO - n_info ); - n_bytes = n_words * sizeof( info[ 0 ] ); - fseek( out, bootimage_size - n_bytes, SEEK_SET ); - if( fread( existing_data, sizeof(info[0]), n_words, out ) != n_words ){ - quit( "Read from boot image failed or was too short", FALSE ); + ** Seek to where the array of module data must begin and read + ** what's already there. + */ + n_words = (N_INFO - n_info); + n_bytes = n_words * sizeof(info[0]); + fseek(out, bootimage_size - n_bytes, SEEK_SET); + if (fread(existing_data, sizeof(info[0]), n_words, out) != n_words) { + quit("Read from boot image failed or was too short", FALSE); } /* - ** If that space is non-zero, we have a problem - */ - for( i = 0; i < n_words; i += 1 ){ - if( existing_data[ i ] != 0 ){ - quit( "Too many programs to load!", FALSE ); + ** If that space is non-zero, we have a problem + */ + for (i = 0; i < n_words; i += 1) { + if (existing_data[i] != 0) { + quit("Too many programs to load!", FALSE); } } /* - ** We know that we're only overwriting zeros at the end of - ** the bootstrap image, so it is ok to go ahead and do it. - */ - fseek( out, bootimage_size - n_bytes, SEEK_SET ); - if( fwrite( info + n_info, sizeof( info[ 0 ] ), n_words, out ) != n_words ){ - quit( "Write to boot image failed or was too short", FALSE ); + ** We know that we're only overwriting zeros at the end of + ** the bootstrap image, so it is ok to go ahead and do it. + */ + fseek(out, bootimage_size - n_bytes, SEEK_SET); + if (fwrite(info + n_info, sizeof(info[0]), n_words, out) != n_words) { + quit("Write to boot image failed or was too short", FALSE); } /* - ** Write the drive index to the image. - */ - fseek( out, 508, SEEK_SET ); - fwrite( (void *)&drive, sizeof(drive), 1, out ); + ** Write the drive index to the image. + */ + fseek(out, 508, SEEK_SET); + fwrite((void *)&drive, sizeof(drive), 1, out); - fclose( out ); + fclose(out); return EXIT_SUCCESS; - } |