User Tools

Site Tools


inbox:macosx.lion

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

inbox:macosx.lion [2013/07/14 09:19] (current)
Line 1: Line 1:
 +====== Stuff with MacOSX Lion ======
 +| →[[doc:​howto:​buildroot.exigence|Procedure on Debian]] | →[[doc:​howto:​buildroot.exigence.bsd|Procedure on ~BSD]] | **→[[doc:​howto:​buildroot.exigence.macosx|Procedure on Mac OS]]** |
 +
 +----
 +:!: Please MERGE this page and [[/​easy.build.macosx]] into this page: **[[doc/​howto/​buildroot.exigence.macosx]]**. Also consult the [[https://​forum.openwrt.org/​viewtopic.php?​id=34676|OpenWrt Forum: Build OpenWrt on Mac OS X 10.7 Lion]]
 +
 +----
 +
 +
 +===== Getting the mktplinkfw ​ =====
 +
 +  * (Revision 29681, 22.1 KB (checked in by juhosg, 7 weeks ago)) working in MacOSX Lion Xcode 4.4 Developer review in 64bit and not need md5.c/md5.h (because md5.c not support 64bit)
 +
 +
 +[[doc/​howto/​generic.flashing.tftp#​getting.tftp.to.work.in.macosx.lion]]
 +
 +I don't think I can merge my changes to the trunk, original file is from
 +
 +https://​dev.openwrt.org/​browser/​trunk/​tools/​firmware-utils/​src/​mktplinkfw.c ​ (Revision 29681)
 +
 +If you need 32bit OSX (or dual 64 and 32) one just change it in the project settings
 +
 +Create new CLI (command line) application,​ then replace all the main.m with this.
 +Then compile, then the output is at the DerivedData/​Project/​Debug directory
 +
 +Summary of changes
 +
 +1) replace all getmd5 with CC_MD5 (x2)
 +
 +2) comment out md5.h
 +
 +3) Add CommonDigest.h
 +
 +4) All the "​struct getmd5"​ comment out
 +
 +
 +I don't know if functions other than "​inspect"​ will work properly
 +
 +<​code>​
 +//
 +//  main.m
 +//   
 +//
 +//  Created by on Saturday,​2/​25/​12.
 +//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
 +//
 +
 +#import <​Foundation/​Foundation.h>​
 +#import <​CommonCrypto/​CommonDigest.h>​
 +/*
 + * Copyright (C) 2009 Gabor Juhos <​juhosg@openwrt.org>​
 + *
 + * This tool was based on:
 + ​* ​  ​TP-Link WR941 V2 firmware checksum fixing tool.
 + ​* ​  ​Copyright (C) 2008,2009 Wang Jian <​lark@linux.net.cn>​
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License version 2 as published
 + * by the Free Software Foundation.
 + *
 + */
 +
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​stdint.h>​
 +#include <​string.h>​
 +#include <​unistd.h> ​    /* for unlink() */
 +#include <​libgen.h>​
 +#include <​getopt.h> ​    /* for getopt() */
 +#include <​stdarg.h>​
 +#include <​errno.h>​
 +#include <​sys/​stat.h>​
 +
 +#include <​arpa/​inet.h>​
 +#include <​netinet/​in.h>​
 +
 +//#include "​md5.h"​
 +
 +#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
 +
 +#define HEADER_VERSION_V1 0x01000000
 +#define HWID_TL_MR3020_V1 0x30200001
 +#define HWID_TL_MR3220_V1 0x32200001
 +#define HWID_TL_MR3420_V1 0x34200001
 +#define HWID_TL_WA701N_V1 0x07010001
 +#define HWID_TL_WA901ND_V1 0x09010001
 +#define HWID_TL_WA901ND_V2 0x09010002
 +#define HWID_TL_WR703N_V1 0x07030101
 +#define HWID_TL_WR741ND_V1 0x07410001
 +#define HWID_TL_WR741ND_V4 0x07410004
 +#define HWID_TL_WR740N_V1 0x07400001
 +#define HWID_TL_WR740N_V3 0x07400003
 +#define HWID_TL_WR743ND_V1 0x07430001
 +#define HWID_TL_WR841N_V1_5 0x08410002
 +#define HWID_TL_WR841ND_V3 0x08410003
 +#define HWID_TL_WR841ND_V5 0x08410005
 +#define HWID_TL_WR841ND_V7 0x08410007
 +#define HWID_TL_WR941ND_V2 0x09410002
 +#define HWID_TL_WR941ND_V4 0x09410004
 +#define HWID_TL_WR1043ND_V1 0x10430001
 +#define HWID_TL_WR2543N_V1 0x25430001
 +
 +#define MD5SUM_LEN 16
 +
 +struct file_info {
 +char *file_name;​ /​* name of the file */
 +uint32_t file_size;​ /​* length of the file */
 +};
 +
 +struct fw_header {
 +uint32_t version;​ /​* header version */
 +char vendor_name[24];​
 +char fw_version[36];​
 +uint32_t hw_id;​ /​* hardware id */
 +uint32_t hw_rev;​ /​* hardware revision */
 +uint32_t unk1;​
 +uint8_t md5sum1[MD5SUM_LEN];​
 +uint32_t unk2;​
 +uint8_t md5sum2[MD5SUM_LEN];​
 +uint32_t unk3;​
 +uint32_t kernel_la;​ /​* kernel load address */
 +uint32_t kernel_ep;​ /​* kernel entry point */
 +uint32_t fw_length;​ /​* total length of the firmware */
 +uint32_t kernel_ofs;​ /​* kernel data offset */
 +uint32_t kernel_len;​ /​* kernel data length */
 +uint32_t rootfs_ofs;​ /​* rootfs data offset */
 +uint32_t rootfs_len;​ /​* rootfs data length */
 +uint32_t boot_ofs;​ /​* bootloader data offset */
 +uint32_t boot_len;​ /​* bootloader data length */
 +uint8_t pad[360];​
 +} __attribute__ ((packed));
 +
 +struct flash_layout {
 +char *id;
 +uint32_t fw_max_len;​
 +uint32_t kernel_la;​
 +uint32_t kernel_ep;​
 +uint32_t rootfs_ofs;​
 +};
 +
 +struct board_info {
 +char *id;
 +uint32_t hw_id;​
 +uint32_t hw_rev;​
 +char *layout_id;​
 +};
 +
 +/*
 + * Globals
 + */
 +static char *ofname;
 +static char *progname;
 +static char *vendor = "​TP-LINK Technologies";​
 +static char *version = "ver. 1.0";
 +
 +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 struct file_info kernel_info;​
 +static uint32_t kernel_la = 0;
 +static uint32_t kernel_ep = 0;
 +static uint32_t kernel_len = 0;
 +static struct file_info rootfs_info;​
 +static uint32_t rootfs_ofs = 0;
 +static uint32_t rootfs_align;​
 +static struct file_info boot_info;
 +static int combined;
 +static int strip_padding;​
 +static int add_jffs2_eof;​
 +static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
 +
 +static struct file_info inspect_info;​
 +static int extract = 0;
 +
 +char md5salt_normal[MD5SUM_LEN] = {
 + 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb,
 + 0xdd, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x38,
 +};
 +
 +char md5salt_boot[MD5SUM_LEN] = {
 + 0x8c, 0xef, 0x33, 0x5b, 0xd5, 0xc5, 0xce, 0xfa,
 + 0xa7, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42,
 +};
 +
 +static struct flash_layout layouts[] = {
 + {
 + .id = "​4M",​
 + .fw_max_len = 0x3c0000,
 + .kernel_la = 0x80060000,
 + .kernel_ep = 0x80060000,
 + .rootfs_ofs = 0x140000,
 + }, {
 + .id = "​4Mlzma",​
 + .fw_max_len = 0x3c0000,
 + .kernel_la = 0x80060000,
 + .kernel_ep = 0x80060000,
 + .rootfs_ofs = 0x100000,
 + }, {
 + .id = "​8M",​
 + .fw_max_len = 0x7c0000,
 + .kernel_la = 0x80060000,
 + .kernel_ep = 0x80060000,
 + .rootfs_ofs = 0x140000,
 + }, {
 + .id = "​8Mlzma",​
 + .fw_max_len = 0x7c0000,
 + .kernel_la = 0x80060000,
 + .kernel_ep = 0x80060000,
 + .rootfs_ofs = 0x100000,
 + }, {
 + /* terminating entry */
 + }
 +};
 +
 +static struct board_info boards[] = {
 + {
 + .id = "​TL-MR3020v1",​
 + .hw_id = HWID_TL_MR3020_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4Mlzma",​
 + }, {
 + .id = "​TL-MR3220v1",​
 + .hw_id = HWID_TL_MR3220_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-MR3420v1",​
 + .hw_id = HWID_TL_MR3420_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WA701Nv1",​
 + .hw_id = HWID_TL_WA701N_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WA901NDv1",​
 + .hw_id = HWID_TL_WA901ND_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id             = "​TL-WA901NDv2",​
 + .hw_id ​         = HWID_TL_WA901ND_V2,​
 + .hw_rev ​        = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR741NDv1",​
 + .hw_id = HWID_TL_WR741ND_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR741NDv4",​
 + .hw_id = HWID_TL_WR741ND_V4,​
 + .hw_rev = 1,
 + .layout_id = "​4Mlzma",​
 + }, {
 + .id = "​TL-WR740Nv1",​
 + .hw_id = HWID_TL_WR740N_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR740Nv3",​
 + .hw_id = HWID_TL_WR740N_V3,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR743NDv1",​
 + .hw_id = HWID_TL_WR743ND_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR841Nv1.5",​
 + .hw_id = HWID_TL_WR841N_V1_5,​
 + .hw_rev = 2,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR841NDv3",​
 + .hw_id = HWID_TL_WR841ND_V3,​
 + .hw_rev = 3,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR841NDv5",​
 + .hw_id = HWID_TL_WR841ND_V5,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR841NDv7",​
 + .hw_id = HWID_TL_WR841ND_V7,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR941NDv2",​
 + .hw_id = HWID_TL_WR941ND_V2,​
 + .hw_rev = 2,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR941NDv4",​
 + .hw_id = HWID_TL_WR941ND_V4,​
 + .hw_rev = 1,
 + .layout_id = "​4M",​
 + }, {
 + .id = "​TL-WR1043NDv1",​
 + .hw_id = HWID_TL_WR1043ND_V1,​
 + .hw_rev = 1,
 + .layout_id = "​8M",​
 + }, {
 + .id = "​TL-WR2543Nv1",​
 + .hw_id = HWID_TL_WR2543N_V1,​
 + .hw_rev = 1,
 + .layout_id = "​8Mlzma",​
 + }, {
 + .id = "​TL-WR703Nv1",​
 + .hw_id = HWID_TL_WR703N_V1,​
 + .hw_rev = 1,
 + .layout_id = "​4Mlzma",​
 + }, {
 + /* terminating entry */
 + }
 +};
 +
 +/*
 + * Message macros
 + */
 +#define ERR(fmt, ...) do { \
 +fflush(0); \
 +fprintf(stderr,​ "[%s] *** error: " fmt "​\n",​ \
 +progname, ## __VA_ARGS__ ); \
 +} while (0)
 +
 +#define ERRS(fmt, ...) do { \
 +int save = errno; \
 +fflush(0); \
 +fprintf(stderr,​ "[%s] *** error: " fmt "​\n",​ \
 +progname, ## __VA_ARGS__,​ strerror(save));​ \
 +} while (0)
 +
 +#define DBG(fmt, ...) do { \
 +fprintf(stderr,​ "[%s] " fmt "​\n",​ progname, ## __VA_ARGS__ ); \
 +} while (0)
 +
 +static struct board_info *find_board(char *id)
 +{
 + struct board_info *ret;
 + struct board_info *board;
 +    ​
 + ret = NULL;
 + for (board = boards; board->​id != NULL; board++){
 + if (strcasecmp(id,​ board->​id) == 0) {
 + ret = board;
 + break;
 + }
 + };
 +    ​
 + return ret;
 +}
 +
 +static struct board_info *find_board_by_hwid(uint32_t hw_id)
 +{
 + struct board_info *board;
 +    ​
 + for (board = boards; board->​id != NULL; board++) {
 + if (hw_id == board->​hw_id)
 + return board;
 + };
 +    ​
 + return NULL;
 +}
 +
 +static struct flash_layout *find_layout(char *id)
 +{
 + struct flash_layout *ret;
 + struct flash_layout *l;
 +    ​
 + ret = NULL;
 + for (l = layouts; l->id != NULL; l++){
 + if (strcasecmp(id,​ l->id) == 0) {
 + ret = l;
 + break;
 + }
 + };
 +    ​
 + return ret;
 +}
 +
 +static void usage(int status)
 +{
 + FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
 + struct board_info *board;
 +    ​
 + fprintf(stream,​ "​Usage:​ %s [OPTIONS...]\n",​ progname);
 + fprintf(stream,​
 +            "​\n"​
 +            "​Options:​\n"​
 +            " ​ -B <​board> ​     create image for the board specified with <​board>​\n"​
 +            " ​ -c              use combined kernel image\n"​
 +            " ​ -E <​ep> ​        ​overwrite kernel entry point with <ep> (hexval prefixed with 0x)\n"
 +            " ​ -L <​la> ​        ​overwrite kernel load address with <la> (hexval prefixed with 0x)\n"
 +            " ​ -H <​hwid> ​      use hardware id specified with <​hwid>​\n"​
 +            " ​ -F <​id> ​        use flash layout specified with <​id>​\n"​
 +            " ​ -k <​file> ​      read kernel image from the file <​file>​\n"​
 +            " ​ -r <​file> ​      read rootfs image from the file <​file>​\n"​
 +            " ​ -a <​align> ​     align the rootfs start on an <​align>​ bytes boundary\n"​
 +            " ​ -R <​offset> ​    ​overwrite rootfs offset with <​offset>​ (hexval prefixed with 0x)\n"
 +            " ​ -o <​file> ​      write output to the file <​file>​\n"​
 +            " ​ -s              strip padding from the end of the image\n"​
 +            " ​ -j              add jffs2 end-of-filesystem markers\n"​
 +            " ​ -N <​vendor> ​    set image vendor to <​vendor>​\n"​
 +            " ​ -V <​version> ​   set image version to <​version>​\n"​
 +            " ​ -i <​file> ​      ​inspect given firmware file <​file>​\n"​
 +            " ​ -x              extract kernel and rootfs while inspecting (requires -i)\n"
 +            " ​ -h              show this screen\n"​
 +            );
 +    ​
 + exit(status);​
 +}
 +
 +//static int get_md5(char *data, int size, char *md5)
 +//{
 +// MD5_CTX ctx;
 +//    ​
 +//​ MD5_Init(&​ctx);​
 +//​ MD5_Update(&​ctx,​ data, size);
 +//​ MD5_Final(md5,​ &ctx);
 +//}
 +
 +static int get_file_stat(struct file_info *fdata)
 +{
 + struct stat st;
 + int res;
 +    ​
 + if (fdata->​file_name == NULL)
 + return 0;
 +    ​
 + res = stat(fdata->​file_name,​ &st);
 + if (res){
 + ERRS("​stat failed on %s", fdata->​file_name);​
 + return res;
 + }
 +    ​
 + fdata->​file_size = st.st_size;
 + return 0;
 +}
 +
 +static int read_to_buf(struct file_info *fdata, char *buf)
 +{
 + FILE *f;
 + int ret = EXIT_FAILURE;​
 +    ​
 + f = fopen(fdata->​file_name,​ "​r"​);​
 + if (f == NULL) {
 + ERRS("​could not open \"​%s\"​ for reading",​ fdata->​file_name);​
 + goto out;
 + }
 +    ​
 + errno = 0;
 + fread(buf, fdata->​file_size,​ 1, f);
 + if (errno != 0) {
 + ERRS("​unable to read from file \"​%s\"",​ fdata->​file_name);​
 + goto out_close;
 + }
 +    ​
 + ret = EXIT_SUCCESS;​
 +    ​
 +out_close:
 + fclose(f);
 +    out:
 + return ret;
 +}
 +
 +static int check_options(void)
 +{
 + int ret;
 +    ​
 + if (inspect_info.file_name) {
 + ret = get_file_stat(&​inspect_info);​
 + if (ret)
 + return ret;
 +        ​
 + return 0;
 + } else if (extract) {
 + ERR("​no firmware for inspection specified"​);​
 + return -1;
 + }
 +    ​
 + if (board_id == NULL && opt_hw_id == NULL) {
 + ERR("​either board or hardware id must be specified"​);​
 + return -1;
 + }
 +    ​
 + if (board_id) {
 + board = find_board(board_id);​
 + if (board == NULL) {
 + ERR("​unknown/​unsupported board id \"​%s\"",​ board_id);
 + return -1;
 + }
 + if (layout_id == NULL)
 + layout_id = board->​layout_id;​
 +        ​
 + hw_id = board->​hw_id;​
 + hw_rev = board->​hw_rev;​
 + } else {
 + if (layout_id == NULL) {
 + ERR("​flash layout is not specified"​);​
 + return -1;
 + }
 + hw_id = strtoul(opt_hw_id,​ NULL, 0);
 +        ​
 + if (opt_hw_rev)
 + hw_rev = strtoul(opt_hw_rev,​ NULL, 0);
 + else
 + hw_rev = 1;
 + }
 +    ​
 + layout = find_layout(layout_id);​
 + if (layout == NULL) {
 + ERR("​unknown flash layout \"​%s\"",​ layout_id);
 + return -1;
 + }
 +    ​
 + if (!kernel_la)
 + kernel_la = layout->​kernel_la;​
 + if (!kernel_ep)
 + kernel_ep = layout->​kernel_ep;​
 + if (!rootfs_ofs)
 + rootfs_ofs = layout->​rootfs_ofs;​
 +    ​
 + if (kernel_info.file_name == NULL) {
 + ERR("​no kernel image specified"​);​
 + return -1;
 + }
 +    ​
 + ret = get_file_stat(&​kernel_info);​
 + if (ret)
 + return ret;
 +    ​
 + kernel_len = kernel_info.file_size;​
 +    ​
 + if (combined) {
 + if (kernel_info.file_size >
 +     layout->​fw_max_len - sizeof(struct fw_header)) {
 + ERR("​kernel image is too big");
 + return -1;
 + }
 + } else {
 + if (rootfs_info.file_name == NULL) {
 + ERR("​no rootfs image specified"​);​
 + return -1;
 + }
 +        ​
 + ret = get_file_stat(&​rootfs_info);​
 + if (ret)
 + return ret;
 +        ​
 + if (rootfs_align) {
 + kernel_len += sizeof(struct fw_header);
 + kernel_len = ALIGN(kernel_len,​ rootfs_align);​
 + kernel_len -= sizeof(struct fw_header);
 +            ​
 + DBG("​kernel length aligned to %u", kernel_len);​
 +            ​
 + if (kernel_len + rootfs_info.file_size >
 +     layout->​fw_max_len - sizeof(struct fw_header)) {
 + ERR("​images are too big");
 + return -1;
 + }
 + } else {
 + if (kernel_info.file_size >
 +     rootfs_ofs - sizeof(struct fw_header)) {
 + ERR("​kernel image is too big");
 + return -1;
 + }
 +            ​
 + if (rootfs_info.file_size >
 +     (layout->​fw_max_len - rootfs_ofs)) {
 + ERR("​rootfs image is too big");
 + return -1;
 + }
 + }
 + }
 +    ​
 + if (ofname == NULL) {
 + ERR("​no output file specified"​);​
 + return -1;
 + }
 +    ​
 + return 0;
 +}
 +
 +static void fill_header(char *buf, int len)
 +{
 + struct fw_header *hdr = (struct fw_header *)buf;
 +    ​
 + memset(hdr,​ 0, sizeof(struct fw_header));​
 +    ​
 + hdr->​version = htonl(HEADER_VERSION_V1);​
 + strncpy(hdr->​vendor_name,​ vendor, sizeof(hdr->​vendor_name));​
 + strncpy(hdr->​fw_version,​ version, sizeof(hdr->​fw_version));​
 + hdr->​hw_id = htonl(hw_id);​
 + hdr->​hw_rev = htonl(hw_rev);​
 +    ​
 + if (boot_info.file_size == 0)
 + memcpy(hdr->​md5sum1,​ md5salt_normal,​ sizeof(hdr->​md5sum1));​
 + else
 + memcpy(hdr->​md5sum1,​ md5salt_boot,​ sizeof(hdr->​md5sum1));​
 +    ​
 + hdr->​kernel_la = htonl(kernel_la);​
 + hdr->​kernel_ep = htonl(kernel_ep);​
 + hdr->​fw_length = htonl(layout->​fw_max_len);​
 + hdr->​kernel_ofs = htonl(sizeof(struct fw_header));​
 + hdr->​kernel_len = htonl(kernel_len);​
 + if (!combined) {
 + hdr->​rootfs_ofs = htonl(rootfs_ofs);​
 + hdr->​rootfs_len = htonl(rootfs_info.file_size);​
 + }
 +    ​
 + CC_MD5(buf,​ len, hdr->​md5sum1);​
 +}
 +
 +static int pad_jffs2(char *buf, int currlen)
 +{
 + int len;
 + uint32_t pad_mask;
 +    ​
 + len = currlen;
 + pad_mask = (64 * 1024);
 + while ((len < layout->​fw_max_len) && (pad_mask != 0)) {
 + uint32_t mask;
 + int i;
 +        ​
 + for (i = 10; i < 32; i++) {
 + mask = 1 << i;
 + if (pad_mask & mask)
 + break;
 + }
 +        ​
 + len = ALIGN(len, mask);
 +        ​
 + for (i = 10; i < 32; i++) {
 + mask = 1 << i;
 + if ((len & (mask - 1)) == 0)
 + pad_mask &= ~mask;
 + }
 +        ​
 + for (i = 0; i < sizeof(jffs2_eof_mark);​ i++)
 + buf[len + i] = jffs2_eof_mark[i];​
 +        ​
 + len += sizeof(jffs2_eof_mark);​
 + }
 +    ​
 + return len;
 +}
 +
 +static int write_fw(char *data, int len)
 +{
 + FILE *f;
 + int ret = EXIT_FAILURE;​
 +    ​
 + f = fopen(ofname,​ "​w"​);​
 + if (f == NULL) {
 + ERRS("​could not open \"​%s\"​ for writing",​ ofname);
 + goto out;
 + }
 +    ​
 + errno = 0;
 + fwrite(data,​ len, 1, f);
 + if (errno) {
 + ERRS("​unable to write output file"​);​
 + goto out_flush;
 + }
 +    ​
 + DBG("​firmware file \"​%s\"​ completed",​ ofname);
 +    ​
 + ret = EXIT_SUCCESS;​
 +    ​
 +out_flush:
 + fflush(f);
 + fclose(f);
 + if (ret != EXIT_SUCCESS) {
 + unlink(ofname);​
 + }
 +    out:
 + return ret;
 +}
 +
 +static int build_fw(void)
 +{
 + int buflen;
 + char *buf;
 + char *p;
 + int ret = EXIT_FAILURE;​
 + int writelen = 0;
 +    ​
 + buflen = layout->​fw_max_len;​
 +    ​
 + buf = malloc(buflen);​
 + if (!buf) {
 + ERR("​no memory for buffer\n"​);​
 + goto out;
 + }
 +    ​
 + memset(buf,​ 0xff, buflen);
 + p = buf + sizeof(struct fw_header);
 + ret = read_to_buf(&​kernel_info,​ p);
 + if (ret)
 + goto out_free_buf;​
 +    ​
 + writelen = sizeof(struct fw_header) + kernel_len;
 +    ​
 + if (!combined) {
 + if (rootfs_align)
 + p = buf + writelen;
 + else
 + p = buf + rootfs_ofs;
 +        ​
 + ret = read_to_buf(&​rootfs_info,​ p);
 + if (ret)
 + goto out_free_buf;​
 +        ​
 + if (rootfs_align)
 + writelen += rootfs_info.file_size;​
 + else
 + writelen = rootfs_ofs + rootfs_info.file_size;​
 +        ​
 + if (add_jffs2_eof)
 + writelen = pad_jffs2(buf,​ writelen);
 + }
 +    ​
 + if (!strip_padding)
 + writelen = buflen;
 +    ​
 + fill_header(buf,​ writelen);
 + ret = write_fw(buf,​ writelen);
 + if (ret)
 + goto out_free_buf;​
 +    ​
 + ret = EXIT_SUCCESS;​
 +    ​
 +out_free_buf:​
 + free(buf);
 +    out:
 + return ret;
 +}
 +
 +/* Helper functions to inspect_fw() representing different output formats */
 +static inline void inspect_fw_pstr(char *label, char *str)
 +{
 + printf("​%-23s:​ %s\n", label, str);
 +}
 +
 +static inline void inspect_fw_phex(char *label, uint32_t val)
 +{
 + printf("​%-23s:​ 0x%08x\n",​ label, val);
 +}
 +
 +static inline void inspect_fw_phexpost(char *label,
 +                                       ​uint32_t val, char *post)
 +{
 + printf("​%-23s:​ 0x%08x (%s)\n",​ label, val, post);
 +}
 +
 +static inline void inspect_fw_phexdef(char *label,
 +                                      uint32_t val, uint32_t defval)
 +{
 + printf("​%-23s:​ 0x%08x ​                 ", label, val);
 +    ​
 + if (val == defval)
 + printf("​(== OpenWrt default)\n"​);​
 + else
 + printf("​(OpenWrt default: 0x%08x)\n",​ defval);
 +}
 +
 +static inline void inspect_fw_phexexp(char *label,
 +                                      uint32_t val, uint32_t expval)
 +{
 + printf("​%-23s:​ 0x%08x ", label, val);
 +    ​
 + if (val == expval)
 + printf("​(ok)\n"​);​
 + else
 + printf("​(expected:​ 0x%08x)\n",​ expval);
 +}
 +
 +static inline void inspect_fw_phexdec(char *label, uint32_t val)
 +{
 + printf("​%-23s:​ 0x%08x / %8u bytes\n",​ label, val, val);
 +}
 +
 +static inline void inspect_fw_phexdecdef(char *label,
 +                                         ​uint32_t val, uint32_t defval)
 +{
 + printf("​%-23s:​ 0x%08x / %8u bytes ", label, val, val);
 +    ​
 + if (val == defval)
 + printf("​(== OpenWrt default)\n"​);​
 + else
 + printf("​(OpenWrt default: 0x%08x)\n",​ defval);
 +}
 +
 +static inline void inspect_fw_pmd5sum(char *label, uint8_t *val, char *text)
 +{
 + int i;
 +    ​
 + printf("​%-23s:",​ label);
 + for (i=0; i<​MD5SUM_LEN;​ i++)
 + printf("​ %02x", val[i]);
 + printf("​ %s\n", text);
 +}
 +
 +static int inspect_fw(void)
 +{
 + char *buf;
 + struct fw_header *hdr;
 + uint8_t md5sum[MD5SUM_LEN];​
 + struct board_info *board;
 + int ret = EXIT_FAILURE;​
 +    ​
 + buf = malloc(inspect_info.file_size);​
 + if (!buf) {
 + ERR("​no memory for buffer!\n"​);​
 + goto out;
 + }
 +    ​
 + ret = read_to_buf(&​inspect_info,​ buf);
 + if (ret)
 + goto out_free_buf;​
 + hdr = (struct fw_header *)buf;
 +    ​
 + inspect_fw_pstr("​File name", inspect_info.file_name);​
 + inspect_fw_phexdec("​File size", inspect_info.file_size);​
 +    ​
 + if (ntohl(hdr->​version) != HEADER_VERSION_V1) {
 + ERR("​file does not seem to have V1 header!\n"​);​
 + goto out_free_buf;​
 + }
 +    ​
 + inspect_fw_phexdec("​Version 1 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));​
 + else
 + memcpy(hdr->​md5sum1,​ md5salt_boot,​ sizeof(md5sum));​
 + CC_MD5(buf,​ inspect_info.file_size,​ hdr->​md5sum1);​
 +    ​
 + if (memcmp(md5sum,​ hdr->​md5sum1,​ sizeof(md5sum))) {
 + inspect_fw_pmd5sum("​Header MD5Sum1",​ md5sum, "​(*ERROR*)"​);​
 + inspect_fw_pmd5sum(" ​         --> expected",​ hdr->​md5sum1,​ ""​);​
 + } else {
 + inspect_fw_pmd5sum("​Header MD5Sum1",​ md5sum, "​(ok)"​);​
 + }
 + if (ntohl(hdr->​unk2) != 0)
 + inspect_fw_phexdec("​Unknown value 2", hdr->​unk2);​
 + inspect_fw_pmd5sum("​Header MD5Sum2",​ hdr->​md5sum2,​
 +                    "​(purpose yet unknown, unchecked here)"​);​
 + if (ntohl(hdr->​unk3) != 0)
 + inspect_fw_phexdec("​Unknown value 3", hdr->​unk3);​
 +    ​
 + printf("​\n"​);​
 +    ​
 + inspect_fw_pstr("​Vendor name", hdr->​vendor_name);​
 + inspect_fw_pstr("​Firmware version",​ hdr->​fw_version);​
 + board = find_board_by_hwid(ntohl(hdr->​hw_id));​
 + if (board) {
 + layout = find_layout(board->​layout_id);​
 + inspect_fw_phexpost("​Hardware ID",
 +                     ntohl(hdr->​hw_id),​ board->​id);​
 + inspect_fw_phexexp("​Hardware Revision",​
 +                    ​ntohl(hdr->​hw_rev),​ board->​hw_rev);​
 + } else {
 + inspect_fw_phexpost("​Hardware ID",
 +                     ntohl(hdr->​hw_id),​ "​unknown"​);​
 + inspect_fw_phex("​Hardware Revision",​
 +                 ntohl(hdr->​hw_rev));​
 + }
 +    ​
 + printf("​\n"​);​
 +    ​
 + inspect_fw_phexdec("​Kernel data offset",​
 +                    ​ntohl(hdr->​kernel_ofs));​
 + inspect_fw_phexdec("​Kernel data length",​
 +                    ​ntohl(hdr->​kernel_len));​
 + if (board) {
 + inspect_fw_phexdef("​Kernel load address",​
 +                    ​ntohl(hdr->​kernel_la),​
 +                    ​layout ? layout->​kernel_la : 0xffffffff);​
 + inspect_fw_phexdef("​Kernel entry point",​
 +                    ​ntohl(hdr->​kernel_ep),​
 +                    ​layout ? layout->​kernel_ep : 0xffffffff);​
 + inspect_fw_phexdecdef("​Rootfs data offset",​
 +                       ntohl(hdr->​rootfs_ofs),​
 +                       layout ? layout->​rootfs_ofs : 0xffffffff);​
 + } else {
 + inspect_fw_phex("​Kernel load address",​
 +                 ntohl(hdr->​kernel_la));​
 + inspect_fw_phex("​Kernel entry point",​
 +                 ntohl(hdr->​kernel_ep));​
 + inspect_fw_phexdec("​Rootfs data offset",​
 +                    ​ntohl(hdr->​rootfs_ofs));​
 + }
 + inspect_fw_phexdec("​Rootfs data length",​
 +                    ​ntohl(hdr->​rootfs_len));​
 + inspect_fw_phexdec("​Boot loader data offset",​
 +                    ​ntohl(hdr->​boot_ofs));​
 + inspect_fw_phexdec("​Boot loader data length",​
 +                    ​ntohl(hdr->​boot_len));​
 + inspect_fw_phexdec("​Total firmware length",​
 +                    ​ntohl(hdr->​fw_length));​
 +    ​
 + if (extract) {
 + FILE *fp;
 + char *filename;
 +        ​
 + printf("​\n"​);​
 +        ​
 + filename = malloc(strlen(inspect_info.file_name) + 8);
 + sprintf(filename,​ "​%s-kernel",​ inspect_info.file_name);​
 + printf("​Extracting kernel to \"​%s\"​...\n",​ filename);
 + fp = fopen(filename,​ "​w"​);​
 + if (fp) {
 + if (!fwrite(buf + ntohl(hdr->​kernel_ofs),​
 +             ntohl(hdr->​kernel_len),​ 1, fp)) {
 + ERR("​error in fwrite(): %s", strerror(errno));​
 + }
 + fclose(fp);​
 + } else {
 + ERR("​error in fopen(): %s", strerror(errno));​
 + }
 + free(filename);​
 +        ​
 + filename = malloc(strlen(inspect_info.file_name) + 8);
 + sprintf(filename,​ "​%s-rootfs",​ inspect_info.file_name);​
 + printf("​Extracting rootfs to \"​%s\"​...\n",​ filename);
 + fp = fopen(filename,​ "​w"​);​
 + if (fp) {
 + if (!fwrite(buf + ntohl(hdr->​rootfs_ofs),​
 +             ntohl(hdr->​rootfs_len),​ 1, fp)) {
 + ERR("​error in fwrite(): %s", strerror(errno));​
 + }
 + fclose(fp);​
 + } else {
 + ERR("​error in fopen(): %s", strerror(errno));​
 + }
 + free(filename);​
 + }
 +    ​
 +out_free_buf:​
 + free(buf);
 +    out:
 + return ret;
 +}
 +
 +int main(int argc, char *argv[])
 +{
 + int ret = EXIT_FAILURE;​
 + int err;
 +    ​
 + FILE *outfile;
 +    ​
 + progname = basename(argv[0]);​
 +    ​
 + while ( 1 ) {
 + int c;
 +        ​
 + c = getopt(argc,​ argv, "​a:​B:​H:​E:​F:​L:​V:​N:​W:​ci:​k:​r:​R:​o:​xhsj"​);​
 + if (c == -1)
 + break;
 +        ​
 + switch (c) {
 +            case '​a':​
 +                sscanf(optarg,​ "​0x%x",​ &​rootfs_align);​
 +                break;
 +            case '​B':​
 +                board_id = optarg;
 +                break;
 +            case '​H':​
 +                opt_hw_id = optarg;
 +                break;
 +            case '​E':​
 +                sscanf(optarg,​ "​0x%x",​ &​kernel_ep);​
 +                break;
 +            case '​F':​
 +                layout_id = optarg;
 +                break;
 +            case '​W':​
 +                opt_hw_rev = optarg;
 +                break;
 +            case '​L':​
 +                sscanf(optarg,​ "​0x%x",​ &​kernel_la);​
 +                break;
 +            case '​V':​
 +                version = optarg;
 +                break;
 +            case '​N':​
 +                vendor = optarg;
 +                break;
 +            case '​c':​
 +                combined++;
 +                break;
 +            case '​k':​
 +                kernel_info.file_name = optarg;
 +                break;
 +            case '​r':​
 +                rootfs_info.file_name = optarg;
 +                break;
 +            case '​R':​
 +                sscanf(optarg,​ "​0x%x",​ &​rootfs_ofs);​
 +                break;
 +            case '​o':​
 +                ofname = optarg;
 +                break;
 +            case '​s':​
 +                strip_padding = 1;
 +                break;
 +            case '​i':​
 +                inspect_info.file_name = optarg;
 +                break;
 +            case '​j':​
 +                add_jffs2_eof = 1;
 +                break;
 +            case '​x':​
 +                extract = 1;
 +                break;
 +            case '​h':​
 +                usage(EXIT_SUCCESS);​
 +                break;
 +            default:
 +                usage(EXIT_FAILURE);​
 +                break;
 + }
 + }
 +    ​
 + ret = check_options();​
 + if (ret)
 + goto out;
 +    ​
 + if (!inspect_info.file_name)
 + ret = build_fw();
 + else
 + ret = inspect_fw();​
 +    ​
 +    out:
 + return ret;
 +}
 +</​code>​
 +
 +===== Some outputs from the above program for 6 firmwares =====
 +
 +
 +Original FW 111103 (cat the mtd1 and mtd2 into /tmp, then tftp it over and merge them with ie: copy /b in DOS)
 +<​code>​
 +File name              :  ​
 +File size              : 0x003c0000 /  3932160 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Header MD5Sum1 ​        : c0 72 33 5f b8 63 23 93 1e 7c 25 8a 8f 49 a7 82 (ok)
 +Header MD5Sum2 ​        : 7d 1a 19 f4 57 b2 98 ed 75 03 02 19 64 87 48 b9 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : TP-LINK Technologies
 +Firmware version ​      : ver. 1.0
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000da2db /   ​893659 bytes
 +Kernel load address ​   : 0x80002000
 +Kernel entry point     : 0x801d6980
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x002c0000 /  2883584 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +MD5 (kernel) = f47785e1d34a94cb457310052be68fa9
 +MD5 (rootfs) = 724b260768caa752ad20ed467d4c78ef
 +
 +893659 Feb 25 04:08 kernel
 +2883584 Feb 25 04:08 rootfs
 +
 +LZMA (magic number 5D 00 00 80) at kernel file
 +from http://​www.mjmwired.net/​kernel/​Documentation/​x86/​boot.txt
 +http://​www.devttys0.com/​2011/​06/​mystery-file-system/​
 +
 +Using 7zip for windows, it shows LZMA:25
 +
 +Kernels between the 111103 and 111129 are the same binary wise, only the complied date "​texts"​ (two places) are different
 +
 +</​code>​
 +
 +FW from Tplink site 111129
 +http://​www.tp-link.cn/​pages/​download-detail.asp?​d=696
 +
 +<​code>​
 +File name              : 111129/​mr11uv1.bin
 +File size              : 0x003c0000 /  3932160 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Unknown value 1        : 0x6813fc20 / 1746140192 bytes
 +Header MD5Sum1 ​        : eb 99 bb c1 73 fd 15 04 9b 52 bd 69 ee 5f b7 1b (ok)
 +Header MD5Sum2 ​        : c9 82 b9 5f 5c c2 30 df f3 5b bd 24 0b cb 52 46 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : TP-LINK Technologies
 +Firmware version ​      : ver. 1.0
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000da300 /   ​893696 bytes
 +Kernel load address ​   : 0x80002000
 +Kernel entry point     : 0x801d6980
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x002c0000 /  2883584 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +893696 Feb 25 04:09 mr11uv1.bin-kernel
 +2883584 Feb 25 04:09 mr11uv1.bin-rootfs
 +
 +MD5 (mr11uv1.bin-kernel) = 5cf9b55ed98e31fd934c1100093206be
 +MD5 (mr11uv1.bin-rootfs) = a79be973a0dd3ec09861de94d4bb8ef9
 +
 +LZMA (magic number 5D 00 00 80) at kernel file
 +
 +Using 7zip for windows, it shows LZMA:25
 +
 +</​code>​
 +
 +
 +The difference between the 11103 and 11129 are (TODO)
 +
 +9 files changed in /etc
 +4 files changed in /lib
 +5 files changed in /usr
 +29 files changed in /web
 +
 +
 +From http://​downloads.openwrt.org/​snapshots/​trunk/​ar71xx/​
 +
 +All are Feb 19, 2012 snapshots
 +
 +openwrt-ar71xx-generic-tl-mr11u-v1-jffs2-factory.bin
 +<​code>​
 +File name              : openwrt-ar71xx-generic-tl-mr11u-v1-jffs2-factory.bin
 +File size              : 0x003c0000 /  3932160 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Header MD5Sum1 ​        : 84 66 3f 25 5a b6 13 54 1e 1a e4 83 98 2e 0b 23 (ok)
 +Header MD5Sum2 ​        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : OpenWrt
 +Firmware version ​      : r30639
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000efe00 /   ​982528 bytes
 +Kernel load address ​   : 0x80060000
 +Kernel entry point     : 0x80060000
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x00220004 /  2228228 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +(magic number 6D 00) at kernel file 
 +
 +Using 7zip for windows, it shows LZMA:23
 +
 +Runs Linux 3.2.5
 +</​code>​
 +
 +openwrt-ar71xx-generic-tl-mr11u-v1-jffs2-sysupgrade.bin
 +<​code>​
 +File name              : openwrt-ar71xx-generic-tl-mr11u-v1-jffs2-sysupgrade.bin
 +File size              : 0x00320004 /  3276804 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Header MD5Sum1 ​        : 21 bb 88 24 cd 12 2f b6 92 1b 22 0d db 54 50 e8 (ok)
 +Header MD5Sum2 ​        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : OpenWrt
 +Firmware version ​      : r30639
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000efe00 /   ​982528 bytes
 +Kernel load address ​   : 0x80060000
 +Kernel entry point     : 0x80060000
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x00220004 /  2228228 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +</​code>​
 +
 +openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin
 +
 +<​code>​
 +File name              : openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin
 +File size              : 0x003c0000 /  3932160 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Header MD5Sum1 ​        : 23 eb 64 02 83 76 f2 58 07 59 9d 92 72 7b 35 ab (ok)
 +Header MD5Sum2 ​        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : OpenWrt
 +Firmware version ​      : r30639
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000e3d5c /   ​933212 bytes
 +Kernel load address ​   : 0x80060000
 +Kernel entry point     : 0x80060000
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x0016b6c2 /  1488578 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +
 +MD5 (openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin-kernel) = e670abedba1561d0b9508748839bdb08
 +MD5 (openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin-rootfs) = fc8b1d348d7ee655c7c373e8920e6eea
 +
 +(same md5 for kernel as below)
 +
 +933212 Feb 25 03:57 openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin-kernel
 +1488578 Feb 25 03:57 openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-factory.bin-rootfs
 +
 +Wrong rootfs offset in the header... should be 0xE3F5C
 +
 +</​code>​
 +
 +openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin
 +<​code>​
 +File name              : openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin
 +File size              : 0x00250004 /  2424836 bytes
 +Version 1 Header size  : 0x00000200 /      512 bytes
 +Header MD5Sum1 ​        : 47 bf 73 ae dd d0 a5 08 c8 cb a9 21 be e0 21 5a (ok)
 +Header MD5Sum2 ​        : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (purpose yet unknown, unchecked here)
 +
 +Vendor name            : OpenWrt
 +Firmware version ​      : r30639
 +Hardware ID            : 0x00110101 (unknown)
 +Hardware Revision ​     : 0x00000001
 +
 +Kernel data offset ​    : 0x00000200 /      512 bytes
 +Kernel data length ​    : 0x000e3d5c /   ​933212 bytes
 +Kernel load address ​   : 0x80060000
 +Kernel entry point     : 0x80060000
 +Rootfs data offset ​    : 0x00100000 /  1048576 bytes
 +Rootfs data length ​    : 0x0016b6c2 /  1488578 bytes
 +Boot loader data offset: 0x00000000 /        0 bytes
 +Boot loader data length: 0x00000000 /        0 bytes
 +Total firmware length ​ : 0x003c0000 /  3932160 bytes
 +
 +Gives error when extracting (why?)
 + *** error: error in fwrite(): Bad address
 +
 +MD5 (openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin-kernel) = e670abedba1561d0b9508748839bdb08
 +MD5 (openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin-rootfs) = 3e5ac7044a1ce39a52a77cf17718a17d
 +
 +933212 Feb 25 03:59 openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin-kernel
 +1380352 Feb 25 03:59 openwrt-ar71xx-generic-tl-mr11u-v1-squashfs-sysupgrade.bin-rootfs
 +
 +(smaller sized rootfs? corrupted?​) ​
 +
 +Wrong rootfs offset in the header... should be 0xE3F5C
 +</​code>​
 +TODO
 +
 +===== To Extract the rootfs of factory image =====
 +
 +from https://​forum.openwrt.org/​viewtopic.php?​pid=151276
 +
 +Use Xcode checkout to get this
 +
 +http://​code.google.com/​p/​firmware-mod-kit/​source/​browse/​trunk/​trunk/​src/​others/​squashfs-4.0-lzma/​
 +
 +then copy the squashfs-4.0-lzma directory from "/​others/"​ out to usb stick, then bootup ie: Parallels Desktop 7 for Mac with the BackBox 2.01 linux ISO image in text mode, then mount the usb stick inside, then do "​make"​ to create the unsquashfs-lzma executable
 +
 +to extract the files, you would need ext2 or the root of the ramdisk is fine too, just make a dir ie: /extracted
 +
 +use unsquashfs-lzma rootfs to extract it 
 +
 +use mksquashfs-lzma pathtoread/ outputFile to recreate image
 +
 +then just paste the result into the offset 100000(IIRC) (you will see the squashfs header), then fix md5, then flash via firmware upgrade
 +
 +===== Making it work with other "​unsupported"​ modems with factory image =====
 +
 +==== patching httpd to remove ERROR commands ====
 +
 +
 +ie: AT+CFUN=1
 +
 +TODO
 +
 +the pppd command run is 
 +<​code>​
 +/​dev/​ttyUSB0 115200 connect chat -V -E -f /​etc/​ppp/​conn-script disconnect chat -
 +V -E -f /​etc/​ppp/​disconn-script defaultroute noaccomp nopcomp lcp-echo-failure 5
 + ​lcp-echo-interval 30 httpd-pid x user_len x passwd_len x special-flag 100 m
 +ru 1480 mtu 1480 usepeerdns noipdefault refuse-chap refuse-mschap refuse-mschap-
 +v2 refuse-eap ipcp-accept-local ipcp-accept-remote unit 0
 +</​code>​
 +
 +==== Result ====
 +
 +
 +Telus/Koodo is fine (can use pap),   
 +
 +Bell Mobility will need some fixing (keeps failing authentication)
 +
 +remove the "​user_len xx passwd_len xx" section, ​ (don't know why but it fixed it)
 +then add your own user "​x"​ password "​x"​
 +
 +Also you have to fix the httpd-pid to match the real pid in the argument, else the pppd will terminate because httpd does not "​detect"​ pppd is online, even though it is.
 +
 +
 +Average time from cold boot to "​online"​ : 1 min 15 seconds
 +
 +TODO
  
inbox/macosx.lion.txt · Last modified: 2013/07/14 09:19 (external edit)