Index: target/linux/brcm63xx/image/Makefile
===================================================================
--- target/linux/brcm63xx/image/Makefile	(revision 11869)
+++ target/linux/brcm63xx/image/Makefile	(working copy)
@@ -9,7 +9,7 @@
 
 LOADADDR = 0x80010000		# RAM start + 16M 
 KERNEL_ENTRY = $(LOADADDR)	# Newer kernels add a jmp to the kernel_entry at the start of the binary
-RAMSIZE = 0x01000000		# 64MB
+RAMSIZE = 0x00010000		# 16MB
 
 LOADER_MAKEOPTS= \
 		KDIR=$(KDIR) \
@@ -72,7 +72,7 @@
 
 define Image/Build
 	$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/openwrt-$(BOARD)-$(1).trx -f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma $(call trxalign/$(1)) -f $(KDIR)/root.$(1)
-	$(call Image/Build/CFE,$(1),96345GW2,6345)
+	$(call Image/Build/CFE,$(1),RTA770BW,6345)
 endef
 
 $(eval $(call BuildImage))
Index: tools/firmware-utils/src/imagetag.c
===================================================================
--- tools/firmware-utils/src/imagetag.c	(revision 11829)
+++ tools/firmware-utils/src/imagetag.c	(working copy)
@@ -51,11 +51,15 @@
 	struct imagecomp	kernel;		/* 116 - 137: The offset and length of the kernel */
 	uint8_t			dualimage[2];	/* 138 - 139: use "0" here */
 	uint8_t			inactive[2];	/* 140 - 141: use "0" here */
-	uint8_t			reserved1[74];	/* 142 - 215: reserved */
-	uint32_t		imagecrc;	/* 216 - 219: crc of the images (net byte order) */
-	uint8_t			reserved2[16];	/* 220 - 235: reserved */
+	uint8_t			reserved1[50];	/* 142 - 191: reserved */
+	uint8_t			headerver;	/*       192: header version */
+	uint8_t                 reserved2[3];	/* 193 - 195: reserved */
+	uint32_t		payloadcrc;	/* 196 - 199: crc of the payload (net byte order) [kernel, rootfs] */
+	uint8_t			reserved3[16];	/* 200 - 215: reserved */
+	uint32_t		imagecrc;	/* 216 - 219: crc of the images (net byte order) [cfe, kernel, rootfs] */
+	uint8_t			reserved4[16];	/* 220 - 235: reserved */
 	uint32_t		headercrc;	/* 236 - 239: crc starting from sig1 until headercrc (net byte order) */
-	uint8_t			reserved3[16];	/* 240 - 255: reserved */
+	uint8_t			reserved5[16];	/* 240 - 255: reserved */
 };
 
 static uint32_t crc32tab[256] = {
@@ -123,8 +127,11 @@
 	struct imagetag tag;
 	struct kernelhdr khdr;
 	FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile;
-	size_t kerneloff, kernellen, rootfsoff, rootfslen, read;
+	size_t kerneloff, kernellen, read;
+	size_t rootfsoff, rootfslen, rootfsoff_aligned, rootfslen_aligned;
 	uint8_t readbuf[1024];
+	uint8_t *padding;
+	uint32_t padding_size;
 	uint32_t crc;
 
 	memset(&tag, 0, sizeof(struct imagetag));
@@ -168,9 +175,9 @@
 
 	/* 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;
+	rootfsoff_aligned = (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;
+	rootfslen_aligned = (rootfslen % FLASH_BS) > 0 ? (((rootfslen / FLASH_BS) + 1) * FLASH_BS) : rootfslen;
 
 	/* Seek to the start of the kernel */
 	fseek(binfile, kerneloff - FLASH_START - FLASH_CFE_SIZE, SEEK_SET);
@@ -186,18 +193,30 @@
 		fwrite(readbuf, sizeof(uint8_t), read, binfile);
 	}
 
+	/* Add padding before rootfs. Increase kernel size by padding length. */
+	padding_size = rootfsoff_aligned - rootfsoff;
+	padding = calloc(1, padding_size);
+	fwrite(padding, sizeof(uint8_t), padding_size, binfile);
+	crc = crc32(crc, padding, padding_size);
+	free(padding);
+	kernellen += padding_size;
+
 	/* Write the RootFS */
-	fseek(binfile, rootfsoff - FLASH_START - FLASH_CFE_SIZE, SEEK_SET);
 	while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) {
 		read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile);
-		/*
-		 * TODO: Is this necessary ?
-		 * crc = crc32(crc, readbuf, read);
-		 */
 		fwrite(readbuf, sizeof(uint8_t), read, binfile);
+		crc = crc32(crc, readbuf, read);
 	}
 
+	/* Add padding after rootfs. */
+	padding_size = rootfslen_aligned - rootfslen;
+	padding = calloc(1, padding_size);
+	fwrite(padding, sizeof(uint8_t), padding_size, binfile);
+	crc = crc32(crc, padding, padding_size);
+	free(padding);
+
 	/* Close the files */
+
 	fclose(kernelfile);
 	fclose(rootfsfile);
 
@@ -208,7 +227,7 @@
 	strcpy(tag.chipid, chipid);
 	strcpy(tag.boardid, boardid);
 	strcpy(tag.bigendian, "1");
-	sprintf(tag.imagelen, "%lu", kernellen + rootfslen);
+	sprintf(tag.imagelen, "%lu", kernellen + rootfslen_aligned);
 
 	/* We don't include CFE */
 	strcpy(tag.cfe.address, "0");
@@ -220,11 +239,23 @@
 	}
 
 	if (rootfsfile) {
-		sprintf(tag.rootfs.address, "%lu", rootfsoff);
-		sprintf(tag.rootfs.len, "%lu", rootfslen);
+		sprintf(tag.rootfs.address, "%lu", rootfsoff_aligned);
+		sprintf(tag.rootfs.len, "%lu", rootfslen_aligned);
 	}
 
+	/* Set image crc. */
 	tag.imagecrc = htonl(crc);
+
+	/* Header Version. If boardid is RTA770BW, set header version and payload crc. */
+	if (!strcmp("RTA770BW", tag.boardid)) {
+		tag.headerver = 0x32;
+		tag.payloadcrc = htonl(crc);
+	} else {
+		tag.headerver = 0x00;
+		tag.payloadcrc = 0x00;
+	}
+
+	/* After all header values have been set, calculate header crc. */
 	tag.headercrc = htonl(crc32(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20));
 
 	fseek(binfile, 0L, SEEK_SET);

