X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=tools%2Ffirmware-utils%2Fsrc%2Fmktplinkfw2.c;h=0b7a15c996c079242055721a8805f37620dc0f6f;hb=78057457912170ceba29792ef02ba441abe8f246;hp=9b9ebf526c144143a26f68b3c565b0a0556471c6;hpb=13b8b8c2e7f3f0acf8d23a28a011a3ea261757f5;p=openwrt%2Fopenwrt.git diff --git a/tools/firmware-utils/src/mktplinkfw2.c b/tools/firmware-utils/src/mktplinkfw2.c index 9b9ebf526c..0b7a15c996 100644 --- a/tools/firmware-utils/src/mktplinkfw2.c +++ b/tools/firmware-utils/src/mktplinkfw2.c @@ -39,32 +39,32 @@ struct file_info { }; struct fw_header { - uint32_t version; /* 0x00: header version */ - char fw_version[48]; /* 0x04: fw version string */ - uint32_t hw_id; /* 0x34: hardware id */ - uint32_t hw_rev; /* 0x38: FIXME: hardware revision? */ - uint32_t unk1; /* 0x3c: 0x00000000 */ - uint8_t md5sum1[MD5SUM_LEN]; /* 0x40 */ - uint32_t unk2; /* 0x50: 0x00000000 */ - uint8_t md5sum2[MD5SUM_LEN]; /* 0x54 */ - uint32_t unk3; /* 0x64: 0xffffffff */ - - uint32_t kernel_la; /* 0x68: kernel load address */ - uint32_t kernel_ep; /* 0x6c: kernel entry point */ - uint32_t fw_length; /* 0x70: total length of the image */ - uint32_t kernel_ofs; /* 0x74: kernel data offset */ - uint32_t kernel_len; /* 0x78: kernel data length */ - uint32_t rootfs_ofs; /* 0x7c: rootfs data offset */ - uint32_t rootfs_len; /* 0x80: rootfs data length */ - uint32_t boot_ofs; /* 0x84: FIXME: seems to be unused */ - uint32_t boot_len; /* 0x88: FIXME: seems to be unused */ - uint16_t unk4; /* 0x8c: 0x55aa */ - uint8_t sver_hi; /* 0x8e */ - uint8_t sver_lo; /* 0x8f */ - uint8_t unk5; /* 0x90: magic: 0xa5 */ - uint8_t ver_hi; /* 0x91 */ - uint8_t ver_mid; /* 0x92 */ - uint8_t ver_lo; /* 0x93 */ + uint32_t version; /* 0x00: header version */ + char fw_version[48]; /* 0x04: fw version string */ + uint32_t hw_id; /* 0x34: hardware id */ + uint32_t hw_rev; /* 0x38: FIXME: hardware revision? */ + uint32_t hw_ver_add; /* 0x3c: additional hardware version */ + uint8_t md5sum1[MD5SUM_LEN]; /* 0x40 */ + uint32_t unk2; /* 0x50: 0x00000000 */ + uint8_t md5sum2[MD5SUM_LEN]; /* 0x54 */ + uint32_t unk3; /* 0x64: 0xffffffff */ + + uint32_t kernel_la; /* 0x68: kernel load address */ + uint32_t kernel_ep; /* 0x6c: kernel entry point */ + uint32_t fw_length; /* 0x70: total length of the image */ + uint32_t kernel_ofs; /* 0x74: kernel data offset */ + uint32_t kernel_len; /* 0x78: kernel data length */ + uint32_t rootfs_ofs; /* 0x7c: rootfs data offset */ + uint32_t rootfs_len; /* 0x80: rootfs data length */ + uint32_t boot_ofs; /* 0x84: bootloader offset */ + uint32_t boot_len; /* 0x88: bootloader length */ + uint16_t unk4; /* 0x8c: 0x55aa */ + uint8_t sver_hi; /* 0x8e */ + uint8_t sver_lo; /* 0x8f */ + uint8_t unk5; /* 0x90: magic: 0xa5 */ + uint8_t ver_hi; /* 0x91 */ + uint8_t ver_mid; /* 0x92 */ + uint8_t ver_lo; /* 0x93 */ uint8_t pad[364]; } __attribute__ ((packed)); @@ -80,6 +80,7 @@ struct board_info { char *id; uint32_t hw_id; uint32_t hw_rev; + uint32_t hw_ver_add; char *layout_id; uint32_t hdr_ver; bool endian_swap; @@ -96,14 +97,15 @@ static char *fw_ver = "0.0.0"; static char *sver = "1.0"; static uint32_t hdr_ver = 2; +static struct board_info custom_board; + static char *board_id; static struct board_info *board; static char *layout_id; static struct flash_layout *layout; static char *opt_hw_id; -static uint32_t hw_id; static char *opt_hw_rev; -static uint32_t hw_rev; +static char *opt_hw_ver_add; static int fw_ver_lo; static int fw_ver_mid; static int fw_ver_hi; @@ -124,7 +126,6 @@ static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; static struct file_info inspect_info; static int extract = 0; -static bool endian_swap = false; char md5salt_normal[MD5SUM_LEN] = { 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb, @@ -132,8 +133,8 @@ char md5salt_normal[MD5SUM_LEN] = { }; char md5salt_boot[MD5SUM_LEN] = { - 0x8c, 0xef, 0x33, 0x5b, 0xd5, 0xc5, 0xce, 0xfa, - 0xa7, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, + 0x8c, 0xef, 0x33, 0x5f, 0xd5, 0xc5, 0xce, 0xfa, + 0xac, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, }; static struct flash_layout layouts[] = { @@ -155,6 +156,12 @@ static struct flash_layout layouts[] = { .kernel_la = 0x80000000, .kernel_ep = 0x80000000, .rootfs_ofs = 0x140000, + }, { + .id = "8MLmtk", + .fw_max_len = 0x7b0000, + .kernel_la = 0x80000000, + .kernel_ep = 0x80000000, + .rootfs_ofs = 0x140000, }, { /* terminating entry */ } @@ -184,6 +191,36 @@ static struct board_info boards[] = { .hw_rev = 0x2f, .layout_id = "16Mltq", .hdr_ver = 2, + }, { + .id = "ArcherC50", + .hw_id = 0xc7500001, + .hw_rev = 69, + .layout_id = "8Mmtk", + .hdr_ver = 3, + .endian_swap = true, + }, { + .id = "ArcherMR200", + .hw_id = 0xd7500001, + .hw_rev = 0x4a, + .layout_id = "8MLmtk", + .hdr_ver = 3, + .endian_swap = true, + }, { + .id = "TL-WR840NV4", + .hw_id = 0x08400004, + .hw_rev = 0x1, + .hw_ver_add = 0x4, + .layout_id = "8Mmtk", + .hdr_ver = 3, + .endian_swap = true, + }, { + .id = "TL-WR841NV13", + .hw_id = 0x08410013, + .hw_rev = 0x268, + .hw_ver_add = 0x13, + .layout_id = "8Mmtk", + .hdr_ver = 3, + .endian_swap = true, }, { /* terminating entry */ } @@ -264,10 +301,12 @@ static void usage(int status) "Options:\n" " -B create image for the board specified with \n" " -c use combined kernel image\n" +" -e swap endianness in kernel load address and entry point\n" " -E overwrite kernel entry point with (hexval prefixed with 0x)\n" " -L overwrite kernel load address with (hexval prefixed with 0x)\n" " -H use hardware id specified with \n" " -W use hardware revision specified with \n" +" -w use additional hardware version specified with \n" " -F use flash layout specified with \n" " -k read kernel image from the file \n" " -r read rootfs image from the file \n" @@ -276,6 +315,8 @@ static void usage(int status) " -o write output to the file \n" " -s strip padding from the end of the image\n" " -j add jffs2 end-of-filesystem markers\n" +" -N set image vendor to \n" +" -T set header version to \n" " -V set image version to \n" " -v set firmware version to \n" " -y set secondary version to \n" @@ -369,22 +410,27 @@ static int check_options(void) if (layout_id == NULL) layout_id = board->layout_id; - hw_id = board->hw_id; - hw_rev = board->hw_rev; if (board->hdr_ver) hdr_ver = board->hdr_ver; - endian_swap = board->endian_swap; } else { + board = &custom_board; + if (layout_id == NULL) { ERR("flash layout is not specified"); return -1; } - hw_id = strtoul(opt_hw_id, NULL, 0); + + board->hw_id = strtoul(opt_hw_id, NULL, 0); if (opt_hw_rev) - hw_rev = strtoul(opt_hw_rev, NULL, 0); + board->hw_rev = strtoul(opt_hw_rev, NULL, 0); + else + board->hw_rev = 1; + + if (opt_hw_ver_add) + board->hw_ver_add = strtoul(opt_hw_ver_add, NULL, 0); else - hw_rev = 1; + board->hw_ver_add = 0; } layout = find_layout(layout_id); @@ -489,8 +535,9 @@ static void fill_header(char *buf, int len) memcpy(hdr->fw_version, version, ver_len); hdr->fw_version[ver_len] = 0; - hdr->hw_id = htonl(hw_id); - hdr->hw_rev = htonl(hw_rev); + hdr->hw_id = htonl(board->hw_id); + hdr->hw_rev = htonl(board->hw_rev); + hdr->hw_ver_add = htonl(board->hw_ver_add); if (boot_info.file_size == 0) { memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); @@ -515,7 +562,6 @@ static void fill_header(char *buf, int len) hdr->boot_ofs = htonl(0); hdr->boot_len = htonl(boot_info.file_size); - hdr->unk1 = htonl(0); hdr->unk2 = htonl(0); hdr->unk3 = htonl(0xffffffff); hdr->unk4 = htons(0x55aa); @@ -528,7 +574,7 @@ static void fill_header(char *buf, int len) hdr->ver_mid = fw_ver_mid; hdr->ver_lo = fw_ver_lo; - if (endian_swap) { + if (board->endian_swap) { hdr->kernel_la = bswap_32(hdr->kernel_la); hdr->kernel_ep = bswap_32(hdr->kernel_ep); } @@ -759,9 +805,6 @@ static int inspect_fw(void) inspect_fw_phexdec("Version 2 Header size", sizeof(struct fw_header)); - if (ntohl(hdr->unk1) != 0) - inspect_fw_phexdec("Unknown value 1", hdr->unk1); - memcpy(md5sum, hdr->md5sum1, sizeof(md5sum)); if (ntohl(hdr->boot_len) == 0) memcpy(hdr->md5sum1, md5salt_normal, sizeof(md5sum)); @@ -800,11 +843,15 @@ static int inspect_fw(void) ntohl(hdr->hw_id), board->id); inspect_fw_phexexp("Hardware Revision", ntohl(hdr->hw_rev), board->hw_rev); + inspect_fw_phexexp("Additional HW Version", + ntohl(hdr->hw_ver_add), board->hw_ver_add); } else { inspect_fw_phexpost("Hardware ID", ntohl(hdr->hw_id), "unknown"); inspect_fw_phex("Hardware Revision", ntohl(hdr->hw_rev)); + inspect_fw_phex("Additional HW Version", + ntohl(hdr->hw_ver_add)); } printf("%-23s: %d.%d.%d-%d.%d\n", "Software version", @@ -899,7 +946,7 @@ int main(int argc, char *argv[]) while ( 1 ) { int c; - c = getopt(argc, argv, "a:B:H:E:F:L:V:N:W:ci:k:r:R:o:xhsjv:y:T:e"); + c = getopt(argc, argv, "a:B:H:E:F:L:V:N:W:w:ci:k:r:R:o:xhsjv:y:T:e"); if (c == -1) break; @@ -922,6 +969,9 @@ int main(int argc, char *argv[]) case 'W': opt_hw_rev = optarg; break; + case 'w': + opt_hw_ver_add = optarg; + break; case 'L': sscanf(optarg, "0x%x", &kernel_la); break; @@ -968,7 +1018,7 @@ int main(int argc, char *argv[]) hdr_ver = atoi(optarg); break; case 'e': - endian_swap = true; + custom_board.endian_swap = true; break; case 'h': usage(EXIT_SUCCESS);