firmware-utils: Add support for the Cisco Meraki MX60/MX60W
authorChris Blake <chrisrblake93@gmail.com>
Wed, 16 Nov 2016 14:35:54 +0000 (08:35 -0600)
committerJohn Crispin <john@phrozen.org>
Mon, 21 Nov 2016 10:09:03 +0000 (11:09 +0100)
This patch adds header support for the Cisco Meraki MX60/MX60W, which
are a part of the apm821xx target. Some structure changes were needed
due to the fact this device uses U-Boot (unlike other devices in
mkmerakifw.c) which uses a different header structure to define the load
offsets for the image.

A thanks to Christian for helping implement this properly.

Cc: Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
tools/firmware-utils/src/mkmerakifw.c

index 61b81c6b5f3a0ec295750a95b48ae8580123bb82..6394cba5235ec8200409a2b58d8816c32df961e4 100644 (file)
 #define HDR_OFF_IMAGELEN       8
 #define HDR_OFF_CHECKSUM       12
 #define HDR_OFF_MAGIC2         32
 #define HDR_OFF_IMAGELEN       8
 #define HDR_OFF_CHECKSUM       12
 #define HDR_OFF_MAGIC2         32
-#define HDR_OFF_FILLER         36
+#define HDR_OFF_MAGIC3         36
 #define HDR_OFF_STATICHASH     40
 #define HDR_OFF_STATICHASH     40
+#define HDR_OFF_KERNEL_OFFSET  40
+#define HDR_OFF_RAMDISK_OFFSET 44
+#define HDR_OFF_FDT_OFFSET     48
+#define HDR_OFF_UNKNOWN_OFFSET 52
 
 struct board_info {
 
 struct board_info {
-       uint32_t magic;
+       uint32_t magic1;
+       uint32_t magic2;
+       uint32_t magic3;
        uint32_t imagelen;
        uint32_t imagelen;
-       unsigned char statichash[20];
+       union {
+               unsigned char statichash[20];
+               struct {
+                       uint32_t kernel_offset;
+                       uint32_t ramdisk_offset;
+                       uint32_t fdt_offset;
+                       uint32_t unknown_offset;
+               } mx60;
+       };
        char *id;
        char *description;
 };
        char *id;
        char *description;
 };
@@ -55,7 +69,8 @@ static const struct board_info boards[] = {
        {
                .id             = "mr18",
                .description    = "Meraki MR18 Access Point",
        {
                .id             = "mr18",
                .description    = "Meraki MR18 Access Point",
-               .magic          = 0x8e73ed8a,
+               .magic1         = 0x8e73ed8a,
+               .magic2         = 0x8e73ed8a,
                .imagelen       = 0x00800000,
                .statichash     = {0xda, 0x39, 0xa3, 0xee, 0x5e,
                                   0x6b, 0x4b, 0x0d, 0x32, 0x55,
                .imagelen       = 0x00800000,
                .statichash     = {0xda, 0x39, 0xa3, 0xee, 0x5e,
                                   0x6b, 0x4b, 0x0d, 0x32, 0x55,
@@ -64,14 +79,34 @@ static const struct board_info boards[] = {
        }, {
                .id             = "mr24",
                .description    = "Meraki MR24 Access Point",
        }, {
                .id             = "mr24",
                .description    = "Meraki MR24 Access Point",
-               .magic          = 0x8e73ed8a,
+               .magic1         = 0x8e73ed8a,
+               .magic2         = 0x8e73ed8a,
                .imagelen       = 0x00800000,
                .statichash     = {0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff},
        }, {
                .imagelen       = 0x00800000,
                .statichash     = {0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff},
        }, {
-
+               .id             = "mx60",
+               .description    = "Meraki MX60/MX60W Security Appliance",
+               .magic1         = 0x8e73ed8a,
+               .magic2         = 0xa1f0beef, /* Enables use of load addr in statichash */
+               .magic3         = 0x00060001, /* This goes along with magic2 */
+               .imagelen       = 0x3fd00000,
+               /* The static hash below does the following:
+                * 1st Row: Kernel Offset
+                * 2nd Row: Ramdisk Offset
+                * 3rd Row: FDT Offset
+                * 4th Row: ? Unused/Unknown ?
+                * 5th Row: ? Unused/Unknown ?
+                */
+               .mx60           = {
+                       .kernel_offset  = 0x10000,
+                       .ramdisk_offset = 0x3FFC00,
+                       .fdt_offset     = 0x0400,
+                       .unknown_offset = 0x0400,
+               },
+       }, {
                /* terminating entry */
        }
 };
                /* terminating entry */
        }
 };
@@ -237,10 +272,10 @@ int main(int argc, char *argv[])
        kernel = buf + HDR_LENGTH;
        fread(kernel, klen, 1, in);
 
        kernel = buf + HDR_LENGTH;
        fread(kernel, klen, 1, in);
 
-       /* Write magic values and filler */
-       writel(buf, HDR_OFF_MAGIC1, board->magic);
-       writel(buf, HDR_OFF_MAGIC2, board->magic);
-       writel(buf, HDR_OFF_FILLER, 0);
+       /* Write magic values */
+       writel(buf, HDR_OFF_MAGIC1, board->magic1);
+       writel(buf, HDR_OFF_MAGIC2, board->magic2);
+       writel(buf, HDR_OFF_MAGIC3, board->magic3);
 
        /* Write header and image length */
        writel(buf, HDR_OFF_HDRLEN, HDR_LENGTH);
 
        /* Write header and image length */
        writel(buf, HDR_OFF_HDRLEN, HDR_LENGTH);
@@ -248,7 +283,19 @@ int main(int argc, char *argv[])
 
        /* Write checksum and static hash */
        sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM);
 
        /* Write checksum and static hash */
        sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM);
-       memcpy(buf + HDR_OFF_STATICHASH, board->statichash, 20);
+
+       switch (board->magic2) {
+       case 0xa1f0beef:
+               writel(buf, HDR_OFF_KERNEL_OFFSET, board->mx60.kernel_offset);
+               writel(buf, HDR_OFF_RAMDISK_OFFSET, board->mx60.ramdisk_offset);
+               writel(buf, HDR_OFF_FDT_OFFSET, board->mx60.fdt_offset),
+               writel(buf, HDR_OFF_UNKNOWN_OFFSET, board->mx60.unknown_offset);
+               break;
+
+       case 0x8e73ed8a:
+               memcpy(buf + HDR_OFF_STATICHASH, board->statichash, 20);
+               break;
+       }
 
        /* Save finished image */
        out = fopen(ofname, "w");
 
        /* Save finished image */
        out = fopen(ofname, "w");