firmware-utils: image generator for D-Link DAP-1330
Signed-off-by: Nicolò Veronese <nicveronese@gmail.com>
This commit is contained in:
		
				
					committed by
					
						
						Matthias Schiffer
					
				
			
			
				
	
			
			
			
						parent
						
							e9eb9393f4
						
					
				
				
					commit
					0d8a0a6a17
				
			@@ -63,6 +63,7 @@ define Host/Compile
 | 
			
		||||
	$(call cc,mkbrncmdline)
 | 
			
		||||
	$(call cc,mkbrnimg)
 | 
			
		||||
	$(call cc,mkdapimg)
 | 
			
		||||
	$(call cc,mkdapimg2)
 | 
			
		||||
	$(call cc, mkcameofw, -Wall)
 | 
			
		||||
	$(call cc,seama md5)
 | 
			
		||||
	$(call cc,oseama md5, -Wall)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										204
									
								
								tools/firmware-utils/src/mkdapimg2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								tools/firmware-utils/src/mkdapimg2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License,
 | 
			
		||||
 * version 2 as published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 * (C) Nicolò Veronese <nicveronese@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <getopt.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>	// htonl
 | 
			
		||||
 | 
			
		||||
// Usage: mkdapimg2 -s signature [-v version] [-r region]
 | 
			
		||||
//                  [-k uImage block size] -i <input> -o <output>
 | 
			
		||||
//
 | 
			
		||||
// NOTE: The kernel block size is used to know the offset of the rootfs
 | 
			
		||||
// in the image file.
 | 
			
		||||
//
 | 
			
		||||
// The system writes in the uImage partition until the end of uImage
 | 
			
		||||
// is reached, after that, the system jumps to the offset specified with the -k
 | 
			
		||||
// parameter and begin writing at the beginning of the rootfs MTD partition.
 | 
			
		||||
//
 | 
			
		||||
// If the -k parameter is the size of the original uImage partition, the system
 | 
			
		||||
// continue writing in the rootfs partition starting from the last block
 | 
			
		||||
// that has been wrote. (This is useful if the new kernel size is
 | 
			
		||||
// different from the original one)
 | 
			
		||||
//
 | 
			
		||||
// Example:
 | 
			
		||||
// ------------------------------------------
 | 
			
		||||
// Creating 7 MTD partitions on "ath-nor0":
 | 
			
		||||
// 0x000000000000-0x000000010000 : "u-boot"
 | 
			
		||||
// 0x000000010000-0x000000020000 : "ART"
 | 
			
		||||
// 0x000000020000-0x000000030000 : "MP"
 | 
			
		||||
// 0x000000030000-0x000000040000 : "config"
 | 
			
		||||
// 0x000000040000-0x000000120000 : "uImage"
 | 
			
		||||
// 0x000000120000-0x000000800000 : "rootfs"
 | 
			
		||||
// 0x000000040000-0x000000800000 : "firmware"
 | 
			
		||||
// ------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// 0x000000120000-0x000000040000 = 0xE0000 -> 917504
 | 
			
		||||
//
 | 
			
		||||
// e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default
 | 
			
		||||
//                 -k 917504 -i sysupgarde.bin -o factory.bin
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// The img_hdr_struct was taken from the D-Link SDK:
 | 
			
		||||
// DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch
 | 
			
		||||
 | 
			
		||||
#define MAX_SIGN_LEN	32
 | 
			
		||||
#define MAX_FW_VER_LEN	16
 | 
			
		||||
#define MAX_REG_LEN	8
 | 
			
		||||
 | 
			
		||||
struct img_hdr_struct {
 | 
			
		||||
	uint32_t hdr_len;
 | 
			
		||||
	uint32_t checksum;
 | 
			
		||||
	uint32_t total_size;
 | 
			
		||||
	uint32_t kernel_size;
 | 
			
		||||
	char signature[MAX_SIGN_LEN];
 | 
			
		||||
	char fw_ver[MAX_FW_VER_LEN];
 | 
			
		||||
	char fw_reg[MAX_REG_LEN];
 | 
			
		||||
} imghdr ;
 | 
			
		||||
 | 
			
		||||
char *progname;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
perrexit(int code, char *msg)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
 | 
			
		||||
	exit(code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
usage()
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname);
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int ac, char *av[])
 | 
			
		||||
{
 | 
			
		||||
	char signature[MAX_SIGN_LEN];
 | 
			
		||||
	char version[MAX_FW_VER_LEN];
 | 
			
		||||
	char region[MAX_REG_LEN];
 | 
			
		||||
	int kernel = 0;
 | 
			
		||||
 | 
			
		||||
	FILE *ifile, *ofile;
 | 
			
		||||
	int c;
 | 
			
		||||
 | 
			
		||||
	uint32_t cksum;
 | 
			
		||||
	uint32_t bcnt;
 | 
			
		||||
 | 
			
		||||
	progname = basename(av[0]);
 | 
			
		||||
 | 
			
		||||
	memset(signature, 0, sizeof(signature));
 | 
			
		||||
	memset(version, 0, sizeof(version));
 | 
			
		||||
	memset(region, 0, sizeof(region));
 | 
			
		||||
 | 
			
		||||
	while ( 1 ) {
 | 
			
		||||
		char *ptr;
 | 
			
		||||
		int c;
 | 
			
		||||
 | 
			
		||||
		c = getopt(ac, av, "s:v:r:k:i:o:");
 | 
			
		||||
		if (c == -1)
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		switch (c) {
 | 
			
		||||
		case 's':
 | 
			
		||||
			if (strlen(optarg) > MAX_SIGN_LEN + 1) {
 | 
			
		||||
				fprintf(stderr, "%s: signature exceeds %d chars\n",
 | 
			
		||||
					progname, MAX_SIGN_LEN);
 | 
			
		||||
				exit(1);
 | 
			
		||||
			}
 | 
			
		||||
			strcpy(signature, optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case 'v':
 | 
			
		||||
			if (strlen(optarg) > MAX_FW_VER_LEN + 1) {
 | 
			
		||||
				fprintf(stderr, "%s: version exceeds %d chars\n",
 | 
			
		||||
					progname, MAX_FW_VER_LEN);
 | 
			
		||||
				exit(1);
 | 
			
		||||
			}
 | 
			
		||||
			strcpy(version, optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case 'r':
 | 
			
		||||
			if (strlen(optarg) > MAX_REG_LEN + 1) {
 | 
			
		||||
				fprintf(stderr, "%s: region exceeds %d chars\n",
 | 
			
		||||
					progname, MAX_REG_LEN);
 | 
			
		||||
				exit(1);
 | 
			
		||||
			}
 | 
			
		||||
			strcpy(region, optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case 'k':
 | 
			
		||||
			kernel = strtoul(optarg, &ptr, 0);
 | 
			
		||||
			if(ptr[0] == 'k'){
 | 
			
		||||
				kernel *= 1000;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case 'i':
 | 
			
		||||
			if ((ifile = fopen(optarg, "r")) == NULL)
 | 
			
		||||
				perrexit(1, optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		case 'o':
 | 
			
		||||
			if ((ofile = fopen(optarg, "w")) == NULL)
 | 
			
		||||
				perrexit(1, optarg);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			usage();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (signature[0] == 0 || ifile == NULL || ofile == NULL) {
 | 
			
		||||
		usage();
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++)
 | 
			
		||||
		cksum += c & 0xff;
 | 
			
		||||
 | 
			
		||||
	if (fseek(ifile, 0, SEEK_SET) < 0)
 | 
			
		||||
		perrexit(2, "fseek on input");
 | 
			
		||||
 | 
			
		||||
	// Fill in the header
 | 
			
		||||
	memset(&imghdr, 0, sizeof(imghdr));
 | 
			
		||||
	imghdr.hdr_len = sizeof(imghdr);
 | 
			
		||||
	imghdr.checksum = htonl(cksum);
 | 
			
		||||
	imghdr.total_size = htonl(bcnt);
 | 
			
		||||
	imghdr.kernel_size = htonl(kernel);
 | 
			
		||||
 | 
			
		||||
	strncpy(imghdr.signature, signature, MAX_SIGN_LEN);
 | 
			
		||||
	strncpy(imghdr.fw_ver, version, MAX_FW_VER_LEN);
 | 
			
		||||
	strncpy(imghdr.fw_reg, region, MAX_REG_LEN);
 | 
			
		||||
 | 
			
		||||
	if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
 | 
			
		||||
		perrexit(2, "fwrite header on output");
 | 
			
		||||
 | 
			
		||||
	while ((c = fgetc(ifile)) != EOF) {
 | 
			
		||||
		if (fputc(c, ofile) == EOF)
 | 
			
		||||
			perrexit(2, "fputc on output");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ferror(ifile))
 | 
			
		||||
		perrexit(2, "fgetc on input");
 | 
			
		||||
 | 
			
		||||
	fclose(ofile);
 | 
			
		||||
	fclose(ifile);
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr, "imgHdr.hdr_len = %lu\n", sizeof(imghdr));
 | 
			
		||||
	fprintf(stderr, "imgHdr.checksum = 0x%08x\n", cksum);
 | 
			
		||||
	fprintf(stderr, "imgHdr.total_size = 0x%08x\n", bcnt);
 | 
			
		||||
	fprintf(stderr, "imgHdr.kernel_size = 0x%08x\n", kernel);
 | 
			
		||||
	fprintf(stderr, "imgHdr.header = %s\n", signature);
 | 
			
		||||
	fprintf(stderr, "imgHdr.fw_ver = %s\n", version);
 | 
			
		||||
	fprintf(stderr, "imgHdr.fw_reg = %s\n", region);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user