imagetag for flashing kamakize from any generic broadcom stock firmware tftp or web interface. (Alice Gate is not generic).
That patch doesn't work, but I have (finally) got one that does. I can't post to Trac right now because it isn't working (502 Bad Gateway)
diff --git a/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c b/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
index d17baf2..7c82527 100644
--- a/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
+++ b/target/linux/brcm63xx/files/drivers/mtd/maps/bcm963xx-flash.c
@@ -114,14 +114,15 @@ static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition *
parts[curpart].name = "rootfs";
parts[curpart].offset = rootfsaddr;
parts[curpart].size = rootfslen;
- if (sparelen > 0)
- parts[curpart].size += sparelen;
+ if (sparelen > 0)
+ parts[curpart].size += sparelen;
curpart++;
};
+
parts[curpart].name = "nvram";
parts[curpart].offset = master->size - master->erasesize;
parts[curpart].size = master->erasesize;
-
+
for (i = 0; i < nrparts; i++)
printk(KERN_INFO PFX "Partition %d is %s offset %x and length %x\n", i, parts[i].name, parts[i].offset, parts[i].size);
diff --git a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
index efc4f02..0de957c 100644
--- a/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
+++ b/target/linux/brcm63xx/files/include/asm-mips/mach-bcm63xx/bcm_tag.h
@@ -14,13 +14,16 @@ struct bcm_tag {
unsigned char totalLength[IMAGE_LEN]; //Total length of image
unsigned char cfeAddress[ADDRESS_LEN]; // Address in memory of CFE
unsigned char cfeLength[IMAGE_LEN]; // Size of CFE
- unsigned char rootAddress[ADDRESS_LEN]; // Address in memory of rootfs
- unsigned char rootLength[IMAGE_LEN]; // Size of rootfs
+ unsigned char cfeRootAddress[ADDRESS_LEN]; // Address in memory of rootfs (for broadcom; for wrt this is only used for flashing the image and is offset of the image)
+ unsigned char cfeRootLength[IMAGE_LEN]; // Size of rootfs
unsigned char kernelAddress[ADDRESS_LEN]; // Address in memory of kernel
unsigned char kernelLength[IMAGE_LEN]; // Size of kernel
unsigned char dualImage[2]; // Unused at present
unsigned char inactiveFlag[2]; // Unused at present
- unsigned char reserved1[74]; // Reserved area not in use
+ unsigned char reserved1[52]; // Reserved area not in use
+ unsigned char rootAddress[ADDRESS_LEN]; // Address in memory of rootfs
+ unsigned char rootLength[IMAGE_LEN]; // Size of rootfs
+
unsigned char imageCRC[4]; // CRC32 of images
unsigned char reserved2[16]; // Unused at present
unsigned char headerCRC[4]; // CRC32 of header excluding tagVersion
diff --git a/target/linux/brcm63xx/image/Makefile b/target/linux/brcm63xx/image/Makefile
index b6ef968..9db2363 100644
--- a/target/linux/brcm63xx/image/Makefile
+++ b/target/linux/brcm63xx/image/Makefile
@@ -28,17 +28,16 @@ define trxalign/squashfs
endef
define Image/Build/CFE
- # Generate the tagged image
+ # Generate the tagged image (CFE)
$(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \
-o $(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin \
-b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR)
# -b $(2) -c $(3) -e $(KERNEL_ENTRY) -l $(LOADADDR)
- $(call prepare_generic_squashfs,$(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin)
endef
define Image/Build/CFEAGPF
- # Generate the tagged image
+ # Generate the tagged image (CFEAGPF)
$(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \
-o $(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin \
-b $(2) -c $(3) -e $(LOADADDR) -l $(LOADADDR) \
@@ -55,6 +54,7 @@ define Image/Build/RedBoot
endef
define Image/Build/CFEOLD
+ # Generate the tagged image (CFEOLD)
$(TOPDIR)/scripts/brcmImage.pl -t -p \
-b $(2) -c $(3) \
-k $(KDIR)/vmlinux.lzma.cfe \
diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c
index af37992..3ada4fd 100644
--- a/tools/firmware-utils/src/imagetag.c
+++ b/tools/firmware-utils/src/imagetag.c
@@ -23,6 +23,8 @@
#define DEFAULT_FW_OFFSET 0x10000
#define DEFAULT_FLASH_START 0xBFC00000
#define DEFAULT_FLASH_BS (64 * 1024)
+#define DEADCODE 0xDEADC0DE
+#define DEADCODE_LEN 4
/* Kernel header */
struct kernelhdr {
@@ -47,11 +49,12 @@ struct imagetag {
uint8_t bigendian[2]; /* 60 - 61: "1" for big endian, "0" for little endian */
uint8_t imagelen[10]; /* 62 - 71: The length of all data that follows */
struct imagecomp cfe; /* 72 - 93: The offset and length of CFE */
- struct imagecomp rootfs; /* 94 - 115: The offset and length of the root file system */
+ struct imagecomp rootfs; /* 94 - 115: The offset of the start of the image and length of the root filesystem; for Broadcom firmware images this is the rootfs but causes flashing problems for WRT hence the addition of wrtrootfs */
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 */
+ uint8_t reserved1[52]; /* 142 - 193: reserved */
+ struct imagecomp wrtrootfs; /* 193 - 215: WRT: real offset and length of the root file system */
uint32_t imagecrc; /* 216 - 219: crc of the images (net byte order) */
uint8_t reserved2[16]; /* 220 - 235: reserved */
uint32_t headercrc; /* 236 - 239: crc starting from sig1 until headercrc (net byte order) */
@@ -116,6 +119,30 @@ size_t getlen(FILE *fp)
return retval;
}
+uint32_t writepadding(FILE *padfile, size_t size, uint32_t crc) {
+ size_t paddingsize, padcount;
+ uint8_t padbuf[1024];
+
+ for (padcount = 0; padcount < 1024; padcount++) {
+ padbuf[padcount] = 0;
+ }
+
+ paddingsize = 0;
+
+ while (paddingsize < size) {
+ if ((size - paddingsize) > 1024) {
+ padcount = 1024;
+ } else {
+ padcount = size - paddingsize;
+ }
+ fwrite(padbuf, sizeof(uint8_t), padcount, padfile);
+
+ paddingsize += padcount;
+ crc = crc32(crc, padbuf, padcount);
+ }
+ return crc;
+}
+
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,
@@ -124,9 +151,10 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
struct imagetag tag;
struct kernelhdr khdr;
FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile;
- size_t kerneloff, kernellen, rootfsoff, rootfslen, read;
+ size_t kerneloff, kernellen, rootfsoff, rootfslen, read, cferootfsoff, cferootfslen, imagelen, imageoff, rootfspaddingsize, origrootfslen;
uint8_t readbuf[1024];
uint32_t crc;
+ const uint32_t deadcode = htonl(DEADCODE);
memset(&tag, 0, sizeof(struct imagetag));
@@ -154,9 +182,17 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
fprintf(stderr, "Unable to open output file \"%s\"\n", bin);
return 1;
}
+ /* Initialize CRC */
+ crc = IMAGETAG_CRC_START;
+
+ /* Initialize image length calculations */
+ imagelen = 0;
+ cferootfslen = 0;
/* Build the kernel address and length (doesn't need to be aligned, read only) */
kerneloff = fwaddr + sizeof(tag);
+ imageoff = kerneloff;
+ cferootfsoff = imageoff;
kernellen = getlen(kernelfile);
/* Build the kernel header */
@@ -167,17 +203,21 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
/* Increase the kernel size by the header size */
kernellen += sizeof(khdr);
+ imagelen += kernellen;
+
/* 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);
+ origrootfslen = getlen(rootfsfile);
+ rootfslen = origrootfslen;
rootfslen = (rootfslen % flash_bs) > 0 ? (((rootfslen / flash_bs) + 1) * flash_bs) : rootfslen;
+ cferootfslen = rootfslen;
/* Seek to the start of the kernel */
fseek(binfile, kerneloff - fwaddr, SEEK_SET);
/* Write the kernel header */
- crc = crc32(IMAGETAG_CRC_START, (uint8_t*)&khdr, sizeof(khdr));
+ crc = crc32(crc, (uint8_t*)&khdr, sizeof(khdr));
fwrite(&khdr, sizeof(khdr), 1, binfile);
/* Write the kernel */
@@ -187,16 +227,39 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
fwrite(readbuf, sizeof(uint8_t), read, binfile);
}
+ /* Write padding from end of kernel to start of RootFS needed so that
+ * RootFS starts on and erase boundary, and calculate its CRC
+ */
+ rootfspaddingsize = rootfsoff - (kerneloff + kernellen );
+ imagelen += rootfspaddingsize;
+ /* FIXME: Don't use this CRC for Alice Gate */
+ crc = writepadding(binfile, rootfspaddingsize, crc);
+
/* Write the RootFS */
- fseek(binfile, rootfsoff - fwaddr, 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);
- */
+ /* FIXME: Don't do this for Alice Gate */
+ crc = crc32(crc, readbuf, read);
+
fwrite(readbuf, sizeof(uint8_t), read, binfile);
}
+ imagelen += origrootfslen;
+
+ /* Write the ending padding and end-of-filesystem marker for RootFS so
+ * that RootFS ends on an erase boundary, and calculate its CRC
+ */
+
+ /* FIXME: Don't use the CRC for Alice Gate */
+ crc = writepadding(binfile, rootfslen - origrootfslen, crc);
+ imagelen += rootfslen - origrootfslen;
+ cferootfslen += rootfslen - origrootfslen;
+
+ /* Write end-of-filesystem marker */
+ /* FIXME: Don't use this CRC for Alice Gate */
+ crc = crc32(crc, (uint8_t*)&deadcode, DEADCODE_LEN);
+ fwrite((uint8_t*)&deadcode, sizeof(uint8_t), DEADCODE_LEN, binfile);
+ imagelen += DEADCODE_LEN;
+ cferootfslen += DEADCODE_LEN;
/* Close the files */
fclose(kernelfile);
@@ -209,7 +272,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
strcpy(tag.chipid, chipid);
strcpy(tag.boardid, boardid);
strcpy(tag.bigendian, "1");
- sprintf(tag.imagelen, "%lu", kernellen + rootfslen);
+ sprintf(tag.imagelen, "%lu", imagelen);
/* We don't include CFE */
strcpy(tag.cfe.address, "0");
@@ -221,8 +284,10 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin,
}
if (rootfsfile) {
- sprintf(tag.rootfs.address, "%lu", rootfsoff);
- sprintf(tag.rootfs.len, "%lu", rootfslen);
+ sprintf(tag.rootfs.address, "%lu", cferootfsoff);
+ sprintf(tag.rootfs.len, "%lu", cferootfslen);
+ sprintf(tag.wrtrootfs.address, "%lu", rootfsoff);
+ sprintf(tag.wrtrootfs.len, "%lu", rootfslen);
}
tag.imagecrc = htonl(crc);