Index: target/linux/brcm63xx/image/Makefile
===================================================================
--- target/linux/brcm63xx/image/Makefile	(revision 12255)
+++ target/linux/brcm63xx/image/Makefile	(working copy)
@@ -9,7 +9,8 @@
 
 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 ?= 0x01000000		# 64MB
+FWTAG ?= 96345GW2
 
 LOADER_MAKEOPTS= \
 		KDIR=$(KDIR) \
@@ -72,7 +73,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),$(FWTAG),6345)
 endef
 
 $(eval $(call BuildImage))
Index: target/linux/brcm63xx/profiles/SE515.mk
===================================================================
--- target/linux/brcm63xx/profiles/SE515.mk	(revision 0)
+++ target/linux/brcm63xx/profiles/SE515.mk	(revision 0)
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/SE515
+  NAME:=Siemens SE515
+  RAMSIZE:= 0x00010000			# 16MB
+  FWTAG:=RTA770BW
+endef
+
+define Profile/SE515/Description
+	Package set optimized for the Siemens SE515.
+endef
+$(eval $(call Profile,SE515))
+
Index: tools/firmware-utils/src/imagetag.c
===================================================================
--- tools/firmware-utils/src/imagetag.c	(revision 12255)
+++ 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 *padbuf;
+	uint32_t pad_kernel, pad_rootfs;
 	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,32 @@
 		fwrite(readbuf, sizeof(uint8_t), read, binfile);
 	}
 
+	/* Allocate buffer for padding. */
+	pad_kernel = rootfsoff_aligned - rootfsoff;
+	pad_rootfs = rootfslen_aligned - rootfslen;
+	padbuf = calloc(1, (pad_kernel > pad_rootfs) ? pad_kernel : pad_rootfs);
+
+	/* Add padding before rootfs. Increase kernel size by padding length. */
+	fwrite(padbuf, sizeof(uint8_t), pad_kernel, binfile);
+	crc = crc32(crc, padbuf, pad_kernel);
+	kernellen += pad_kernel;
+
 	/* 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. */
+	fwrite(padbuf, sizeof(uint8_t), pad_rootfs, binfile);
+	crc = crc32(crc, padbuf, pad_rootfs);
+	
+	/* Free padding buffer. */
+	free(padbuf);
+
 	/* Close the files */
+
 	fclose(kernelfile);
 	fclose(rootfsfile);
 
@@ -208,7 +229,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 +241,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);
