diff options
Diffstat (limited to 'tools/firmware-utils')
| -rw-r--r-- | tools/firmware-utils/Makefile | 3 | ||||
| -rw-r--r-- | tools/firmware-utils/src/imagetag.c | 517 | ||||
| -rw-r--r-- | tools/firmware-utils/src/imagetag.ggo | 45 | ||||
| -rw-r--r-- | tools/firmware-utils/src/imagetag_cmdline.c | 1163 | ||||
| -rw-r--r-- | tools/firmware-utils/src/imagetag_cmdline.h | 272 | 
5 files changed, 1781 insertions, 219 deletions
| diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index ace2aaae2..eb42f630f 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -15,7 +15,6 @@ define cc  	$(CC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2)  endef -  define Host/Compile  	mkdir -p $(HOST_BUILD_DIR)/bin  	$(call cc,addpattern) @@ -33,7 +32,7 @@ define Host/Compile  	$(call cc,mkcasfw)  	$(call cc,mkfwimage,-lz)  	$(call cc,mkfwimage2,-lz) -	$(call cc,imagetag) +	$(call cc,imagetag imagetag_cmdline)  	$(call cc,add_header)  	$(call cc,makeamitbin)  	$(call cc,encode_crc) diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c index 0ecbada28..1818daaca 100644 --- a/tools/firmware-utils/src/imagetag.c +++ b/tools/firmware-utils/src/imagetag.c @@ -4,7 +4,7 @@   * for more details.   *   * Copyright (C) 2008 Axel Gembe <ago@bastart.eu.org> - * Copyright (C) 2009 Daniel Dickinson <crazycshore@gmail.com> + * Copyright (C) 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>   */  #include <stdio.h> @@ -17,25 +17,10 @@  #include <netinet/in.h>  #include "bcm_tag.h" +#include "imagetag_cmdline.h" -#define IMAGETAG_MAGIC1			"Broadcom Corporatio" -#define IMAGETAG_MAGIC2			"ver. 2.0" -#define IMAGETAG_VER			"6" -#define IMAGETAG_DEFAULT_LOADADDR	0x80010000 -#define DEFAULT_FW_OFFSET		0x10000 -#define DEFAULT_FLASH_START		0xBFC00000 -#define DEFAULT_FLASH_BS		(64 * 1024)  #define DEADCODE			0xDEADC0DE -union int2char { -  uint32_t input; -  char output[4]; -}; - -/* Convert uint32_t CRC to bigendian and copy it into a character array */ -#define int2tag(tag, value)  intchar.input = htonl(value);	\ -	  memcpy(tag, intchar.output, sizeof(union int2char)) -  /* Kernel header */  struct kernelhdr {  	uint32_t		loadaddr;	/* Kernel load address */ @@ -80,6 +65,11 @@ static uint32_t crc32tab[256] = {  	0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D  }; +void int2tag(char *tag, uint32_t value) { +  uint32_t network = htonl(value); +  memcpy(tag, (char *)(&network), 4); +} +  uint32_t crc32(uint32_t crc, uint8_t *data, size_t len)  {  	while (len--) @@ -126,38 +116,29 @@ size_t getlen(FILE *fp)  	return retval;  } -int tagfile(const char *kernel, const char *rootfs, const char *bin, -	    const char *boardid, const char *chipid, const uint32_t fwaddr, -	    const uint32_t loadaddr, const uint32_t entry, -	    const char *ver, const char *magic2, const uint32_t flash_bs, -	    const char *rsignature, const char *layoutver) +int tagfile(const char *kernel, const char *rootfs, const char *bin, \ +			const struct gengetopt_args_info *args, \ +			uint32_t flash_start, uint32_t image_offset, \ +			uint32_t block_size, uint32_t load_address, uint32_t entry)  {  	struct bcm_tag tag;  	struct kernelhdr khdr; -	FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile; -	size_t kerneloff, kernellen, rootfsoff, rootfslen, read, imagelen, rootfsoffpadlen, kernelfslen; +	FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile = NULL, *cfefile = NULL; +	size_t cfeoff, cfelen, kerneloff, kernellen, rootfsoff, rootfslen, \ +	  read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen;  	uint8_t readbuf[1024];  	uint32_t imagecrc = IMAGETAG_CRC_START;  	uint32_t kernelcrc = IMAGETAG_CRC_START;  	uint32_t rootfscrc = IMAGETAG_CRC_START;  	uint32_t kernelfscrc = IMAGETAG_CRC_START; +	uint32_t fwaddr = 0; +	uint8_t crc_val;  	const uint32_t deadcode = htonl(DEADCODE); -        union int2char intchar; -        int i; -        int is_pirelli = 0; - -	memset(&tag, 0, sizeof(struct bcm_tag)); +	int i; +	int is_pirelli = 0; -	if (strlen(boardid) >= sizeof(tag.boardid)) { -		fprintf(stderr, "Board id is too long!\n"); -		return 1; -	} -	/* Likewise chipid */ -	if (strlen(chipid) >= sizeof(tag.chipid)) { -		fprintf(stderr, "Chip id is too long!\n"); -		return 1; -	} +	memset(&tag, 0, sizeof(struct bcm_tag));  	if (!kernel || !rootfs) {  		fprintf(stderr, "imagetag can't create an image without both kernel and rootfs\n"); @@ -178,122 +159,253 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,  		return 1;  	} -	/* Build the kernel address and length (doesn't need to be aligned, read only) */ -	kerneloff = fwaddr + sizeof(tag); -	kernellen = getlen(kernelfile); - -	/* Build the kernel header */ -	khdr.loadaddr	= htonl(loadaddr); -	khdr.entry	= htonl(entry); -	khdr.lzmalen	= htonl(kernellen); +	if ((args->cfe_given) && (args->cfe_arg)) { +	  if (!(cfefile = fopen(args->cfe_arg, "rb"))) { +		fprintf(stderr, "Unable to open CFE file \"%s\"\n", args->cfe_arg); +	  } +	} -	/* Increase the kernel size by the header size */ -	kernellen += sizeof(khdr); +	fwaddr = flash_start + image_offset; +	if (cfefile) { +	  cfeoff = flash_start;		   +	  cfelen = getlen(cfefile); +	  /* Seek to the start of the file after tag */ +	  fseek(binfile, sizeof(tag), SEEK_SET); +	   +	  /* Write the cfe */ +	  while (cfefile && !feof(cfefile) && !ferror(cfefile)) { +		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), cfefile); +		fwrite(readbuf, sizeof(uint8_t), read, binfile); +	  } -	/* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */ -	rootfsoff = kerneloff + kernellen; -	rootfsoff = (rootfsoff % flash_bs) > 0 ? (((rootfsoff / flash_bs) + 1) * flash_bs) : rootfsoff; -	rootfslen = getlen(rootfsfile); -	rootfslen = ( (rootfslen % flash_bs) > 0 ? (((rootfslen / flash_bs) + 1) * flash_bs) : rootfslen ); -	imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); -	rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); +	} else { +	  cfeoff = 0; +	  cfelen = 0; +	} -	/* Seek to the start of the kernel */ -	fseek(binfile, kerneloff - fwaddr, SEEK_SET); +	if (!args->root_first_flag) { +	  /* Build the kernel address and length (doesn't need to be aligned, read only) */ +	  kerneloff = fwaddr + sizeof(tag); +	   +	  kernellen = getlen(kernelfile); +	   +	  if (!args->kernel_file_has_header_flag) { +		/* Build the kernel header */ +		khdr.loadaddr	= htonl(load_address); +		khdr.entry	= htonl(entry); +		khdr.lzmalen	= htonl(kernellen); +		 +		/* Increase the kernel size by the header size */ +		kernellen += sizeof(khdr);	   +	  } +	   +	  /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */ +	  rootfsoff = kerneloff + kernellen; +	  rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff; +	  rootfslen = getlen(rootfsfile); +	  rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); +	  imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); +	  rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); +	   +	  /* Seek to the start of the kernel */ +	  fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); +	   +	  /* Write the kernel header */ +	  fwrite(&khdr, sizeof(khdr), 1, binfile); +	   +	  /* Write the kernel */ +	  while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { +		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile); +		fwrite(readbuf, sizeof(uint8_t), read, binfile); +	  } -	/* Write the kernel header */ -	fwrite(&khdr, sizeof(khdr), 1, binfile); +	  /* Write the RootFS */ +	  fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); +	  while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { +		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile); +		fwrite(readbuf, sizeof(uint8_t), read, binfile); +	  } + +	  /* Align image to specified erase block size and append deadc0de */ +	  printf("Data alignment to %dk with 'deadc0de' appended\n", block_size/1024); +	  fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET); +	  fwrite(&deadcode, sizeof(uint32_t), 1, binfile); + +	  /* Flush the binfile buffer so that when we read from file, it contains +	   * everything in the buffer +	   */ +	  fflush(binfile); + +	  /* Compute the crc32 of the entire image (deadC0de included) */ +	  imagecrc = compute_crc32(imagecrc, binfile, kerneloff - fwaddr + cfelen, imagelen); +	  /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ +	  kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); +	  /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ +	  kernelfscrc = compute_crc32(kernelfscrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen + rootfslen + sizeof(deadcode)); +	  /* Compute the crc32 of the flashImageStart to rootLength. +	   * The broadcom firmware assumes the rootfs starts the image, +	   * therefore uses the rootfs start to determine where to flash +	   * the image.  Since we have the kernel first we have to give +	   * it the kernel address, but the crc uses the length +	   * associated with this address, which is added to the kernel +	   * length to determine the length of image to flash and thus +	   * needs to be rootfs + deadcode +	   */ +	  rootfscrc = compute_crc32(rootfscrc, binfile, kerneloff - fwaddr + cfelen, rootfslen + sizeof(deadcode)); -	/* Write the kernel */ -	while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { +	} else { +	  /* Build the kernel address and length (doesn't need to be aligned, read only) */ +	  rootfsoff = fwaddr + sizeof(tag); +	  oldrootfslen = getlen(rootfsfile); +	  rootfslen = oldrootfslen; +	  rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); +	  kerneloffpadlen = rootfslen - oldrootfslen; + +	  kerneloff = rootfsoff + rootfslen; +	  kernellen = getlen(kernelfile); + +	  imagelen = cfelen + rootfslen + kernellen; +	   +	  /* Seek to the start of the kernel */ +	  fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); +	   +	  if (!args->kernel_file_has_header_flag) { +		/* Build the kernel header */ +		khdr.loadaddr	= htonl(load_address); +		khdr.entry	= htonl(entry); +		khdr.lzmalen	= htonl(kernellen); +		 +		/* Write the kernel header */ +		fwrite(&khdr, sizeof(khdr), 1, binfile); +	   +		/* Increase the kernel size by the header size */ +		kernellen += sizeof(khdr);	   +	  } +	   +	  /* Write the kernel */ +	  while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) {  		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile);  		fwrite(readbuf, sizeof(uint8_t), read, binfile); -	} +	  } -	/* Write the RootFS */ -	fseek(binfile, rootfsoff - fwaddr, SEEK_SET); -	while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { +	  /* Write the RootFS */ +	  fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); +	  while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {  		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);  		fwrite(readbuf, sizeof(uint8_t), read, binfile); +	  } + +	  /* Flush the binfile buffer so that when we read from file, it contains +	   * everything in the buffer +	   */ +	  fflush(binfile); + +	  /* Compute the crc32 of the entire image (deadC0de included) */ +	  imagecrc = compute_crc32(imagecrc, binfile, sizeof(tag), imagelen); +	  /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ +	  kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); +	  kernelfscrc = compute_crc32(kernelfscrc, binfile, rootfsoff - fwaddr + cfelen, kernellen + rootfslen); +	  rootfscrc = compute_crc32(rootfscrc, binfile, rootfsoff - fwaddr + cfelen, rootfslen);  	} -	/* Align image to specified erase block size and append deadc0de */ -	printf("Data alignment to %dk with 'deadc0de' appended\n", flash_bs/1024); -	fseek(binfile, rootfsoff + rootfslen - fwaddr, SEEK_SET); -	fwrite(&deadcode, sizeof(uint32_t), 1, binfile); - -	/* Flush the binfile buffer so that when we read from file, it contains -         * everything in the buffer -	 */ -	fflush(binfile); - -	/* Compute the crc32 of the entire image (deadC0de included) */ -	imagecrc = compute_crc32(imagecrc, binfile, kerneloff - fwaddr, imagelen); -        /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ -	kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr, kernellen + rootfsoffpadlen); -        /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ -	kernelfscrc = compute_crc32(kernelfscrc, binfile, kerneloff - fwaddr, kernellen + rootfsoffpadlen + rootfslen + sizeof(deadcode)); -	/* Compute the crc32 of the flashImageStart to rootLength. -         * The broadcom firmware assumes the rootfs starts the image, -         * therefore uses the rootfs start to determine where to flash -         * the image.  Since we have the kernel first we have to give -         * it the kernel address, but the crc uses the length -         * associated with this address, which is added to the kernel -         * length to determine the length of image to flash and thus -         * needs to be rootfs + deadcode -         */ -	rootfscrc = compute_crc32(rootfscrc, binfile, kerneloff - fwaddr, rootfslen + sizeof(deadcode)); -  	/* Close the files */ +	if (cfefile) { +	  fclose(cfefile); +	}  	fclose(kernelfile);  	fclose(rootfsfile);  	/* Build the tag */ -	strncpy(tag.tagVersion, ver, TAGVER_LEN); -	strncpy(tag.sig_1, IMAGETAG_MAGIC1, sizeof(tag.sig_1) - 1); -	strncpy(tag.sig_2, magic2, sizeof(tag.sig_2) - 1); -	strcpy(tag.chipid, chipid); -	strcpy(tag.boardid, boardid); +	strncpy(tag.tagVersion, args->tag_version_arg, sizeof(tag.tagVersion) - 1); +	strncpy(tag.sig_1, args->signature_arg, sizeof(tag.sig_1) - 1); +	strncpy(tag.sig_2, args->signature2_arg, sizeof(tag.sig_2) - 1); +	strncpy(tag.chipid, args->chipid_arg, sizeof(tag.chipid) - 1); +	strncpy(tag.boardid, args->boardid_arg, sizeof(tag.boardid) - 1);  	strcpy(tag.big_endian, "1");  	sprintf(tag.totalLength, "%lu", imagelen); -	/* We don't include CFE */ -	strcpy(tag.cfeAddress, "0"); -	strcpy(tag.cfeLength, "0"); +	if (args->cfe_given) { +	  sprintf(tag.cfeAddress, "%lu", flash_start); +	  sprintf(tag.cfeLength, "%lu", cfelen); +	} else { +	  /* We don't include CFE */ +	  strcpy(tag.cfeAddress, "0"); +	  strcpy(tag.cfeLength, "0"); +	} -        sprintf(tag.kernelAddress, "%lu", kerneloff); +	sprintf(tag.kernelAddress, "%lu", kerneloff);  	sprintf(tag.kernelLength, "%lu", kernellen + rootfsoffpadlen); -        sprintf(tag.flashImageStart, "%lu", kerneloff); -	sprintf(tag.rootLength, "%lu", rootfslen + sizeof(deadcode)); -	if (rsignature) { -	    strncpy(tag.rsa_signature, rsignature, RSASIG_LEN); +	if (args->root_first_flag) { +	  sprintf(tag.flashImageStart, "%lu", rootfsoff); +	  sprintf(tag.rootLength, "%lu", rootfslen);	   +	} else { +	  sprintf(tag.flashImageStart, "%lu", kerneloff); +	  sprintf(tag.rootLength, "%lu", rootfslen + sizeof(deadcode)); +	} + +	if (args->rsa_signature_given) { +	    strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN); +	} + +	if (args->layoutver_given) { +	    strncpy(tag.flashLayoutVer, args->layoutver_arg, TAGLAYOUT_LEN);  	} -        if (layoutver) { -	    strncpy(tag.flashLayoutVer, layoutver, TAGLAYOUT_LEN); +	if (args->info1_given) { +	  strncpy(tag.information1, args->info1_arg, TAGINFO1_LEN); +	} + +	if (args->info2_given) { +	  strncpy(tag.information2, args->info2_arg, TAGINFO2_LEN); +	} + +	if (args->reserved1_given) { +	  strncpy(tag.reserved1, args->reserved1_arg, 8); +	} + +	if (args->reserved2_given) { +	  strncpy(tag.reserved2, args->reserved2_arg, 16); +	} + +	if (args->altinfo_given) { +	  strncpy(&tag.information1[0], args->altinfo_arg, ALTTAGINFO_LEN); +	} + +	if (args->second_image_flag_given) { +	  if (strncmp(args->second_image_flag_arg, "2", DUALFLAG_LEN) != 0) {		 +		strncpy(tag.dualImage, args->second_image_flag_arg, DUALFLAG_LEN); +	  } +	} + +	if (args->inactive_given) { +	  if (strncmp(args->inactive_arg, "2", INACTIVEFLAG_LEN) != 0) {		 +		strncpy(tag.inactiveFlag, args->second_image_flag_arg, INACTIVEFLAG_LEN); +	  }  	}  	for (i = 0; i < NUM_PIRELLI; i++) { -		if (strncmp(boardid, pirellitab[i], BOARDID_LEN) == 0) { +		if (strncmp(args->boardid_arg, pirellitab[i], BOARDID_LEN) == 0) {  			is_pirelli = 1;  			break;  		}  	}  	if ( !is_pirelli ) { -		int2tag(tag.imageCRC, imagecrc); +	  int2tag(tag.imageCRC, kernelfscrc);  	} else { -	        int2tag(tag.imageCRC, kernelcrc); +	  int2tag(tag.imageCRC, kernelcrc);  	} -        int2tag(tag.kernelCRC, kernelcrc); -        int2tag(tag.rootfsCRC, rootfscrc); + +	int2tag(&(tag.rootfsCRC[0]), rootfscrc); +	int2tag(tag.kernelCRC, kernelcrc);  	int2tag(tag.fskernelCRC, kernelfscrc);  	int2tag(tag.headerCRC, crc32(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20));  	fseek(binfile, 0L, SEEK_SET);  	fwrite(&tag, sizeof(uint8_t), sizeof(tag), binfile); +    fflush(binfile);  	fclose(binfile);  	return 0; @@ -301,122 +413,93 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,  int main(int argc, char **argv)  { -        int c, i; -	char *kernel, *rootfs, *bin, *boardid, *chipid, *magic2, *ver, *tagid, *rsignature, *layoutver; -	uint32_t flashstart, fwoffset, loadaddr, entry; -	uint32_t fwaddr, flash_bs; -	int tagidfound = 0; +    int c, i; +	char *kernel, *rootfs, *bin; +	uint32_t flash_start, image_offset, block_size, load_address, entry; +	flash_start = image_offset = block_size = load_address = entry = 0; +	struct gengetopt_args_info parsed_args; -	kernel = rootfs = bin = boardid = chipid = magic2 = ver = rsignature = layoutver = NULL; -	entry = 0; +	kernel = rootfs = bin = NULL; -	flashstart = DEFAULT_FLASH_START; -	fwoffset = DEFAULT_FW_OFFSET; -	loadaddr = IMAGETAG_DEFAULT_LOADADDR; -	flash_bs = DEFAULT_FLASH_BS; +	if (cmdline_parser(argc, argv, &parsed_args)) { +	  exit(1); +	} -	printf("Broadcom image tagger - v1.0.0\n"); +	printf("Broadcom 63xx image tagger - v2.0.0\n");  	printf("Copyright (C) 2008 Axel Gembe\n");  	printf("Copyright (C) 2009-2010 Daniel Dickinson\n"); - -	while ((c = getopt(argc, argv, "i:f:o:b:c:s:n:v:m:k:l:e:h:r:y:")) != -1) { -		switch (c) { -			case 'i': -				kernel = optarg; -				break; -			case 'f': -				rootfs = optarg; -				break; -			case 'o': -				bin = optarg; -				break; -			case 'b': -				boardid = optarg; -				break; -			case 'c': -				chipid = optarg; -				break; -			case 's': -				flashstart = strtoul(optarg, NULL, 16); -				break; -			case 'n': -				fwoffset = strtoul(optarg, NULL, 16); -				break; -			case 'v': -				ver = optarg; -				break; -			case 'm': -				magic2 = optarg; -				break; -			case 'k': -				flash_bs = strtoul(optarg, NULL, 16); -				break; -			case 'l': -				loadaddr = strtoul(optarg, NULL, 16); -				break; -			case 'e': -				entry = strtoul(optarg, NULL, 16); -				break; -		        case 'r': -			        rsignature = optarg; -				break; -		        case 'y': -			        layoutver = optarg; -				break; -			case 'h': -			default: -				fprintf(stderr, "Usage: imagetag <parameters>\n\n"); -				fprintf(stderr, "	-i <kernel>		- The LZMA compressed kernel file to include in the image\n"); -				fprintf(stderr, "	-f <rootfs>		- The RootFS file to include in the image\n"); -				fprintf(stderr, "	-o <bin>		- The output file\n"); -				fprintf(stderr, "	-b <boardid>		- The board id to set in the image (i.e. \"96345GW2\")\n"); -				fprintf(stderr, "	-c <chipid>		- The chip id to set in the image (i.e. \"6345\")\n"); -				fprintf(stderr, "	-s <flashstart> 	- Flash start address (i.e. \"0xBFC00000\"\n"); -				fprintf(stderr, "	-n <fwoffset>   	- \n"); -				fprintf(stderr, "	-v <version>		- \n"); -				fprintf(stderr, "	-m <magic2>		- \n"); -				fprintf(stderr, "	-k <flash_bs>		- flash erase block size\n"); -				fprintf(stderr, "	-l <loadaddr>		- Address where the kernel expects to be loaded (defaults to 0x80010000)\n"); -				fprintf(stderr, "	-e <entry>		- Address where the kernel entry point will end up\n"); -				fprintf(stderr, "       -r <signature>          - vendor specific signature, for those that need it"); -				fprintf(stderr, "       -y <layoutver>          - Flash Layout Version (2.2x code versions need this)"); -				fprintf(stderr, "	-h			- Displays this text\n\n"); -				return 1; -		} +	printf("Licensed under the terms of the Gnu General Public License\n"); + +	kernel = parsed_args.kernel_arg; +	rootfs = parsed_args.rootfs_arg; +	bin = parsed_args.output_arg; +	if (strlen(parsed_args.tag_version_arg) >= TAGVER_LEN) { +	  fprintf(stderr, "Error: Tag Version (tag_version,v) too long.\n"); +	  exit(1);  	} - -	if (!boardid || !chipid) { -		fprintf(stderr, "You need to specify the board (-b) and chip id (-c)!\n"); -		return 1; +	if (strlen(parsed_args.boardid_arg) >= BOARDID_LEN) { +	  fprintf(stderr, "Error: Board ID (boardid,b) too long.\n"); +	  exit(1);  	} - -	if (entry == 0) { -		fprintf(stderr, "You need to specify the kernel entry (-e)\n"); -		return 1; +	if (strlen(parsed_args.chipid_arg) >= CHIPID_LEN) { +	  fprintf(stderr, "Error: Chip ID (chipid,c) too long.\n"); +	  exit(1);  	} - -	/* Fallback to defaults */ - -	fwaddr = flashstart + fwoffset; - -	if (!magic2) { -		magic2 = malloc(sizeof(char) * 14); -		if (!magic2) { -			perror("malloc"); -			return 1; -		} -		strcpy(magic2, IMAGETAG_MAGIC2); +	if (strlen(parsed_args.signature_arg) >= SIG1_LEN) { +	  fprintf(stderr, "Error: Magic string (signature,a) too long.\n"); +	  exit(1); +	} +	if (strlen(parsed_args.signature2_arg) >= SIG2_LEN) { +	  fprintf(stderr, "Error: Second magic string (signature2,m) too long.\n"); +	  exit(1); +	} +	if (parsed_args.layoutver_given) { +	  if (strlen(parsed_args.layoutver_arg) > FLASHLAYOUTVER_LEN) { +		fprintf(stderr, "Error: Flash layout version (layoutver,y) too long.\n"); +		exit(1); +	  } +	} +	if (parsed_args.rsa_signature_given) { +	  if (strlen(parsed_args.rsa_signature_arg) > RSASIG_LEN) { +		fprintf(stderr, "Error: RSA Signature (rsa_signature,r) too long.\n"); +		exit(1); +	  }  	} -	if (!ver) { -		ver = malloc(sizeof(char) * 4); -		if (!ver) { -			perror("malloc"); -			return 1; -		} -		strcpy(ver, IMAGETAG_VER); +	if (parsed_args.info1_given) { +	  if (strlen(parsed_args.info1_arg) >= TAGINFO1_LEN) { +		fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); +		exit(1); +	  }  	} +	if (parsed_args.info2_given) { +	  if (strlen(parsed_args.info2_arg) >= TAGINFO2_LEN) { +		fprintf(stderr, "Error: Vendor Information 2 (info2) too long.\n"); +		exit(1); +	  } +	} -	return tagfile(kernel, rootfs, bin, boardid, chipid, fwaddr, loadaddr, entry, ver, magic2, flash_bs, rsignature, layoutver); +	if (parsed_args.altinfo_given) { +	  if (strlen(parsed_args.altinfo_arg) >= ALTTAGINFO_LEN) { +		fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); +		exit(1); +	  } +	} +	flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16); +	image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16); +	block_size = strtoul(parsed_args.block_size_arg, NULL, 16); + +	if (!parsed_args.kernel_file_has_header_flag) { +	  load_address = strtoul(parsed_args.load_addr_arg, NULL, 16); +	  entry = strtoul(parsed_args.entry_arg, NULL, 16); +	  if (load_address == 0) { +		fprintf(stderr, "Error: Invalid value for load address\n"); +	  } +	  if (entry == 0) { +		fprintf(stderr, "Error: Invalid value for entry\n"); +	  } +	} +	 +	return tagfile(kernel, rootfs, bin, &parsed_args, flash_start, image_offset, block_size, load_address, entry);  } diff --git a/tools/firmware-utils/src/imagetag.ggo b/tools/firmware-utils/src/imagetag.ggo new file mode 100644 index 000000000..4b9d5d361 --- /dev/null +++ b/tools/firmware-utils/src/imagetag.ggo @@ -0,0 +1,45 @@ +# Command line option parsing generator file for imagetag +# Supplied-To: gengetopt +# +# Copyright 2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> +# +# This file is subject to the terms and conditions of the GNU General Public +# License.  See the file "COPYING" in the main directory of this archive +# for more details. +# + +package "imagetag" +version "2.0.0" +purpose "Generate image with CFE imagetag for Broadcom 63xx routers." +description "Copyright (C) 2008 Axel Gembe +Copyright (C) 2009-2010 Daniel Dickinson +Licensed unter the terms of the Gnu General Public License. + +Given a root filesystem, a linux kernel, and an optional CFE, generates an image with an imagetag for a Broadcom 63xx-based router.  Additional parameters to be specified depend on the specfic brand and model of router." +args "--file-name=imagetag_cmdline" + +option "kernel" i "File with LZMA compressed kernel to include in the image." string typestr="filename"  required +option "rootfs" f "File with RootFS to include in the image." string typestr="filename" required +option "output" o "Name of output file." string typestr="filename" required +option "cfe" - "File with CFE to include in the image." string typestr="filename" optional +option "boardid" b "Board ID to set in the image (must match what router expects, e.g. \"96345GW2\")." string required +option "chipid" c "Chip ID to set in the image (must match the actual hardware, e.g. \"6345\")." string required +option "flash-start" s "Flash start address." string typestr="address" optional default="0xBFC00000" +option "image-offset" n "Offset from start address for the first byte after the CFE (in memory)." string typestr="offset" default="0x10000" optional +option "tag-version" v "Version number for imagetag format." string default="6" optional +option "signature" a "Magic string (signature), for boards that need it." string default="Broadcom Corporatio" optional +option "signature2" m "Second magic string (signature2)." string default="ver. 2.0" optional +option "block-size" k "Flash erase block size." string optional default="0x10000" +option "load-addr" l "Kernel load address." string typestr="address" required +option "entry" e "Address where the kernel entry point will be for booting." string typestr="address" required +option "layoutver" y "Flash layout version (version 2.2x of the Broadcom code requires this)." string optional +option "info1" 1 "String for first vendor information section." string optional +option "altinfo" - "String for vendor information section (alternate/pirelli)." string optional +option "info2" 2 "String for second vendor information section." string optional +option "root-first" - "Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory)." flag off +option "rsa-signature" r "String for RSA Signature section." string optional +option "second-image-flag" - "Dual Image Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional +option "inactive" - "Inactive Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional +option "reserved1" - "String for first reserved section." string optional +option "reserved2" - "String for second reserved section." string optional +option "kernel-file-has-header" - "Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed" flag off diff --git a/tools/firmware-utils/src/imagetag_cmdline.c b/tools/firmware-utils/src/imagetag_cmdline.c new file mode 100644 index 000000000..85f214bc6 --- /dev/null +++ b/tools/firmware-utils/src/imagetag_cmdline.c @@ -0,0 +1,1163 @@ +/* +  File autogenerated by gengetopt version 2.22.4 +  generated with the following command: +  gengetopt --file-name=imagetag_cmdline --file-name=imagetag_cmdline + +  The developers of gengetopt consider the fixed text that goes in all +  gengetopt output files to be in the public domain: +  we make no copyright claims on it. +*/ + +/* If we use autoconf.  */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef FIX_UNUSED +#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ +#endif + +#include <getopt.h> + +#include "imagetag_cmdline.h" + +const char *gengetopt_args_info_purpose = "Generate image with CFE imagetag for Broadcom 63xx routers."; + +const char *gengetopt_args_info_usage = "Usage: imagetag [OPTIONS]..."; + +const char *gengetopt_args_info_description = "Copyright (C) 2008 Axel Gembe\nCopyright (C) 2009-2010 Daniel Dickinson\nLicensed unter the terms of the Gnu General Public License.\n\nGiven a root filesystem, a linux kernel, and an optional CFE, generates an \nimage with an imagetag for a Broadcom 63xx-based router.  Additional parameters \nto be specified depend on the specfic brand and model of router."; + +const char *gengetopt_args_info_help[] = { +  "  -h, --help                    Print help and exit", +  "  -V, --version                 Print version and exit", +  "  -i, --kernel=filename         File with LZMA compressed kernel to include in \n                                  the image.", +  "  -f, --rootfs=filename         File with RootFS to include in the image.", +  "  -o, --output=filename         Name of output file.", +  "      --cfe=filename            File with CFE to include in the image.", +  "  -b, --boardid=STRING          Board ID to set in the image (must match what \n                                  router expects, e.g. \"96345GW2\").", +  "  -c, --chipid=STRING           Chip ID to set in the image (must match the \n                                  actual hardware, e.g. \"6345\").", +  "  -s, --flash-start=address     Flash start address.  (default=`0xBFC00000')", +  "  -n, --image-offset=offset     Offset from start address for the first byte \n                                  after the CFE (in memory).  \n                                  (default=`0x10000')", +  "  -v, --tag-version=STRING      Version number for imagetag format.  \n                                  (default=`6')", +  "  -a, --signature=STRING        Magic string (signature), for boards that need \n                                  it.  (default=`Broadcom Corporatio')", +  "  -m, --signature2=STRING       Second magic string (signature2).  \n                                  (default=`ver. 2.0')", +  "  -k, --block-size=STRING       Flash erase block size.  (default=`0x10000')", +  "  -l, --load-addr=address       Kernel load address.", +  "  -e, --entry=address           Address where the kernel entry point will be \n                                  for booting.", +  "  -y, --layoutver=STRING        Flash layout version (version 2.2x of the \n                                  Broadcom code requires this).", +  "  -1, --info1=STRING            String for first vendor information section.", +  "      --altinfo=STRING          String for vendor information section \n                                  (alternate/pirelli).", +  "  -2, --info2=STRING            String for second vendor information section.", +  "      --root-first              Put the rootfs before the kernel (only for \n                                  stock images, e.g. captured from the router's \n                                  flash memory).  (default=off)", +  "  -r, --rsa-signature=STRING    String for RSA Signature section.", +  "      --second-image-flag=flag-value\n                                Dual Image Flag (2=not-specified).  (possible \n                                  values=\"0\", \"1\", \"2\" default=`2')", +  "      --inactive=flag-value     Inactive Flag (2=not-specified).  (possible \n                                  values=\"0\", \"1\", \"2\" default=`2')", +  "      --reserved1=STRING        String for first reserved section.", +  "      --reserved2=STRING        String for second reserved section.", +  "      --kernel-file-has-header  Indicates that the kernel file includes the \n                                  kernel header with correct load address and \n                                  entry point, so no changes are needed  \n                                  (default=off)", +    0 +}; + +typedef enum {ARG_NO +  , ARG_FLAG +  , ARG_STRING +} cmdline_parser_arg_type; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, +                        struct cmdline_parser_params *params, const char *additional_error); + +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); + +const char *cmdline_parser_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */ +const char *cmdline_parser_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */ + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ +  args_info->help_given = 0 ; +  args_info->version_given = 0 ; +  args_info->kernel_given = 0 ; +  args_info->rootfs_given = 0 ; +  args_info->output_given = 0 ; +  args_info->cfe_given = 0 ; +  args_info->boardid_given = 0 ; +  args_info->chipid_given = 0 ; +  args_info->flash_start_given = 0 ; +  args_info->image_offset_given = 0 ; +  args_info->tag_version_given = 0 ; +  args_info->signature_given = 0 ; +  args_info->signature2_given = 0 ; +  args_info->block_size_given = 0 ; +  args_info->load_addr_given = 0 ; +  args_info->entry_given = 0 ; +  args_info->layoutver_given = 0 ; +  args_info->info1_given = 0 ; +  args_info->altinfo_given = 0 ; +  args_info->info2_given = 0 ; +  args_info->root_first_given = 0 ; +  args_info->rsa_signature_given = 0 ; +  args_info->second_image_flag_given = 0 ; +  args_info->inactive_given = 0 ; +  args_info->reserved1_given = 0 ; +  args_info->reserved2_given = 0 ; +  args_info->kernel_file_has_header_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ +  FIX_UNUSED (args_info); +  args_info->kernel_arg = NULL; +  args_info->kernel_orig = NULL; +  args_info->rootfs_arg = NULL; +  args_info->rootfs_orig = NULL; +  args_info->output_arg = NULL; +  args_info->output_orig = NULL; +  args_info->cfe_arg = NULL; +  args_info->cfe_orig = NULL; +  args_info->boardid_arg = NULL; +  args_info->boardid_orig = NULL; +  args_info->chipid_arg = NULL; +  args_info->chipid_orig = NULL; +  args_info->flash_start_arg = gengetopt_strdup ("0xBFC00000"); +  args_info->flash_start_orig = NULL; +  args_info->image_offset_arg = gengetopt_strdup ("0x10000"); +  args_info->image_offset_orig = NULL; +  args_info->tag_version_arg = gengetopt_strdup ("6"); +  args_info->tag_version_orig = NULL; +  args_info->signature_arg = gengetopt_strdup ("Broadcom Corporatio"); +  args_info->signature_orig = NULL; +  args_info->signature2_arg = gengetopt_strdup ("ver. 2.0"); +  args_info->signature2_orig = NULL; +  args_info->block_size_arg = gengetopt_strdup ("0x10000"); +  args_info->block_size_orig = NULL; +  args_info->load_addr_arg = NULL; +  args_info->load_addr_orig = NULL; +  args_info->entry_arg = NULL; +  args_info->entry_orig = NULL; +  args_info->layoutver_arg = NULL; +  args_info->layoutver_orig = NULL; +  args_info->info1_arg = NULL; +  args_info->info1_orig = NULL; +  args_info->altinfo_arg = NULL; +  args_info->altinfo_orig = NULL; +  args_info->info2_arg = NULL; +  args_info->info2_orig = NULL; +  args_info->root_first_flag = 0; +  args_info->rsa_signature_arg = NULL; +  args_info->rsa_signature_orig = NULL; +  args_info->second_image_flag_arg = gengetopt_strdup ("2"); +  args_info->second_image_flag_orig = NULL; +  args_info->inactive_arg = gengetopt_strdup ("2"); +  args_info->inactive_orig = NULL; +  args_info->reserved1_arg = NULL; +  args_info->reserved1_orig = NULL; +  args_info->reserved2_arg = NULL; +  args_info->reserved2_orig = NULL; +  args_info->kernel_file_has_header_flag = 0; +   +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + + +  args_info->help_help = gengetopt_args_info_help[0] ; +  args_info->version_help = gengetopt_args_info_help[1] ; +  args_info->kernel_help = gengetopt_args_info_help[2] ; +  args_info->rootfs_help = gengetopt_args_info_help[3] ; +  args_info->output_help = gengetopt_args_info_help[4] ; +  args_info->cfe_help = gengetopt_args_info_help[5] ; +  args_info->boardid_help = gengetopt_args_info_help[6] ; +  args_info->chipid_help = gengetopt_args_info_help[7] ; +  args_info->flash_start_help = gengetopt_args_info_help[8] ; +  args_info->image_offset_help = gengetopt_args_info_help[9] ; +  args_info->tag_version_help = gengetopt_args_info_help[10] ; +  args_info->signature_help = gengetopt_args_info_help[11] ; +  args_info->signature2_help = gengetopt_args_info_help[12] ; +  args_info->block_size_help = gengetopt_args_info_help[13] ; +  args_info->load_addr_help = gengetopt_args_info_help[14] ; +  args_info->entry_help = gengetopt_args_info_help[15] ; +  args_info->layoutver_help = gengetopt_args_info_help[16] ; +  args_info->info1_help = gengetopt_args_info_help[17] ; +  args_info->altinfo_help = gengetopt_args_info_help[18] ; +  args_info->info2_help = gengetopt_args_info_help[19] ; +  args_info->root_first_help = gengetopt_args_info_help[20] ; +  args_info->rsa_signature_help = gengetopt_args_info_help[21] ; +  args_info->second_image_flag_help = gengetopt_args_info_help[22] ; +  args_info->inactive_help = gengetopt_args_info_help[23] ; +  args_info->reserved1_help = gengetopt_args_info_help[24] ; +  args_info->reserved2_help = gengetopt_args_info_help[25] ; +  args_info->kernel_file_has_header_help = gengetopt_args_info_help[26] ; +   +} + +void +cmdline_parser_print_version (void) +{ +  printf ("%s %s\n", +     (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), +     CMDLINE_PARSER_VERSION); +} + +static void print_help_common(void) { +  cmdline_parser_print_version (); + +  if (strlen(gengetopt_args_info_purpose) > 0) +    printf("\n%s\n", gengetopt_args_info_purpose); + +  if (strlen(gengetopt_args_info_usage) > 0) +    printf("\n%s\n", gengetopt_args_info_usage); + +  printf("\n"); + +  if (strlen(gengetopt_args_info_description) > 0) +    printf("%s\n\n", gengetopt_args_info_description); +} + +void +cmdline_parser_print_help (void) +{ +  int i = 0; +  print_help_common(); +  while (gengetopt_args_info_help[i]) +    printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ +  clear_given (args_info); +  clear_args (args_info); +  init_args_info (args_info); +} + +void +cmdline_parser_params_init(struct cmdline_parser_params *params) +{ +  if (params) +    {  +      params->override = 0; +      params->initialize = 1; +      params->check_required = 1; +      params->check_ambiguity = 0; +      params->print_errors = 1; +    } +} + +struct cmdline_parser_params * +cmdline_parser_params_create(void) +{ +  struct cmdline_parser_params *params =  +    (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); +  cmdline_parser_params_init(params);   +  return params; +} + +static void +free_string_field (char **s) +{ +  if (*s) +    { +      free (*s); +      *s = 0; +    } +} + + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + +  free_string_field (&(args_info->kernel_arg)); +  free_string_field (&(args_info->kernel_orig)); +  free_string_field (&(args_info->rootfs_arg)); +  free_string_field (&(args_info->rootfs_orig)); +  free_string_field (&(args_info->output_arg)); +  free_string_field (&(args_info->output_orig)); +  free_string_field (&(args_info->cfe_arg)); +  free_string_field (&(args_info->cfe_orig)); +  free_string_field (&(args_info->boardid_arg)); +  free_string_field (&(args_info->boardid_orig)); +  free_string_field (&(args_info->chipid_arg)); +  free_string_field (&(args_info->chipid_orig)); +  free_string_field (&(args_info->flash_start_arg)); +  free_string_field (&(args_info->flash_start_orig)); +  free_string_field (&(args_info->image_offset_arg)); +  free_string_field (&(args_info->image_offset_orig)); +  free_string_field (&(args_info->tag_version_arg)); +  free_string_field (&(args_info->tag_version_orig)); +  free_string_field (&(args_info->signature_arg)); +  free_string_field (&(args_info->signature_orig)); +  free_string_field (&(args_info->signature2_arg)); +  free_string_field (&(args_info->signature2_orig)); +  free_string_field (&(args_info->block_size_arg)); +  free_string_field (&(args_info->block_size_orig)); +  free_string_field (&(args_info->load_addr_arg)); +  free_string_field (&(args_info->load_addr_orig)); +  free_string_field (&(args_info->entry_arg)); +  free_string_field (&(args_info->entry_orig)); +  free_string_field (&(args_info->layoutver_arg)); +  free_string_field (&(args_info->layoutver_orig)); +  free_string_field (&(args_info->info1_arg)); +  free_string_field (&(args_info->info1_orig)); +  free_string_field (&(args_info->altinfo_arg)); +  free_string_field (&(args_info->altinfo_orig)); +  free_string_field (&(args_info->info2_arg)); +  free_string_field (&(args_info->info2_orig)); +  free_string_field (&(args_info->rsa_signature_arg)); +  free_string_field (&(args_info->rsa_signature_orig)); +  free_string_field (&(args_info->second_image_flag_arg)); +  free_string_field (&(args_info->second_image_flag_orig)); +  free_string_field (&(args_info->inactive_arg)); +  free_string_field (&(args_info->inactive_orig)); +  free_string_field (&(args_info->reserved1_arg)); +  free_string_field (&(args_info->reserved1_orig)); +  free_string_field (&(args_info->reserved2_arg)); +  free_string_field (&(args_info->reserved2_orig)); +   +   + +  clear_given (args_info); +} + +/** + * @param val the value to check + * @param values the possible values + * @return the index of the matched value: + * -1 if no value matched, + * -2 if more than one value has matched + */ +static int +check_possible_values(const char *val, const char *values[]) +{ +  int i, found, last; +  size_t len; + +  if (!val)   /* otherwise strlen() crashes below */ +    return -1; /* -1 means no argument for the option */ + +  found = last = 0; + +  for (i = 0, len = strlen(val); values[i]; ++i) +    { +      if (strncmp(val, values[i], len) == 0) +        { +          ++found; +          last = i; +          if (strlen(values[i]) == len) +            return i; /* exact macth no need to check more */ +        } +    } + +  if (found == 1) /* one match: OK */ +    return last; + +  return (found ? -2 : -1); /* return many values or none matched */ +} + + +static void +write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) +{ +  int found = -1; +  if (arg) { +    if (values) { +      found = check_possible_values(arg, values);       +    } +    if (found >= 0) +      fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); +    else +      fprintf(outfile, "%s=\"%s\"\n", opt, arg); +  } else { +    fprintf(outfile, "%s\n", opt); +  } +} + + +int +cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) +{ +  int i = 0; + +  if (!outfile) +    { +      fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); +      return EXIT_FAILURE; +    } + +  if (args_info->help_given) +    write_into_file(outfile, "help", 0, 0 ); +  if (args_info->version_given) +    write_into_file(outfile, "version", 0, 0 ); +  if (args_info->kernel_given) +    write_into_file(outfile, "kernel", args_info->kernel_orig, 0); +  if (args_info->rootfs_given) +    write_into_file(outfile, "rootfs", args_info->rootfs_orig, 0); +  if (args_info->output_given) +    write_into_file(outfile, "output", args_info->output_orig, 0); +  if (args_info->cfe_given) +    write_into_file(outfile, "cfe", args_info->cfe_orig, 0); +  if (args_info->boardid_given) +    write_into_file(outfile, "boardid", args_info->boardid_orig, 0); +  if (args_info->chipid_given) +    write_into_file(outfile, "chipid", args_info->chipid_orig, 0); +  if (args_info->flash_start_given) +    write_into_file(outfile, "flash-start", args_info->flash_start_orig, 0); +  if (args_info->image_offset_given) +    write_into_file(outfile, "image-offset", args_info->image_offset_orig, 0); +  if (args_info->tag_version_given) +    write_into_file(outfile, "tag-version", args_info->tag_version_orig, 0); +  if (args_info->signature_given) +    write_into_file(outfile, "signature", args_info->signature_orig, 0); +  if (args_info->signature2_given) +    write_into_file(outfile, "signature2", args_info->signature2_orig, 0); +  if (args_info->block_size_given) +    write_into_file(outfile, "block-size", args_info->block_size_orig, 0); +  if (args_info->load_addr_given) +    write_into_file(outfile, "load-addr", args_info->load_addr_orig, 0); +  if (args_info->entry_given) +    write_into_file(outfile, "entry", args_info->entry_orig, 0); +  if (args_info->layoutver_given) +    write_into_file(outfile, "layoutver", args_info->layoutver_orig, 0); +  if (args_info->info1_given) +    write_into_file(outfile, "info1", args_info->info1_orig, 0); +  if (args_info->altinfo_given) +    write_into_file(outfile, "altinfo", args_info->altinfo_orig, 0); +  if (args_info->info2_given) +    write_into_file(outfile, "info2", args_info->info2_orig, 0); +  if (args_info->root_first_given) +    write_into_file(outfile, "root-first", 0, 0 ); +  if (args_info->rsa_signature_given) +    write_into_file(outfile, "rsa-signature", args_info->rsa_signature_orig, 0); +  if (args_info->second_image_flag_given) +    write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, cmdline_parser_second_image_flag_values); +  if (args_info->inactive_given) +    write_into_file(outfile, "inactive", args_info->inactive_orig, cmdline_parser_inactive_values); +  if (args_info->reserved1_given) +    write_into_file(outfile, "reserved1", args_info->reserved1_orig, 0); +  if (args_info->reserved2_given) +    write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0); +  if (args_info->kernel_file_has_header_given) +    write_into_file(outfile, "kernel-file-has-header", 0, 0 ); +   + +  i = EXIT_SUCCESS; +  return i; +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ +  FILE *outfile; +  int i = 0; + +  outfile = fopen(filename, "w"); + +  if (!outfile) +    { +      fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); +      return EXIT_FAILURE; +    } + +  i = cmdline_parser_dump(outfile, args_info); +  fclose (outfile); + +  return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ +  cmdline_parser_release (args_info); +} + +/** @brief replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ +  char *result = 0; +  if (!s) +    return result; + +  result = (char*)malloc(strlen(s) + 1); +  if (result == (char*)0) +    return (char*)0; +  strcpy(result, s); +  return result; +} + +int +cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) +{ +  return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, +                   struct cmdline_parser_params *params) +{ +  int result; +  result = cmdline_parser_internal (argc, argv, args_info, params, 0); + +  if (result == EXIT_FAILURE) +    { +      cmdline_parser_free (args_info); +      exit (EXIT_FAILURE); +    } +   +  return result; +} + +int +cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ +  int result; +  struct cmdline_parser_params params; +   +  params.override = override; +  params.initialize = initialize; +  params.check_required = check_required; +  params.check_ambiguity = 0; +  params.print_errors = 1; + +  result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); + +  if (result == EXIT_FAILURE) +    { +      cmdline_parser_free (args_info); +      exit (EXIT_FAILURE); +    } +   +  return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ +  int result = EXIT_SUCCESS; + +  if (cmdline_parser_required2(args_info, prog_name, 0) > 0) +    result = EXIT_FAILURE; + +  if (result == EXIT_FAILURE) +    { +      cmdline_parser_free (args_info); +      exit (EXIT_FAILURE); +    } +   +  return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ +  int error = 0; +  FIX_UNUSED (additional_error); + +  /* checks for required options */ +  if (! args_info->kernel_given) +    { +      fprintf (stderr, "%s: '--kernel' ('-i') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->rootfs_given) +    { +      fprintf (stderr, "%s: '--rootfs' ('-f') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->output_given) +    { +      fprintf (stderr, "%s: '--output' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->boardid_given) +    { +      fprintf (stderr, "%s: '--boardid' ('-b') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->chipid_given) +    { +      fprintf (stderr, "%s: '--chipid' ('-c') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->load_addr_given) +    { +      fprintf (stderr, "%s: '--load-addr' ('-l') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +  if (! args_info->entry_given) +    { +      fprintf (stderr, "%s: '--entry' ('-e') option required%s\n", prog_name, (additional_error ? additional_error : "")); +      error = 1; +    } +   +   +  /* checks for dependences among options */ + +  return error; +} + + +static char *package_name = 0; + +/** + * @brief updates an option + * @param field the generic pointer to the field to update + * @param orig_field the pointer to the orig field + * @param field_given the pointer to the number of occurrence of this option + * @param prev_given the pointer to the number of occurrence already seen + * @param value the argument for this option (if null no arg was specified) + * @param possible_values the possible values for this option (if specified) + * @param default_value the default value (in case the option only accepts fixed values) + * @param arg_type the type of this option + * @param check_ambiguity @see cmdline_parser_params.check_ambiguity + * @param override @see cmdline_parser_params.override + * @param no_free whether to free a possible previous value + * @param multiple_option whether this is a multiple option + * @param long_opt the corresponding long option + * @param short_opt the corresponding short option (or '-' if none) + * @param additional_error possible further error specification + */ +static +int update_arg(void *field, char **orig_field, +               unsigned int *field_given, unsigned int *prev_given,  +               char *value, const char *possible_values[], +               const char *default_value, +               cmdline_parser_arg_type arg_type, +               int check_ambiguity, int override, +               int no_free, int multiple_option, +               const char *long_opt, char short_opt, +               const char *additional_error) +{ +  char *stop_char = 0; +  const char *val = value; +  int found; +  char **string_field; +  FIX_UNUSED (field); + +  stop_char = 0; +  found = 0; + +  if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) +    { +      if (short_opt != '-') +        fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",  +               package_name, long_opt, short_opt, +               (additional_error ? additional_error : "")); +      else +        fprintf (stderr, "%s: `--%s' option given more than once%s\n",  +               package_name, long_opt, +               (additional_error ? additional_error : "")); +      return 1; /* failure */ +    } + +  if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) +    { +      if (short_opt != '-') +        fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",  +          package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, +          (additional_error ? additional_error : "")); +      else +        fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",  +          package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, +          (additional_error ? additional_error : "")); +      return 1; /* failure */ +    } +     +  if (field_given && *field_given && ! override) +    return 0; +  if (prev_given) +    (*prev_given)++; +  if (field_given) +    (*field_given)++; +  if (possible_values) +    val = possible_values[found]; + +  switch(arg_type) { +  case ARG_FLAG: +    *((int *)field) = !*((int *)field); +    break; +  case ARG_STRING: +    if (val) { +      string_field = (char **)field; +      if (!no_free && *string_field) +        free (*string_field); /* free previous string */ +      *string_field = gengetopt_strdup (val); +    } +    break; +  default: +    break; +  }; + + +  /* store the original value */ +  switch(arg_type) { +  case ARG_NO: +  case ARG_FLAG: +    break; +  default: +    if (value && orig_field) { +      if (no_free) { +        *orig_field = value; +      } else { +        if (*orig_field) +          free (*orig_field); /* free previous string */ +        *orig_field = gengetopt_strdup (value); +      } +    } +  }; + +  return 0; /* OK */ +} + + +int +cmdline_parser_internal ( +  int argc, char **argv, struct gengetopt_args_info *args_info, +                        struct cmdline_parser_params *params, const char *additional_error) +{ +  int c;	/* Character of the parsed option.  */ + +  int error = 0; +  struct gengetopt_args_info local_args_info; +   +  int override; +  int initialize; +  int check_required; +  int check_ambiguity; +   +  package_name = argv[0]; +   +  override = params->override; +  initialize = params->initialize; +  check_required = params->check_required; +  check_ambiguity = params->check_ambiguity; + +  if (initialize) +    cmdline_parser_init (args_info); + +  cmdline_parser_init (&local_args_info); + +  optarg = 0; +  optind = 0; +  opterr = params->print_errors; +  optopt = '?'; + +  while (1) +    { +      int option_index = 0; + +      static struct option long_options[] = { +        { "help",	0, NULL, 'h' }, +        { "version",	0, NULL, 'V' }, +        { "kernel",	1, NULL, 'i' }, +        { "rootfs",	1, NULL, 'f' }, +        { "output",	1, NULL, 'o' }, +        { "cfe",	1, NULL, 0 }, +        { "boardid",	1, NULL, 'b' }, +        { "chipid",	1, NULL, 'c' }, +        { "flash-start",	1, NULL, 's' }, +        { "image-offset",	1, NULL, 'n' }, +        { "tag-version",	1, NULL, 'v' }, +        { "signature",	1, NULL, 'a' }, +        { "signature2",	1, NULL, 'm' }, +        { "block-size",	1, NULL, 'k' }, +        { "load-addr",	1, NULL, 'l' }, +        { "entry",	1, NULL, 'e' }, +        { "layoutver",	1, NULL, 'y' }, +        { "info1",	1, NULL, '1' }, +        { "altinfo",	1, NULL, 0 }, +        { "info2",	1, NULL, '2' }, +        { "root-first",	0, NULL, 0 }, +        { "rsa-signature",	1, NULL, 'r' }, +        { "second-image-flag",	1, NULL, 0 }, +        { "inactive",	1, NULL, 0 }, +        { "reserved1",	1, NULL, 0 }, +        { "reserved2",	1, NULL, 0 }, +        { "kernel-file-has-header",	0, NULL, 0 }, +        { 0,  0, 0, 0 } +      }; + +      c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:", long_options, &option_index); + +      if (c == -1) break;	/* Exit from `while (1)' loop.  */ + +      switch (c) +        { +        case 'h':	/* Print help and exit.  */ +          cmdline_parser_print_help (); +          cmdline_parser_free (&local_args_info); +          exit (EXIT_SUCCESS); + +        case 'V':	/* Print version and exit.  */ +          cmdline_parser_print_version (); +          cmdline_parser_free (&local_args_info); +          exit (EXIT_SUCCESS); + +        case 'i':	/* File with LZMA compressed kernel to include in the image..  */ +         +         +          if (update_arg( (void *)&(args_info->kernel_arg),  +               &(args_info->kernel_orig), &(args_info->kernel_given), +              &(local_args_info.kernel_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "kernel", 'i', +              additional_error)) +            goto failure; +         +          break; +        case 'f':	/* File with RootFS to include in the image..  */ +         +         +          if (update_arg( (void *)&(args_info->rootfs_arg),  +               &(args_info->rootfs_orig), &(args_info->rootfs_given), +              &(local_args_info.rootfs_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "rootfs", 'f', +              additional_error)) +            goto failure; +         +          break; +        case 'o':	/* Name of output file..  */ +         +         +          if (update_arg( (void *)&(args_info->output_arg),  +               &(args_info->output_orig), &(args_info->output_given), +              &(local_args_info.output_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "output", 'o', +              additional_error)) +            goto failure; +         +          break; +        case 'b':	/* Board ID to set in the image (must match what router expects, e.g. \"96345GW2\")..  */ +         +         +          if (update_arg( (void *)&(args_info->boardid_arg),  +               &(args_info->boardid_orig), &(args_info->boardid_given), +              &(local_args_info.boardid_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "boardid", 'b', +              additional_error)) +            goto failure; +         +          break; +        case 'c':	/* Chip ID to set in the image (must match the actual hardware, e.g. \"6345\")..  */ +         +         +          if (update_arg( (void *)&(args_info->chipid_arg),  +               &(args_info->chipid_orig), &(args_info->chipid_given), +              &(local_args_info.chipid_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "chipid", 'c', +              additional_error)) +            goto failure; +         +          break; +        case 's':	/* Flash start address..  */ +         +         +          if (update_arg( (void *)&(args_info->flash_start_arg),  +               &(args_info->flash_start_orig), &(args_info->flash_start_given), +              &(local_args_info.flash_start_given), optarg, 0, "0xBFC00000", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "flash-start", 's', +              additional_error)) +            goto failure; +         +          break; +        case 'n':	/* Offset from start address for the first byte after the CFE (in memory)..  */ +         +         +          if (update_arg( (void *)&(args_info->image_offset_arg),  +               &(args_info->image_offset_orig), &(args_info->image_offset_given), +              &(local_args_info.image_offset_given), optarg, 0, "0x10000", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "image-offset", 'n', +              additional_error)) +            goto failure; +         +          break; +        case 'v':	/* Version number for imagetag format..  */ +         +         +          if (update_arg( (void *)&(args_info->tag_version_arg),  +               &(args_info->tag_version_orig), &(args_info->tag_version_given), +              &(local_args_info.tag_version_given), optarg, 0, "6", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "tag-version", 'v', +              additional_error)) +            goto failure; +         +          break; +        case 'a':	/* Magic string (signature), for boards that need it..  */ +         +         +          if (update_arg( (void *)&(args_info->signature_arg),  +               &(args_info->signature_orig), &(args_info->signature_given), +              &(local_args_info.signature_given), optarg, 0, "Broadcom Corporatio", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "signature", 'a', +              additional_error)) +            goto failure; +         +          break; +        case 'm':	/* Second magic string (signature2)..  */ +         +         +          if (update_arg( (void *)&(args_info->signature2_arg),  +               &(args_info->signature2_orig), &(args_info->signature2_given), +              &(local_args_info.signature2_given), optarg, 0, "ver. 2.0", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "signature2", 'm', +              additional_error)) +            goto failure; +         +          break; +        case 'k':	/* Flash erase block size..  */ +         +         +          if (update_arg( (void *)&(args_info->block_size_arg),  +               &(args_info->block_size_orig), &(args_info->block_size_given), +              &(local_args_info.block_size_given), optarg, 0, "0x10000", ARG_STRING, +              check_ambiguity, override, 0, 0, +              "block-size", 'k', +              additional_error)) +            goto failure; +         +          break; +        case 'l':	/* Kernel load address..  */ +         +         +          if (update_arg( (void *)&(args_info->load_addr_arg),  +               &(args_info->load_addr_orig), &(args_info->load_addr_given), +              &(local_args_info.load_addr_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "load-addr", 'l', +              additional_error)) +            goto failure; +         +          break; +        case 'e':	/* Address where the kernel entry point will be for booting..  */ +         +         +          if (update_arg( (void *)&(args_info->entry_arg),  +               &(args_info->entry_orig), &(args_info->entry_given), +              &(local_args_info.entry_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "entry", 'e', +              additional_error)) +            goto failure; +         +          break; +        case 'y':	/* Flash layout version (version 2.2x of the Broadcom code requires this)..  */ +         +         +          if (update_arg( (void *)&(args_info->layoutver_arg),  +               &(args_info->layoutver_orig), &(args_info->layoutver_given), +              &(local_args_info.layoutver_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "layoutver", 'y', +              additional_error)) +            goto failure; +         +          break; +        case '1':	/* String for first vendor information section..  */ +         +         +          if (update_arg( (void *)&(args_info->info1_arg),  +               &(args_info->info1_orig), &(args_info->info1_given), +              &(local_args_info.info1_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "info1", '1', +              additional_error)) +            goto failure; +         +          break; +        case '2':	/* String for second vendor information section..  */ +         +         +          if (update_arg( (void *)&(args_info->info2_arg),  +               &(args_info->info2_orig), &(args_info->info2_given), +              &(local_args_info.info2_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "info2", '2', +              additional_error)) +            goto failure; +         +          break; +        case 'r':	/* String for RSA Signature section..  */ +         +         +          if (update_arg( (void *)&(args_info->rsa_signature_arg),  +               &(args_info->rsa_signature_orig), &(args_info->rsa_signature_given), +              &(local_args_info.rsa_signature_given), optarg, 0, 0, ARG_STRING, +              check_ambiguity, override, 0, 0, +              "rsa-signature", 'r', +              additional_error)) +            goto failure; +         +          break; + +        case 0:	/* Long option with no short option */ +          /* File with CFE to include in the image..  */ +          if (strcmp (long_options[option_index].name, "cfe") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->cfe_arg),  +                 &(args_info->cfe_orig), &(args_info->cfe_given), +                &(local_args_info.cfe_given), optarg, 0, 0, ARG_STRING, +                check_ambiguity, override, 0, 0, +                "cfe", '-', +                additional_error)) +              goto failure; +           +          } +          /* String for vendor information section (alternate/pirelli)..  */ +          else if (strcmp (long_options[option_index].name, "altinfo") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->altinfo_arg),  +                 &(args_info->altinfo_orig), &(args_info->altinfo_given), +                &(local_args_info.altinfo_given), optarg, 0, 0, ARG_STRING, +                check_ambiguity, override, 0, 0, +                "altinfo", '-', +                additional_error)) +              goto failure; +           +          } +          /* Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory)..  */ +          else if (strcmp (long_options[option_index].name, "root-first") == 0) +          { +           +           +            if (update_arg((void *)&(args_info->root_first_flag), 0, &(args_info->root_first_given), +                &(local_args_info.root_first_given), optarg, 0, 0, ARG_FLAG, +                check_ambiguity, override, 1, 0, "root-first", '-', +                additional_error)) +              goto failure; +           +          } +          /* Dual Image Flag (2=not-specified)..  */ +          else if (strcmp (long_options[option_index].name, "second-image-flag") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->second_image_flag_arg),  +                 &(args_info->second_image_flag_orig), &(args_info->second_image_flag_given), +                &(local_args_info.second_image_flag_given), optarg, cmdline_parser_second_image_flag_values, "2", ARG_STRING, +                check_ambiguity, override, 0, 0, +                "second-image-flag", '-', +                additional_error)) +              goto failure; +           +          } +          /* Inactive Flag (2=not-specified)..  */ +          else if (strcmp (long_options[option_index].name, "inactive") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->inactive_arg),  +                 &(args_info->inactive_orig), &(args_info->inactive_given), +                &(local_args_info.inactive_given), optarg, cmdline_parser_inactive_values, "2", ARG_STRING, +                check_ambiguity, override, 0, 0, +                "inactive", '-', +                additional_error)) +              goto failure; +           +          } +          /* String for first reserved section..  */ +          else if (strcmp (long_options[option_index].name, "reserved1") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->reserved1_arg),  +                 &(args_info->reserved1_orig), &(args_info->reserved1_given), +                &(local_args_info.reserved1_given), optarg, 0, 0, ARG_STRING, +                check_ambiguity, override, 0, 0, +                "reserved1", '-', +                additional_error)) +              goto failure; +           +          } +          /* String for second reserved section..  */ +          else if (strcmp (long_options[option_index].name, "reserved2") == 0) +          { +           +           +            if (update_arg( (void *)&(args_info->reserved2_arg),  +                 &(args_info->reserved2_orig), &(args_info->reserved2_given), +                &(local_args_info.reserved2_given), optarg, 0, 0, ARG_STRING, +                check_ambiguity, override, 0, 0, +                "reserved2", '-', +                additional_error)) +              goto failure; +           +          } +          /* Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed.  */ +          else if (strcmp (long_options[option_index].name, "kernel-file-has-header") == 0) +          { +           +           +            if (update_arg((void *)&(args_info->kernel_file_has_header_flag), 0, &(args_info->kernel_file_has_header_given), +                &(local_args_info.kernel_file_has_header_given), optarg, 0, 0, ARG_FLAG, +                check_ambiguity, override, 1, 0, "kernel-file-has-header", '-', +                additional_error)) +              goto failure; +           +          } +           +          break; +        case '?':	/* Invalid option.  */ +          /* `getopt_long' already printed an error message.  */ +          goto failure; + +        default:	/* bug: option not considered.  */ +          fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); +          abort (); +        } /* switch */ +    } /* while */ + + + +  if (check_required) +    { +      error += cmdline_parser_required2 (args_info, argv[0], additional_error); +    } + +  cmdline_parser_release (&local_args_info); + +  if ( error ) +    return (EXIT_FAILURE); + +  return 0; + +failure: +   +  cmdline_parser_release (&local_args_info); +  return (EXIT_FAILURE); +} diff --git a/tools/firmware-utils/src/imagetag_cmdline.h b/tools/firmware-utils/src/imagetag_cmdline.h new file mode 100644 index 000000000..a38914841 --- /dev/null +++ b/tools/firmware-utils/src/imagetag_cmdline.h @@ -0,0 +1,272 @@ +/** @file imagetag_cmdline.h + *  @brief The header file for the command line option parser + *  generated by GNU Gengetopt version 2.22.4 + *  http://www.gnu.org/software/gengetopt. + *  DO NOT modify this file, since it can be overwritten + *  @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef IMAGETAG_CMDLINE_H +#define IMAGETAG_CMDLINE_H + +/* If we use autoconf.  */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> /* for FILE */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name (used for printing errors) */ +#define CMDLINE_PARSER_PACKAGE "imagetag" +#endif + +#ifndef CMDLINE_PARSER_PACKAGE_NAME +/** @brief the complete program name (used for help and version) */ +#define CMDLINE_PARSER_PACKAGE_NAME "imagetag" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION "2.0.0" +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ +  const char *help_help; /**< @brief Print help and exit help description.  */ +  const char *version_help; /**< @brief Print version and exit help description.  */ +  char * kernel_arg;	/**< @brief File with LZMA compressed kernel to include in the image..  */ +  char * kernel_orig;	/**< @brief File with LZMA compressed kernel to include in the image. original value given at command line.  */ +  const char *kernel_help; /**< @brief File with LZMA compressed kernel to include in the image. help description.  */ +  char * rootfs_arg;	/**< @brief File with RootFS to include in the image..  */ +  char * rootfs_orig;	/**< @brief File with RootFS to include in the image. original value given at command line.  */ +  const char *rootfs_help; /**< @brief File with RootFS to include in the image. help description.  */ +  char * output_arg;	/**< @brief Name of output file..  */ +  char * output_orig;	/**< @brief Name of output file. original value given at command line.  */ +  const char *output_help; /**< @brief Name of output file. help description.  */ +  char * cfe_arg;	/**< @brief File with CFE to include in the image..  */ +  char * cfe_orig;	/**< @brief File with CFE to include in the image. original value given at command line.  */ +  const char *cfe_help; /**< @brief File with CFE to include in the image. help description.  */ +  char * boardid_arg;	/**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\")..  */ +  char * boardid_orig;	/**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\"). original value given at command line.  */ +  const char *boardid_help; /**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\"). help description.  */ +  char * chipid_arg;	/**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\")..  */ +  char * chipid_orig;	/**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\"). original value given at command line.  */ +  const char *chipid_help; /**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\"). help description.  */ +  char * flash_start_arg;	/**< @brief Flash start address. (default='0xBFC00000').  */ +  char * flash_start_orig;	/**< @brief Flash start address. original value given at command line.  */ +  const char *flash_start_help; /**< @brief Flash start address. help description.  */ +  char * image_offset_arg;	/**< @brief Offset from start address for the first byte after the CFE (in memory). (default='0x10000').  */ +  char * image_offset_orig;	/**< @brief Offset from start address for the first byte after the CFE (in memory). original value given at command line.  */ +  const char *image_offset_help; /**< @brief Offset from start address for the first byte after the CFE (in memory). help description.  */ +  char * tag_version_arg;	/**< @brief Version number for imagetag format. (default='6').  */ +  char * tag_version_orig;	/**< @brief Version number for imagetag format. original value given at command line.  */ +  const char *tag_version_help; /**< @brief Version number for imagetag format. help description.  */ +  char * signature_arg;	/**< @brief Magic string (signature), for boards that need it. (default='Broadcom Corporatio').  */ +  char * signature_orig;	/**< @brief Magic string (signature), for boards that need it. original value given at command line.  */ +  const char *signature_help; /**< @brief Magic string (signature), for boards that need it. help description.  */ +  char * signature2_arg;	/**< @brief Second magic string (signature2). (default='ver. 2.0').  */ +  char * signature2_orig;	/**< @brief Second magic string (signature2). original value given at command line.  */ +  const char *signature2_help; /**< @brief Second magic string (signature2). help description.  */ +  char * block_size_arg;	/**< @brief Flash erase block size. (default='0x10000').  */ +  char * block_size_orig;	/**< @brief Flash erase block size. original value given at command line.  */ +  const char *block_size_help; /**< @brief Flash erase block size. help description.  */ +  char * load_addr_arg;	/**< @brief Kernel load address..  */ +  char * load_addr_orig;	/**< @brief Kernel load address. original value given at command line.  */ +  const char *load_addr_help; /**< @brief Kernel load address. help description.  */ +  char * entry_arg;	/**< @brief Address where the kernel entry point will be for booting..  */ +  char * entry_orig;	/**< @brief Address where the kernel entry point will be for booting. original value given at command line.  */ +  const char *entry_help; /**< @brief Address where the kernel entry point will be for booting. help description.  */ +  char * layoutver_arg;	/**< @brief Flash layout version (version 2.2x of the Broadcom code requires this)..  */ +  char * layoutver_orig;	/**< @brief Flash layout version (version 2.2x of the Broadcom code requires this). original value given at command line.  */ +  const char *layoutver_help; /**< @brief Flash layout version (version 2.2x of the Broadcom code requires this). help description.  */ +  char * info1_arg;	/**< @brief String for first vendor information section..  */ +  char * info1_orig;	/**< @brief String for first vendor information section. original value given at command line.  */ +  const char *info1_help; /**< @brief String for first vendor information section. help description.  */ +  char * altinfo_arg;	/**< @brief String for vendor information section (alternate/pirelli)..  */ +  char * altinfo_orig;	/**< @brief String for vendor information section (alternate/pirelli). original value given at command line.  */ +  const char *altinfo_help; /**< @brief String for vendor information section (alternate/pirelli). help description.  */ +  char * info2_arg;	/**< @brief String for second vendor information section..  */ +  char * info2_orig;	/**< @brief String for second vendor information section. original value given at command line.  */ +  const char *info2_help; /**< @brief String for second vendor information section. help description.  */ +  int root_first_flag;	/**< @brief Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory). (default=off).  */ +  const char *root_first_help; /**< @brief Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory). help description.  */ +  char * rsa_signature_arg;	/**< @brief String for RSA Signature section..  */ +  char * rsa_signature_orig;	/**< @brief String for RSA Signature section. original value given at command line.  */ +  const char *rsa_signature_help; /**< @brief String for RSA Signature section. help description.  */ +  char * second_image_flag_arg;	/**< @brief Dual Image Flag (2=not-specified). (default='2').  */ +  char * second_image_flag_orig;	/**< @brief Dual Image Flag (2=not-specified). original value given at command line.  */ +  const char *second_image_flag_help; /**< @brief Dual Image Flag (2=not-specified). help description.  */ +  char * inactive_arg;	/**< @brief Inactive Flag (2=not-specified). (default='2').  */ +  char * inactive_orig;	/**< @brief Inactive Flag (2=not-specified). original value given at command line.  */ +  const char *inactive_help; /**< @brief Inactive Flag (2=not-specified). help description.  */ +  char * reserved1_arg;	/**< @brief String for first reserved section..  */ +  char * reserved1_orig;	/**< @brief String for first reserved section. original value given at command line.  */ +  const char *reserved1_help; /**< @brief String for first reserved section. help description.  */ +  char * reserved2_arg;	/**< @brief String for second reserved section..  */ +  char * reserved2_orig;	/**< @brief String for second reserved section. original value given at command line.  */ +  const char *reserved2_help; /**< @brief String for second reserved section. help description.  */ +  int kernel_file_has_header_flag;	/**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed (default=off).  */ +  const char *kernel_file_has_header_help; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed help description.  */ +   +  unsigned int help_given ;	/**< @brief Whether help was given.  */ +  unsigned int version_given ;	/**< @brief Whether version was given.  */ +  unsigned int kernel_given ;	/**< @brief Whether kernel was given.  */ +  unsigned int rootfs_given ;	/**< @brief Whether rootfs was given.  */ +  unsigned int output_given ;	/**< @brief Whether output was given.  */ +  unsigned int cfe_given ;	/**< @brief Whether cfe was given.  */ +  unsigned int boardid_given ;	/**< @brief Whether boardid was given.  */ +  unsigned int chipid_given ;	/**< @brief Whether chipid was given.  */ +  unsigned int flash_start_given ;	/**< @brief Whether flash-start was given.  */ +  unsigned int image_offset_given ;	/**< @brief Whether image-offset was given.  */ +  unsigned int tag_version_given ;	/**< @brief Whether tag-version was given.  */ +  unsigned int signature_given ;	/**< @brief Whether signature was given.  */ +  unsigned int signature2_given ;	/**< @brief Whether signature2 was given.  */ +  unsigned int block_size_given ;	/**< @brief Whether block-size was given.  */ +  unsigned int load_addr_given ;	/**< @brief Whether load-addr was given.  */ +  unsigned int entry_given ;	/**< @brief Whether entry was given.  */ +  unsigned int layoutver_given ;	/**< @brief Whether layoutver was given.  */ +  unsigned int info1_given ;	/**< @brief Whether info1 was given.  */ +  unsigned int altinfo_given ;	/**< @brief Whether altinfo was given.  */ +  unsigned int info2_given ;	/**< @brief Whether info2 was given.  */ +  unsigned int root_first_given ;	/**< @brief Whether root-first was given.  */ +  unsigned int rsa_signature_given ;	/**< @brief Whether rsa-signature was given.  */ +  unsigned int second_image_flag_given ;	/**< @brief Whether second-image-flag was given.  */ +  unsigned int inactive_given ;	/**< @brief Whether inactive was given.  */ +  unsigned int reserved1_given ;	/**< @brief Whether reserved1 was given.  */ +  unsigned int reserved2_given ;	/**< @brief Whether reserved2 was given.  */ +  unsigned int kernel_file_has_header_given ;	/**< @brief Whether kernel-file-has-header was given.  */ + +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ +  int override; /**< @brief whether to override possibly already present options (default 0) */ +  int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ +  int check_required; /**< @brief whether to check that all required options were provided (default 1) */ +  int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ +  int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char **argv, +  struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char **argv, +  struct gengetopt_args_info *args_info, +  int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char **argv, +  struct gengetopt_args_info *args_info, +  struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into an already open FILE stream. + * @param outfile the stream where to dump options + * @param args_info the option struct to dump + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_dump(FILE *outfile, +  struct gengetopt_args_info *args_info); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, +  struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Initializes all the fields a cmdline_parser_params structure  + * to their default values + * @param params the structure to initialize + */ +void cmdline_parser_params_init(struct cmdline_parser_params *params); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to their default values + * @return the created and initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_create(void); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + *   possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, +  const char *prog_name); + +extern const char *cmdline_parser_second_image_flag_values[];  /**< @brief Possible values for second-image-flag. */ +extern const char *cmdline_parser_inactive_values[];  /**< @brief Possible values for inactive. */ + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* IMAGETAG_CMDLINE_H */ | 
