aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile160
-rw-r--r--tools/autoconf/Makefile18
-rw-r--r--tools/autoconf/patches/000-relocatable.patch90
-rw-r--r--tools/autoconf/patches/001-no_emacs_lib.patch4
-rw-r--r--tools/autoconf/patches/002-musl_host_fixup.patch24
-rw-r--r--tools/automake/Makefile29
-rw-r--r--tools/automake/patches/000-relocatable.patch108
-rw-r--r--tools/automake/patches/100-aclocal-skip-not-existing-directories.patch16
-rw-r--r--tools/automake/patches/200-do-not-override-silent-rules.patch13
-rw-r--r--tools/b43-tools/Makefile50
-rwxr-xr-xtools/b43-tools/files/b43-fwsquash.py149
-rw-r--r--tools/b43-tools/patches/001-fw-dirname.patch16
-rw-r--r--tools/b43-tools/patches/002-no_libfl.patch14
-rw-r--r--tools/bc/Makefile21
-rw-r--r--tools/bc/patches/001-no_doc.patch23
-rw-r--r--tools/bison/Makefile18
-rw-r--r--tools/bison/patches/000-relocatable.patch20
-rw-r--r--tools/bison/patches/010-intl-stub-compat.patch8
-rw-r--r--tools/bison/patches/100-fix-gets-removal.patch19
-rwxr-xr-xtools/bison/scripts/yacc2
-rw-r--r--tools/ccache/Makefile44
-rwxr-xr-xtools/ccache/files/ccache_cc2
-rwxr-xr-xtools/ccache/files/ccache_cxx2
-rw-r--r--tools/ccache/patches/100-honour-copts.patch10
-rw-r--r--tools/cloog/Makefile39
-rw-r--r--tools/cmake/Makefile25
-rw-r--r--tools/cmake/patches/100-disable_qt_tests.patch34
-rw-r--r--tools/cmake/patches/110-libarchive-fix-libressl-compat.patch11
-rw-r--r--tools/cmake/patches/120-curl-fix-libressl-linking.patch37
-rw-r--r--tools/cmake/patches/130-bootstrap_parallel_make_flag.patch14
-rw-r--r--tools/cmake/patches/140-libarchive-fix-libressl.patch37
-rw-r--r--tools/coreutils/Makefile37
-rw-r--r--tools/coreutils/patches/001-fix-macos-vasnprintf.patch25
-rw-r--r--tools/dosfstools/Makefile27
-rw-r--r--tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch27
-rw-r--r--tools/e2fsprogs/Makefile32
-rw-r--r--tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch2
-rw-r--r--tools/e2fsprogs/patches/002-dont-build-e4defrag.patch11
-rw-r--r--tools/e2fsprogs/patches/002-freebsd_fix.patch18
-rw-r--r--tools/e2fsprogs/patches/003-darwin_directio_fix.patch36
-rw-r--r--tools/e2fsprogs/patches/003-openbsd-compat.patch12
-rw-r--r--tools/e2fsprogs/patches/004-big_endian_compile_fix.patch26
-rw-r--r--tools/e2fsprogs/patches/004-darwin-compat.patch22
-rw-r--r--tools/elftosb/Makefile26
-rw-r--r--tools/elftosb/patches/001-libm.patch11
-rw-r--r--tools/elftosb/patches/002-fix-header-path.patch19
-rw-r--r--tools/elftosb/patches/003-use-ldflags.patch26
-rw-r--r--tools/expat/Makefile26
-rw-r--r--tools/findutils/Makefile21
-rw-r--r--tools/findutils/patches/100-include_sysmacros.patch13
-rw-r--r--tools/findutils/patches/110-glibc-change-work-around.patch104
-rw-r--r--tools/firmware-utils/Makefile42
-rw-r--r--tools/firmware-utils/src/addpattern.c49
-rw-r--r--tools/firmware-utils/src/airlink.c332
-rw-r--r--tools/firmware-utils/src/asustrx.c256
-rw-r--r--[l---------]tools/firmware-utils/src/bcm_tag.h71
-rw-r--r--tools/firmware-utils/src/bcmalgo.c248
-rw-r--r--tools/firmware-utils/src/bcmalgo.h83
-rw-r--r--tools/firmware-utils/src/buffalo-enc.c36
-rw-r--r--tools/firmware-utils/src/buffalo-lib.c6
-rw-r--r--tools/firmware-utils/src/buffalo-lib.h20
-rw-r--r--tools/firmware-utils/src/buffalo-tag.c46
-rw-r--r--tools/firmware-utils/src/buffalo-tftp.c2
-rw-r--r--tools/firmware-utils/src/csysimg.h1
-rw-r--r--tools/firmware-utils/src/dgfirmware.c1
-rw-r--r--tools/firmware-utils/src/dgn3500sum.c166
-rw-r--r--tools/firmware-utils/src/dns313-header.c239
-rw-r--r--tools/firmware-utils/src/edimax_fw_header.c386
-rw-r--r--tools/firmware-utils/src/fix-u-media-header.c354
-rw-r--r--tools/firmware-utils/src/hcsmakeimage.c203
-rw-r--r--tools/firmware-utils/src/imagetag.c101
-rw-r--r--tools/firmware-utils/src/imagetag.ggo2
-rw-r--r--tools/firmware-utils/src/imagetag_cmdline.c178
-rw-r--r--tools/firmware-utils/src/imagetag_cmdline.h61
-rw-r--r--tools/firmware-utils/src/jcgimage.c425
-rw-r--r--tools/firmware-utils/src/lzma2eva.c2
-rw-r--r--tools/firmware-utils/src/md5.c551
-rw-r--r--tools/firmware-utils/src/md5.h92
-rw-r--r--tools/firmware-utils/src/mkbrnimg.c22
-rw-r--r--tools/firmware-utils/src/mkbuffaloimg.c223
-rw-r--r--tools/firmware-utils/src/mkcameofw.c433
-rw-r--r--tools/firmware-utils/src/mkcasfw.c8
-rw-r--r--tools/firmware-utils/src/mkchkimg.c22
-rw-r--r--tools/firmware-utils/src/mkcsysimg.c9
-rw-r--r--tools/firmware-utils/src/mkdapimg.c226
-rw-r--r--tools/firmware-utils/src/mkdapimg2.c204
-rw-r--r--tools/firmware-utils/src/mkdcs932.c39
-rw-r--r--tools/firmware-utils/src/mkdhpimg.c85
-rw-r--r--tools/firmware-utils/src/mkdlinkfw-lib.c172
-rw-r--r--tools/firmware-utils/src/mkdlinkfw-lib.h83
-rw-r--r--tools/firmware-utils/src/mkdlinkfw.c665
-rw-r--r--tools/firmware-utils/src/mkdniimg.c2
-rw-r--r--tools/firmware-utils/src/mkfwimage.c20
-rw-r--r--tools/firmware-utils/src/mkfwimage2.c6
-rw-r--r--tools/firmware-utils/src/mkheader_gemtek.c211
-rw-r--r--tools/firmware-utils/src/mkhilinkfw.c323
-rw-r--r--tools/firmware-utils/src/mkmerakifw-old.c369
-rw-r--r--tools/firmware-utils/src/mkmerakifw.c320
-rw-r--r--tools/firmware-utils/src/mkplanexfw.c2
-rw-r--r--tools/firmware-utils/src/mkporayfw.c791
-rw-r--r--tools/firmware-utils/src/mkrtn56uimg.c293
-rw-r--r--tools/firmware-utils/src/mksenaofw.c420
-rw-r--r--tools/firmware-utils/src/mksercommfw.c255
-rw-r--r--tools/firmware-utils/src/mktplinkfw-lib.c265
-rw-r--r--tools/firmware-utils/src/mktplinkfw-lib.h68
-rw-r--r--tools/firmware-utils/src/mktplinkfw.c769
-rw-r--r--tools/firmware-utils/src/mktplinkfw2.c628
-rw-r--r--tools/firmware-utils/src/mkwrggimg.c283
-rw-r--r--tools/firmware-utils/src/mkzcfw.c2
-rw-r--r--tools/firmware-utils/src/mkzynfw.c5
-rw-r--r--tools/firmware-utils/src/nand_ecc.c2
-rw-r--r--tools/firmware-utils/src/osbridge-crc.c2
-rw-r--r--tools/firmware-utils/src/oseama.c556
-rw-r--r--tools/firmware-utils/src/otrx.c592
-rw-r--r--tools/firmware-utils/src/pc1crypt.c2
-rw-r--r--tools/firmware-utils/src/ptgen.c126
-rw-r--r--tools/firmware-utils/src/seama.c529
-rw-r--r--tools/firmware-utils/src/seama.h108
-rw-r--r--tools/firmware-utils/src/spw303v.c2
-rw-r--r--tools/firmware-utils/src/srec2bin.c2
-rw-r--r--tools/firmware-utils/src/tplink-safeloader.c2084
-rw-r--r--tools/firmware-utils/src/trx.c22
-rw-r--r--tools/firmware-utils/src/wndr3700.c150
-rw-r--r--tools/firmware-utils/src/wrt400n.c2
-rw-r--r--tools/firmware-utils/src/xorimage.c1
-rw-r--r--tools/firmware-utils/src/zyimage.c148
-rw-r--r--tools/firmware-utils/src/zyxbcm.c259
-rw-r--r--tools/flex/Makefile19
-rw-r--r--tools/flex/patches/100-disable-tests-docs.patch13
-rw-r--r--tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch27
-rw-r--r--tools/flock/Makefile5
-rw-r--r--tools/flock/src/flock.c17
-rw-r--r--tools/genext2fs/Makefile3
-rw-r--r--tools/genext2fs/patches/100-c99_scanf.patch21
-rw-r--r--tools/genext2fs/patches/200-autoconf.patch13
-rw-r--r--tools/genext2fs/patches/300-blocksize-creator.patch558
-rw-r--r--tools/genext2fs/patches/400-byteswap_fix.patch44
-rw-r--r--tools/gengetopt/Makefile30
-rw-r--r--tools/gengetopt/patches/100-dependency_fix.patch11
-rw-r--r--tools/gengetopt/patches/200-no_docs_tests.patch13
-rw-r--r--tools/gmp/Makefile17
-rw-r--r--tools/gmp/patches/000-OE-amd64.patch16
-rw-r--r--tools/gmp/patches/000-OE-configure.patch193
-rw-r--r--tools/include/byteswap.h2
-rw-r--r--tools/include/elf.h (renamed from tools/sstrip/include/elf.h)704
-rw-r--r--tools/include/endian.h5
-rw-r--r--tools/include/getline.h68
-rw-r--r--tools/ipkg-utils/Makefile32
-rw-r--r--tools/ipkg-utils/patches/100-build_clean.patch35
-rw-r--r--tools/ipkg-utils/patches/110-buildpackage.patch23
-rw-r--r--tools/ipkg-utils/patches/111-buildpackage_conffiles.patch11
-rw-r--r--tools/ipkg-utils/patches/120-build_tar.patch36
-rw-r--r--tools/ipkg-utils/patches/130-tar_wildcards.patch23
-rw-r--r--tools/ipkg-utils/patches/140-portability.patch19
-rw-r--r--tools/ipkg-utils/patches/150-uppercase_letters.patch22
-rw-r--r--tools/ipkg-utils/patches/160-find.patch39
-rw-r--r--tools/ipkg-utils/patches/170-resolve_conffiles.patch23
-rw-r--r--tools/ipkg-utils/patches/180-add_installed_size.patch14
-rw-r--r--tools/ipkg-utils/patches/190-preserve_permissions.patch12
-rw-r--r--tools/isl/Makefile27
-rw-r--r--tools/kernel2minor/Makefile29
-rw-r--r--tools/libelf/Makefile6
-rw-r--r--tools/libressl/Makefile27
-rw-r--r--tools/libtool/Makefile15
-rw-r--r--tools/libtool/patches/000-relocatable.patch53
-rw-r--r--tools/libtool/patches/160-passthrough-ssp.patch12
-rw-r--r--tools/libtool/patches/200-openwrt-branding.patch8
-rw-r--r--tools/lzma-old/Makefile4
-rw-r--r--tools/lzma-old/patches/120-add-cflags.patch11
-rw-r--r--tools/lzma/Makefile2
-rw-r--r--tools/lzma/patches/101-move-copyright-to-usage-info.patch20
-rw-r--r--tools/m4/Makefile15
-rw-r--r--tools/m4/patches/001-fix-macos-vasnprintf.patch25
-rw-r--r--tools/m4/patches/010-glibc-change-work-around.patch118
-rw-r--r--tools/make-ext4fs/Makefile28
-rw-r--r--tools/make-ext4fs/patches/100-add-ldflags.patch11
-rw-r--r--tools/missing-macros/Makefile4
-rwxr-xr-xtools/missing-macros/src/bin/help2man29
-rwxr-xr-xtools/missing-macros/src/bin/makeinfo112
-rw-r--r--tools/missing-macros/src/m4/esd.m4196
-rw-r--r--tools/missing-macros/src/m4/xaw.m465
-rw-r--r--tools/missing-macros/src/m4/xmms.m4149
-rw-r--r--tools/mkimage/Makefile29
-rw-r--r--tools/mkimage/patches/010-freebsd-ulong-fix.patch8
-rw-r--r--tools/mkimage/patches/020-darwin-10_7-getline-fix.patch22
-rw-r--r--tools/mkimage/patches/020-include_compile_fix.patch10
-rw-r--r--tools/mkimage/patches/030-allow-to-use-different-magic.patch98
-rw-r--r--tools/mkimage/patches/050-image_h_portability.patch31
-rw-r--r--tools/mkimage/patches/060-remove_kernel_includes.patch35
-rw-r--r--tools/mkimage/patches/080-remove_compiler_check.patch16
-rw-r--r--tools/mkimage/patches/100-freebsd-compat.patch14
-rw-r--r--tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch68
-rw-r--r--tools/mkimage/patches/210-link-libcrypto-static.patch14
-rw-r--r--tools/mklibs/Makefile12
-rw-r--r--tools/mklibs/patches/001-compile.patch8
-rw-r--r--tools/mklibs/patches/001-missing_stdio.patch10
-rw-r--r--tools/mklibs/patches/002-disable_symbol_checks.patch23
-rw-r--r--tools/mklibs/patches/003-no_copy.patch10
-rw-r--r--tools/mklibs/patches/004-libpthread_link.patch10
-rw-r--r--tools/mklibs/patches/005-duplicate_syms.patch (renamed from tools/mklibs/patches/006-duplicate_syms.patch)13
-rw-r--r--tools/mklibs/patches/005-readelf_fixes.patch33
-rw-r--r--tools/mklibs/patches/006-uclibc_init.patch (renamed from tools/mklibs/patches/007-uclibc_init.patch)6
-rw-r--r--tools/mklibs/patches/007-gc_sections.patch (renamed from tools/mklibs/patches/008-gc_sections.patch)6
-rw-r--r--tools/mklibs/patches/008-uclibc_libgcc_link.patch (renamed from tools/mklibs/patches/009-uclibc_libgcc_link.patch)10
-rw-r--r--tools/mklibs/patches/009-uclibc_libpthread_symbols.patch (renamed from tools/mklibs/patches/010-uclibc_libpthread_symbols.patch)12
-rw-r--r--tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch20
-rw-r--r--tools/mklibs/patches/011-remove_multiarch.patch10
-rw-r--r--tools/mm-macros/Makefile10
-rw-r--r--tools/mpc/Makefile19
-rw-r--r--tools/mpfr/Makefile18
-rw-r--r--tools/mpfr/patches/000-upstream_cumulative.patch1945
-rw-r--r--tools/mpfr/patches/001-no_tests.patch26
-rw-r--r--tools/mpfr/patches/001-only_src.patch22
-rw-r--r--tools/mpfr/patches/100-freebsd-compat.patch10
-rw-r--r--tools/mtd-utils/Makefile57
-rw-r--r--tools/mtd-utils/patches/100-optional_lzo.patch0
-rw-r--r--tools/mtd-utils/patches/100-sscanf_fix.patch11
-rw-r--r--tools/mtd-utils/patches/101-ubifs-optional_lzo.patch0
-rw-r--r--tools/mtd-utils/patches/110-portability.patch91
-rw-r--r--tools/mtd-utils/patches/120-cygwin_fixes.patch457
-rw-r--r--tools/mtd-utils/patches/130-lzma_jffs2.patch144
-rw-r--r--tools/mtd-utils/patches/131-fix_lib_compile.patch11
-rw-r--r--tools/mtd-utils/patches/133-error-fix.patch20
-rw-r--r--tools/mtd-utils/patches/134-freebsd_loff_t.patch13
-rw-r--r--tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch119
-rw-r--r--tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch404
-rw-r--r--tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch89
-rw-r--r--tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch68
-rw-r--r--tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch60
-rw-r--r--tools/mtools/Makefile38
-rw-r--r--tools/mtools/patches/100-compile_fix.patch19
-rw-r--r--tools/padjffs2/Makefile6
-rw-r--r--tools/padjffs2/src/Makefile2
-rw-r--r--tools/padjffs2/src/padjffs2.c83
-rw-r--r--tools/patch-image/Makefile (renamed from tools/patch-cmdline/Makefile)9
-rw-r--r--tools/patch-image/src/patch-cmdline.c (renamed from tools/patch-cmdline/src/patch-cmdline.c)16
-rw-r--r--tools/patch-image/src/patch-dtb.c103
-rw-r--r--tools/patch/Makefile23
-rw-r--r--tools/patchelf/Makefile26
-rw-r--r--tools/pkg-config/Makefile21
-rw-r--r--tools/pkg-config/patches/100-disable_compat_cmd.patch22
-rw-r--r--tools/ppl/Makefile35
-rw-r--r--tools/ppl/patches/001-gmp_5_fix.patch38
-rw-r--r--tools/qemu/Makefile35
-rw-r--r--tools/qemu/patches/010-freebsd-fix.patch11
-rw-r--r--tools/quilt/Makefile17
-rw-r--r--tools/quilt/patches/000-relocatable.patch165
-rw-r--r--tools/quilt/patches/001-fix_compile.patch6
-rw-r--r--tools/quilt/patches/100-patch_2.6.1_version.patch15
-rw-r--r--tools/scons/Makefile35
-rwxr-xr-xtools/scons/files/pywrap.sh15
-rw-r--r--tools/scons/patches/001-platform_env.patch11
-rw-r--r--tools/sdimage/Makefile34
-rw-r--r--tools/sed/Makefile25
-rw-r--r--tools/sparse/Makefile24
-rw-r--r--tools/squashfs/Makefile8
-rw-r--r--tools/squashfs/patches/100-lzma.patch4
-rw-r--r--tools/squashfs/patches/110-no_nonstatic_inline.patch11
-rw-r--r--tools/squashfs/patches/120-add-fixed-timestamp-support.patch79
-rw-r--r--tools/squashfs/patches/130-include_sysmacros.patch20
-rw-r--r--tools/squashfs4/Makefile6
-rw-r--r--tools/squashfs4/patches/130-include_sysmacros.patch20
-rw-r--r--tools/squashfs4/patches/160-expose_lzma_xz_options.patch6
-rw-r--r--tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch8
-rw-r--r--tools/squashfs4/patches/180-openbsd_compat.patch24
-rw-r--r--tools/squashfs4/patches/190-no_nonstatic_inline.patch36
-rw-r--r--tools/squashfs4/patches/200-add-fixed-timestamp-option.patch82
-rw-r--r--tools/sstrip/Makefile4
-rw-r--r--tools/sstrip/src/sstrip.c9
-rw-r--r--tools/tar/Makefile31
-rw-r--r--tools/tar/patches/100-symlink-force-root-name.patch27
-rw-r--r--tools/tar/patches/110-symlink-force-permissions.patch10
-rw-r--r--tools/upslug2/Makefile5
-rw-r--r--tools/upx/Makefile35
-rw-r--r--tools/upx/patches/100-lzmaonly.patch156
-rw-r--r--tools/wrt350nv2-builder/Makefile8
-rw-r--r--tools/wrt350nv2-builder/src/ioapi.h16
-rw-r--r--tools/wrt350nv2-builder/src/wrt350nv2-builder.c76
-rw-r--r--tools/xfce-macros/Makefile32
-rw-r--r--tools/xorg-macros/Makefile31
-rw-r--r--tools/xz/Makefile21
-rw-r--r--tools/yaffs2/Makefile37
-rw-r--r--tools/yaffs2/patches/100-compile.patch125
-rw-r--r--tools/zlib/Makefile41
-rw-r--r--tools/zlib/patches/900-overridable-pc-exec-prefix.patch14
285 files changed, 19228 insertions, 7085 deletions
diff --git a/tools/Makefile b/tools/Makefile
index 4fe91f665a1..9a354f6c706 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -10,62 +10,109 @@ curdir:=tools
# subdirectories to descend into
tools-y :=
-ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN)$(CONFIG_GCC_LLVM),)
-tools-y += gmp mpfr mpc libelf
+
+ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
+ BUILD_TOOLCHAIN := y
+ ifdef CONFIG_GCC_USE_GRAPHITE
+ BUILD_ISL = y
+ endif
+endif
+ifneq ($(CONFIG_SDK)$(CONFIG_PACKAGE_kmod-b43)$(CONFIG_PACKAGE_b43legacy-firmware)$(CONFIG_BRCMSMAC_USE_FW_FROM_WL),)
+ BUILD_B43_TOOLS = y
endif
-tools-y += m4 libtool autoconf automake flex bison pkg-config sed mklibs
-tools-y += sstrip ipkg-utils genext2fs e2fsprogs mtd-utils mkimage
-tools-y += firmware-utils patch-cmdline quilt yaffs2 flock padjffs2
-tools-y += mm-macros xorg-macros xfce-macros missing-macros xz cmake
+
+tools-$(BUILD_TOOLCHAIN) += gmp mpfr mpc libelf expat
+tools-y += m4 libtool autoconf automake flex bison pkg-config mklibs zlib
+tools-y += sstrip make-ext4fs e2fsprogs mtd-utils mkimage
+tools-y += firmware-utils patch-image quilt padjffs2
+tools-y += mm-macros missing-macros cmake scons bc findutils gengetopt patchelf
+tools-y += mtools dosfstools libressl
tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2
-tools-$(CONFIG_powerpc) += upx
tools-$(CONFIG_TARGET_x86) += qemu
-ifneq ($(CONFIG_TARGET_ar71xx),)
-tools-y += lzma-old squashfs
-endif
+tools-$(CONFIG_TARGET_mxs) += elftosb sdimage
+tools-$(CONFIG_TARGET_ar71xx) += lzma-old
+tools-$(CONFIG_TARGET_ar71xx)$(CONFIG_TARGET_ath79) += squashfs
+tools-$(CONFIG_USES_MINOR) += kernel2minor
tools-y += lzma squashfs4
+tools-$(BUILD_B43_TOOLS) += b43-tools
+tools-$(BUILD_ISL) += isl
+tools-$(CONFIG_USE_SPARSE) += sparse
+tools-$(CONFIG_TARGET_apm821xx) += genext2fs
-ifdef CONFIG_GCC_USE_GRAPHITE
- ifeq ($(CONFIG_GCC_USE_SYSTEM_PPL_CLOOG),)
- tools-y += ppl cloog
- $(curdir)/cloog/compile := $(curdir)/ppl/install
- endif
+# builddir dependencies
+$(curdir)/bison/compile := $(curdir)/flex/compile
+$(curdir)/flex/compile := $(curdir)/libtool/compile
+$(curdir)/libtool/compile := $(curdir)/m4/compile $(curdir)/autoconf/compile $(curdir)/automake/compile $(curdir)/missing-macros/compile
+$(curdir)/squashfs/compile := $(curdir)/lzma-old/compile
+$(curdir)/squashfs4/compile := $(curdir)/xz/compile $(curdir)/zlib/compile
+$(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile
+$(curdir)/autoconf/compile := $(curdir)/m4/compile
+$(curdir)/automake/compile := $(curdir)/m4/compile $(curdir)/autoconf/compile $(curdir)/pkg-config/compile $(curdir)/xz/compile
+$(curdir)/gmp/compile := $(curdir)/libtool/compile
+$(curdir)/mpc/compile := $(curdir)/mpfr/compile $(curdir)/gmp/compile
+$(curdir)/mpfr/compile := $(curdir)/gmp/compile
+$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
+$(curdir)/mklibs/compile := $(curdir)/libtool/compile
+$(curdir)/qemu/compile := $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
+$(curdir)/upslug2/compile := $(curdir)/libtool/compile
+$(curdir)/mm-macros/compile := $(curdir)/libtool/compile
+$(curdir)/missing-macros/compile := $(curdir)/autoconf/compile
+$(curdir)/e2fsprogs/compile := $(curdir)/libtool/compile
+$(curdir)/libelf/compile := $(curdir)/libtool/compile
+$(curdir)/sdcc/compile := $(curdir)/bison/compile
+$(curdir)/b43-tools/compile := $(curdir)/bison/compile
+$(curdir)/padjffs2/compile := $(curdir)/findutils/compile
+$(curdir)/isl/compile := $(curdir)/gmp/compile
+$(curdir)/bc/compile := $(curdir)/bison/compile
+$(curdir)/findutils/compile := $(curdir)/bison/compile
+$(curdir)/gengetopt/compile := $(curdir)/libtool/compile
+$(curdir)/patchelf/compile := $(curdir)/libtool/compile
+$(curdir)/dosfstools/compile := $(curdir)/autoconf/compile $(curdir)/automake/compile
+$(curdir)/libressl/compile := $(curdir)/pkg-config/compile
+$(curdir)/mkimage/compile += $(curdir)/libressl/compile
+$(curdir)/firmware-utils/compile += $(curdir)/libressl/compile $(curdir)/zlib/compile
+$(curdir)/cmake/compile += $(curdir)/libressl/compile
+$(curdir)/zlib/compile := $(curdir)/cmake/compile
+$(curdir)/wrt350nv2-builder/compile := $(curdir)/zlib/compile
+$(curdir)/lzma-old/compile := $(curdir)/zlib/compile
+$(curdir)/make-ext4fs/compile := $(curdir)/zlib/compile
+
+ifneq ($(HOST_OS),Linux)
+ tools-y += coreutils
endif
-# builddir dependencies
-$(curdir)/bison/compile := $(curdir)/flex/install
-$(curdir)/pkg-config/compile := $(curdir)/sed/install
-$(curdir)/libtool/compile := $(curdir)/sed/install
-$(curdir)/squashfs/compile := $(curdir)/lzma-old/install
-$(curdir)/squashfs4/compile := $(curdir)/xz/install
-$(curdir)/quilt/compile := $(curdir)/sed/install $(curdir)/autoconf/install
-$(curdir)/dtc/compile := $(curdir)/bison/install
-$(curdir)/autoconf/compile := $(curdir)/m4/install $(curdir)/libtool/install
-$(curdir)/automake/compile := $(curdir)/m4/install $(curdir)/autoconf/install $(curdir)/pkg-config/install
-$(curdir)/gmp/compile := $(curdir)/automake/install
-$(curdir)/mpc/compile := $(curdir)/mpfr/install $(curdir)/gmp/install
-$(curdir)/mpfr/compile := $(curdir)/gmp/install
-$(curdir)/ppl/compile := $(curdir)/gmp/install
-$(curdir)/cloog/compile := $(curdir)/ppl/install
-$(curdir)/mtd-utils/compile := $(curdir)/e2fsprogs/install $(curdir)/xz/install
-$(curdir)/mkimage/compile := $(curdir)/sed/install
-$(curdir)/qemu/compile := $(curdir)/e2fsprogs/install
-$(curdir)/upslug2/compile := $(curdir)/automake/install
-$(curdir)/mm-macros/compile := $(curdir)/automake/install
-$(curdir)/xorg-macros/compile := $(curdir)/automake/install
-$(curdir)/xfce-macros/compile := $(curdir)/automake/install
-$(curdir)/missing-macros/compile := $(curdir)/automake/install
-$(curdir)/e2fsprogs/compile := $(curdir)/automake/install
-$(curdir)/libelf/compile := $(curdir)/automake/install
-
-ifneq ($(CONFIG_CCACHE),)
-$(foreach tool, $(tools-y), $(eval $(curdir)/$(tool)/compile += $(curdir)/ccache/install))
+ifneq ($(CONFIG_CCACHE)$(CONFIG_SDK),)
+$(foreach tool, $(filter-out xz patch,$(tools-y)), $(eval $(curdir)/$(tool)/compile += $(curdir)/ccache/compile))
tools-y += ccache
endif
+# in case there is no patch tool on the host we need to make patch tool a
+# dependency for tools which have patches directory
+$(foreach tool, $(tools-y), $(if $(wildcard $(curdir)/$(tool)/patches),$(eval $(curdir)/$(tool)/compile += $(curdir)/patch/compile)))
+
+$(foreach tool, $(filter-out xz,$(tools-y)), $(eval $(curdir)/$(tool)/compile += $(curdir)/xz/compile))
+
+# make any tool depend on tar, xz and patch to ensure that archives can be unpacked and patched properly
+tools-core := tar xz patch
+
+$(foreach tool, $(tools-y), $(eval $(curdir)/$(tool)/compile += $(patsubst %,$(curdir)/%/compile,$(tools-core))))
+tools-y += $(tools-core)
+
+# make core tools depend on sed and flock
+$(foreach tool, $(tools-core), $(eval $(curdir)/$(tool)/compile += $(curdir)/sed/compile))
+
+$(curdir)/sed/compile := $(curdir)/flock/compile
+tools-y += flock sed
+
+$(curdir)/autoremove := 1
$(curdir)/builddirs := $(tools-y) $(tools-dep) $(tools-)
$(curdir)/builddirs-default := $(tools-y)
+ifdef CHECK_ALL
+$(curdir)/builddirs-check:=$($(curdir)/builddirs)
+$(curdir)/builddirs-download:=$($(curdir)/builddirs)
+endif
+
ifndef DUMP_TARGET_DB
define PrepareStaging
@for dir in $(1); do ( \
@@ -90,30 +137,17 @@ $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build
ln -sf lib $(STAGING_DIR_HOST)/lib64
touch $@
-
-define PrepareCommand
-$(STAGING_DIR_HOST)/bin/$(1): $(STAGING_DIR)/.prepared
- @mkdir -p "$$(dir $$@)"; rm -f "$$@"
- @export FILE="$$$$(which $(2) 2>/dev/null | grep -v 'not found' | head -n1)"; [ -n "$$$$FILE" ] || { \
- echo "Command $(1) not found."; false; \
- }; ln -s "$$$$FILE" "$$@"
-
-endef
endif
-$(eval $(call PrepareCommand,find,gfind find))
-$(eval $(call PrepareCommand,md5sum,md5sum $(SCRIPT_DIR)/md5sum))
-$(eval $(call PrepareCommand,cp,gcp cp))
-$(eval $(call PrepareCommand,stat,gstat stat))
-$(eval $(call PrepareCommand,seq,gseq seq))
-
-$(curdir)/cmddeps = $(patsubst %,$(STAGING_DIR_HOST)/bin/%,find md5sum cp stat seq)
-$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps)
-$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps)
+$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared
+$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared
# prerequisites for the individual targets
$(curdir)/ := .config prereq
-$(curdir)//install = $(1)/compile
-$(eval $(call stampfile,$(curdir),tools,install,,CONFIG_CCACHE CONFIG_powerpc CONFIG_GCC_VERSION_4_5 CONFIG_GCC_USE_GRAPHITE CONFIG_TARGET_orion_generic))
+$(curdir)/install: $(curdir)/compile
+
+tools_enabled = $(foreach tool,$(sort $(tools-y) $(tools-)),$(if $(filter $(tool),$(tools-y)),y,n))
+$(eval $(call stampfile,$(curdir),tools,compile,,_$(subst $(space),,$(tools_enabled))))
+$(eval $(call stampfile,$(curdir),tools,check,$(TMP_DIR)/.build))
$(eval $(call subdir,$(curdir)))
diff --git a/tools/autoconf/Makefile b/tools/autoconf/Makefile
index f5d22c3ff85..6eb64d77d51 100644
--- a/tools/autoconf/Makefile
+++ b/tools/autoconf/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,19 +7,19 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=autoconf
-PKG_VERSION:=2.68
+PKG_VERSION:=2.69
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/autoconf
-PKG_MD5SUM:=864d785215aa60d627c91fcb21b05b07
+PKG_HASH:=64ebcec9f8ac5b2487125a86a7760d2591ac9e1d3dbd59489633f9de62a57684
include $(INCLUDE_DIR)/host-build.mk
-define Host/Configure
- $(call Host/Configure/Default,\
- --datarootdir=$(STAGING_DIR_HOST)/share \
- )
-endef
+HOST_CONFIGURE_ARGS += \
+ --datarootdir=$(STAGING_DIR_HOST)/share
+
+HOST_CONFIGURE_VARS += \
+ PERL="/usr/bin/env perl"
define Host/Compile
export SHELL="$(BASH)"; $(MAKE) -C $(HOST_BUILD_DIR)
diff --git a/tools/autoconf/patches/000-relocatable.patch b/tools/autoconf/patches/000-relocatable.patch
index 0b83a2b44c3..12e94ae9a15 100644
--- a/tools/autoconf/patches/000-relocatable.patch
+++ b/tools/autoconf/patches/000-relocatable.patch
@@ -1,6 +1,6 @@
--- a/bin/autoheader.in
+++ b/bin/autoheader.in
-@@ -29,7 +29,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -28,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
BEGIN
{
@@ -10,7 +10,7 @@
unshift @INC, "$pkgdatadir";
# Override SHELL. On DJGPP SHELL may not be set to a shell
-@@ -51,7 +52,7 @@ use strict;
+@@ -50,7 +51,7 @@ use strict;
use vars qw ($config_h %verbatim %symbol);
# Lib files.
@@ -21,7 +21,21 @@
my @prepend_include;
--- a/bin/autom4te.in
+++ b/bin/autom4te.in
-@@ -25,7 +25,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -1,10 +1,12 @@
+-#! @PERL@ -w
++#! @PERL@
+ # -*- perl -*-
+ # @configure_input@
+
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
+ # autom4te - Wrapper around M4 libraries.
+ # Copyright (C) 2001-2003, 2005-2012 Free Software Foundation, Inc.
+
+@@ -24,7 +26,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
BEGIN
{
@@ -31,7 +45,7 @@
unshift @INC, $pkgdatadir;
# Override SHELL. On DJGPP SHELL may not be set to a shell
-@@ -45,7 +46,8 @@ use File::Basename;
+@@ -44,7 +47,8 @@ use File::Basename;
use strict;
# Data directory.
@@ -41,7 +55,7 @@
# $LANGUAGE{LANGUAGE} -- Automatic options for LANGUAGE.
my %language;
-@@ -88,7 +90,7 @@ my @include;
+@@ -87,7 +91,7 @@ my @include;
my $freeze = 0;
# $M4.
@@ -50,7 +64,7 @@
# Some non-GNU m4's don't reject the --help option, so give them /dev/null.
fatal "need GNU m4 1.4 or later: $m4"
if system "$m4 --help </dev/null 2>&1 | grep reload-state >/dev/null";
-@@ -270,6 +272,12 @@ sub load_configuration ($)
+@@ -269,6 +273,12 @@ sub load_configuration ($)
my @words = shellwords ($_);
my $type = shift @words;
@@ -65,7 +79,21 @@
fatal "$file:$.: end-language missing for: $lang"
--- a/bin/autoreconf.in
+++ b/bin/autoreconf.in
-@@ -27,7 +27,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -1,10 +1,12 @@
+-#! @PERL@ -w
++#! @PERL@
+ # -*- perl -*-
+ # @configure_input@
+
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
+ # autoreconf - install the GNU Build System in a directory tree
+ # Copyright (C) 1994, 1999-2012 Free Software Foundation, Inc.
+
+@@ -26,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
BEGIN
{
@@ -75,7 +103,7 @@
unshift @INC, $pkgdatadir;
# Override SHELL. On DJGPP SHELL may not be set to a shell
-@@ -107,9 +108,9 @@ Written by David J. MacKenzie and Akim D
+@@ -106,9 +109,9 @@ Written by David J. MacKenzie and Akim D
";
# Lib files.
@@ -90,8 +118,18 @@
my $libtoolize = $ENV{'LIBTOOLIZE'} || 'libtoolize';
--- a/bin/autoscan.in
+++ b/bin/autoscan.in
-@@ -26,7 +26,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -1,4 +1,4 @@
+-#! @PERL@ -w
++#! @PERL@
+ # -*- perl -*-
+ # @configure_input@
+@@ -23,9 +23,12 @@
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
BEGIN
{
- my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
@@ -100,7 +138,7 @@
unshift @INC, $pkgdatadir;
# Override SHELL. On DJGPP SHELL may not be set to a shell
-@@ -92,10 +93,10 @@ my $configure_scan = 'configure.scan';
+@@ -91,10 +94,10 @@ my $configure_scan = 'configure.scan';
my $log;
# Autoconf and lib files.
@@ -115,8 +153,18 @@
# -----
--- a/bin/autoupdate.in
+++ b/bin/autoupdate.in
-@@ -27,7 +27,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -1,4 +1,4 @@
+-#! @PERL@ -w
++#! @PERL@
+ # -*- perl -*-
+ # @configure_input@
+@@ -24,9 +24,12 @@
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
BEGIN
{
- my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
@@ -125,7 +173,7 @@
unshift @INC, $pkgdatadir;
# Override SHELL. On DJGPP SHELL may not be set to a shell
-@@ -51,10 +52,10 @@ my $autom4te = $ENV{'AUTOM4TE'} || '@bin
+@@ -50,10 +53,10 @@ my $autom4te = $ENV{'AUTOM4TE'} || '@bin
my $autoconf = "$autom4te --language=autoconf";
# We need to find m4sugar.
my @prepend_include;
@@ -140,7 +188,21 @@
# $HELP
--- a/bin/ifnames.in
+++ b/bin/ifnames.in
-@@ -31,7 +31,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+@@ -1,10 +1,12 @@
+-#! @PERL@ -w
++#! @PERL@
+ # -*- perl -*-
+ # @configure_input@
+
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
+ # ifnames - print the identifiers used in C preprocessor conditionals
+
+ # Copyright (C) 1994-1995, 1999-2003, 2005-2012 Free Software
+@@ -31,7 +33,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
BEGIN
{
@@ -152,7 +214,7 @@
# Override SHELL. On DJGPP SHELL may not be set to a shell
--- a/bin/autoconf.as
+++ b/bin/autoconf.as
-@@ -85,7 +85,11 @@ exit_missing_arg='
+@@ -84,7 +84,11 @@ exit_missing_arg='
# restore font-lock: '
# Variables.
diff --git a/tools/autoconf/patches/001-no_emacs_lib.patch b/tools/autoconf/patches/001-no_emacs_lib.patch
index 02e115d48be..35c51642e84 100644
--- a/tools/autoconf/patches/001-no_emacs_lib.patch
+++ b/tools/autoconf/patches/001-no_emacs_lib.patch
@@ -1,6 +1,6 @@
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
-@@ -16,7 +16,7 @@
+@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -11,7 +11,7 @@
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
-@@ -226,7 +226,7 @@ target_alias = @target_alias@
+@@ -225,7 +225,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
diff --git a/tools/autoconf/patches/002-musl_host_fixup.patch b/tools/autoconf/patches/002-musl_host_fixup.patch
new file mode 100644
index 00000000000..4dcb1ec3c12
--- /dev/null
+++ b/tools/autoconf/patches/002-musl_host_fixup.patch
@@ -0,0 +1,24 @@
+--- a/build-aux/config.sub
++++ b/build-aux/config.sub
+@@ -122,9 +122,9 @@ esac
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+- knetbsd*-gnu* | netbsd*-gnu* | \
++ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-musl* | \
++ linux-newlib* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
++ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+@@ -1360,7 +1360,7 @@ case $os in
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+- | -linux-newlib* | -linux-uclibc* \
++ | -linux-musl* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
diff --git a/tools/automake/Makefile b/tools/automake/Makefile
index c30a9900e61..c016f1d76a6 100644
--- a/tools/automake/Makefile
+++ b/tools/automake/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2012 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,25 +7,40 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=automake
-PKG_VERSION:=1.11.1
+PKG_CPE_ID:=cpe:/a:gnu:automake
+PKG_VERSION:=1.15.1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/automake
-PKG_MD5SUM:=c2972c4d9b3e29c03d5f2af86249876f
+PKG_HASH:=af6ba39142220687c500f79b4aa2f181d9b24e4f8d8ec497cea4ba26c64bedaf
include $(INCLUDE_DIR)/host-build.mk
-HOST_CONFIGURE_ARGS += --datarootdir=$(STAGING_DIR_HOST)/share
-HOST_CONFIGURE_VARS += am_cv_prog_PERL_ithreads=no
+HOST_CONFIGURE_ARGS += \
+ --datarootdir=$(STAGING_DIR_HOST)/share \
+ --disable-silent-rules
+
+HOST_CONFIGURE_VARS += \
+ PERL="/usr/bin/env perl" \
+ am_cv_prog_PERL_ithreads=no
+
+define Host/Configure
+ (cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) STAGING_DIR="" ./bootstrap)
+ $(call Host/Configure/Default)
+endef
define Host/Install
+ # remove old automake resources to avoid version conflicts
+ rm -rf $(STAGING_DIR_HOST)/share/aclocal-[0-9]*
+ rm -rf $(STAGING_DIR_HOST)/share/automake-[0-9]*
$(MAKE) -C $(HOST_BUILD_DIR) install
mv $(STAGING_DIR_HOST)/bin/aclocal $(STAGING_DIR_HOST)/bin/aclocal.real
$(INSTALL_BIN) ./files/aclocal $(STAGING_DIR_HOST)/bin
ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.9
ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.10
ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11
- ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11.1
+ ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.11.6
+ ln -sf aclocal $(STAGING_DIR_HOST)/bin/aclocal-1.15
endef
define Host/Clean
diff --git a/tools/automake/patches/000-relocatable.patch b/tools/automake/patches/000-relocatable.patch
index 3255b97518f..d05b25e61c2 100644
--- a/tools/automake/patches/000-relocatable.patch
+++ b/tools/automake/patches/000-relocatable.patch
@@ -1,18 +1,42 @@
---- a/aclocal.in
-+++ b/aclocal.in
-@@ -28,7 +28,8 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
+--- a/lib/Automake/Config.in
++++ b/lib/Automake/Config.in
+@@ -32,7 +32,7 @@ our $PACKAGE = '@PACKAGE@';
+ our $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
+ our $VERSION = '@VERSION@';
+ our $RELEASE_YEAR = '@RELEASE_YEAR@';
+-our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@';
++our $libdir = $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@';
+
+ our $perl_threads = 0;
+ # We need at least this version for CLONE support.
+--- a/bin/aclocal.in
++++ b/bin/aclocal.in
+@@ -1,10 +1,12 @@
+-#!@PERL@ -w
++#!@PERL@
+ # -*- perl -*-
+ # @configure_input@
+
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
+ # aclocal - create aclocal.m4 by scanning configure.ac
+
+ # Copyright (C) 1996-2017 Free Software Foundation, Inc.
+@@ -27,7 +29,7 @@ eval 'case $# in 0) exec @PERL@ -S "$0";
BEGIN
{
-- my $perllibdir = $ENV{'perllibdir'} || '@datadir@/@PACKAGE@-@APIVERSION@';
-+ my $perllibdir = $ENV{'perllibdir'} ||
-+ ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@');
- unshift @INC, (split '@PATH_SEPARATOR@', $perllibdir);
+- @Aclocal::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@')
++ @Aclocal::perl_libdirs = ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@')
+ unless @Aclocal::perl_libdirs;
+ unshift @INC, @Aclocal::perl_libdirs;
}
-
-@@ -57,8 +58,8 @@ $perl_threads = 0;
- # @system_includes can be augmented with the `dirlist' file. Also
- # --acdir will reset both @automake_includes and @system_includes.
+@@ -69,8 +71,8 @@ $perl_threads = 0;
+ # ACLOCAL_PATH environment variable, and reset with the '--system-acdir'
+ # option.
my @user_includes = ();
-my @automake_includes = ("@datadir@/aclocal-$APIVERSION");
-my @system_includes = ('@datadir@/aclocal');
@@ -21,26 +45,52 @@
# Whether we should copy M4 file in $user_includes[0].
my $install = 0;
---- a/automake.in
-+++ b/automake.in
-@@ -31,7 +31,8 @@ package Language;
+--- a/bin/automake.in
++++ b/bin/automake.in
+@@ -1,10 +1,12 @@
+-#!@PERL@ -w
++#!@PERL@
+ # -*- perl -*-
+ # @configure_input@
+
+ eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
+ if 0;
+
++$^W = 1;
++
+ # automake - create Makefile.in from Makefile.am
+ # Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+@@ -31,7 +33,7 @@ use strict;
BEGIN
{
-- my $perllibdir = $ENV{'perllibdir'} || '@datadir@/@PACKAGE@-@APIVERSION@';
-+ my $perllibdir = $ENV{'perllibdir'} ||
-+ ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@');
- unshift @INC, (split '@PATH_SEPARATOR@', $perllibdir);
+- @Automake::perl_libdirs = ('@datadir@/@PACKAGE@-@APIVERSION@')
++ @Automake::perl_libdirs = ($ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@')
+ unless @Automake::perl_libdirs;
+ unshift @INC, @Automake::perl_libdirs;
- # Override SHELL. This is required on DJGPP so that system() uses
---- a/lib/Automake/Config.in
-+++ b/lib/Automake/Config.in
-@@ -28,7 +28,7 @@ our @EXPORT = qw ($APIVERSION $PACKAGE $
- our $APIVERSION = '@APIVERSION@';
- our $PACKAGE = '@PACKAGE@';
- our $VERSION = '@VERSION@';
--our $libdir = '@datadir@/@PACKAGE@-@APIVERSION@';
-+our $libdir = $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/@PACKAGE@-@APIVERSION@' : '@datadir@/@PACKAGE@-@APIVERSION@';
- our $perl_threads = @PERL_THREADS@;
+--- a/t/wrap/aclocal.in
++++ b/t/wrap/aclocal.in
+@@ -1,6 +1,8 @@
+-#!@PERL@ -w
++#!@PERL@
+ # @configure_input@
+
++$^W = 1;
++
+ # Copyright (C) 2012-2017 Free Software Foundation, Inc.
+
+ # This program is free software; you can redistribute it and/or modify
+--- a/t/wrap/automake.in
++++ b/t/wrap/automake.in
+@@ -1,6 +1,8 @@
+-#!@PERL@ -w
++#!@PERL@
+ # @configure_input@
+
++$^W = 1;
++
+ # Copyright (C) 2012-2017 Free Software Foundation, Inc.
- 1;;
+ # This program is free software; you can redistribute it and/or modify
diff --git a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
index cc1f49d519e..ad019ddd1ae 100644
--- a/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
+++ b/tools/automake/patches/100-aclocal-skip-not-existing-directories.patch
@@ -1,15 +1,15 @@
---- a/aclocal.in
-+++ b/aclocal.in
-@@ -310,6 +310,12 @@ sub scan_m4_dirs ($@)
+--- a/bin/aclocal.in
++++ b/bin/aclocal.in
+@@ -356,6 +356,12 @@ sub scan_m4_dirs ($$@)
foreach my $m4dir (@dirlist)
{
+ if (! -d $m4dir)
-+ {
-+ msg ('override', "warning: skipping not existing directory `$m4dir'");
-+ next;
-+ }
++ {
++ msg ('override', "warning: skipping not existing directory `$m4dir'");
++ next;
++ }
+
if (! opendir (DIR, $m4dir))
{
- fatal "couldn't open directory `$m4dir': $!";
+ # TODO: maybe avoid complaining only if errno == ENONENT?
diff --git a/tools/automake/patches/200-do-not-override-silent-rules.patch b/tools/automake/patches/200-do-not-override-silent-rules.patch
new file mode 100644
index 00000000000..e8ba8c5ca54
--- /dev/null
+++ b/tools/automake/patches/200-do-not-override-silent-rules.patch
@@ -0,0 +1,13 @@
+diff -ruN automake-1.15/m4/silent.m4 automake-1.15.mod/m4/silent.m4
+--- automake-1.15/m4/silent.m4 2014-12-30 22:53:05.000000000 +0100
++++ automake-1.15.mod/m4/silent.m4 2015-03-11 12:00:26.280586399 +0100
+@@ -41,7 +41,8 @@
+ else
+ am_cv_make_support_nested_variables=no
+ fi])
+-if test $am_cv_make_support_nested_variables = yes; then
++#if test $am_cv_make_support_nested_variables = yes; then
++if false; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
diff --git a/tools/b43-tools/Makefile b/tools/b43-tools/Makefile
new file mode 100644
index 00000000000..a99b0c9e53d
--- /dev/null
+++ b/tools/b43-tools/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=b43-tools
+PKG_DATE:=2017-09-13
+
+PKG_SOURCE_URL:=https://github.com/mbuesch/b43-tools.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)
+PKG_SOURCE_VERSION:=27892ef741e7f1d08cb939744f8b8f5dac7b04ae
+PKG_MIRROR_HASH:=f914c36ac566e9e3b5a3a04de16ddb014fcad6a1cf25cdd8e4825c708d28d3f4
+HOST_BUILD_DIR=$(BUILD_DIR_HOST)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/host-build.mk
+
+
+define Host/Compile
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/fwcutter \
+ CFLAGS="$(HOST_CFLAGS) -include endian.h" \
+ $(HOST_MAKE_FLAGS) \
+ $(1) QUIET_SPARSE=:
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/assembler \
+ CFLAGS="$(HOST_CFLAGS) -include endian.h" \
+ $(HOST_MAKE_FLAGS) \
+ LDFLAGS= \
+ $(1) QUIET_SPARSE=:
+endef
+
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/fwcutter/b43-fwcutter $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/assembler/b43-asm.bin $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) ./files/b43-fwsquash.py $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/b43-fwcutter
+ rm -f $(STAGING_DIR_HOST)/bin/b43-asm
+ rm -f $(STAGING_DIR_HOST)/bin/b43-asm.bin
+ rm -f $(STAGING_DIR_HOST)/bin/b43-fwsquash.py
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/b43-tools/files/b43-fwsquash.py b/tools/b43-tools/files/b43-fwsquash.py
new file mode 100755
index 00000000000..2946d7c3c32
--- /dev/null
+++ b/tools/b43-tools/files/b43-fwsquash.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+#
+# b43 firmware file squasher
+# Removes unnecessary firmware files
+#
+# Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+#
+# Licensed under the GNU/GPL version 2 or (at your option) any later version.
+#
+
+import sys
+import os
+
+def usage():
+ print("Usage: %s PHYTYPES COREREVS /path/to/extracted/firmware" % sys.argv[0])
+ print("")
+ print("PHYTYPES is a comma separated list of:")
+ print("A => A-PHY")
+ print("AG => Dual A-PHY G-PHY")
+ print("G => G-PHY")
+ print("LP => LP-PHY")
+ print("N => N-PHY")
+ print("HT => HT-PHY")
+ print("LCN => LCN-PHY")
+ print("LCN40 => LCN40-PHY")
+ print("AC => AC-PHY")
+ print("")
+ print("COREREVS is a comma separated list of core revision numbers.")
+
+if len(sys.argv) != 4:
+ usage()
+ sys.exit(1)
+
+phytypes = sys.argv[1]
+corerevs = sys.argv[2]
+fwpath = sys.argv[3]
+
+phytypes = phytypes.split(',')
+try:
+ corerevs = map(lambda r: int(r), corerevs.split(','))
+except ValueError:
+ print("ERROR: \"%s\" is not a valid COREREVS string\n" % corerevs)
+ usage()
+ sys.exit(1)
+
+
+fwfiles = os.listdir(fwpath)
+fwfiles = filter(lambda str: str.endswith(".fw"), fwfiles)
+if not fwfiles:
+ print("ERROR: No firmware files found in %s" % fwpath)
+ sys.exit(1)
+
+required_fwfiles = []
+
+def revs_match(revs_a, revs_b):
+ for rev in revs_a:
+ if rev in revs_b:
+ return True
+ return False
+
+def phytypes_match(types_a, types_b):
+ for type in types_a:
+ type = type.strip().upper()
+ if type in types_b:
+ return True
+ return False
+
+revmapping = {
+ "ucode2.fw" : ( (2,3,), ("G",), ),
+ "ucode4.fw" : ( (4,), ("G",), ),
+ "ucode5.fw" : ( (5,6,7,8,9,10,), ("G","A","AG",), ),
+ "ucode11.fw" : ( (11,12,), ("N",), ),
+ "ucode13.fw" : ( (13,), ("LP","G",), ),
+ "ucode14.fw" : ( (14,), ("LP",), ),
+ "ucode15.fw" : ( (15,), ("LP",), ),
+ "ucode16_mimo.fw" : ( (16,17,18,19,23,), ("N",), ),
+# "ucode16_lp.fw" : ( (16,17,18,19,), ("LP",), ),
+ "ucode24_lcn.fw" : ( (24,), ("LCN",), ),
+ "ucode25_mimo.fw" : ( (25,28,), ("N",), ),
+ "ucode25_lcn.fw" : ( (25,28,), ("LCN",), ),
+ "ucode26_mimo.fw" : ( (26,), ("HT",), ),
+ "ucode29_mimo.fw" : ( (29,), ("HT",), ),
+ "ucode30_mimo.fw" : ( (30,), ("N",), ),
+ "ucode33_lcn40.fw" : ( (33,), ("LCN40",), ),
+ "ucode40.fw" : ( (40,), ("AC",), ),
+ "ucode42.fw" : ( (42,), ("AC",), ),
+ "pcm4.fw" : ( (1,2,3,4,), ("G",), ),
+ "pcm5.fw" : ( (5,6,7,8,9,10,), ("G","A","AG",), ),
+}
+
+initvalmapping = {
+ "a0g1initvals5.fw" : ( (5,6,7,8,9,10,), ("AG",), ),
+ "a0g0initvals5.fw" : ( (5,6,7,8,9,10,), ("A", "AG",), ),
+ "b0g0initvals2.fw" : ( (2,4,), ("G",), ),
+ "b0g0initvals5.fw" : ( (5,6,7,8,9,10,), ("G",), ),
+ "b0g0initvals13.fw" : ( (13,), ("G",), ),
+ "n0initvals11.fw" : ( (11,12,), ("N",), ),
+ "n0initvals16.fw" : ( (16,17,18,23,), ("N",), ),
+ "n0initvals24.fw" : ( (24,), ("N",), ),
+ "n0initvals25.fw" : ( (25,28,), ("N",), ),
+ "n16initvals30.fw" : ( (30,), ("N",), ),
+ "lp0initvals13.fw" : ( (13,), ("LP",), ),
+ "lp0initvals14.fw" : ( (14,), ("LP",), ),
+ "lp0initvals15.fw" : ( (15,), ("LP",), ),
+# "lp0initvals16.fw" : ( (16,17,18,), ("LP",), ),
+ "lcn0initvals24.fw" : ( (24,), ("LCN",), ),
+ "ht0initvals26.fw" : ( (26,), ("HT",), ),
+ "ht0initvals29.fw" : ( (29,), ("HT",), ),
+ "lcn400initvals33.fw" : ( (33,), ("LCN40",), ),
+ "ac0initvals40.fw" : ( (40,), ("AC",), ),
+ "ac1initvals42.fw" : ( (42,), ("AC",), ),
+ "a0g1bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("AG",), ),
+ "a0g0bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("A", "AG"), ),
+ "b0g0bsinitvals5.fw" : ( (5,6,7,8,9,10,), ("G",), ),
+ "n0bsinitvals11.fw" : ( (11,12,), ("N",), ),
+ "n0bsinitvals16.fw" : ( (16,17,18,23,), ("N",), ),
+ "n0bsinitvals24.fw" : ( (24,), ("N",), ),
+ "n0bsinitvals25.fw" : ( (25,28,), ("N",), ),
+ "n16bsinitvals30.fw" : ( (30,), ("N",), ),
+ "lp0bsinitvals13.fw" : ( (13,), ("LP",), ),
+ "lp0bsinitvals14.fw" : ( (14,), ("LP",), ),
+ "lp0bsinitvals15.fw" : ( (15,), ("LP",), ),
+# "lp0bsinitvals16.fw" : ( (16,17,18,), ("LP",), ),
+ "lcn0bsinitvals24.fw" : ( (24,), ("LCN",), ),
+ "ht0bsinitvals26.fw" : ( (26,), ("HT",), ),
+ "ht0bsinitvals29.fw" : ( (29,), ("HT",), ),
+ "lcn400bsinitvals33.fw" : ( (33,), ("LCN40",), ),
+ "ac0bsinitvals40.fw" : ( (40,), ("AC",), ),
+ "ac1bsinitvals42.fw" : ( (42,), ("AC",), ),
+}
+
+for f in fwfiles:
+ if f in revmapping:
+ if revs_match(corerevs, revmapping[f][0]) and\
+ phytypes_match(phytypes, revmapping[f][1]):
+ required_fwfiles += [f]
+ continue
+ if f in initvalmapping:
+ if revs_match(corerevs, initvalmapping[f][0]) and\
+ phytypes_match(phytypes, initvalmapping[f][1]):
+ required_fwfiles += [f]
+ continue
+ print("WARNING: Firmware file %s not found in the mapping lists" % f)
+
+for f in fwfiles:
+ if f not in required_fwfiles:
+ print("Deleting %s" % f)
+ os.unlink(fwpath + '/' + f)
+
diff --git a/tools/b43-tools/patches/001-fw-dirname.patch b/tools/b43-tools/patches/001-fw-dirname.patch
new file mode 100644
index 00000000000..1fd4c66323e
--- /dev/null
+++ b/tools/b43-tools/patches/001-fw-dirname.patch
@@ -0,0 +1,16 @@
+--- a/fwcutter/fwcutter.c
++++ b/fwcutter/fwcutter.c
+@@ -50,13 +50,8 @@
+ #include "fwcutter.h"
+ #include "fwcutter_list.h"
+
+-#if defined(__DragonFly__) || defined(__FreeBSD__)
+-#define V3_FW_DIRNAME "v3"
+-#define V4_FW_DIRNAME "v4"
+-#else
+ #define V3_FW_DIRNAME "b43legacy"
+ #define V4_FW_DIRNAME "b43"
+-#endif
+
+ static struct cmdline_args cmdargs;
+
diff --git a/tools/b43-tools/patches/002-no_libfl.patch b/tools/b43-tools/patches/002-no_libfl.patch
new file mode 100644
index 00000000000..2e55b0803b5
--- /dev/null
+++ b/tools/b43-tools/patches/002-no_libfl.patch
@@ -0,0 +1,14 @@
+--- a/assembler/main.c
++++ b/assembler/main.c
+@@ -1268,6 +1268,11 @@ static void initialize(void)
+ #endif /* YYDEBUG */
+ }
+
++int yywrap(void)
++{
++ return 1;
++}
++
+ int main(int argc, char **argv)
+ {
+ int err, res = 1;
diff --git a/tools/bc/Makefile b/tools/bc/Makefile
new file mode 100644
index 00000000000..3d505d6032f
--- /dev/null
+++ b/tools/bc/Makefile
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bc
+PKG_VERSION:=1.06.95
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://alpha.gnu.org/gnu/bc \
+ http://gnualpha.uib.no/bc/ \
+ http://mirrors.fe.up.pt/pub/gnu-alpha/bc/ \
+ http://www.nic.funet.fi/pub/gnu/alpha/gnu/bc/
+PKG_HASH:=7ee4abbcfac03d8a6e1a8a3440558a3d239d6b858585063e745c760957725ecc
+
+include $(INCLUDE_DIR)/host-build.mk
+
+$(eval $(call HostBuild))
diff --git a/tools/bc/patches/001-no_doc.patch b/tools/bc/patches/001-no_doc.patch
new file mode 100644
index 00000000000..50deee8c89d
--- /dev/null
+++ b/tools/bc/patches/001-no_doc.patch
@@ -0,0 +1,23 @@
+diff -urN bc-1.06.95/Makefile.am bc-1.06.95.new/Makefile.am
+--- bc-1.06.95/Makefile.am 2005-05-27 01:05:41.000000000 +0100
++++ bc-1.06.95.new/Makefile.am 2013-07-09 09:33:31.521490710 +0100
+@@ -1,6 +1,6 @@
+ ## Process this file with automake to produce Makefile.in
+
+-SUBDIRS = lib bc dc doc
++SUBDIRS = lib bc dc
+
+ MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
+ stamp-h $(distdir).tar.gz h/number.h depcomp missing
+diff -urN bc-1.06.95/Makefile.in bc-1.06.95.new/Makefile.in
+--- bc-1.06.95/Makefile.in 2006-09-05 03:39:30.000000000 +0100
++++ bc-1.06.95.new/Makefile.in 2013-07-09 09:33:28.565490767 +0100
+@@ -149,7 +149,7 @@
+ sharedstatedir = @sharedstatedir@
+ sysconfdir = @sysconfdir@
+ target_alias = @target_alias@
+-SUBDIRS = lib bc dc doc
++SUBDIRS = lib bc dc
+ MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
+ stamp-h $(distdir).tar.gz h/number.h depcomp missing
+
diff --git a/tools/bison/Makefile b/tools/bison/Makefile
index 01820e27550..68e06ae33b5 100644
--- a/tools/bison/Makefile
+++ b/tools/bison/Makefile
@@ -1,5 +1,5 @@
-#
-# Copyright (C) 2008 OpenWrt.org
+#
+# Copyright (C) 2008-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,12 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bison
-PKG_VERSION:=2.4.3
+PKG_VERSION:=3.0.5
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_MD5SUM:=c1d3ea81bc370dbd43b6f0b2cd21287e
-PKG_CAT:=bzcat
+PKG_HASH:=075cef2e814642e30e10e8155e93022e4a91ca38a65aa1d5467d4e969f97f338
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
@@ -21,4 +22,9 @@ define Host/Clean
$(call Host/Clean/Default)
endef
+define Host/Install
+ $(call Host/Install/Default)
+ $(INSTALL_BIN) ./scripts/yacc $(STAGING_DIR_HOST)/bin/yacc
+endef
+
$(eval $(call HostBuild))
diff --git a/tools/bison/patches/000-relocatable.patch b/tools/bison/patches/000-relocatable.patch
deleted file mode 100644
index f83bb1e7eea..00000000000
--- a/tools/bison/patches/000-relocatable.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -77,6 +77,7 @@ MOSTLYCLEANFILES = yacc
-
- yacc:
- echo '#! /bin/sh' >$@
-+ echo 'test -n "$$STAGING_DIR" && exec "$$STAGING_DIR/../host/bin/bison" -y "$$@"' >>$@
- echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@
- chmod a+x $@
-
---- a/src/Makefile.in
-+++ b/src/Makefile.in
-@@ -1352,6 +1352,7 @@ uninstall-am: uninstall-binPROGRAMS unin
-
- yacc:
- echo '#! /bin/sh' >$@
-+ echo 'test -n "$$STAGING_DIR" && exec "$$STAGING_DIR/../host/bin/bison" -y "$$@"' >>$@
- echo "exec '$(bindir)/bison' -y "'"$$@"' >>$@
- chmod a+x $@
-
diff --git a/tools/bison/patches/010-intl-stub-compat.patch b/tools/bison/patches/010-intl-stub-compat.patch
index 7690e10ed8b..98234209cdc 100644
--- a/tools/bison/patches/010-intl-stub-compat.patch
+++ b/tools/bison/patches/010-intl-stub-compat.patch
@@ -1,8 +1,8 @@
--- a/src/main.c
+++ b/src/main.c
-@@ -57,9 +57,9 @@ main (int argc, char *argv[])
+@@ -60,9 +60,9 @@
{
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
- (void) bindtextdomain (PACKAGE, LOCALEDIR);
- (void) bindtextdomain ("bison-runtime", LOCALEDIR);
@@ -11,5 +11,5 @@
+ bindtextdomain ("bison-runtime", LOCALEDIR);
+ textdomain (PACKAGE);
- uniqstrs_new ();
-
+ {
+ char const *cp = getenv ("LC_CTYPE");
diff --git a/tools/bison/patches/100-fix-gets-removal.patch b/tools/bison/patches/100-fix-gets-removal.patch
new file mode 100644
index 00000000000..563c12040c5
--- /dev/null
+++ b/tools/bison/patches/100-fix-gets-removal.patch
@@ -0,0 +1,19 @@
+diff --git a/lib/stdio.in.h b/lib/stdio.in.h
+index ff7c9c8..f391832 100644
+--- a/lib/stdio.in.h
++++ b/lib/stdio.in.h
+@@ -739,14 +739,6 @@ _GL_WARN_ON_USE (getline, "getline is unportable - "
+ # endif
+ #endif
+
+-/* It is very rare that the developer ever has full control of stdin,
+- so any use of gets warrants an unconditional warning; besides, C11
+- removed it. */
+-#undef gets
+-#if HAVE_RAW_DECL_GETS && !defined __cplusplus
+-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
+-#endif
+-
+ #if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
+ struct obstack;
+ /* Grow an obstack with formatted output. Return the number of
diff --git a/tools/bison/scripts/yacc b/tools/bison/scripts/yacc
new file mode 100755
index 00000000000..8f73e26fb13
--- /dev/null
+++ b/tools/bison/scripts/yacc
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec bison -y "$@"
diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile
index 21123b316db..111bd91bb63 100644
--- a/tools/ccache/Makefile
+++ b/tools/ccache/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -8,37 +8,29 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/target.mk
PKG_NAME:=ccache
-PKG_VERSION:=3.1.3
+PKG_VERSION:=3.4.2
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://samba.org/ftp/ccache/
-PKG_MD5SUM:=b952d75e9ca37209d608ea58d84135cd
-PKG_CAT:=zcat
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://download.samba.org/pub/ccache/ \
+ https://samba.org/ftp/ccache/
+PKG_HASH:=18a8b14367d63d3d37fb6c33cba60e1b7fcd7a63d608df97c9771ae0d234fee2
include $(INCLUDE_DIR)/host-build.mk
-ifneq ($(strip $(shell which ccache >/dev/null && echo found)),found)
- define Host/Compile
- $(MAKE) CC="$(HOSTCC_NOCACHE)" -C $(HOST_BUILD_DIR)
- endef
+HOST_CONFIGURE_VARS += CC="$(HOSTCC_NOCACHE)"
- define Host/Clean
+define Host/Install/ccache
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/
+ $(CP) ./files/* $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
-$(MAKE) -C $(HOST_BUILD_DIR) uninstall
$(call Host/Clean/Default)
- endef
-else
- define Host/Prepare
- endef
- define Host/Configure
- endef
- define Host/Compile
- endef
- define Host/Install
- endef
- define Host/Clean
- endef
- define Download
- endef
-endif
+endef
+define Host/Install
+ $(call Host/Install/Default)
+ $(call Host/Install/ccache)
+endef
$(eval $(call HostBuild))
diff --git a/tools/ccache/files/ccache_cc b/tools/ccache/files/ccache_cc
new file mode 100755
index 00000000000..01c4ad42a21
--- /dev/null
+++ b/tools/ccache/files/ccache_cc
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec ccache "${TARGET_CC_NOCACHE}" "$@"
diff --git a/tools/ccache/files/ccache_cxx b/tools/ccache/files/ccache_cxx
new file mode 100755
index 00000000000..cc60eb3a13c
--- /dev/null
+++ b/tools/ccache/files/ccache_cxx
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec ccache "${TARGET_CXX_NOCACHE}" "$@"
diff --git a/tools/ccache/patches/100-honour-copts.patch b/tools/ccache/patches/100-honour-copts.patch
new file mode 100644
index 00000000000..1916d17c60e
--- /dev/null
+++ b/tools/ccache/patches/100-honour-copts.patch
@@ -0,0 +1,10 @@
+--- a/src/ccache.c
++++ b/src/ccache.c
+@@ -1859,6 +1859,7 @@ calculate_object_hash(struct args *args,
+ "CPLUS_INCLUDE_PATH",
+ "OBJC_INCLUDE_PATH",
+ "OBJCPLUS_INCLUDE_PATH", // clang
++ "GCC_HONOUR_COPTS",
+ NULL
+ };
+ for (const char **p = envvars; *p; ++p) {
diff --git a/tools/cloog/Makefile b/tools/cloog/Makefile
deleted file mode 100644
index 945258263c2..00000000000
--- a/tools/cloog/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (C) 2009 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=cloog-ppl
-PKG_VERSION:=0.15.10
-
-PKG_SOURCE_URL:=ftp://gcc.gnu.org/pub/gcc/infrastructure
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=04aa756179b6d850d9ffa50f61b91895
-
-HOST_FIXUP:=autoreconf
-
-include $(INCLUDE_DIR)/host-build.mk
-
-unexport CFLAGS
-
-HOST_CONFIGURE_VARS += \
- LIBS=-lstdc++
-
-HOST_CONFIGURE_ARGS += \
- --enable-static \
- --disable-shared \
- --with-ppl=$(BUILD_DIR_HOST)
-
-define Host/Configure
- (cd $(HOST_BUILD_DIR)/$(3); \
- $(HOST_CONFIGURE_CMD) \
- $(HOST_CONFIGURE_VARS) \
- $(HOST_CONFIGURE_ARGS); \
- )
-endef
-
-
-$(eval $(call HostBuild))
diff --git a/tools/cmake/Makefile b/tools/cmake/Makefile
index d5e885ca335..340c47cb078 100644
--- a/tools/cmake/Makefile
+++ b/tools/cmake/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,12 +7,29 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cmake
-PKG_VERSION:=2.8.4
+PKG_VERSION:=3.12.1
+PKG_CPE_ID:=cpe:/a:kitware:cmake
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://www.cmake.org/files/v2.8/
-PKG_MD5SUM:=209b7d1d04b2e00986538d74ba764fcf
+PKG_SOURCE_URL:=https://cmake.org/files/v3.12/ \
+ https://fossies.org/linux/misc/
+PKG_HASH:=c53d5c2ce81d7a957ee83e3e635c8cda5dfe20c9d501a4828ee28e1615e57ab2
+
+HOST_BUILD_PARALLEL:=1
+HOST_CONFIGURE_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
+HOST_CONFIGURE_VARS += \
+ MAKEFLAGS="$(HOST_JOBS)" \
+ CXXFLAGS="$(HOST_CFLAGS)"
+
+HOST_CONFIGURE_ARGS := \
+ $(if $(MAKE_JOBSERVER),--parallel="$(MAKE_JOBSERVER)") \
+ --prefix=$(STAGING_DIR_HOST)
+
+ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+ HOST_MAKE_FLAGS += VERBOSE=1
+endif
+
$(eval $(call HostBuild))
diff --git a/tools/cmake/patches/100-disable_qt_tests.patch b/tools/cmake/patches/100-disable_qt_tests.patch
new file mode 100644
index 00000000000..a354e1cac1d
--- /dev/null
+++ b/tools/cmake/patches/100-disable_qt_tests.patch
@@ -0,0 +1,34 @@
+--- a/Tests/RunCMake/CMakeLists.txt
++++ b/Tests/RunCMake/CMakeLists.txt
+@@ -290,15 +290,6 @@ add_RunCMake_test(no_install_prefix)
+ add_RunCMake_test(configure_file)
+ add_RunCMake_test(CTestTimeoutAfterMatch)
+
+-find_package(Qt4 QUIET)
+-find_package(Qt5Core QUIET)
+-if (QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0)
+- add_RunCMake_test(IncompatibleQt)
+-endif()
+-if (QT4_FOUND)
+- add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
+-endif()
+-
+ find_package(PkgConfig QUIET)
+ if(PKG_CONFIG_FOUND)
+ add_RunCMake_test(FindPkgConfig)
+--- a/Tests/CMakeLists.txt
++++ b/Tests/CMakeLists.txt
+@@ -435,13 +435,6 @@ if(BUILD_TESTING)
+
+ list(APPEND TEST_BUILD_DIRS ${CMake_TEST_INSTALL_PREFIX})
+
+- if(NOT DEFINED CMake_TEST_Qt4)
+- set(CMake_TEST_Qt4 1)
+- endif()
+- if(CMake_TEST_Qt4 AND NOT QT4_FOUND)
+- find_package(Qt4 QUIET)
+- endif()
+-
+ if(CMake_TEST_Qt4 AND QT4_FOUND)
+ # test whether the Qt4 which has been found works, on some machines
+ # which run nightly builds there were errors like "wrong file format"
diff --git a/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch b/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch
new file mode 100644
index 00000000000..ba6565b6af0
--- /dev/null
+++ b/tools/cmake/patches/110-libarchive-fix-libressl-compat.patch
@@ -0,0 +1,11 @@
+--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
+@@ -28,7 +28,7 @@
+ #include <openssl/evp.h>
+ #include <openssl/opensslv.h>
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #include <stdlib.h> /* malloc, free */
+ #include <string.h> /* memset */
+ static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
diff --git a/tools/cmake/patches/120-curl-fix-libressl-linking.patch b/tools/cmake/patches/120-curl-fix-libressl-linking.patch
new file mode 100644
index 00000000000..20c5052cce1
--- /dev/null
+++ b/tools/cmake/patches/120-curl-fix-libressl-linking.patch
@@ -0,0 +1,37 @@
+From: Jo-Philipp Wich <jo@mein.io>
+Date: Wed, 11 Jan 2017 03:36:04 +0100
+Subject: [PATCH] cmcurl: link librt
+
+When cmake is linked against LibreSSL, there might be an indirect
+dependency on librt on certain systems if LibreSSL's libcrypto uses
+clock_gettime() from librt:
+
+ [ 28%] Linking C executable LIBCURL
+ .../lib/libcrypto.a(getentropy_linux.o): In function `getentropy_fallback':
+ getentropy_linux.c:(.text+0x16d): undefined reference to `clock_gettime'
+ getentropy_linux.c:(.text+0x412): undefined reference to `clock_gettime'
+ collect2: error: ld returned 1 exit status
+ make[5]: *** [Utilities/cmcurl/LIBCURL] Error 1
+
+Modify the cmcurl CMakeLists.txt to check for clock_gettime() in librt
+and unconditionally link the rt library when the symbol is found.
+
+Signed-off-by: Jo-Philipp Wich <jo@mein.io>
+---
+--- a/Utilities/cmcurl/CMakeLists.txt
++++ b/Utilities/cmcurl/CMakeLists.txt
+@@ -452,6 +452,14 @@ if(CMAKE_USE_OPENSSL)
+ set(USE_OPENSSL ON)
+ set(HAVE_LIBCRYPTO ON)
+ set(HAVE_LIBSSL ON)
++ check_library_exists("rt" clock_gettime "" HAVE_LIBRT)
++ if(HAVE_LIBRT)
++ list(APPEND OPENSSL_LIBRARIES rt)
++ endif()
++ check_library_exists("pthread" pthread_once "" HAVE_PTHREAD)
++ if(HAVE_PTHREAD)
++ list(APPEND OPENSSL_LIBRARIES pthread)
++ endif()
+ list(APPEND CURL_LIBS ${OPENSSL_LIBRARIES})
+ include_directories(${OPENSSL_INCLUDE_DIR})
+ set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
diff --git a/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch
new file mode 100644
index 00000000000..375bc5d979c
--- /dev/null
+++ b/tools/cmake/patches/130-bootstrap_parallel_make_flag.patch
@@ -0,0 +1,14 @@
+--- a/bootstrap
++++ b/bootstrap
+@@ -1163,7 +1163,10 @@ int main(){ printf("1%c", (char)0x0a); r
+ ' > "test.c"
+ cmake_original_make_flags="${cmake_make_flags}"
+ if [ "x${cmake_parallel_make}" != "x" ]; then
+- cmake_make_flags="${cmake_make_flags} -j ${cmake_parallel_make}"
++ case "$cmake_paralle_make" in
++ [0-9]*) cmake_parallel_make="-j ${cmake_parallel_make}";;
++ esac
++ cmake_make_flags="${cmake_make_flags} ${cmake_parallel_make}"
+ fi
+ for a in ${cmake_make_processors}; do
+ if [ -z "${cmake_make_processor}" ] && cmake_try_make "${a}" "${cmake_make_flags}" >> ../cmake_bootstrap.log 2>&1; then
diff --git a/tools/cmake/patches/140-libarchive-fix-libressl.patch b/tools/cmake/patches/140-libarchive-fix-libressl.patch
new file mode 100644
index 00000000000..ad8a0969a8f
--- /dev/null
+++ b/tools/cmake/patches/140-libarchive-fix-libressl.patch
@@ -0,0 +1,37 @@
+From 5da00ad75b09e262774ec3675bbe4d5a4502a852 Mon Sep 17 00:00:00 2001
+From: Bernard Spil <brnrd@FreeBSD.org>
+Date: Sun, 1 Apr 2018 23:01:44 +0200
+Subject: [PATCH] fix build with LibreSSL 2.7
+
+LibreSSL 2.7 adds OpenSSL 1.1 API leading to conflicts on method names
+
+See also: https://bugs.freebsd.org/226853
+Signed-off-by: Bernard Spil <brnrd@FreeBSD.org>
+---
+ libarchive/archive_openssl_hmac_private.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h
+@@ -28,7 +28,8 @@
+ #include <openssl/hmac.h>
+ #include <openssl/opensslv.h>
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
+ #include <stdlib.h> /* malloc, free */
+ #include <string.h> /* memset */
+ static inline HMAC_CTX *HMAC_CTX_new(void)
+--- a/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
++++ b/Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h
+@@ -28,7 +28,8 @@
+ #include <openssl/evp.h>
+ #include <openssl/opensslv.h>
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
+ #include <stdlib.h> /* malloc, free */
+ #include <string.h> /* memset */
+ static inline EVP_MD_CTX *EVP_MD_CTX_new(void)
diff --git a/tools/coreutils/Makefile b/tools/coreutils/Makefile
new file mode 100644
index 00000000000..4109fd77b37
--- /dev/null
+++ b/tools/coreutils/Makefile
@@ -0,0 +1,37 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=coreutils
+PKG_CPE_ID:=cpe:/a:gnu:coreutils
+PKG_VERSION:=8.27
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNU/coreutils
+PKG_HASH:=8891d349ee87b9ff7870f52b6d9312a9db672d2439d289bc57084771ca21656b
+
+HOST_BUILD_PARALLEL := 1
+
+BUILD_PROGRAMS = date readlink
+
+include $(INCLUDE_DIR)/host-build.mk
+
+BUILD_BINS = $(patsubst %,src/%,$(BUILD_PROGRAMS))
+
+HOST_CONFIGURE_ARGS += \
+ --enable-install-program=$(subst $(space),$(comma),$(strip $(BUILD_PROGRAMS)))
+
+HOST_MAKE_FLAGS += \
+ PROGRAMS="$(BUILD_BINS)" \
+ LIBRARIES= MANS= SUBDIRS=.
+
+define Host/Install
+ $(INSTALL_DIR) $(1)/bin
+ $(CP) $(patsubst %,$(HOST_BUILD_DIR)/%,$(BUILD_BINS)) $(1)/bin/
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/coreutils/patches/001-fix-macos-vasnprintf.patch b/tools/coreutils/patches/001-fix-macos-vasnprintf.patch
new file mode 100644
index 00000000000..e41315d34ec
--- /dev/null
+++ b/tools/coreutils/patches/001-fix-macos-vasnprintf.patch
@@ -0,0 +1,25 @@
+--- a/lib/vasnprintf.c
++++ b/lib/vasnprintf.c
+@@ -4858,7 +4858,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *
+ #endif
+ *fbp = dp->conversion;
+ #if USE_SNPRINTF
+-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
++# if ! (((__GLIBC__ > 2 \
++ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
++ && !defined __UCLIBC__) \
++ || (defined __APPLE__ && defined __MACH__) \
++ || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+ fbp[1] = '%';
+ fbp[2] = 'n';
+ fbp[3] = '\0';
+@@ -4872,6 +4876,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *
+ in format strings in writable memory may crash the program
+ (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
+ in this situation. */
++ /* macOS 10.13 High Sierra behaves like glibc with
++ _FORTIFY_SOURCE=2, and older macOS releases
++ presumably do not need %n. */
+ /* On native Windows systems (such as mingw), we can avoid using
+ %n because:
+ - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
diff --git a/tools/dosfstools/Makefile b/tools/dosfstools/Makefile
new file mode 100644
index 00000000000..e34ceaf32be
--- /dev/null
+++ b/tools/dosfstools/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2012-2015 OpenWrt.org
+# Copyright (C) 2016 LEDE-Project.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=dosfstools
+PKG_CPE_ID:=cpe:/a:dosfstools_project:dosfstools
+PKG_VERSION:=4.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/dosfstools/dosfstools/releases/download/v$(PKG_VERSION)/ \
+ http://fossies.org/linux/misc
+PKG_HASH:=e6b2aca70ccc3fe3687365009dd94a2e18e82b688ed4e260e04b7412471cc173
+
+HOST_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/host-build.mk
+
+ifeq ($(HOST_OS),Darwin)
+HOST_CFLAGS += -UHAVE_ENDIAN_H
+endif
+
+$(eval $(call HostBuild))
diff --git a/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch b/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch
new file mode 100644
index 00000000000..ea933208216
--- /dev/null
+++ b/tools/dosfstools/patches/0002-Switch-to-AC_CHECK_LIB-for-iconv-library-linking.patch
@@ -0,0 +1,27 @@
+From 1c6c135ee15e449c1bf2e76d5307f83a3a1d7425 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Tue, 11 Oct 2016 12:07:48 +0200
+Subject: [PATCH] Switch to AC_CHECK_LIB for iconv library linking.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+AC_SEARCH_LIB doesn't work properly for openwrt/lede when building dosfstools
+as a package.
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -59,7 +59,7 @@ if test "x$with_udev" != "xno"; then
+ [true])
+ fi
+
+-AC_SEARCH_LIBS(iconv_open, iconv)
++AC_CHECK_LIB(iconv, iconv_open)
+
+ # xxd (distributed with vim) is used in the testsuite
+ AC_CHECK_PROG([XXD_FOUND], [xxd], [yes])
diff --git a/tools/e2fsprogs/Makefile b/tools/e2fsprogs/Makefile
index 0bfcfb4f0f1..0e12cdd9011 100644
--- a/tools/e2fsprogs/Makefile
+++ b/tools/e2fsprogs/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2010 OpenWrt.org
+# Copyright (C) 2010-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -8,24 +8,30 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=e2fsprogs
-PKG_VERSION:=1.41.13
-PKG_MD5SUM:=7508a192c7a9471e2128424f4eafac1c
+PKG_CPE_ID:=cpe:/a:e2fsprogs_project:e2fsprogs
+PKG_VERSION:=1.44.3
+PKG_HASH:=5d899f7d30f481cc0c6a049ebe26ebe145f1b524182ea1ecde4086162d4e4bb6
PKG_RELEASE:=1
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=@SF/e2fsprogs
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/kernel/people/tytso/e2fsprogs/v$(PKG_VERSION)/
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
-TARGET_CFLAGS += $(FPIC)
+HOST_CFLAGS += $(FPIC)
+
+HOST_CONFIGURE_ARGS += \
+ --disable-elf-shlibs \
+ --enable-libuuid \
+ --disable-tls \
+ --disable-nls
-CONFIGURE_ARGS += \
- --disable-shared \
- --enable-static \
- --disable-rpath \
- --enable-elf-shlibs \
- --enable-dynamic-e2fsck \
- --disable-tls
+define Host/Prepare
+ $(call Host/Prepare/Default)
+ rm -rf $(HOST_BUILD_DIR)/doc
+endef
define Host/Install
$(Host/Install/Default)
diff --git a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch b/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch
index 4dbece5cef7..67a30f610b5 100644
--- a/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch
+++ b/tools/e2fsprogs/patches/001-exit_0_on_corrected_errors.patch
@@ -1,6 +1,6 @@
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
-@@ -65,7 +65,7 @@
+@@ -73,7 +73,7 @@
* Exit codes used by fsck-type programs
*/
#define FSCK_OK 0 /* No errors */
diff --git a/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch b/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch
new file mode 100644
index 00000000000..2a7842f6554
--- /dev/null
+++ b/tools/e2fsprogs/patches/002-dont-build-e4defrag.patch
@@ -0,0 +1,11 @@
+--- a/misc/Makefile.in
++++ b/misc/Makefile.in
+@@ -11,7 +11,7 @@ INSTALL = @INSTALL@
+
+ @MCONFIG@
+
+-@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG= e4defrag
++@DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_PROG=
+ @DEFRAG_CMT@@LINUX_CMT@E4DEFRAG_MAN= e4defrag.8
+
+ @LINUX_CMT@E4CRYPT_PROG = e4crypt
diff --git a/tools/e2fsprogs/patches/002-freebsd_fix.patch b/tools/e2fsprogs/patches/002-freebsd_fix.patch
deleted file mode 100644
index 5065e05d1d7..00000000000
--- a/tools/e2fsprogs/patches/002-freebsd_fix.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/lib/ext2fs/tdb.c
-+++ b/lib/ext2fs/tdb.c
-@@ -29,6 +29,7 @@ Last Changed Date: 2007-06-22 13:36:10 -
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-+#include <sys/file.h>
- #ifdef CONFIG_STAND_ALONE
- #define HAVE_MMAP
- #define HAVE_STRDUP
-@@ -55,7 +56,6 @@ Last Changed Date: 2007-06-22 13:36:10 -
- #include <utime.h>
- #endif
- #include <sys/stat.h>
--#include <sys/file.h>
- #include <fcntl.h>
-
- #ifdef HAVE_SYS_MMAN_H
diff --git a/tools/e2fsprogs/patches/003-darwin_directio_fix.patch b/tools/e2fsprogs/patches/003-darwin_directio_fix.patch
deleted file mode 100644
index 971c7ad99b4..00000000000
--- a/tools/e2fsprogs/patches/003-darwin_directio_fix.patch
+++ /dev/null
@@ -1,36 +0,0 @@
---- a/lib/ext2fs/unix_io.c
-+++ b/lib/ext2fs/unix_io.c
-@@ -428,6 +428,7 @@ static errcode_t unix_open(const char *n
- struct unix_private_data *data = NULL;
- errcode_t retval;
- int open_flags;
-+ int f_nocache = 0;
- struct stat st;
- #ifdef __linux__
- struct utsname ut;
-@@ -464,7 +465,11 @@ static errcode_t unix_open(const char *n
- if (flags & IO_FLAG_EXCLUSIVE)
- open_flags |= O_EXCL;
- if (flags & IO_FLAG_DIRECT_IO)
-+#if !defined(O_DIRECT) && defined(F_NOCACHE)
-+ f_nocache = F_NOCACHE;
-+#else
- open_flags |= O_DIRECT;
-+#endif
- data->flags = flags;
-
- #ifdef HAVE_OPEN64
-@@ -477,6 +482,13 @@ static errcode_t unix_open(const char *n
- goto cleanup;
- }
-
-+ if (f_nocache) {
-+ if (fcntl(data->dev, f_nocache, 1) < 0) {
-+ retval = errno;
-+ goto cleanup;
-+ }
-+ }
-+
- #ifdef BLKSSZGET
- if (flags & IO_FLAG_DIRECT_IO) {
- if (ioctl(data->dev, BLKSSZGET, &data->align) != 0)
diff --git a/tools/e2fsprogs/patches/003-openbsd-compat.patch b/tools/e2fsprogs/patches/003-openbsd-compat.patch
new file mode 100644
index 00000000000..492b8a88608
--- /dev/null
+++ b/tools/e2fsprogs/patches/003-openbsd-compat.patch
@@ -0,0 +1,12 @@
+--- a/lib/blkid/getsize.c
++++ b/lib/blkid/getsize.c
+@@ -29,6 +29,9 @@
+ #include <fcntl.h>
+ #ifdef HAVE_SYS_IOCTL_H
+ #include <sys/ioctl.h>
++#ifdef __OpenBSD__
++#include <sys/dkio.h>
++#endif
+ #endif
+ #ifdef HAVE_LINUX_FD_H
+ #include <linux/fd.h>
diff --git a/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch b/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch
deleted file mode 100644
index 9c3e3360e78..00000000000
--- a/tools/e2fsprogs/patches/004-big_endian_compile_fix.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Theodore Ts'o <tytso@mit.edu>
-Date: Fri, 17 Dec 2010 03:11:43 +0000 (-0500)
-Subject: libext2fs: Fix compile bug on big-endian architectures
-X-Git-Url: http://git.kernel.org/?p=fs%2Fext2%2Fe2fsprogs.git;a=commitdiff_plain;h=9098c986b64bb65a2b7fcd2724a400ba1f451f6b
-
-libext2fs: Fix compile bug on big-endian architectures
-
-Addresses-Sourceforge-Bug: #3138115
-
-Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
----
-
-diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
-index 6f6cec2..12427e0 100644
---- a/lib/ext2fs/swapfs.c
-+++ b/lib/ext2fs/swapfs.c
-@@ -72,7 +72,7 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
- sb->s_flags = ext2fs_swab32(sb->s_flags);
- sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
- sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
-- sb->s_snapshot_id = ext2fs_swab32(s_snapshot_id);
-+ sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
- sb->s_snapshot_r_blocks_count =
- ext2fs_swab64(sb->s_snapshot_r_blocks_count);
- sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);
-
diff --git a/tools/e2fsprogs/patches/004-darwin-compat.patch b/tools/e2fsprogs/patches/004-darwin-compat.patch
new file mode 100644
index 00000000000..d84aa121ca5
--- /dev/null
+++ b/tools/e2fsprogs/patches/004-darwin-compat.patch
@@ -0,0 +1,22 @@
+--- a/lib/blkid/blkid_types.h.in
++++ b/lib/blkid/blkid_types.h.in
+@@ -9,6 +9,8 @@
+
+ @ASM_TYPES_HEADER@
+
++#include <stdint.h>
++
+ #ifndef HAVE___U8
+ #define HAVE___U8
+ #ifdef __U8_TYPEDEF
+--- a/lib/ext2fs/ext2_types.h.in
++++ b/lib/ext2fs/ext2_types.h.in
+@@ -9,6 +9,8 @@
+
+ @ASM_TYPES_HEADER@
+
++#include <stdint.h>
++
+ #ifndef HAVE___U8
+ #define HAVE___U8
+ #ifdef __U8_TYPEDEF
diff --git a/tools/elftosb/Makefile b/tools/elftosb/Makefile
new file mode 100644
index 00000000000..9079ac5803d
--- /dev/null
+++ b/tools/elftosb/Makefile
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=elftosb
+PKG_VERSION:=10.12.01
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://repository.timesys.com/buildsources/e/elftosb/elftosb-10.12.01/
+PKG_HASH:=77bb6981620f7575b87d136d94c7daa88dd09195959cc75fc18b138369ecd42b
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Compile
+ $(MAKE) -C $(HOST_BUILD_DIR) LDFLAGS="$(HOST_LDFLAGS)"
+endef
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/bld/linux/elftosb $(STAGING_DIR_HOST)/bin/elftosb
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/elftosb/patches/001-libm.patch b/tools/elftosb/patches/001-libm.patch
new file mode 100644
index 00000000000..02705d24bb7
--- /dev/null
+++ b/tools/elftosb/patches/001-libm.patch
@@ -0,0 +1,11 @@
+--- elftosb-10.12.01/makefile.rules 2012-03-15 11:01:44.979020178 -0400
++++ elftosb-10.12.01/makefile.rules 2012-03-15 11:01:16.332761989 -0400
+@@ -101,7 +101,7 @@
+ keygen.o
+
+
+-LIBS = -lstdc++
++LIBS = -lstdc++ -lm
+
+
+ ifeq ("${UNAMES}", "Linux")
diff --git a/tools/elftosb/patches/002-fix-header-path.patch b/tools/elftosb/patches/002-fix-header-path.patch
new file mode 100644
index 00000000000..5e3b5091b90
--- /dev/null
+++ b/tools/elftosb/patches/002-fix-header-path.patch
@@ -0,0 +1,19 @@
+This package had an absolute path for sys/types.h, which doesn't
+make much sense. It breaks on newer Ubuntu systems, and probably many
+others once multiarch becomes more common.
+
+This patch makes the types a relative path, and allows the system
+to use whatever include paths it feels are correct.
+
+diff -Naurp elftosb-10.12.01-orig/common/stdafx.h elftosb-10.12.01/common/stdafx.h
+--- elftosb-10.12.01-orig/common/stdafx.h 2012-07-12 13:30:10.990249396 -0400
++++ elftosb-10.12.01/common/stdafx.h 2012-07-12 13:30:06.858249391 -0400
+@@ -27,7 +27,7 @@
+ // For Linux systems only, types.h only defines the signed
+ // integer types. This is not professional code.
+ // Update: They are defined in the header files in the more recent version of redhat enterprise gcc.
+-#include "/usr/include/sys/types.h"
++#include <sys/types.h>
+ #include <stdint.h>
+ //typedef unsigned long uint32_t;
+ //typedef unsigned short uint16_t;
diff --git a/tools/elftosb/patches/003-use-ldflags.patch b/tools/elftosb/patches/003-use-ldflags.patch
new file mode 100644
index 00000000000..82fd1e8d0ae
--- /dev/null
+++ b/tools/elftosb/patches/003-use-ldflags.patch
@@ -0,0 +1,26 @@
+--- a/makefile.rules
++++ b/makefile.rules
+@@ -131,19 +131,20 @@ exec_always:
+ @echo "LIBS = ${LIBS}"
+ @echo "EXEC_FILE = ${EXEC_FILE}"
+ @echo "BUILD_DIR = ${BUILD_DIR}"
++ @echo "LDFLAGS = ${LDFLAGS}"
+
+ clean:
+ rm -f ${OBJ_FILES_ELFTOSB2} ${OBJ_FILES_SBTOOL} ${OBJ_FILES_KEYGEN} \
+ ${EXEC_FILE_ELFTOSB2} ${EXEC_FILE_SBTOOL} ${EXEC_FILE_KEYGEN}
+
+ elftosb: ${OBJ_FILES_ELFTOSB2}
+- gcc ${OBJ_FILES_ELFTOSB2} ${LIBS} -o ${EXEC_FILE_ELFTOSB2}
++ gcc ${OBJ_FILES_ELFTOSB2} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_ELFTOSB2}
+
+ sbtool: ${OBJ_FILES_SBTOOL}
+- gcc ${OBJ_FILES_SBTOOL} ${LIBS} -o ${EXEC_FILE_SBTOOL}
++ gcc ${OBJ_FILES_SBTOOL} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_SBTOOL}
+
+ keygen: ${OBJ_FILES_KEYGEN}
+- gcc ${OBJ_FILES_KEYGEN} ${LIBS} -o ${EXEC_FILE_KEYGEN}
++ gcc ${OBJ_FILES_KEYGEN} ${LIBS} ${LDFLAGS} -o ${EXEC_FILE_KEYGEN}
+
+
+ #ifeq ("${UNAMES}", "Linux")
diff --git a/tools/expat/Makefile b/tools/expat/Makefile
new file mode 100644
index 00000000000..fab04e011fa
--- /dev/null
+++ b/tools/expat/Makefile
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=expat
+PKG_CPE_ID:=cpe:/a:libexpat:expat
+PKG_VERSION:=2.2.5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_HASH:=d9dc32efba7e74f788fcc4f212a43216fc37cf5f23f4c2339664d473353aedf6
+PKG_SOURCE_URL:=@SF/expat
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(MAKE) -C $(HOST_BUILD_DIR) install
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/findutils/Makefile b/tools/findutils/Makefile
new file mode 100644
index 00000000000..c1c45eeaabd
--- /dev/null
+++ b/tools/findutils/Makefile
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2006-2016 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=findutils
+PKG_CPE_ID:=cpe:/a:gnu:findutils
+PKG_VERSION:=4.6.0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
+PKG_HASH:=ded4c9f73731cd48fec3b6bdaccce896473b6d8e337e9612e16cf1431bb1169d
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+$(eval $(call HostBuild))
diff --git a/tools/findutils/patches/100-include_sysmacros.patch b/tools/findutils/patches/100-include_sysmacros.patch
new file mode 100644
index 00000000000..82b1ee9a42b
--- /dev/null
+++ b/tools/findutils/patches/100-include_sysmacros.patch
@@ -0,0 +1,13 @@
+--- a/gl/lib/mountlist.c
++++ b/gl/lib/mountlist.c
+@@ -17,6 +17,10 @@
+
+ #include <config.h>
+
++#ifdef MAJOR_IN_SYSMACROS
++# include <sys/sysmacros.h>
++#endif
++
+ #include "mountlist.h"
+
+ #include <limits.h>
diff --git a/tools/findutils/patches/110-glibc-change-work-around.patch b/tools/findutils/patches/110-glibc-change-work-around.patch
new file mode 100644
index 00000000000..91b69274c8e
--- /dev/null
+++ b/tools/findutils/patches/110-glibc-change-work-around.patch
@@ -0,0 +1,104 @@
+Subject: Workaround change in glibc
+
+Temporary workaround to compile with glibc 2.28, which
+deprecated some constants
+
+Based on the workaround made for the tools/m4 package
+
+--- a/gl/lib/stdio-impl.h
++++ b/gl/lib/stdio-impl.h
+@@ -18,6 +18,12 @@
+ the same implementation of stdio extension API, except that some fields
+ have different naming conventions, or their access requires some casts. */
+
++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
++ problem by defining it ourselves. FIXME: Do not rely on glibc
++ internals. */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+
+ /* BSD stdio derived implementations. */
+
+--- a/gl/lib/freadahead.c
++++ b/gl/lib/freadahead.c
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ return 0;
+ return (fp->_IO_read_end - fp->_IO_read_ptr)
+--- a/gl/lib/fseeko.c
++++ b/gl/lib/fseeko.c
+@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int when
+ #endif
+
+ /* These tests are based on fpurge.c. */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_read_end == fp->_IO_read_ptr
+ && fp->_IO_write_ptr == fp->_IO_write_base
+ && fp->_IO_save_base == NULL)
+@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int when
+ return -1;
+ }
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_flags &= ~_IO_EOF_SEEN;
+ fp->_offset = pos;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+--- a/gl/lib/fflush.c
++++ b/gl/lib/fflush.c
+@@ -33,7 +33,7 @@
+ #undef fflush
+
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
+ static void
+@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
+
+ #endif
+
+-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
+
+ # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
+ if (stream == NULL || ! freading (stream))
+ return fflush (stream);
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ clear_ungetc_buffer_preserving_position (stream);
+
+--- a/gl/lib/freading.c
++++ b/gl/lib/freading.c
+@@ -31,7 +31,7 @@ freading (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return ((fp->_flags & _IO_NO_WRITES) != 0
+ || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
+ && fp->_IO_read_base != NULL));
+--- a/gl/lib/fpurge.c
++++ b/gl/lib/fpurge.c
+@@ -62,7 +62,7 @@ fpurge (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_IO_read_end = fp->_IO_read_ptr;
+ fp->_IO_write_ptr = fp->_IO_write_base;
+ /* Avoid memory leak when there is an active ungetc buffer. */
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
index 43642235465..436a43794cd 100644
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -12,51 +12,79 @@ include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/kernel.mk
define cc
- $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2)
+ $(HOSTCC) $(HOST_CFLAGS) -include endian.h $(HOST_LDFLAGS) -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) $(foreach src,$(1),src/$(src).c) $(2)
endef
define Host/Compile
mkdir -p $(HOST_BUILD_DIR)/bin
$(call cc,addpattern)
+ $(call cc,asustrx)
$(call cc,trx)
+ $(call cc,otrx)
$(call cc,motorola-bin)
$(call cc,dgfirmware)
+ $(call cc,mksenaofw md5)
$(call cc,trx2usr)
$(call cc,ptgen)
- $(call cc,airlink)
$(call cc,srec2bin)
$(call cc,mkmylofw)
$(call cc,mkcsysimg)
$(call cc,mkzynfw)
$(call cc,lzma2eva,-lz)
$(call cc,mkcasfw)
- $(call cc,mkfwimage,-lz)
+ $(call cc,mkfwimage,-lz -Wall)
$(call cc,mkfwimage2,-lz)
- $(call cc,imagetag imagetag_cmdline)
+ $(call cc,imagetag imagetag_cmdline cyg_crc32)
$(call cc,add_header)
$(call cc,makeamitbin)
$(call cc,encode_crc)
$(call cc,nand_ecc)
$(call cc,mkplanexfw sha1)
- $(call cc,mktplinkfw md5)
+ $(call cc,mktplinkfw mktplinkfw-lib md5, -Wall -fgnu89-inline)
+ $(call cc,mktplinkfw2 mktplinkfw-lib md5, -fgnu89-inline)
+ $(call cc,tplink-safeloader md5, -Wall --std=gnu99)
$(call cc,pc1crypt)
$(call cc,osbridge-crc)
$(call cc,wrt400n cyg_crc32)
- $(call cc,wndr3700)
$(call cc,mkdniimg)
$(call cc,mktitanimg)
$(call cc,mkchkimg)
$(call cc,mkzcfw cyg_crc32)
$(call cc,spw303v)
+ $(call cc,zyxbcm)
$(call cc,trx2edips)
$(call cc,xorimage)
$(call cc,buffalo-enc buffalo-lib, -Wall)
$(call cc,buffalo-tag buffalo-lib, -Wall)
$(call cc,buffalo-tftp buffalo-lib, -Wall)
$(call cc,mkwrgimg md5, -Wall)
+ $(call cc,mkwrggimg md5, -Wall)
$(call cc,mkedimaximg)
$(call cc,mkbrncmdline)
$(call cc,mkbrnimg)
+ $(call cc,mkdapimg)
+ $(call cc,mkdapimg2)
+ $(call cc, mkcameofw, -Wall)
+ $(call cc,seama md5)
+ $(call cc,oseama md5, -Wall)
+ $(call cc,fix-u-media-header cyg_crc32,-Wall)
+ $(call cc,hcsmakeimage bcmalgo)
+ $(call cc,mkporayfw, -Wall)
+ $(call cc,mkhilinkfw, -lcrypto)
+ $(call cc,mkdcs932, -Wall)
+ $(call cc,mkheader_gemtek,-lz)
+ $(call cc,mkrtn56uimg, -lz)
+ $(call cc,dgn3500sum, -Wall)
+ $(call cc,edimax_fw_header, -Wall)
+ $(call cc,mkmerakifw sha1, -Wall)
+ $(call cc,mkmerakifw-old, -Wall)
+ $(call cc,jcgimage, -lz -Wall)
+ $(call cc,mkbuffaloimg, -Wall)
+ $(call cc,zyimage, -Wall)
+ $(call cc,mkdhpimg buffalo-lib, -Wall)
+ $(call cc,mkdlinkfw mkdlinkfw-lib, -lz -Wall --std=gnu99)
+ $(call cc,dns313-header, -Wall)
+ $(call cc,mksercommfw, -Wall --std=gnu99)
endef
define Host/Install
diff --git a/tools/firmware-utils/src/addpattern.c b/tools/firmware-utils/src/addpattern.c
index da6797c9ced..9bc48653356 100644
--- a/tools/firmware-utils/src/addpattern.c
+++ b/tools/firmware-utils/src/addpattern.c
@@ -58,6 +58,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -77,10 +78,11 @@
/* (from 3.00.24 firmware cyutils.h) */
#define SUPPORT_4704_CHIP 0x0008
#define SUPPORT_5352E_CHIP 0x0010
+/* (from WD My Net Wi-Fi Range Extender's cyutils.s) */
+#define SUPPORT_4703_CHIP 0x0020
struct code_header { /* from cyutils.h */
- char magic[4];
- char res1[4]; /* for extra magic */
+ char magic[8];
char fwdate[3];
char fwvern[3];
char id[4]; /* U2ND */
@@ -105,11 +107,25 @@ struct board_info {
struct board_info boards[] = {
{
+ .id = "E2100L",
+ .pattern = "NL1X",
+ .hw_ver = 0x00,
+ .sn = 0x0f,
+ .flags = {0x3f, 0x00},
+ },
+ {
.id = "WRT160NL",
.pattern = "NL16",
.hw_ver = 0x00,
.sn = 0x0f,
.flags = {0x3f, 0x00},
+ },
+ {
+ .id = "mynet-rext",
+ .pattern = "WDHNSTFH",
+ .hw_ver = 0x00,
+ .sn = 0x00,
+ .flags = {0x3f, 0x00},
}, {
/* Terminating entry */
.id = NULL,
@@ -126,6 +142,20 @@ void usage(void)
exit(EXIT_FAILURE);
}
+static time_t source_date_epoch = -1;
+static void set_source_date_epoch() {
+ char *env = getenv("SOURCE_DATE_EPOCH");
+ char *endptr = env;
+ errno = 0;
+ if (env && *env) {
+ source_date_epoch = strtoull(env, &endptr, 10);
+ if (errno || (endptr && *endptr != '\0')) {
+ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
+ exit(1);
+ }
+ }
+}
+
struct board_info *find_board(char *id)
{
struct board_info *board;
@@ -243,8 +273,8 @@ int main(int argc, char **argv)
hdr->flags[1] = board->flags[1];
}
- if (strlen(pattern) != 4) {
- fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern);
+ if (strlen(pattern) > 8) {
+ fprintf(stderr, "illegal pattern \"%s\"\n", pattern);
usage();
}
@@ -258,7 +288,10 @@ int main(int argc, char **argv)
usage();
}
- if (time(&t) == (time_t)(-1)) {
+ set_source_date_epoch();
+ if (source_date_epoch != -1) {
+ t = source_date_epoch;
+ } else if ((time(&t) == (time_t)(-1))) {
fprintf(stderr, "time call failed\n");
return EXIT_FAILURE;
}
@@ -270,16 +303,16 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
- memcpy(&hdr->magic, pattern, 4);
+ memcpy(hdr->magic, pattern, strlen(pattern));
if (pbotflag)
- memcpy(&hdr->res1, pbotpat, 4);
+ memcpy(&hdr->magic[4], pbotpat, 4);
hdr->fwdate[0] = ptm->tm_year % 100;
hdr->fwdate[1] = ptm->tm_mon + 1;
hdr->fwdate[2] = ptm->tm_mday;
hdr->fwvern[0] = v0;
hdr->fwvern[1] = v1;
hdr->fwvern[2] = v2;
- memcpy(&hdr->id, CODE_ID, strlen(CODE_ID));
+ memcpy(hdr->id, CODE_ID, strlen(CODE_ID));
off = sizeof(struct code_header);
diff --git a/tools/firmware-utils/src/airlink.c b/tools/firmware-utils/src/airlink.c
deleted file mode 100644
index 560a58df59e..00000000000
--- a/tools/firmware-utils/src/airlink.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Thanks to Vassily Galinsky for this tool
-*****************************************************************************
-AIRLINK AR525W firmware image structure
- -8:-5 Extended (httpd) header checksum - sum2
- -4:-1 Extended (httpd) header magic - "ARRN" - 0x4e525241
- 0: 3 Standard (tftpd) header magic - "GMTK" - 0x4b544d47
- 4: 7 Standard (tftpd) header checksum - sum1
- 8: b 0
- c: f Size of compressed linux kernel
- 10:13 Size of firmware image file with standard header
- 14:17 Product code - 0x5
- 18:1b Bootloader checksum - sum0
- 1c:1f 0
- 20: Compressed linux kernel
- - Squashfs or jffs2 file system - kernel dependent - either 32 bytes or sector aligned
-*****************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-
-typedef unsigned char uchar;
-
-uint32_t crctab[257] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
- 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
- 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
- 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
- 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
- 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
- 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
- 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
- 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
- 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
- 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
- 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
- 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
- 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
- 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
- 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
- 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
- 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
- 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
- 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
- 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
- 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
- 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
- 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
- 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
- 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
- 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
- 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
- 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
- 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
- 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
- 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
- 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
- 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
- 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
- 0
-};
-
-uint32_t header[] = {
- 0x00000000, 0x4e525241,
- 0x4b544d47, 0x00000000, 0x00000000, 0x000afd4a,
- 0x00000000, 0x00000005, 0x00000000, 0x00000000
-};
-
-static int JFFS2 = 0;
-
-int generate_image(char *kname, char *fsname, char *fname, int EHDR)
-{
- int i;
- uint32_t lenk, lens;
- uchar *bk, *bs;
- int fkd, ffd, fsd;
- fkd = open(kname, O_RDONLY);
- ffd = creat(fname, 0644);
- if ((fkd < 0) || (ffd < 0))
- return -1;
- if (fsname) {
- fsd = open(fsname, O_RDONLY);
- if (fsd < 0)
- return -1;
- }
- lenk = lseek(fkd, 0, SEEK_END);
- header[5] = lenk;
- bk = (uchar *) mmap(NULL, lenk, PROT_READ, MAP_SHARED, fkd, 0);
- if (bk == MAP_FAILED)
- return -1;
- if (fsname) {
- lens = lseek(fsd, 0, SEEK_END);
- bs = (uchar *) mmap(NULL, lens, PROT_READ, MAP_SHARED, fsd,
- 0);
- if (bs == MAP_FAILED)
- return -1;
- }
- if (EHDR)
- write(ffd, header, 0x28);
- else
- write(ffd, header + 2, 0x20);
- write(ffd, bk, lenk);
- lenk += 0x20;
- if (!JFFS2) JFFS2 = 0x20;
- printf("Padding header+kernel - 0x%x + 0x%x = 0x%x\n",
- lenk, ((lenk - 1 + JFFS2) / JFFS2) * JFFS2 - lenk,
- ((lenk - 1 + JFFS2) / JFFS2) * JFFS2);
- for (i = 0; i < ((lenk - 1 + JFFS2) / JFFS2) * JFFS2 - lenk; i++)
- write(ffd, header, 1);
- if (fsname) {
- write(ffd, bs, lens);
- close(fsd);
- }
- close(ffd);
- close(fkd);
- return 0;
-}
-
-uint32_t crc32(uchar * buf, uint32_t len)
-{
- register int i;
- uint32_t sum;
- register uint32_t s0;
- s0 = ~0;
- for (i = 0; i < len; i++) {
- s0 = (s0 >> 8) ^ crctab[(uchar) (s0 & 0xFF) ^ buf[i]];
- }
- sum = ~s0;
- return sum;
-}
-
-void usage(char *prog)
-{
- printf("Usage: %s [-b 0/1] image_filename \n", prog);
- printf(" update checksums for firmware file\n");
- printf
- ("Usage: %s [-b 0/1] [-j erasesize_in_kibytes] [-e] kernel filesystem image_filename \n",
- prog);
- printf(" generate firmware file and update checksums\n");
- printf("--------------------------------------------------\n");
- printf(" -e - generate header for web upload\n");
- printf(" -b 0/1 - clear/update bootloader checksum\n");
- printf(" -j erasesize_in_kibytes - generate header for jffs2 filesystem\n");
-}
-
-int main(int argc, char **argv)
-{
- uchar b[0x400];
- char EHDR = 0;
- char BHDR = 0;
- int c, fd;
- extern char *optarg;
- extern int optind, optopt;
-
- while ((c = getopt(argc, argv, "b:ej:")) != -1) {
- switch (c) {
- case 'b':
- if (optarg[0] == '1')
- BHDR = 1;
- break;
- case 'e':
- EHDR = 1;
- break;
- case 'j':
- sscanf(optarg, "%i", &JFFS2);
- JFFS2 *= 1024;
- break;
- case '?':
- fprintf(stderr, "\nError: unknown arg %c\n\n\n",
- optopt);
- usage(argv[0]);
- exit(-1);
- }
- }
- if (((argc - optind) < 1) && ((argc - optind) > 3)) {
- usage(argv[0]);
- exit(-1);
- }
- if ((argc - optind) == 3)
- if (generate_image
- (argv[optind], argv[optind + 1], argv[optind + 2],
- EHDR)) {
- fprintf(stderr,
- "\nError generating image file %s\n\n\n",
- argv[argc - 1]);
- usage(argv[0]);
- exit(-1);
- }
- if ((argc - optind) == 2)
- if (generate_image
- (argv[optind], NULL, argv[optind + 1], EHDR)) {
- fprintf(stderr,
- "\nError generating image file %s\n\n\n",
- argv[argc - 1]);
- usage(argv[0]);
- exit(-1);
- }
-
- fd = open(argv[argc - 1], O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "\nImage file not found %s\n\n\n",
- argv[argc - 1]);
- usage(argv[0]);
- exit(-1);
- }
- long i, len = lseek(fd, 0, SEEK_END);
- lseek(fd, 0, SEEK_SET);
- uchar *buf = malloc(len);
- read(fd, buf, len);
- uint32_t sum, l0;
- uint32_t MagicS = 0x474d544b;
- uint32_t MagicE = 0x4152524e;
- if (ntohl(*((uint32_t *) buf)) == MagicS) {
- fprintf(stderr,
- "Image without extra 8 bytes - Standard header\n");
- buf[0x10] = len & 0xff;
- buf[0x11] = (len >> 8) & 0xff;
- buf[0x12] = (len >> 16) & 0xff;
- buf[0x13] = (len >> 24) & 0xff;
- lseek(fd, 0x10, SEEK_SET);
- write(fd, buf + 0x10, 0x4);
- EHDR = 0;
- } else if ((ntohl(*((uint32_t *) (buf + 0x8))) == MagicS)
- && ((ntohl(*((uint32_t *) (buf + 0x4))) == MagicE))) {
- fprintf(stderr,
- "Image with extra 8 bytes - Extended header\n");
- *((uint32_t *) (buf + 0x18)) = len - 8;
- buf[0x18] = (len - 8) & 0xff;
- buf[0x19] = ((len - 8) >> 8) & 0xff;
- buf[0x1a] = ((len - 8) >> 16) & 0xff;
- buf[0x1b] = ((len - 8) >> 24) & 0xff;
- lseek(fd, 0x18, SEEK_SET);
- write(fd, buf + 0x18, 0x4);
- buf += 8;
- EHDR = 1;
- } else if (len == buf[0x10] | ((uint32_t)buf[0x11] << 8) | ((uint32_t)buf[0x12] << 16) | ((uint32_t)buf[0x13] << 24)) {
- fprintf(stderr,
- "Image without extra 8 bytes - Standard header\n");
- EHDR = 0;
- } else if (len == (buf[0x18] | ((uint32_t)buf[0x19] << 8) | ((uint32_t)buf[0x1a] << 16) | ((uint32_t)buf[0x1b] << 24)) + 8) {
- fprintf(stderr,
- "Image with extra 8 bytes - Extended header\n");
- buf += 8;
- EHDR = 1;
- } else {
- fprintf(stderr, "ERROR: Wrong image size\n");
- exit(-1);
- }
- l0 = buf[0x10] | ((uint32_t)buf[0x11] << 8) | ((uint32_t)buf[0x12] << 16) | ((uint32_t)buf[0x13] << 24);
- if (!BHDR)
- *((uint32_t *) & buf[0x18]) = 0;
- unsigned long sum0 = buf[0x18] | ((uint32_t)buf[0x19] << 8) | ((uint32_t)buf[0x1a] << 16) | ((uint32_t)buf[0x1b] << 24);
- unsigned long sum1 = buf[0x4] | ((uint32_t)buf[0x5] << 8) | ((uint32_t)buf[0x6] << 16) | ((uint32_t)buf[0x7] << 24);
- *((uint32_t *) & buf[0x4]) = 0x0L;
- memcpy(b, buf, 0x100);
- memcpy(b + 0x100, buf + ((l0 >> 1) - ((l0 & 0x6) >> 1)), 0x100);
- memcpy(b + 0x200, buf + (l0 - 0x200), 0x200);
- *((uint32_t *) & b[0x18]) = 0x0L;
-
- sum = crc32(b, 0x400);
- printf("CRC32 sum0 - (%x, %x, %x)\n", sum, sum0, 0x400);
- if (EHDR)
- lseek(fd, 0x20, SEEK_SET);
- else
- lseek(fd, 0x18, SEEK_SET);
- buf[0x18] = (BHDR ? sum : sum0) & 0xff;
- buf[0x19] = ((BHDR ? sum : sum0) >> 8) & 0xff;
- buf[0x1a] = ((BHDR ? sum : sum0) >> 16) & 0xff;
- buf[0x1b] = ((BHDR ? sum : sum0) >> 24) & 0xff;
- write(fd, &buf[0x18], 0x4);
-
- sum = crc32(buf, l0);
- printf("CRC32 sum1 - (%x, %x, %x)\n", sum, sum1, l0);
- if (EHDR)
- lseek(fd, 0xC, SEEK_SET);
- else
- lseek(fd, 0x4, SEEK_SET);
- buf[0x4] = sum & 0xff;
- buf[0x5] = (sum >> 8) & 0xff;
- buf[0x6] = (sum >> 16) & 0xff;
- buf[0x7] = (sum >> 24) & 0xff;
- write(fd, &buf[0x4], 0x4);
- if (EHDR) {
- unsigned long sum2 = buf[-0x8] | ((uint32_t)buf[-0x7] << 8) | ((uint32_t)buf[-0x6] << 16) | ((uint32_t)buf[-0x5] << 24);
- *((uint32_t *) & buf[-0x8]) = 0L;
- sum = crc32(buf - 0x4, len - 0x4);
- printf("CRC32 sum2 - (%x, %x, %x)\n", sum, sum2,
- len - 0x4);
- lseek(fd, 0, SEEK_SET);
- *((uint32_t *) & buf[-0x8]) = htonl(sum);
- write(fd, &buf[-0x8], 0x4);
- buf -= 8;
- }
- close(fd);
- free(buf);
- return 0;
-}
diff --git a/tools/firmware-utils/src/asustrx.c b/tools/firmware-utils/src/asustrx.c
new file mode 100644
index 00000000000..67f2680b31b
--- /dev/null
+++ b/tools/firmware-utils/src/asustrx.c
@@ -0,0 +1,256 @@
+/*
+ * asustrx
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <byteswap.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_le32(x) bswap_32(x)
+#define le32_to_cpu(x) bswap_32(x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#else
+#error "Unsupported endianness"
+#endif
+
+#define TRX_MAGIC 0x30524448
+#define TRX_FLAGS_OFFSET 12
+
+struct trx_header {
+ uint32_t magic;
+ uint32_t length;
+ uint32_t crc32;
+ uint16_t flags;
+ uint16_t version;
+ uint32_t offset[3];
+};
+
+struct asustrx_tail {
+ uint8_t version[4];
+ char productid[12];
+ uint8_t unused[48];
+};
+
+char *in_path = NULL;
+char *out_path = NULL;
+char *productid = NULL;
+uint8_t version[4] = { };
+
+static const uint32_t crc32_tbl[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+};
+
+static void parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "i:o:p:v:")) != -1) {
+ switch (c) {
+ case 'i':
+ in_path = optarg;
+ break;
+ case 'o':
+ out_path = optarg;
+ break;
+ case 'p':
+ productid = optarg;
+ break;
+ case 'v':
+ if (sscanf(optarg, "%hu.%hu.%hu.%hu", &version[0], &version[1], &version[2], &version[3]) != 4)
+ fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg);
+ break;
+ }
+ }
+}
+
+static void usage() {
+ printf("Usage:\n");
+ printf("\t-i file\t\t\t\tinput TRX file\n");
+ printf("\t-o file\t\t\t\toutput Asus TRX file\n");
+ printf("\t-p productid\t\t\tproduct (device) ID\n");
+ printf("\t-v version\t\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n");
+}
+
+int main(int argc, char **argv) {
+ struct trx_header hdr;
+ struct asustrx_tail tail = { };
+ FILE *in, *out;
+ uint8_t buf[1024];
+ size_t bytes;
+ size_t length = 0;
+ uint32_t crc32 = 0xffffffff;
+ int i;
+ int err = 0;
+
+ /* Parse & validate arguments */
+ parse_options(argc, argv);
+ if (!in_path || !out_path || !productid) {
+ usage();
+ err = -EINVAL;
+ goto err;
+ }
+
+ /* Fill Asus tail */
+ tail.version[0] = version[0];
+ tail.version[1] = version[1];
+ tail.version[2] = version[2];
+ tail.version[3] = version[3];
+ strncpy(tail.productid, productid, sizeof(tail.productid));
+
+ /* Open files */
+ in = fopen(in_path, "r");
+ if (!in) {
+ fprintf(stderr, "Couldn't open %s\n", in_path);
+ err = -EIO;
+ goto err;
+ }
+ out = fopen(out_path, "w+");
+ if (!out) {
+ fprintf(stderr, "Couldn't open %s\n", out_path);
+ err = -EIO;
+ goto err;
+ }
+
+ /* Check is there is empty place for Asus tail */
+ bytes = sizeof(struct asustrx_tail);
+ fseek(in, -bytes, SEEK_END);
+ if (fread(buf, 1, bytes, in) != bytes) {
+ fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path);
+ err = -EIO;
+ goto err;
+ }
+ for (i = 0; i < bytes; i++) {
+ if (buf[i]) {
+ fprintf(stderr, "Input TRX doesn't have last 64 B empty %s\n", out_path);
+ err = -ENOSPC;
+ goto err;
+ }
+ }
+
+ /* Copy whole TRX */
+ rewind(in);
+ while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (fwrite(buf, 1, bytes, out) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
+ err = -EIO;
+ goto err;
+ }
+ }
+
+ /* Overwrite last 64 B with Asus tail */
+ bytes = sizeof(tail);
+ fseek(out, -bytes, SEEK_CUR);
+ if (fwrite(&tail, 1, bytes, out) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
+ err = -EIO;
+ goto err;
+ }
+
+ /* Calculate crc32 */
+ fseek(out, TRX_FLAGS_OFFSET, SEEK_SET);
+ length = TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, sizeof(buf), out )) > 0) {
+ length += bytes;
+ for (i = 0; i < bytes; i++)
+ crc32 = crc32_tbl[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
+ }
+
+ /* Update header */
+ bytes = sizeof(hdr);
+ rewind(out);
+ if (fread(&hdr, 1, sizeof(hdr), out) != bytes) {
+ fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path);
+ err = -EIO;
+ goto err;
+ }
+ hdr.crc32 = cpu_to_le32(crc32);
+ rewind(out);
+ if (fwrite(&hdr, 1, bytes, out) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
+ err = -EIO;
+ goto err;
+ }
+
+err:
+ if (out)
+ fclose(out);
+ if (in)
+ fclose(in);
+ return err;
+}
diff --git a/tools/firmware-utils/src/bcm_tag.h b/tools/firmware-utils/src/bcm_tag.h
index 2e977a2d7a6..2730edc9ad9 120000..100644
--- a/tools/firmware-utils/src/bcm_tag.h
+++ b/tools/firmware-utils/src/bcm_tag.h
@@ -1 +1,70 @@
-../../../target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h \ No newline at end of file
+#ifndef __BCM63XX_TAG_H
+#define __BCM63XX_TAG_H
+
+#define TAGVER_LEN 4 /* Length of Tag Version */
+#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
+#define SIG1_LEN 20 /* Company Signature 1 Length */
+#define SIG2_LEN 14 /* Company Signature 2 Lenght */
+#define BOARDID_LEN 16 /* Length of BoardId */
+#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
+#define CHIPID_LEN 6 /* Chip Id Length */
+#define IMAGE_LEN 10 /* Length of Length Field */
+#define ADDRESS_LEN 12 /* Length of Address field */
+#define DUALFLAG_LEN 2 /* Dual Image flag Length */
+#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
+#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
+#define CRC_LEN 4 /* Length of CRC in bytes */
+#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
+
+#define NUM_PIRELLI 2
+#define IMAGETAG_CRC_START 0xFFFFFFFF
+
+#define PIRELLI_BOARDS { \
+ "AGPF-S0", \
+ "DWV-S0", \
+}
+
+/*
+ * The broadcom firmware assumes the rootfs starts the image,
+ * therefore uses the rootfs start (flashImageAddress)
+ * to determine where to flash the image. Since we have the kernel first
+ * we have to give it the kernel address, but the crc uses the length
+ * associated with this address (rootLength), which is added to the kernel
+ * length (kernelLength) to determine the length of image to flash and thus
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
+*/
+
+struct bcm_tag {
+ char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag
+ char sig_1[SIG1_LEN]; // 4-23: Company Line 1
+ char sig_2[SIG2_LEN]; // 24-37: Company Line 2
+ char chipid[CHIPID_LEN]; // 38-43: Chip this image is for
+ char boardid[BOARDID_LEN]; // 44-59: Board name
+ char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE
+ char totalLength[IMAGE_LEN]; // 62-71: Total length of image
+ char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE
+ char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE
+ char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware)
+ char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing
+ char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel
+ char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel
+ char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present
+ char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present
+ char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this)
+ char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT)
+ char flashLayoutVer[FLASHLAYOUTVER_LEN];// 192-195: Version flash layout
+ char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32
+ char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information
+ char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate)
+ char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition
+ char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition
+ char imageSequence[4]; // 228-231: Image sequence number
+ char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot
+ char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion
+ char reserved2[16]; // 240-255: Unused at present
+};
+
+#endif /* __BCM63XX_TAG_H */
diff --git a/tools/firmware-utils/src/bcmalgo.c b/tools/firmware-utils/src/bcmalgo.c
new file mode 100644
index 00000000000..e7d3b113bec
--- /dev/null
+++ b/tools/firmware-utils/src/bcmalgo.c
@@ -0,0 +1,248 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include "bcmalgo.h"
+
+
+#define UTIL_VERSION "0.1"
+#define ENDIAN_REVERSE_NEEDED
+
+uint32_t reverse_endian32 ( uint32_t data )
+{
+#ifdef ENDIAN_REVERSE_NEEDED
+ return 0 | ( data & 0x000000ff ) << 24
+ | ( data & 0x0000ff00 ) << 8
+ | ( data & 0x00ff0000 ) >> 8
+ | ( data & 0xff000000 ) >> 24;
+#else
+ return data;
+#endif
+}
+
+uint16_t reverse_endian16 ( uint16_t data )
+{
+#ifdef ENDIAN_REVERSE_NEEDED
+ return 0 | ( data & 0x00ff ) << 8
+ | ( data & 0xff00 ) >> 8;
+#else
+ return data;
+#endif
+}
+
+
+
+uint32_t get_buffer_crc ( char* filebuffer,size_t size )
+{
+
+ long crc=0xffffffffL;
+ long crcxor = 0xffffffffL;
+ long num4 = 0xffffffffL;
+ long num5 = size;
+ long num6 = 0x4c11db7L;
+ long num7 = 0x80000000L;
+ int i;
+ long j;
+ for ( i = 0; i < ( num5 ); i++ )
+ {
+ long num2 = filebuffer[i];
+ for ( j = 0x80L; j != 0L; j = j >> 1 )
+ {
+ long num3 = crc & num7;
+ crc = crc << 1;
+ if ( ( num2 & j ) != 0L )
+ {
+ num3 ^= num7;
+ }
+ if ( num3 != 0L )
+ {
+ crc ^= num6;
+ }
+ }
+ }
+ crc ^= crcxor;
+ crc &= num4;
+
+ uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 );
+ uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 );
+ uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 );
+ uint8_t b4 = ( uint8_t ) ( crc & 0xffL );
+ int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 );
+ return reverse_endian32 ( crc_result );
+}
+
+//Thnx to Vector for the algo.
+uint32_t get_file_crc ( char* filename )
+{
+ struct stat buf;
+ stat ( filename,&buf );
+ char* filebuffer = malloc ( buf.st_size+10 );
+ FILE* fd = fopen ( filename,"r" );
+ fread ( filebuffer, 1, buf.st_size,fd );
+ fclose ( fd );
+ uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size );
+ free ( filebuffer );
+ return crc;
+}
+
+
+
+uint16_t get_hcs ( ldr_header_t* hd )
+{
+ uint8_t* head = ( uint8_t* ) hd;
+ uint8_t hcs_minor;
+ uint8_t hcs_major;
+ uint16_t n = 0xffff;
+ uint16_t m = 0;
+ int state = 0;
+ int i,j;
+ for ( i = 0; i < 0x54; i++ )
+ {
+ uint16_t m = head[i];
+ m = m << 8;
+ for ( j = 0; j < 8; j++ )
+ {
+ if ( ( ( n ^ m ) & 0x8000 ) == 0 )
+ {
+ state = 0;
+ }
+ else
+ {
+ state = 1;
+ }
+ n = n << 1;
+ if ( state )
+ {
+ n ^= 0x1021;
+ }
+ m = m << 1;
+ }
+ n &= 0xffff;
+ }
+ n ^= 0xffff;
+ hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 );
+ hcs_minor = ( uint8_t ) ( n & 0xff );
+ uint16_t hcs = hcs_major <<8 | hcs_minor;
+ return hcs;
+}
+
+ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data )
+{
+ ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) );
+ hd->magic=reverse_endian16 ( magic );
+ hd->control=0; //FixMe: Make use of it once compression is around
+ hd->rev_min = reverse_endian16 ( rev_min );
+ hd->rev_maj = reverse_endian16 ( rev_maj );
+ hd->build_date = reverse_endian32 ( build_date );
+ hd->filelen = reverse_endian32 ( filelen );
+ hd->ldaddress = reverse_endian32 ( ldaddress );
+ printf ( "Creating header for %s...\n", filename );
+ if ( strlen ( filename ) >63 )
+ {
+ printf ( "[!] Filename too long - stripping it to 63 bytes.\n" );
+ strncpy ( ( char* ) &hd->filename, filename, 63 );
+ hd->filename[63]=0x00;
+ }
+ else
+ {
+ strcpy ( ( char* ) &hd->filename, filename );
+ }
+ hd->crc=reverse_endian32 ( crc_data );
+ hd->hcs = reverse_endian16 ( get_hcs ( hd ) );
+ return hd;
+}
+
+static char control_unc[] = "Uncompressed";
+static char control_lz[] = "LZRW1/KH";
+static char control_mlzo[] = "mini-LZO";
+static char control_nrv[] = "NRV2D99 [Bootloader?]";
+static char control_nstdlzma[] = "(non-standard) LZMA";
+static char control_unk[] = "Unknown";
+char* get_control_info ( uint16_t control )
+{
+ control = reverse_endian16 ( control );
+ switch ( control )
+ {
+ case 0:
+ return control_unc;
+ break;
+ case 1:
+ return control_lz;
+ break;
+ case 2:
+ return control_mlzo;
+ break;
+ case 3:
+ return control_unc;
+ break;
+ case 4:
+ return control_nrv;
+ break;
+ case 5:
+ return control_nstdlzma;
+ break;
+ case 6:
+ return control_unc;
+ break;
+ case 7:
+ return control_unc;
+ break;
+ default:
+ return control_unk;
+ break;
+ }
+
+}
+
+int dump_header ( ldr_header_t* hd )
+{
+ printf ( "=== Header Information ===\n" );
+ printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) );
+ printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) );
+ printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) );
+ printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) );
+ printf ( "File name :\t%s\n", ( char* ) &hd->filename );
+ printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) );
+ printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe:
+ printf ( "HCS:\t\t0x%04X ",reverse_endian16 ( hd->hcs ) );
+ uint16_t hcs = get_hcs ( hd );
+ int ret=0;
+ if ( hcs ==reverse_endian16 ( hd->hcs ) )
+ {
+ printf ( "(OK!)\n" );
+ }
+ else
+ {
+ printf ( "(ERROR! expected 0x%04X)\n",hcs );
+ ret=1;
+ }
+//printf("HCS:\t0x%02X",reverse_endian32(hd->hcs));
+ printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe:
+ printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what
+ printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) );
+ printf ( "=== Binary Header Dump===\n" );
+ int i,j;
+ uint8_t* head = ( uint8_t* ) hd;
+ for ( i=0;i<=sizeof ( ldr_header_t );i++ )
+ {
+ if ( i % 8==0 )
+ printf ( "\n" );
+ printf ( "0x%02x ",head[i] );
+ }
+ printf ( "\n\n== End Of Header dump ==\n" );
+ return ret;
+}
+
+
+void print_copyright()
+{
+ printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" );
+ printf ( "Copyright (C) 2009 Andrew 'Necromant' Andrianov\n"
+ "This is free software, and you are welcome to redistribute it\n"
+ "under certain conditions. See COPYING for details\n" );
+}
diff --git a/tools/firmware-utils/src/bcmalgo.h b/tools/firmware-utils/src/bcmalgo.h
new file mode 100644
index 00000000000..46647cf6d3d
--- /dev/null
+++ b/tools/firmware-utils/src/bcmalgo.h
@@ -0,0 +1,83 @@
+#ifndef bcmutils_H
+#define bcmutils_H
+
+typedef struct
+{
+ uint16_t magic;
+ uint16_t control;
+ uint16_t rev_maj;
+ uint16_t rev_min;
+ uint32_t build_date;
+ uint32_t filelen;
+ uint32_t ldaddress;
+ char filename[64];
+ uint16_t hcs;
+ uint16_t her_znaet_chto; //v dushe ne ebu
+ uint32_t crc;
+} ldr_header_t;
+
+
+/**
+ * Reverses endianess of a 32bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time
+ * @param data
+ * @return
+ */
+uint32_t reverse_endian32 ( uint32_t data );
+
+/**
+ * Reverses endianess of a 16bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time
+ * @param data
+ * @return
+ */
+uint16_t reverse_endian16 ( uint16_t data );
+/**
+ * Calculates the strange crc (used by bcm modems) of the file. Thnx fly out to Vector for the algorithm.
+ * @param filename
+ * @return
+ */
+uint32_t get_file_crc ( char* filename );
+
+/**
+ * Calculates HCS of the header.
+ * @param hd
+ * @return
+ */
+uint16_t get_hcs ( ldr_header_t* hd );
+
+/**
+ * Constructs the header of the image with the information given It also automagically calculates HCS and writes it there.
+ * @param magic - magic device bytes
+ * @param rev_maj - major revision
+ * @param rev_min - minor revision
+ * @param build_date - build date (seconds from EPOCH UTC)
+ * @param filelen - file length in bytes
+ * @param ldaddress - Load adress
+ * @param filename - filename
+ * @param crc_data - the crc of the data
+ * @return
+ */
+ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data );
+
+/**
+ * Dumps header information to stdout.
+ * @param hd
+ */
+int dump_header ( ldr_header_t* hd );
+
+
+/**
+ * Returns a null terminated string describing what the control number meens
+ * DO NOT FREE IT!!!
+ * @param control
+ * @return
+ */
+char* get_control_info ( uint16_t control );
+#endif
+
+/**
+ * Calculates bcmCRC of a data buffer.
+ * @param filebuffer - pointer to buffer
+ * @param size - buffer size
+ * @return
+ */
+uint32_t get_buffer_crc ( char* filebuffer, size_t size );
diff --git a/tools/firmware-utils/src/buffalo-enc.c b/tools/firmware-utils/src/buffalo-enc.c
index 13d270b3f73..08fad4ee61b 100644
--- a/tools/firmware-utils/src/buffalo-enc.c
+++ b/tools/firmware-utils/src/buffalo-enc.c
@@ -34,6 +34,8 @@ static unsigned char seed = 'O';
static char *product;
static char *version;
static int do_decrypt;
+static int offset;
+static int size;
void usage(int status)
{
@@ -52,6 +54,8 @@ void usage(int status)
" -p <product> set product name to <product>\n"
" -v <version> set version to <version>\n"
" -h show this screen\n"
+" -O Offset of encrypted data in file (decryption)\n"
+" -S Size of unencrypted data in file (encryption)\n"
);
exit(status);
@@ -85,8 +89,9 @@ static int decrypt_file(void)
memset(&ep, '\0', sizeof(ep));
ep.key = (unsigned char *) crypt_key;
+ ep.longstate = longstate;
- err = decrypt_buf(&ep, buf, src_len);
+ err = decrypt_buf(&ep, buf + offset, src_len - offset);
if (err) {
ERR("unable to decrypt '%s'", ifname);
goto out;
@@ -99,7 +104,7 @@ static int decrypt_file(void)
printf("Data len\t: %u\n", ep.datalen);
printf("Checksum\t: 0x%08x\n", ep.csum);
- err = write_buf_to_file(ofname, buf, ep.datalen);
+ err = write_buf_to_file(ofname, buf + offset, ep.datalen);
if (err) {
ERR("unable to write to file '%s'", ofname);
goto out;
@@ -115,7 +120,7 @@ out:
static int encrypt_file(void)
{
struct enc_param ep;
- ssize_t src_len;
+ ssize_t src_len, tail_dst, tail_len, tail_src;
unsigned char *buf;
uint32_t hdrlen;
ssize_t totlen = 0;
@@ -128,8 +133,12 @@ static int encrypt_file(void)
goto out;
}
- totlen = enc_compute_buf_len(product, version, src_len);
- hdrlen = enc_compute_header_len(product, version);
+ if (size) {
+ tail_dst = enc_compute_buf_len(product, version, size);
+ tail_len = src_len - size;
+ totlen = tail_dst + tail_len;
+ } else
+ totlen = enc_compute_buf_len(product, version, src_len);
buf = malloc(totlen);
if (buf == NULL) {
@@ -137,12 +146,21 @@ static int encrypt_file(void)
goto out;
}
+ hdrlen = enc_compute_header_len(product, version);
+
err = read_file_to_buf(ifname, &buf[hdrlen], src_len);
if (err) {
ERR("unable to read from file '%s'", ofname);
goto free_buf;
}
+ if (size) {
+ tail_src = hdrlen + size;
+ memmove(&buf[tail_dst], &buf[tail_src], tail_len);
+ memset(&buf[tail_src], 0, tail_dst - tail_src);
+ src_len = size;
+ }
+
memset(&ep, '\0', sizeof(ep));
ep.key = (unsigned char *) crypt_key;
ep.seed = seed;
@@ -238,7 +256,7 @@ int main(int argc, char *argv[])
while ( 1 ) {
int c;
- c = getopt(argc, argv, "adi:m:o:hp:v:k:r:s:");
+ c = getopt(argc, argv, "adi:m:o:hlp:v:k:O:r:s:S:");
if (c == -1)
break;
@@ -270,6 +288,12 @@ int main(int argc, char *argv[])
case 's':
seed = strtoul(optarg, NULL, 16);
break;
+ case 'O':
+ offset = strtoul(optarg, NULL, 0);
+ break;
+ case 'S':
+ size = strtoul(optarg, NULL, 0);
+ break;
case 'h':
usage(EXIT_SUCCESS);
break;
diff --git a/tools/firmware-utils/src/buffalo-lib.c b/tools/firmware-utils/src/buffalo-lib.c
index 29aee9f88dd..b1d5ede0a28 100644
--- a/tools/firmware-utils/src/buffalo-lib.c
+++ b/tools/firmware-utils/src/buffalo-lib.c
@@ -179,7 +179,7 @@ int bcrypt_buf(unsigned char seed, unsigned char *key, unsigned char *src,
uint32_t buffalo_csum(uint32_t csum, void *buf, unsigned long len)
{
- char *p = buf;
+ signed char *p = buf;
while (len--) {
int i;
@@ -249,10 +249,10 @@ static uint32_t get_be32(void *data)
static int check_magic(void *magic)
{
- if (!memcmp("start", magic, ENC_MAGIC_LEN));
+ if (!memcmp("start", magic, ENC_MAGIC_LEN))
return 0;
- if (!memcmp("asar1", magic, ENC_MAGIC_LEN));
+ if (!memcmp("asar1", magic, ENC_MAGIC_LEN))
return 0;
return -1;
diff --git a/tools/firmware-utils/src/buffalo-lib.h b/tools/firmware-utils/src/buffalo-lib.h
index ba8a5081294..7eb9bf53987 100644
--- a/tools/firmware-utils/src/buffalo-lib.h
+++ b/tools/firmware-utils/src/buffalo-lib.h
@@ -69,6 +69,26 @@ struct buffalo_tag2 {
uint8_t unknown2[3];
} __attribute ((packed));
+struct buffalo_tag3 {
+ unsigned char product[TAG_PRODUCT_LEN];
+ unsigned char brand[TAG_BRAND_LEN];
+ unsigned char ver_major[TAG_VERSION_LEN];
+ unsigned char ver_minor[TAG_VERSION_LEN];
+ unsigned char region_code[2];
+ uint32_t region_mask;
+ unsigned char unknown0[2];
+ unsigned char language[TAG_LANGUAGE_LEN];
+ unsigned char platform[TAG_PLATFORM_LEN];
+ unsigned char hwv[TAG_HWVER_LEN];
+ unsigned char hwv_val[TAG_HWVER_VAL_LEN];
+ uint8_t unknown1[24];
+
+ uint32_t total_len;
+ uint32_t crc;
+ uint32_t len1;
+ uint32_t base2;
+} __attribute ((packed));
+
#define ENC_PRODUCT_LEN 32
#define ENC_VERSION_LEN 8
#define ENC_MAGIC_LEN 6
diff --git a/tools/firmware-utils/src/buffalo-tag.c b/tools/firmware-utils/src/buffalo-tag.c
index b5db72ef968..6d479f7fba9 100644
--- a/tools/firmware-utils/src/buffalo-tag.c
+++ b/tools/firmware-utils/src/buffalo-tag.c
@@ -48,6 +48,7 @@ static uint32_t base2;
static char *region_code;
static uint32_t region_mask;
static int num_regions;
+static int dhp;
void usage(int status)
{
@@ -63,6 +64,7 @@ void usage(int status)
" -d <base2>\n"
" -f <flag> set flag to <flag>\n"
" -i <file> read input from the file <file>\n"
+" -I <file> read input from the file <file> for DHP series\n"
" -l <language> set language to <language>\n"
" -m <version> set minor version to <version>\n"
" -o <file> write output to the file <file>\n"
@@ -227,6 +229,37 @@ static void fixup_tag2(unsigned char *buf, ssize_t buflen)
tag->crc = htonl(buffalo_crc(buf, buflen));
}
+static void fixup_tag3(unsigned char *buf, ssize_t totlen)
+{
+ struct buffalo_tag3 *tag = (struct buffalo_tag3 *) buf;
+
+ memset(tag, '\0', sizeof(*tag));
+
+ memcpy(tag->brand, brand, strlen(brand));
+ memcpy(tag->product, product, strlen(product));
+ memcpy(tag->platform, platform, strlen(platform));
+ memcpy(tag->ver_major, major, strlen(major));
+ memcpy(tag->ver_minor, minor, strlen(minor));
+ memcpy(tag->language, language, strlen(language));
+
+ if (num_regions > 1) {
+ tag->region_code[0] = 'M';
+ tag->region_code[1] = '_';
+ tag->region_mask = htonl(region_mask);
+ } else {
+ memcpy(tag->region_code, region_code, 2);
+ }
+
+ tag->total_len = htonl(totlen);
+ tag->len1 = htonl(fsize[0]);
+ tag->base2 = htonl(base2);
+
+ if (hwver) {
+ memcpy(tag->hwv, "hwv", 3);
+ memcpy(tag->hwv_val, hwver, strlen(hwver));
+ }
+}
+
static int tag_file(void)
{
unsigned char *buf;
@@ -237,7 +270,9 @@ static int tag_file(void)
int ret = -1;
int i;
- if (num_files == 1)
+ if (dhp)
+ hdrlen = sizeof(struct buffalo_tag3);
+ else if (num_files == 1)
hdrlen = sizeof(struct buffalo_tag);
else
hdrlen = sizeof(struct buffalo_tag2);
@@ -270,7 +305,9 @@ static int tag_file(void)
offset += fsize[i];
}
- if (num_files == 1)
+ if (dhp)
+ fixup_tag3(buf, fsize[0] + 200);
+ else if (num_files == 1)
fixup_tag(buf, buflen);
else
fixup_tag2(buf, buflen);
@@ -299,7 +336,7 @@ int main(int argc, char *argv[])
while ( 1 ) {
int c;
- c = getopt(argc, argv, "a:b:c:d:f:hi:l:m:o:p:r:sv:w:");
+ c = getopt(argc, argv, "a:b:c:d:f:hi:l:m:o:p:r:sv:w:I:");
if (c == -1)
break;
@@ -319,6 +356,9 @@ int main(int argc, char *argv[])
case 'f':
flag = strtoul(optarg, NULL, 2);
break;
+ case 'I':
+ dhp = 1;
+ /* FALLTHROUGH */
case 'i':
err = process_ifname(optarg);
if (err)
diff --git a/tools/firmware-utils/src/buffalo-tftp.c b/tools/firmware-utils/src/buffalo-tftp.c
index 1a2551a41c7..087f9955b64 100644
--- a/tools/firmware-utils/src/buffalo-tftp.c
+++ b/tools/firmware-utils/src/buffalo-tftp.c
@@ -70,7 +70,6 @@ static int crypt_file(void)
{
unsigned char *buf = NULL;
ssize_t src_len;
- ssize_t crypt_len;
int err;
int ret = -1;
@@ -92,7 +91,6 @@ static int crypt_file(void)
goto out;
}
- crypt_len = (src_len > 512) ? 512 : src_len;
if (do_decrypt)
crypt_header(buf, 512, crypt_key2, crypt_key1);
else
diff --git a/tools/firmware-utils/src/csysimg.h b/tools/firmware-utils/src/csysimg.h
index 19dfbd4334c..65ab062f31e 100644
--- a/tools/firmware-utils/src/csysimg.h
+++ b/tools/firmware-utils/src/csysimg.h
@@ -49,6 +49,7 @@
#define SIG_BR6114WG SIG_BR6104IPC
#define SIG_BR6524K "2-K-"
#define SIG_BR6524KP "2-KP" /* FIXME: valid? */
+#define SIG_BR6524N "WNRA"
#define SIG_BR6524WG "2-WG" /* FIXME: valid? */
#define SIG_BR6524WP "2-WP" /* FIXME: valid? */
#define SIG_BR6541K "4--K"
diff --git a/tools/firmware-utils/src/dgfirmware.c b/tools/firmware-utils/src/dgfirmware.c
index 5ff3b69646d..e3257f10779 100644
--- a/tools/firmware-utils/src/dgfirmware.c
+++ b/tools/firmware-utils/src/dgfirmware.c
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#define IMG_SIZE 0x3e0000
diff --git a/tools/firmware-utils/src/dgn3500sum.c b/tools/firmware-utils/src/dgn3500sum.c
new file mode 100644
index 00000000000..eb80e6c01b0
--- /dev/null
+++ b/tools/firmware-utils/src/dgn3500sum.c
@@ -0,0 +1,166 @@
+/* **************************************************************************
+
+ This program creates a modified 16bit checksum used for the Netgear
+ DGN3500 series routers. The difference between this and a standard
+ checksum is that every 0x100 bytes added 0x100 have to be subtracted
+ from the sum.
+
+ (C) 2013 Marco Antonio Mauro <marcus90 at gmail.com>
+
+ Based on previous unattributed work.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ ************************************************************************* */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+unsigned char PidDataWW[70] =
+{
+ 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
+ 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
+} ;
+
+unsigned char PidDataDE[70] =
+{
+ 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
+ 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
+} ;
+
+unsigned char PidDataNA[70] =
+{
+ 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
+ 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
+} ;
+
+/* *******************************************************************
+ Reads the file into memory and returns pointer to the buffer. */
+static char *readfile(char *filename, int *size)
+{
+ FILE *fp;
+ char *buffer;
+ struct stat info;
+
+ if (stat(filename,&info)!=0)
+ return NULL;
+
+ if ((fp=fopen(filename,"r"))==NULL)
+ return NULL;
+
+ buffer=NULL;
+ for (;;)
+ {
+ if ((buffer=(char *)malloc(info.st_size+1))==NULL)
+ break;
+
+ if (fread(buffer,1,info.st_size,fp)!=info.st_size)
+ {
+ free(buffer);
+ buffer=NULL;
+ break;
+ }
+
+ buffer[info.st_size]='\0';
+ if(size) *size = info.st_size;
+
+ break;
+ }
+
+ (void)fclose(fp);
+
+ return buffer;
+}
+
+
+/* ******************************************************************* */
+int main(int argc, char** argv)
+{
+ unsigned long start, i;
+ char *endptr, *buffer, *p;
+ int count; // size of file in bytes
+ unsigned short sum = 0, sum1 = 0;
+ char sumbuf[9];
+
+ if(argc < 3) {
+ printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]);
+ return 1;
+ }
+
+
+ FILE *fp = fopen(argv[1], "a");
+ if(!fp) {
+ printf("ERROR: File not writeable!\n");
+ return 1;
+ }
+ if(argc == 4)
+ {
+ printf("%s: PID type: %s\n", argv[0], argv[3]);
+ if(strcmp(argv[3], "DE")==0)
+ fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */
+ else if(strcmp(argv[3], "NA")==0)
+ fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */
+ else /* if(strcmp(argv[3], "WW")) */
+ fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */
+ }
+ else
+ fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */
+
+ fclose(fp);
+
+ /* Read the file to calculate the checksums */
+ buffer = readfile(argv[1], &count);
+ if(!buffer) {
+ printf("ERROR: File %s not found!\n", argv[1]);
+ return 1;
+ }
+
+ p = buffer;
+ for(i = 0; i < count; i++)
+ {
+ sum += p[i];
+ }
+
+ start = strtol(argv[2], &endptr, 16);
+ p = buffer+start;
+ for(i = 0; i < count - start; i++)
+ {
+ sum1 += p[i];
+ }
+
+ sprintf(sumbuf,"%04X%04X",sum1,sum);
+ /* Append the 2 checksums to end of file */
+ fp = fopen(argv[1], "a");
+ if(!fp) {
+ printf("ERROR: File not writeable!\n");
+ return 1;
+ }
+ fwrite(sumbuf, 8, sizeof(char), fp);
+ fclose(fp);
+ free(buffer);
+ return 0;
+}
diff --git a/tools/firmware-utils/src/dns313-header.c b/tools/firmware-utils/src/dns313-header.c
new file mode 100644
index 00000000000..e69e57e7baa
--- /dev/null
+++ b/tools/firmware-utils/src/dns313-header.c
@@ -0,0 +1,239 @@
+/*
+ * dns313-header.c
+ *
+ * Program to add the modified U-Boot header to a binary used with
+ * the D-Link DNS-313 boot loader when booting directly from an
+ * EXT2 formatted hard drive.
+ *
+ * The DNS313 use the same header on zImage, ramdisk, rootfs.
+ *
+ * Written by Linus Walleij <linus.walleij@linaro.org>
+ * License terms: GPLv2
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/*
+ * This is the U-Boot magic number, so the U-Boot header was used
+ * (obviously) as a template for this custom header.
+ */
+#define IH_MAGIC 0x27051956
+#define HEADER_SIZE 0x68
+
+#define OFFSET_MAGIC 0x00
+#define OFFSET_HCRC 0x04
+#define OFFSET_TIME 0x08
+#define OFFSET_SIZE 0x0c
+#define OFFSET_LOAD 0x10
+#define OFFSET_EP 0x14
+#define OFFSET_DCRC 0x18
+#define OFFSET_OS 0x1c
+#define OFFSET_ARCH 0x1d
+#define OFFSET_TYPE 0x1e
+#define OFFSET_COMP 0x1f
+#define OFFSET_NAME 0x20
+#define NAME_LEN 0x20
+#define OFFSET_MODEL 0x40
+#define MODEL_LEN 0x10
+#define OFFSET_VERSION 0x50
+#define VERSION_LEN 0x10
+#define OFFSET_MAC 0x60
+#define MAC_LEN 6
+
+static const uint32_t crc32_table[256] = {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+};
+
+static uint32_t crc32(uint32_t crc,
+ const unsigned char *buf,
+ unsigned int len)
+{
+ crc = crc ^ 0xffffffffUL;
+ do {
+ crc = crc32_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+static void be_wr(unsigned char *buf, uint32_t val)
+{
+ buf[0] = (val >> 24) & 0xFFU;
+ buf[1] = (val >> 16) & 0xFFU;
+ buf[2] = (val >> 8) & 0xFFU;
+ buf[3] = val & 0xFFU;
+}
+
+int main(int argc, char **argv)
+{
+ int fdin;
+ int fdout;
+ struct stat sb;
+ uint32_t filesize;
+ uint32_t padding;
+ int ret = 0;
+ const char *pathin;
+ const char *pathout;
+ unsigned char *buffer;
+ unsigned char *infop;
+ uint32_t sum;
+ size_t bufsize;
+ size_t bytes;
+ int i;
+
+ if (argc < 3) {
+ printf("Too few arguments.\n");
+ printf("%s <infile> <outfile>\n", argv[0]);
+ }
+
+ pathin = argv[1];
+ pathout = argv[2];
+
+ ret = stat(pathin, &sb);
+ if (ret < 0)
+ return ret;
+
+ filesize = sb.st_size;
+ padding = filesize % 4;
+ printf("INFILE: %s, size: %08x bytes\n", pathin, filesize);
+ /* File + extended header size */
+ bufsize = filesize + HEADER_SIZE;
+
+ printf("Allocate %08x bytes\n", bufsize);
+ buffer = malloc(bufsize);
+ if (!buffer) {
+ printf("OOM: could not allocate buffer\n");
+ return 0;
+ }
+
+ memset(buffer, 0x00, bufsize);
+
+ /* Read file to buffer */
+ fdin = open(pathin, O_RDONLY);
+ if (!fdin) {
+ printf("ERROR: could not open input file\n");
+ return 0;
+ }
+ bytes = read(fdin, buffer + HEADER_SIZE, filesize);
+ if (bytes < filesize) {
+ printf("ERROR: could not read entire file\n");
+ return 0;
+ }
+ close(fdin);
+
+ /* PREP HEADER AND FOOTER */
+ infop = buffer;
+
+ be_wr(buffer + OFFSET_MAGIC, IH_MAGIC);
+
+ /* FIXME: use actual time */
+ be_wr(buffer + OFFSET_TIME, 0x4c06738c);
+ be_wr(buffer + OFFSET_SIZE, filesize);
+
+ /* Load address & entry point */
+ be_wr(buffer + OFFSET_LOAD, 0x00008000);
+ be_wr(buffer + OFFSET_EP, 0x00008000);
+
+ buffer[OFFSET_OS] = 0x05; /* Linux */
+ buffer[OFFSET_ARCH] = 0x02; /* ARM */
+ buffer[OFFSET_TYPE] = 0x02; /* OS kernel image */
+ buffer[OFFSET_COMP] = 0x01; /* gzip */
+
+ /* The vendor firmware just hardcodes this */
+ strncpy(buffer + OFFSET_NAME, "kernel.img", NAME_LEN);
+ buffer[OFFSET_NAME + NAME_LEN - 1] = '\0';
+ strncpy(buffer + OFFSET_MODEL, "dns-313v3", MODEL_LEN);
+ buffer[OFFSET_MODEL + MODEL_LEN - 1] = '\0';
+ strncpy(buffer + OFFSET_VERSION, "2.01b04", VERSION_LEN);
+ buffer[OFFSET_VERSION + VERSION_LEN - 1] = '\0';
+ /* Just some MAC address from the example */
+ buffer[OFFSET_MAC] = 0x00;
+ buffer[OFFSET_MAC + 1] = 0x80;
+ buffer[OFFSET_MAC + 2] = 0xc8;
+ buffer[OFFSET_MAC + 3] = 0x16;
+ buffer[OFFSET_MAC + 4] = 0x81;
+ buffer[OFFSET_MAC + 5] = 0x68;
+
+ /* Checksum payload */
+ sum = crc32(0, buffer + HEADER_SIZE, filesize);
+ be_wr(buffer + OFFSET_DCRC, sum);
+ printf("data checksum: 0x%08x\n", sum);
+
+ /* Checksum header, then write that into the header checksum */
+ sum = crc32(0, buffer, HEADER_SIZE);
+ be_wr(buffer + OFFSET_HCRC, sum);
+ printf("header checksum: 0x%08x\n", sum);
+
+ printf("OUTFILE: %s, size: %08x bytes\n", pathout, bufsize);
+ fdout = open(pathout, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP);
+ if (!fdout) {
+ printf("ERROR: could not open output file\n");
+ return 0;
+ }
+ bytes = write(fdout, buffer, bufsize);
+ if (bytes < bufsize) {
+ printf("ERROR: could not write complete output file\n");
+ return 0;
+ }
+ close(fdout);
+
+ free(buffer);
+
+ return 0;
+}
diff --git a/tools/firmware-utils/src/edimax_fw_header.c b/tools/firmware-utils/src/edimax_fw_header.c
new file mode 100644
index 00000000000..b85e3a1781c
--- /dev/null
+++ b/tools/firmware-utils/src/edimax_fw_header.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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>
+
+#define MAX_MAGIC_LEN 16
+#define MAX_MODEL_LEN 32
+#define MAX_VERSION_LEN 14
+#define MAX_MTD_NAME_LEN 16
+
+#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+
+struct edimax_header {
+ char magic[MAX_MAGIC_LEN];
+ char model[MAX_MODEL_LEN];
+ unsigned char force;
+ unsigned char header_csum;
+ unsigned char data_csum;
+ uint32_t data_size;
+ uint32_t start_addr;
+ uint32_t end_addr;
+ char fw_version[MAX_VERSION_LEN];
+ unsigned char type;
+ char mtd_name[MAX_MTD_NAME_LEN];
+} __attribute__ ((packed));
+
+/*
+ * Globals
+ */
+static char *ofname;
+static char *ifname;
+static char *progname;
+
+static char *model;
+static char *magic = "eDiMaX";
+static char *fw_version = "";
+static char *mtd_name;
+static int force;
+static uint32_t start_addr;
+static uint32_t end_addr;
+static uint8_t image_type;
+static int data_size;
+
+/*
+ * 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 " (%s)\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
+} while (0)
+
+static void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -e <addr> set end addr to <addr>\n"
+" -f set force flag\n"
+" -h show this screen\n"
+" -i <file> read input data from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -m <model> set model to <model>\n"
+" -M <magic> set image magic to <magic>\n"
+" -n <name> set MTD device name to <name>\n"
+" -s <addr> set start address to <addr>\n"
+" -t <type> set image type to <type>\n"
+" -v <version> set firmware version to <version>\n"
+ );
+
+ exit(status);
+}
+
+int
+str2u32(char *arg, uint32_t *val)
+{
+ char *err = NULL;
+ uint32_t t;
+
+ errno=0;
+ t = strtoul(arg, &err, 0);
+ if (errno || (err==arg) || ((err != NULL) && *err)) {
+ return -1;
+ }
+
+ *val = t;
+ return 0;
+}
+
+int
+str2u8(char *arg, uint8_t *val)
+{
+ char *err = NULL;
+ uint32_t t;
+
+ errno=0;
+ t = strtoul(arg, &err, 0);
+ if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) {
+ return -1;
+ }
+
+ *val = t & 0xFF;
+ return 0;
+}
+
+static int get_file_size(char *name)
+{
+ struct stat st;
+ int res;
+
+ res = stat(name, &st);
+ if (res){
+ ERRS("stat failed on %s", name);
+ return -1;
+ }
+
+ return st.st_size;
+}
+
+static int read_to_buf(char *name, char *buf, int buflen)
+{
+ FILE *f;
+ int ret = EXIT_FAILURE;
+
+ f = fopen(name, "r");
+ if (f == NULL) {
+ ERRS("could not open \"%s\" for reading", name);
+ goto out;
+ }
+
+ errno = 0;
+ fread(buf, buflen, 1, f);
+ if (errno != 0) {
+ ERRS("unable to read from file \"%s\"", name);
+ goto out_close;
+ }
+
+ ret = EXIT_SUCCESS;
+
+out_close:
+ fclose(f);
+out:
+ return ret;
+}
+
+static int check_options(void)
+{
+#define CHKSTR(_name, _msg) \
+ do { \
+ if (_name == NULL) { \
+ ERR("no %s specified", _msg); \
+ return -1; \
+ } \
+ } while (0)
+
+#define CHKSTRLEN(_name, _msg) \
+ do { \
+ int field_len; \
+ CHKSTR(_name, _msg); \
+ field_len = FIELD_SIZEOF(struct edimax_header, _name) - 1; \
+ if (strlen(_name) > field_len) { \
+ ERR("'%s' is too long, max %s length is %d", \
+ _name, _msg, field_len); \
+ return -1; \
+ } \
+ } while (0)
+
+ CHKSTR(ofname, "output file");
+ CHKSTR(ifname, "input file");
+
+ CHKSTRLEN(magic, "magic");
+ CHKSTRLEN(model, "model");
+ CHKSTRLEN(mtd_name, "MTD device name");
+ CHKSTRLEN(fw_version, "firware version");
+
+ data_size = get_file_size(ifname);
+ if (data_size < 0)
+ return -1;
+
+ return 0;
+}
+
+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 unsigned char checksum(unsigned char *p, unsigned len)
+{
+ unsigned char csum = 0;
+
+ while (len--)
+ csum += *p++;
+
+ csum ^= 0xb9;
+
+ return csum;
+}
+
+static int build_fw(void)
+{
+ int buflen;
+ char *buf;
+ char *data;
+ struct edimax_header *hdr;
+ int ret = EXIT_FAILURE;
+
+ buflen = sizeof(struct edimax_header) + data_size;
+
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ data = buf + sizeof(struct edimax_header);
+
+ /* read input file */
+ ret = read_to_buf(ifname, data, data_size);
+ if (ret)
+ goto out_free_buf;
+
+ /* fill firmware header */
+ hdr = (struct edimax_header *)buf;
+ memset(hdr, 0, sizeof(struct edimax_header));
+
+ strncpy(hdr->model, model, sizeof(hdr->model));
+ strncpy(hdr->magic, magic, sizeof(hdr->magic));
+ strncpy(hdr->fw_version, fw_version, sizeof(hdr->fw_version));
+ strncpy(hdr->mtd_name, mtd_name, sizeof(hdr->mtd_name));
+
+ hdr->force = force;
+ hdr->start_addr = htonl(start_addr);
+ hdr->end_addr = htonl(end_addr);
+ hdr->data_size = htonl(data_size);
+ hdr->type = image_type;
+
+ hdr->data_csum = checksum((unsigned char *)data, data_size);
+ hdr->header_csum = checksum((unsigned char *)hdr,
+ sizeof(struct edimax_header));
+
+ ret = write_fw(buf, buflen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+out_free_buf:
+ free(buf);
+out:
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "e:fhi:o:m:M:n:s:t:v:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'e':
+ if (str2u32(optarg, &end_addr)) {
+ ERR("%s is invalid '%s'",
+ "end address", optarg);
+ goto out;
+ }
+ break;
+ case 'f':
+ force = 1;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 'm':
+ model = optarg;
+ break;
+ case 'M':
+ magic = optarg;
+ break;
+ case 'n':
+ mtd_name = optarg;
+ break;
+ case 's':
+ if (str2u32(optarg, &start_addr)) {
+ ERR("%s is invalid '%s'",
+ "start address", optarg);
+ goto out;
+ }
+ break;
+ case 't':
+ if (str2u8(optarg, &image_type)) {
+ ERR("%s is invalid '%s'",
+ "image type", optarg);
+ goto out;
+ }
+ break;
+ case 'v':
+ fw_version = optarg;
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret)
+ goto out;
+
+ ret = build_fw();
+
+out:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/fix-u-media-header.c b/tools/firmware-utils/src/fix-u-media-header.c
new file mode 100644
index 00000000000..21f184e66da
--- /dev/null
+++ b/tools/firmware-utils/src/fix-u-media-header.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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 "cyg_crc.h"
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define IH_MAGIC 0x27051956 /* Image Magic Number */
+#define IH_NMLEN 32 /* Image Name Length */
+
+#define UM_MAGIC 0x55525F46
+#define UM_HEADER_LEN 12
+
+/*
+ * all data in network byte order (aka natural aka bigendian)
+ */
+struct u_media_header {
+ uint32_t ih_magic; /* Image Header Magic Number */
+ uint32_t ih_hcrc; /* Image Header CRC Checksum */
+ uint32_t ih_time; /* Image Creation Timestamp */
+ uint32_t ih_size; /* Image Data Size */
+ uint32_t ih_load; /* Data Load Address */
+ uint32_t ih_ep; /* Entry Point Address */
+ uint32_t ih_dcrc; /* Image Data CRC Checksum */
+ uint8_t ih_os; /* Operating System */
+ uint8_t ih_arch; /* CPU architecture */
+ uint8_t ih_type; /* Image Type */
+ uint8_t ih_comp; /* Compression Type */
+ uint8_t ih_name[IH_NMLEN - UM_HEADER_LEN]; /* Image Name */
+
+ uint32_t ih_UMedia_magic; /* U-Media magic number */
+ uint32_t ih_UMedia_boardID; /* U-Media board ID */
+ uint8_t ih_UMedia_imageType; /* U-Media image type */
+ uint8_t ih_UMedia_LoadDefault; /* U-Media load to factory default setting */
+ uint8_t ih_UMedia_temp1; /* U-Media didn't use this tag */
+ uint8_t ih_UMedia_temp2; /* U-Media didn't use this tag */
+} __attribute__ ((packed));
+
+struct if_info {
+ char *file_name; /* name of the file */
+ uint32_t file_size; /* length of the file */
+};
+
+static char *progname;
+static char *ofname;
+static struct if_info if_info;
+static int factory_defaults;
+static uint32_t board_id;
+static uint8_t image_type;
+
+/*
+ * 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 " (%s)\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
+} while (0)
+
+static void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -B <board_id> set board ID to <board_id>\n"
+" -i <file> read input from the file <file>\n"
+" -F load factory defaults\n"
+" -o <file> write output to the file <file>\n"
+" -T <type> set image type to <type>\n"
+" -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+static int str2u32(char *arg, uint32_t *val)
+{
+ char *err = NULL;
+ uint32_t t;
+
+ errno=0;
+ t = strtoul(arg, &err, 0);
+ if (errno || (err==arg) || ((err != NULL) && *err)) {
+ return -1;
+ }
+
+ *val = t;
+ return 0;
+}
+
+static int str2u8(char *arg, uint8_t *val)
+{
+ char *err = NULL;
+ uint32_t t;
+
+ errno=0;
+ t = strtoul(arg, &err, 0);
+ if (errno || (err==arg) || ((err != NULL) && *err)) {
+ return -1;
+ }
+
+ if (t > 255)
+ return -1;
+
+ *val = t;
+ return 0;
+}
+
+static int get_file_stat(struct if_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 if_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 (ofname == NULL) {
+ ERR("no %s specified", "output file");
+ return -1;
+ }
+
+ if (if_info.file_name == NULL) {
+ ERR("no %s specified", "input file");
+ return -1;
+ }
+
+ ret = get_file_stat(&if_info);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+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;
+ }
+
+ ret = EXIT_SUCCESS;
+
+out_flush:
+ fflush(f);
+ fclose(f);
+ if (ret != EXIT_SUCCESS) {
+ unlink(ofname);
+ }
+out:
+ return ret;
+}
+
+static int fix_header(void)
+{
+ int buflen;
+ char *buf;
+ uint32_t crc, crc_orig;
+ struct u_media_header *hdr;
+ int ret = EXIT_FAILURE;
+
+ buflen = if_info.file_size;
+ if (buflen < sizeof(*hdr)) {
+ ERR("invalid input file\n");
+ return ret;
+ }
+
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ ret = read_to_buf(&if_info, buf);
+ if (ret)
+ goto out_free_buf;
+
+ hdr = (struct u_media_header *) buf;
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+ ERR("invalid input file, bad magic\n");
+ goto out_free_buf;
+ }
+
+ /* verify header CRC */
+ crc_orig = ntohl(hdr->ih_hcrc);
+ hdr->ih_hcrc = 0;
+ crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr));
+ if (crc != crc_orig) {
+ ERR("invalid input file, bad header CRC\n");
+ goto out_free_buf;
+ }
+
+ hdr->ih_name[IH_NMLEN - UM_HEADER_LEN - 1] = '\0';
+
+ /* set U-Media specific fields */
+ hdr->ih_UMedia_magic = htonl(UM_MAGIC);
+ hdr->ih_UMedia_boardID = htonl(board_id);
+ hdr->ih_UMedia_imageType = image_type;
+ hdr->ih_UMedia_LoadDefault = (factory_defaults) ? 1 : 0;
+
+ /* update header CRC */
+ crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr));
+ hdr->ih_hcrc = htonl(crc);
+
+ ret = write_fw(buf, buflen);
+ if (ret)
+ goto out_free_buf;
+
+ DBG("U-Media header fixed in \"%s\"", ofname);
+
+ ret = EXIT_SUCCESS;
+
+out_free_buf:
+ free(buf);
+out:
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "B:Fi:o:T:h");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ if (str2u32(optarg, &board_id)) {
+ ERR("%s is invalid '%s'",
+ "board ID", optarg);
+ goto out;
+ }
+ break;
+ case 'T':
+ if (str2u8(optarg, &image_type)) {
+ ERR("%s is invalid '%s'",
+ "image type", optarg);
+ goto out;
+ }
+ break;
+ case 'F':
+ factory_defaults = 1;
+ break;
+ case 'i':
+ if_info.file_name = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret)
+ goto out;
+
+ ret = fix_header();
+
+out:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/hcsmakeimage.c b/tools/firmware-utils/src/hcsmakeimage.c
new file mode 100644
index 00000000000..7baa7b5845e
--- /dev/null
+++ b/tools/firmware-utils/src/hcsmakeimage.c
@@ -0,0 +1,203 @@
+#include <stdlib.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <libgen.h>
+#include "bcmalgo.h"
+
+
+int flag_print_version;
+int flag_print_help;
+int flag_compress;
+
+uint16_t sa2100_magic = 0x2100;
+uint16_t sa3349_magic = 0x3349;
+uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away....
+uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image
+
+static void print_help ( const char* ename )
+{
+ printf ( "Firmware image packer and calculator for broadcom-based modems.\n" );
+ printf ( "Part of bcm-utils package.\n" );
+ printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" );
+ printf ( "usage: %s [options]\n", ename );
+ printf ( "Valid options are:\n" );
+ printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" );
+ printf ( "\t\t\t these can be sa2100 (for DPC2100 modem),\n\t\t\t sa3349 (haxorware guys use this one for some reason),\n\t\t\t or a custom hex value e.g. 0xFFFF\n" );
+ printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" );
+ printf ( "--rev_maj=value\t\t - major revision number. default 0\n" );
+ printf ( "--rev_min=value\t\t - minor revision number default 0\n" );
+ printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" );
+ printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" );
+ printf ( "--input_file=value\t - What file are we packing?\n" );
+ printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" );
+#ifdef _HAX0RSTYLE
+ printf ( "--credz\t - Give some credz!\n" );
+#endif
+ printf ( "\n" );
+}
+
+static time_t source_date_epoch = -1;
+static void set_source_date_epoch() {
+ char *env = getenv("SOURCE_DATE_EPOCH");
+ char *endptr = env;
+ errno = 0;
+ if (env && *env) {
+ source_date_epoch = strtoull(env, &endptr, 10);
+ if (errno || (endptr && *endptr != '\0')) {
+ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
+ exit(1);
+ }
+ }
+}
+
+int main ( int argc, char** argv )
+{
+ if ( argc<2 )
+ {
+ print_help ( argv[0] );
+ }
+
+ static struct option long_options[] =
+ {
+ {"magic_bytes", required_argument, 0, 'm'},
+ {"rev_maj", required_argument, 0, 'j'},
+ {"rev_min", required_argument, 0, 'n'},
+ {"ldaddress", required_argument, 0, 'l'},
+ {"filename", required_argument, 0, 'f'},
+ {"input_file", required_argument, 0, 'i'},
+ {"output_file", required_argument, 0, 'o'},
+ {"compress", no_argument, &flag_compress, 'c'},
+ {"version", no_argument, &flag_print_version, 'v'},
+ {"help", no_argument, &flag_print_help, 'h'},
+ {0, 0, 0, 0}
+ };
+ int option_index = 0;
+ int opt_result=0;
+ char* filename=NULL;
+ char* input=NULL;
+ char* magic=NULL;
+ char* major=NULL;
+ char* minor=NULL;
+ char* ldaddr=NULL;
+ char* output=NULL;
+
+ while ( opt_result>=0 )
+ {
+ opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index );
+ switch ( opt_result )
+ {
+ case 0:
+ printf ( "o!\n" );
+ break;
+ case 'h':
+ print_help ( argv[0] );
+ break;
+ case 'l':
+ ldaddr=optarg;
+ break;
+ case 'f':
+ filename=optarg;
+ break;
+ case 'i':
+ input=optarg;
+ break;
+ case 'o':
+ output=optarg;
+ break;
+ case 'm':
+ magic=optarg;
+ break;
+ case 'j':
+ major=optarg;
+ break;
+ case 'n':
+ minor=optarg;
+ break;
+ }
+ }
+ if ( input==NULL )
+ {
+ printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" );
+ exit ( 1 );
+ }
+ if ( access ( input,R_OK ) !=0 )
+ {
+ printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input );
+ exit ( 1 );
+ }
+ uint32_t magicnum=sa2100_magic;
+
+ if ( magic )
+ {
+ if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else
+ if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else
+ {
+ sscanf ( magic, "0x%04X", &magicnum );
+ }
+ }
+ unsigned int majrev=0;
+ if ( major )
+ {
+ sscanf ( major, "%d", &majrev );
+ }
+ unsigned int minrev=0;
+ if ( minor )
+ {
+ sscanf ( minor, "%d", &minrev );
+ }
+ uint32_t ldaddress = default_load_address;
+ if ( ldaddr )
+ {
+ sscanf ( ldaddr, "0x%08X", &ldaddress );
+ }
+ char* dupe = strdup(input);
+ char* fname = basename ( dupe );
+ if ( filename )
+ {
+ fname = filename;
+ }
+
+ time_t t = -1;
+ set_source_date_epoch();
+ if (source_date_epoch != -1) {
+ t = source_date_epoch;
+ } else if ((time(&t) == (time_t)(-1))) {
+ fprintf(stderr, "time call failed\n");
+ return EXIT_FAILURE;
+ }
+
+ struct stat buf;
+ stat ( input,&buf );
+ ldr_header_t* head = construct_header ( magicnum, (uint16_t) majrev, (uint16_t) minrev, ( uint32_t ) t, ( uint32_t ) buf.st_size, ldaddress, fname, get_file_crc ( input ) );
+ free(dupe);
+ //uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc
+ //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r");
+ //fread(head,sizeof(ldr_header_t),1,fd);
+ char* filebuffer = malloc ( buf.st_size+10 );
+ FILE* fd = fopen ( input,"r" );
+ fread ( filebuffer, 1, buf.st_size,fd );
+ if (!output)
+ {
+ output = malloc(strlen(input+5));
+ strcpy(output,input);
+ strcat(output,".bin");
+ }
+ dump_header ( head );
+ FILE* fd_out = fopen ( output,"w+" );
+ if (!fd_out)
+ {
+ fprintf(stderr, "Failed to open output file: %s\n", output);
+ exit(1);
+ }
+ fwrite ( head,1,sizeof ( ldr_header_t ),fd_out );
+ fwrite ( filebuffer,1,buf.st_size,fd_out );
+ printf("Firmware image %s is ready\n", output);
+ return 0;
+}
diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c
index bebaba2f29d..bc70399ccaa 100644
--- a/tools/firmware-utils/src/imagetag.c
+++ b/tools/firmware-utils/src/imagetag.c
@@ -11,13 +11,14 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
-#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <netinet/in.h>
+#include <inttypes.h>
#include "bcm_tag.h"
#include "imagetag_cmdline.h"
+#include "cyg_crc.h"
#define DEADCODE 0xDEADC0DE
@@ -30,54 +31,11 @@ struct kernelhdr {
static char pirellitab[NUM_PIRELLI][BOARDID_LEN] = PIRELLI_BOARDS;
-static uint32_t crc32tab[256] = {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-};
-
void int2tag(char *tag, uint32_t value) {
uint32_t network = htonl(value);
memcpy(tag, (char *)(&network), 4);
}
-uint32_t crc32(uint32_t crc, uint8_t *data, size_t len)
-{
- while (len--)
- crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF];
-
- return crc;
-}
-
uint32_t compute_crc32(uint32_t crc, FILE *binfile, size_t compute_start, size_t compute_len)
{
uint8_t readbuf[1024];
@@ -88,14 +46,14 @@ uint32_t compute_crc32(uint32_t crc, FILE *binfile, size_t compute_start, size_t
/* read block of 1024 bytes */
while (binfile && !feof(binfile) && !ferror(binfile) && (compute_len >= sizeof(readbuf))) {
read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), binfile);
- crc = crc32(crc, readbuf, read);
+ crc = cyg_crc32_accumulate(crc, readbuf, read);
compute_len = compute_len - read;
}
/* Less than 1024 bytes remains, read compute_len bytes */
if (binfile && !feof(binfile) && !ferror(binfile) && (compute_len > 0)) {
read = fread(readbuf, sizeof(uint8_t), compute_len, binfile);
- crc = crc32(crc, readbuf, read);
+ crc = cyg_crc32_accumulate(crc, readbuf, read);
}
return crc;
@@ -125,7 +83,8 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
struct kernelhdr khdr;
FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile = NULL, *cfefile = NULL;
size_t cfeoff, cfelen, kerneloff, kernellen, rootfsoff, rootfslen, \
- read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen;
+ read, imagelen, rootfsoffpadlen = 0, kernelfslen, kerneloffpadlen = 0, oldrootfslen, \
+ rootfsend;
uint8_t readbuf[1024];
uint32_t imagecrc = IMAGETAG_CRC_START;
uint32_t kernelcrc = IMAGETAG_CRC_START;
@@ -199,11 +158,19 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
kernellen += sizeof(khdr);
}
- /* Build the rootfs address and length (start and end do need to be aligned on flash erase block boundaries */
+ /* Build the rootfs address and length */
rootfsoff = kerneloff + kernellen;
- rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff;
- rootfslen = getlen(rootfsfile);
- rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen );
+ /* align the start if requested */
+ if (args->align_rootfs_flag)
+ rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff;
+ else
+ rootfsoff = (rootfsoff % 4) > 0 ? (((rootfsoff / 4) + 1) * 4) : rootfsoff;
+
+ /* align the end */
+ rootfsend = rootfsoff + getlen(rootfsfile);
+ if ((rootfsend % block_size) > 0)
+ rootfsend = (((rootfsend / block_size) + 1) * block_size);
+ rootfslen = rootfsend - rootfsoff;
imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode);
rootfsoffpadlen = rootfsoff - (kerneloff + kernellen);
@@ -231,6 +198,19 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET);
fwrite(&deadcode, sizeof(uint32_t), 1, binfile);
+ oldrootfslen = rootfslen;
+ if (args->pad_given) {
+ uint32_t allfs = 0xffffffff;
+ uint32_t pad_size = args->pad_arg * 1024 * 1024;
+
+ printf("Padding image to %d bytes ...\n", pad_size);
+ while (imagelen < pad_size) {
+ fwrite(&allfs, sizeof(uint32_t), 1, binfile);
+ imagelen += 4;
+ rootfslen += 4;
+ }
+ }
+
/* Flush the binfile buffer so that when we read from file, it contains
* everything in the buffer
*/
@@ -260,6 +240,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
rootfslen = oldrootfslen;
rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen );
kerneloffpadlen = rootfslen - oldrootfslen;
+ oldrootfslen = rootfslen;
kerneloff = rootfsoff + rootfslen;
kernellen = getlen(kernelfile);
@@ -325,7 +306,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
sprintf(tag.totalLength, "%lu", imagelen);
if (args->cfe_given) {
- sprintf(tag.cfeAddress, "%lu", flash_start);
+ sprintf(tag.cfeAddress, "%" PRIu32, flash_start);
sprintf(tag.cfeLength, "%lu", cfelen);
} else {
/* We don't include CFE */
@@ -343,7 +324,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
sprintf(tag.flashImageStart, "%lu", kerneloff);
sprintf(tag.flashRootLength, "%lu", rootfslen + sizeof(deadcode));
}
- int2tag(tag.rootLength, rootfslen + sizeof(deadcode));
+ int2tag(tag.rootLength, oldrootfslen + sizeof(deadcode));
if (args->rsa_signature_given) {
strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN);
@@ -366,7 +347,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
}
if (args->altinfo_given) {
- strncpy(&tag.information1[0], args->altinfo_arg, ALTTAGINFO_LEN);
+ strncpy(tag.information1, args->altinfo_arg, TAGINFO1_LEN);
}
if (args->second_image_flag_given) {
@@ -397,7 +378,7 @@ int tagfile(const char *kernel, const char *rootfs, const char *bin, \
int2tag(&(tag.rootfsCRC[0]), rootfscrc);
int2tag(tag.kernelCRC, kernelcrc);
int2tag(tag.fskernelCRC, kernelfscrc);
- int2tag(tag.headerCRC, crc32(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20));
+ int2tag(tag.headerCRC, cyg_crc32_accumulate(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20));
fseek(binfile, 0L, SEEK_SET);
fwrite(&tag, sizeof(uint8_t), sizeof(tag), binfile);
@@ -418,7 +399,7 @@ int main(int argc, char **argv)
kernel = rootfs = bin = NULL;
- if (cmdline_parser(argc, argv, &parsed_args)) {
+ if (imagetag_cmdline(argc, argv, &parsed_args)) {
exit(1);
}
@@ -483,6 +464,14 @@ int main(int argc, char **argv)
exit(1);
}
}
+
+ if (parsed_args.pad_given) {
+ if (parsed_args.pad_arg < 0) {
+ fprintf(stderr, "Error: pad size must be positive.\r");
+ exit(1);
+ }
+ }
+
flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16);
image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16);
block_size = strtoul(parsed_args.block_size_arg, NULL, 16);
diff --git a/tools/firmware-utils/src/imagetag.ggo b/tools/firmware-utils/src/imagetag.ggo
index 7e8e7d90e32..73184852935 100644
--- a/tools/firmware-utils/src/imagetag.ggo
+++ b/tools/firmware-utils/src/imagetag.ggo
@@ -42,3 +42,5 @@ option "second-image-flag" - "Dual Image Flag (2=not-specified)." values="0", "1
option "inactive" - "Inactive Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional
option "reserved2" - "String for second reserved section." string optional
option "kernel-file-has-header" - "Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed" flag off
+option "pad" p "Pad the image to this size if smaller (in MiB)" int typestr="size (in MiB)" optional
+option "align-rootfs" - "Align the rootfs start to erase block size" flag off
diff --git a/tools/firmware-utils/src/imagetag_cmdline.c b/tools/firmware-utils/src/imagetag_cmdline.c
index 91ac90b09d0..86c90bbb678 100644
--- a/tools/firmware-utils/src/imagetag_cmdline.c
+++ b/tools/firmware-utils/src/imagetag_cmdline.c
@@ -1,7 +1,7 @@
/*
- File autogenerated by gengetopt version 2.22.4
+ File autogenerated by gengetopt version 2.22.5
generated with the following command:
- gengetopt --file-name=imagetag_cmdline --file-name=imagetag_cmdline
+ gengetopt -i imagetag.ggo -f imagetag_cmdline --file-name=imagetag_cmdline
The developers of gengetopt consider the fixed text that goes in all
gengetopt output files to be in the public domain:
@@ -58,13 +58,16 @@ const char *gengetopt_args_info_help[] = {
" --inactive=flag-value Inactive Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')",
" --reserved2=STRING String for second reserved section.",
" --kernel-file-has-header Indicates that the kernel file includes the \n kernel header with correct load address and \n entry point, so no changes are needed \n (default=off)",
+ " -p, --pad=size (in MiB) Pad the image to this size if smaller (in MiB)",
+ " --align-rootfs Align the rootfs start to erase block size \n (default=off)",
0
};
typedef enum {ARG_NO
, ARG_FLAG
, ARG_STRING
-} cmdline_parser_arg_type;
+ , ARG_INT
+} imagetag_cmdline_arg_type;
static
void clear_given (struct gengetopt_args_info *args_info);
@@ -72,14 +75,14 @@ static
void clear_args (struct gengetopt_args_info *args_info);
static int
-cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
- struct cmdline_parser_params *params, const char *additional_error);
+imagetag_cmdline_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
+ struct imagetag_cmdline_params *params, const char *additional_error);
static int
-cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);
+imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error);
-const char *cmdline_parser_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */
-const char *cmdline_parser_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */
+const char *imagetag_cmdline_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */
+const char *imagetag_cmdline_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */
static char *
gengetopt_strdup (const char *s);
@@ -113,6 +116,8 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->inactive_given = 0 ;
args_info->reserved2_given = 0 ;
args_info->kernel_file_has_header_given = 0 ;
+ args_info->pad_given = 0 ;
+ args_info->align_rootfs_given = 0 ;
}
static
@@ -165,6 +170,8 @@ void clear_args (struct gengetopt_args_info *args_info)
args_info->reserved2_arg = NULL;
args_info->reserved2_orig = NULL;
args_info->kernel_file_has_header_flag = 0;
+ args_info->pad_orig = NULL;
+ args_info->align_rootfs_flag = 0;
}
@@ -199,19 +206,21 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->inactive_help = gengetopt_args_info_help[23] ;
args_info->reserved2_help = gengetopt_args_info_help[24] ;
args_info->kernel_file_has_header_help = gengetopt_args_info_help[25] ;
+ args_info->pad_help = gengetopt_args_info_help[26] ;
+ args_info->align_rootfs_help = gengetopt_args_info_help[27] ;
}
void
-cmdline_parser_print_version (void)
+imagetag_cmdline_print_version (void)
{
printf ("%s %s\n",
- (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
- CMDLINE_PARSER_VERSION);
+ (strlen(IMAGETAG_CMDLINE_PACKAGE_NAME) ? IMAGETAG_CMDLINE_PACKAGE_NAME : IMAGETAG_CMDLINE_PACKAGE),
+ IMAGETAG_CMDLINE_VERSION);
}
static void print_help_common(void) {
- cmdline_parser_print_version ();
+ imagetag_cmdline_print_version ();
if (strlen(gengetopt_args_info_purpose) > 0)
printf("\n%s\n", gengetopt_args_info_purpose);
@@ -226,7 +235,7 @@ static void print_help_common(void) {
}
void
-cmdline_parser_print_help (void)
+imagetag_cmdline_print_help (void)
{
int i = 0;
print_help_common();
@@ -235,7 +244,7 @@ cmdline_parser_print_help (void)
}
void
-cmdline_parser_init (struct gengetopt_args_info *args_info)
+imagetag_cmdline_init (struct gengetopt_args_info *args_info)
{
clear_given (args_info);
clear_args (args_info);
@@ -243,7 +252,7 @@ cmdline_parser_init (struct gengetopt_args_info *args_info)
}
void
-cmdline_parser_params_init(struct cmdline_parser_params *params)
+imagetag_cmdline_params_init(struct imagetag_cmdline_params *params)
{
if (params)
{
@@ -255,12 +264,12 @@ cmdline_parser_params_init(struct cmdline_parser_params *params)
}
}
-struct cmdline_parser_params *
-cmdline_parser_params_create(void)
+struct imagetag_cmdline_params *
+imagetag_cmdline_params_create(void)
{
- struct cmdline_parser_params *params =
- (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
- cmdline_parser_params_init(params);
+ struct imagetag_cmdline_params *params =
+ (struct imagetag_cmdline_params *)malloc(sizeof(struct imagetag_cmdline_params));
+ imagetag_cmdline_params_init(params);
return params;
}
@@ -276,7 +285,7 @@ free_string_field (char **s)
static void
-cmdline_parser_release (struct gengetopt_args_info *args_info)
+imagetag_cmdline_release (struct gengetopt_args_info *args_info)
{
free_string_field (&(args_info->kernel_arg));
@@ -323,6 +332,7 @@ cmdline_parser_release (struct gengetopt_args_info *args_info)
free_string_field (&(args_info->inactive_orig));
free_string_field (&(args_info->reserved2_arg));
free_string_field (&(args_info->reserved2_orig));
+ free_string_field (&(args_info->pad_orig));
@@ -384,13 +394,13 @@ write_into_file(FILE *outfile, const char *opt, const char *arg, const char *val
int
-cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
+imagetag_cmdline_dump(FILE *outfile, struct gengetopt_args_info *args_info)
{
int i = 0;
if (!outfile)
{
- fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
+ fprintf (stderr, "%s: cannot dump options to stream\n", IMAGETAG_CMDLINE_PACKAGE);
return EXIT_FAILURE;
}
@@ -439,13 +449,17 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
if (args_info->rsa_signature_given)
write_into_file(outfile, "rsa-signature", args_info->rsa_signature_orig, 0);
if (args_info->second_image_flag_given)
- write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, cmdline_parser_second_image_flag_values);
+ write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, imagetag_cmdline_second_image_flag_values);
if (args_info->inactive_given)
- write_into_file(outfile, "inactive", args_info->inactive_orig, cmdline_parser_inactive_values);
+ write_into_file(outfile, "inactive", args_info->inactive_orig, imagetag_cmdline_inactive_values);
if (args_info->reserved2_given)
write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0);
if (args_info->kernel_file_has_header_given)
write_into_file(outfile, "kernel-file-has-header", 0, 0 );
+ if (args_info->pad_given)
+ write_into_file(outfile, "pad", args_info->pad_orig, 0);
+ if (args_info->align_rootfs_given)
+ write_into_file(outfile, "align-rootfs", 0, 0 );
i = EXIT_SUCCESS;
@@ -453,7 +467,7 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
}
int
-cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
+imagetag_cmdline_file_save(const char *filename, struct gengetopt_args_info *args_info)
{
FILE *outfile;
int i = 0;
@@ -462,20 +476,20 @@ cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_
if (!outfile)
{
- fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
+ fprintf (stderr, "%s: cannot open file for writing: %s\n", IMAGETAG_CMDLINE_PACKAGE, filename);
return EXIT_FAILURE;
}
- i = cmdline_parser_dump(outfile, args_info);
+ i = imagetag_cmdline_dump(outfile, args_info);
fclose (outfile);
return i;
}
void
-cmdline_parser_free (struct gengetopt_args_info *args_info)
+imagetag_cmdline_free (struct gengetopt_args_info *args_info)
{
- cmdline_parser_release (args_info);
+ imagetag_cmdline_release (args_info);
}
/** @brief replacement of strdup, which is not standard */
@@ -494,21 +508,21 @@ gengetopt_strdup (const char *s)
}
int
-cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
+imagetag_cmdline (int argc, char **argv, struct gengetopt_args_info *args_info)
{
- return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
+ return imagetag_cmdline2 (argc, argv, args_info, 0, 1, 1);
}
int
-cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
- struct cmdline_parser_params *params)
+imagetag_cmdline_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
+ struct imagetag_cmdline_params *params)
{
int result;
- result = cmdline_parser_internal (argc, argv, args_info, params, 0);
+ result = imagetag_cmdline_internal (argc, argv, args_info, params, 0);
if (result == EXIT_FAILURE)
{
- cmdline_parser_free (args_info);
+ imagetag_cmdline_free (args_info);
exit (EXIT_FAILURE);
}
@@ -516,10 +530,10 @@ cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info
}
int
-cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
+imagetag_cmdline2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
{
int result;
- struct cmdline_parser_params params;
+ struct imagetag_cmdline_params params;
params.override = override;
params.initialize = initialize;
@@ -527,11 +541,11 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i
params.check_ambiguity = 0;
params.print_errors = 1;
- result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
+ result = imagetag_cmdline_internal (argc, argv, args_info, &params, 0);
if (result == EXIT_FAILURE)
{
- cmdline_parser_free (args_info);
+ imagetag_cmdline_free (args_info);
exit (EXIT_FAILURE);
}
@@ -539,16 +553,16 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i
}
int
-cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
+imagetag_cmdline_required (struct gengetopt_args_info *args_info, const char *prog_name)
{
int result = EXIT_SUCCESS;
- if (cmdline_parser_required2(args_info, prog_name, 0) > 0)
+ if (imagetag_cmdline_required2(args_info, prog_name, 0) > 0)
result = EXIT_FAILURE;
if (result == EXIT_FAILURE)
{
- cmdline_parser_free (args_info);
+ imagetag_cmdline_free (args_info);
exit (EXIT_FAILURE);
}
@@ -556,7 +570,7 @@ cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog
}
int
-cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error)
+imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error)
{
int error = 0;
FIX_UNUSED (additional_error);
@@ -623,8 +637,8 @@ static char *package_name = 0;
* @param possible_values the possible values for this option (if specified)
* @param default_value the default value (in case the option only accepts fixed values)
* @param arg_type the type of this option
- * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
- * @param override @see cmdline_parser_params.override
+ * @param check_ambiguity @see imagetag_cmdline_params.check_ambiguity
+ * @param override @see imagetag_cmdline_params.override
* @param no_free whether to free a possible previous value
* @param multiple_option whether this is a multiple option
* @param long_opt the corresponding long option
@@ -636,7 +650,7 @@ int update_arg(void *field, char **orig_field,
unsigned int *field_given, unsigned int *prev_given,
char *value, const char *possible_values[],
const char *default_value,
- cmdline_parser_arg_type arg_type,
+ imagetag_cmdline_arg_type arg_type,
int check_ambiguity, int override,
int no_free, int multiple_option,
const char *long_opt, char short_opt,
@@ -690,6 +704,9 @@ int update_arg(void *field, char **orig_field,
case ARG_FLAG:
*((int *)field) = !*((int *)field);
break;
+ case ARG_INT:
+ if (val) *((int *)field) = strtol (val, &stop_char, 0);
+ break;
case ARG_STRING:
if (val) {
string_field = (char **)field;
@@ -702,6 +719,17 @@ int update_arg(void *field, char **orig_field,
break;
};
+ /* check numeric conversion */
+ switch(arg_type) {
+ case ARG_INT:
+ if (val && !(stop_char && *stop_char == '\0')) {
+ fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
+ return 1; /* failure */
+ }
+ break;
+ default:
+ ;
+ };
/* store the original value */
switch(arg_type) {
@@ -725,9 +753,9 @@ int update_arg(void *field, char **orig_field,
int
-cmdline_parser_internal (
+imagetag_cmdline_internal (
int argc, char **argv, struct gengetopt_args_info *args_info,
- struct cmdline_parser_params *params, const char *additional_error)
+ struct imagetag_cmdline_params *params, const char *additional_error)
{
int c; /* Character of the parsed option. */
@@ -747,9 +775,9 @@ cmdline_parser_internal (
check_ambiguity = params->check_ambiguity;
if (initialize)
- cmdline_parser_init (args_info);
+ imagetag_cmdline_init (args_info);
- cmdline_parser_init (&local_args_info);
+ imagetag_cmdline_init (&local_args_info);
optarg = 0;
optind = 0;
@@ -787,23 +815,25 @@ cmdline_parser_internal (
{ "inactive", 1, NULL, 0 },
{ "reserved2", 1, NULL, 0 },
{ "kernel-file-has-header", 0, NULL, 0 },
+ { "pad", 1, NULL, 'p' },
+ { "align-rootfs", 0, NULL, 0 },
{ 0, 0, 0, 0 }
};
- c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:", long_options, &option_index);
+ c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:p:", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */
switch (c)
{
case 'h': /* Print help and exit. */
- cmdline_parser_print_help ();
- cmdline_parser_free (&local_args_info);
+ imagetag_cmdline_print_help ();
+ imagetag_cmdline_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'V': /* Print version and exit. */
- cmdline_parser_print_version ();
- cmdline_parser_free (&local_args_info);
+ imagetag_cmdline_print_version ();
+ imagetag_cmdline_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'i': /* File with LZMA compressed kernel to include in the image.. */
@@ -1010,6 +1040,18 @@ cmdline_parser_internal (
goto failure;
break;
+ case 'p': /* Pad the image to this size if smaller (in MiB). */
+
+
+ if (update_arg( (void *)&(args_info->pad_arg),
+ &(args_info->pad_orig), &(args_info->pad_given),
+ &(local_args_info.pad_given), optarg, 0, 0, ARG_INT,
+ check_ambiguity, override, 0, 0,
+ "pad", 'p',
+ additional_error))
+ goto failure;
+
+ break;
case 0: /* Long option with no short option */
/* File with CFE to include in the image.. */
@@ -1059,7 +1101,7 @@ cmdline_parser_internal (
if (update_arg( (void *)&(args_info->second_image_flag_arg),
&(args_info->second_image_flag_orig), &(args_info->second_image_flag_given),
- &(local_args_info.second_image_flag_given), optarg, cmdline_parser_second_image_flag_values, "2", ARG_STRING,
+ &(local_args_info.second_image_flag_given), optarg, imagetag_cmdline_second_image_flag_values, "2", ARG_STRING,
check_ambiguity, override, 0, 0,
"second-image-flag", '-',
additional_error))
@@ -1073,7 +1115,7 @@ cmdline_parser_internal (
if (update_arg( (void *)&(args_info->inactive_arg),
&(args_info->inactive_orig), &(args_info->inactive_given),
- &(local_args_info.inactive_given), optarg, cmdline_parser_inactive_values, "2", ARG_STRING,
+ &(local_args_info.inactive_given), optarg, imagetag_cmdline_inactive_values, "2", ARG_STRING,
check_ambiguity, override, 0, 0,
"inactive", '-',
additional_error))
@@ -1106,6 +1148,18 @@ cmdline_parser_internal (
goto failure;
}
+ /* Align the rootfs start to erase block size. */
+ else if (strcmp (long_options[option_index].name, "align-rootfs") == 0)
+ {
+
+
+ if (update_arg((void *)&(args_info->align_rootfs_flag), 0, &(args_info->align_rootfs_given),
+ &(local_args_info.align_rootfs_given), optarg, 0, 0, ARG_FLAG,
+ check_ambiguity, override, 1, 0, "align-rootfs", '-',
+ additional_error))
+ goto failure;
+
+ }
break;
case '?': /* Invalid option. */
@@ -1113,7 +1167,7 @@ cmdline_parser_internal (
goto failure;
default: /* bug: option not considered. */
- fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
+ fprintf (stderr, "%s: option unknown: %c%s\n", IMAGETAG_CMDLINE_PACKAGE, c, (additional_error ? additional_error : ""));
abort ();
} /* switch */
} /* while */
@@ -1122,10 +1176,10 @@ cmdline_parser_internal (
if (check_required)
{
- error += cmdline_parser_required2 (args_info, argv[0], additional_error);
+ error += imagetag_cmdline_required2 (args_info, argv[0], additional_error);
}
- cmdline_parser_release (&local_args_info);
+ imagetag_cmdline_release (&local_args_info);
if ( error )
return (EXIT_FAILURE);
@@ -1134,6 +1188,6 @@ cmdline_parser_internal (
failure:
- cmdline_parser_release (&local_args_info);
+ imagetag_cmdline_release (&local_args_info);
return (EXIT_FAILURE);
}
diff --git a/tools/firmware-utils/src/imagetag_cmdline.h b/tools/firmware-utils/src/imagetag_cmdline.h
index c566a9f2932..3f55c509bb3 100644
--- a/tools/firmware-utils/src/imagetag_cmdline.h
+++ b/tools/firmware-utils/src/imagetag_cmdline.h
@@ -1,6 +1,6 @@
/** @file imagetag_cmdline.h
* @brief The header file for the command line option parser
- * generated by GNU Gengetopt version 2.22.4
+ * generated by GNU Gengetopt version 2.22.5
* http://www.gnu.org/software/gengetopt.
* DO NOT modify this file, since it can be overwritten
* @author GNU Gengetopt by Lorenzo Bettini */
@@ -19,19 +19,19 @@
extern "C" {
#endif /* __cplusplus */
-#ifndef CMDLINE_PARSER_PACKAGE
+#ifndef IMAGETAG_CMDLINE_PACKAGE
/** @brief the program name (used for printing errors) */
-#define CMDLINE_PARSER_PACKAGE "imagetag"
+#define IMAGETAG_CMDLINE_PACKAGE "imagetag"
#endif
-#ifndef CMDLINE_PARSER_PACKAGE_NAME
+#ifndef IMAGETAG_CMDLINE_PACKAGE_NAME
/** @brief the complete program name (used for help and version) */
-#define CMDLINE_PARSER_PACKAGE_NAME "imagetag"
+#define IMAGETAG_CMDLINE_PACKAGE_NAME "imagetag"
#endif
-#ifndef CMDLINE_PARSER_VERSION
+#ifndef IMAGETAG_CMDLINE_VERSION
/** @brief the program version */
-#define CMDLINE_PARSER_VERSION "2.0.0"
+#define IMAGETAG_CMDLINE_VERSION "2.0.0"
#endif
/** @brief Where the command line options are stored */
@@ -109,6 +109,11 @@ struct gengetopt_args_info
const char *reserved2_help; /**< @brief String for second reserved section. help description. */
int kernel_file_has_header_flag; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed (default=off). */
const char *kernel_file_has_header_help; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed help description. */
+ int pad_arg; /**< @brief Pad the image to this size if smaller (in MiB). */
+ char * pad_orig; /**< @brief Pad the image to this size if smaller (in MiB) original value given at command line. */
+ const char *pad_help; /**< @brief Pad the image to this size if smaller (in MiB) help description. */
+ int align_rootfs_flag; /**< @brief Align the rootfs start to erase block size (default=off). */
+ const char *align_rootfs_help; /**< @brief Align the rootfs start to erase block size help description. */
unsigned int help_given ; /**< @brief Whether help was given. */
unsigned int version_given ; /**< @brief Whether version was given. */
@@ -136,11 +141,13 @@ struct gengetopt_args_info
unsigned int inactive_given ; /**< @brief Whether inactive was given. */
unsigned int reserved2_given ; /**< @brief Whether reserved2 was given. */
unsigned int kernel_file_has_header_given ; /**< @brief Whether kernel-file-has-header was given. */
+ unsigned int pad_given ; /**< @brief Whether pad was given. */
+ unsigned int align_rootfs_given ; /**< @brief Whether align-rootfs was given. */
} ;
/** @brief The additional parameters to pass to parser functions */
-struct cmdline_parser_params
+struct imagetag_cmdline_params
{
int override; /**< @brief whether to override possibly already present options (default 0) */
int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */
@@ -163,7 +170,7 @@ extern const char *gengetopt_args_info_help[];
* @param args_info the structure where option information will be stored
* @return 0 if everything went fine, NON 0 if an error took place
*/
-int cmdline_parser (int argc, char **argv,
+int imagetag_cmdline (int argc, char **argv,
struct gengetopt_args_info *args_info);
/**
@@ -175,9 +182,9 @@ int cmdline_parser (int argc, char **argv,
* @param initialize whether to initialize the option structure my_args_info
* @param check_required whether to check that all required options were provided
* @return 0 if everything went fine, NON 0 if an error took place
- * @deprecated use cmdline_parser_ext() instead
+ * @deprecated use imagetag_cmdline_ext() instead
*/
-int cmdline_parser2 (int argc, char **argv,
+int imagetag_cmdline2 (int argc, char **argv,
struct gengetopt_args_info *args_info,
int override, int initialize, int check_required);
@@ -189,9 +196,9 @@ int cmdline_parser2 (int argc, char **argv,
* @param params additional parameters for the parser
* @return 0 if everything went fine, NON 0 if an error took place
*/
-int cmdline_parser_ext (int argc, char **argv,
+int imagetag_cmdline_ext (int argc, char **argv,
struct gengetopt_args_info *args_info,
- struct cmdline_parser_params *params);
+ struct imagetag_cmdline_params *params);
/**
* Save the contents of the option struct into an already open FILE stream.
@@ -199,7 +206,7 @@ int cmdline_parser_ext (int argc, char **argv,
* @param args_info the option struct to dump
* @return 0 if everything went fine, NON 0 if an error took place
*/
-int cmdline_parser_dump(FILE *outfile,
+int imagetag_cmdline_dump(FILE *outfile,
struct gengetopt_args_info *args_info);
/**
@@ -209,44 +216,44 @@ int cmdline_parser_dump(FILE *outfile,
* @param args_info the option struct to save
* @return 0 if everything went fine, NON 0 if an error took place
*/
-int cmdline_parser_file_save(const char *filename,
+int imagetag_cmdline_file_save(const char *filename,
struct gengetopt_args_info *args_info);
/**
* Print the help
*/
-void cmdline_parser_print_help(void);
+void imagetag_cmdline_print_help(void);
/**
* Print the version
*/
-void cmdline_parser_print_version(void);
+void imagetag_cmdline_print_version(void);
/**
- * Initializes all the fields a cmdline_parser_params structure
+ * Initializes all the fields a imagetag_cmdline_params structure
* to their default values
* @param params the structure to initialize
*/
-void cmdline_parser_params_init(struct cmdline_parser_params *params);
+void imagetag_cmdline_params_init(struct imagetag_cmdline_params *params);
/**
- * Allocates dynamically a cmdline_parser_params structure and initializes
+ * Allocates dynamically a imagetag_cmdline_params structure and initializes
* all its fields to their default values
- * @return the created and initialized cmdline_parser_params structure
+ * @return the created and initialized imagetag_cmdline_params structure
*/
-struct cmdline_parser_params *cmdline_parser_params_create(void);
+struct imagetag_cmdline_params *imagetag_cmdline_params_create(void);
/**
* Initializes the passed gengetopt_args_info structure's fields
* (also set default values for options that have a default)
* @param args_info the structure to initialize
*/
-void cmdline_parser_init (struct gengetopt_args_info *args_info);
+void imagetag_cmdline_init (struct gengetopt_args_info *args_info);
/**
* Deallocates the string fields of the gengetopt_args_info structure
* (but does not deallocate the structure itself)
* @param args_info the structure to deallocate
*/
-void cmdline_parser_free (struct gengetopt_args_info *args_info);
+void imagetag_cmdline_free (struct gengetopt_args_info *args_info);
/**
* Checks that all the required options were specified
@@ -255,11 +262,11 @@ void cmdline_parser_free (struct gengetopt_args_info *args_info);
* possible errors
* @return
*/
-int cmdline_parser_required (struct gengetopt_args_info *args_info,
+int imagetag_cmdline_required (struct gengetopt_args_info *args_info,
const char *prog_name);
-extern const char *cmdline_parser_second_image_flag_values[]; /**< @brief Possible values for second-image-flag. */
-extern const char *cmdline_parser_inactive_values[]; /**< @brief Possible values for inactive. */
+extern const char *imagetag_cmdline_second_image_flag_values[]; /**< @brief Possible values for second-image-flag. */
+extern const char *imagetag_cmdline_inactive_values[]; /**< @brief Possible values for inactive. */
#ifdef __cplusplus
diff --git a/tools/firmware-utils/src/jcgimage.c b/tools/firmware-utils/src/jcgimage.c
new file mode 100644
index 00000000000..354c26be19b
--- /dev/null
+++ b/tools/firmware-utils/src/jcgimage.c
@@ -0,0 +1,425 @@
+/*
+ * jcgimage - Create a JCG firmware image
+ *
+ * Copyright (C) 2015 Reinhard Max <reinhard@m4x.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+/*
+ * JCG firmware update images consist of a 512 byte header and a
+ * modified uImage (details below) as the payload.
+ *
+ * The payload is obfuscated by XORing it with a key that is generated
+ * from parts of the header. Fortunately only non-essential parts of
+ * the header are used for this and zeroing them results in a zero
+ * key, effectively disabling the obfuscation and allowing us to use
+ * clear text payloads.
+ *
+ * The mandatory parts of the header are:
+ *
+ * - A magic string of "YSZJ" at offset 0.
+ * - A value of 1 at offset 39 (header format version?)
+ * - A CRC32 checksum of the payload at offset 504.
+ * - A CRC32 checksum of the header at offset 508.
+ *
+ * An image constructed by these rules will be accepted by JCG's
+ * U-Boot in resuce mode via TFTP and the payload will be written to
+ * the flash starting at offset 0x00050000.
+ *
+ * JCG's U-Boot does check the content or size of the payload
+ * image. If it is too large, it wraps around and overwrites U-Boot,
+ * requiring JTAG to revive the board. To prevent such bricking from
+ * happening, this tool refuses to build such overlong images.
+ *
+ * Two more conditions have to be met for a JCG image to be accepted
+ * as a valid update by the web interface of the stock firware:
+ *
+ * - The bytes at offsets 109 and 111 in the header must be a binary
+ * representation of the first two components of the firmware
+ * version as displayed in the update web form, or it will be
+ * rejected as "incorrect product".
+ *
+ * - The payload must start with a valid uImage header whose data
+ * CRC checksum matches the whole rest of the update file rather
+ * than just the number of bytes specified in the size field of the
+ * header.
+ *
+ * This last condition is met by JCG's original firmware images,
+ * because they have both, kernel and rootfs inside the uImage and
+ * abuse the last four bytes of the name field to record the offset of
+ * the file system from the start of the uImage header. This tool
+ * produces such images when called with -k and -r, which are meant to
+ * repack the original firmware after modifying the file systen,
+ * e.g. to add debugging tools and enable shell access.
+ *
+ * In contrast, OpenWrt sysupgrade images consist of a uImage that
+ * only contains the kernel and has the rootfs appended to it. Hence,
+ * the CRC over kernel and file system does not match the one in the
+ * uImage header. Fixing this by adjusting the uImage header is not
+ * possible, because it makes the uImage unusable for booting. Instead
+ * we append four "patch" bytes to the end of the file system, that
+ * are calculated to force the checksum of kernel+fs to be the same as
+ * for the kernel alone.
+ *
+ */
+
+#include <zlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <arpa/inet.h>
+#include <assert.h>
+
+/*
+ * JCG Firmware image header
+ */
+#define JH_MAGIC 0x59535a4a /* "YSZJ" */
+struct jcg_header {
+ uint32_t jh_magic;
+ uint8_t jh_version[32]; /* Firmware version string.
+ Fill with zeros to avoid encryption */
+ uint32_t jh_type; /* must be 1 */
+ uint8_t jh_info[64]; /* Firmware info string. Fill with
+ zeros to avoid encryption */
+ uint32_t jh_time; /* Image creation time in seconds since
+ * the Epoch. Does not seem to be used
+ * by the stock firmware. */
+ uint16_t jh_major; /* Major fimware version */
+ uint16_t jh_minor; /* Minor fimrmware version */
+ uint8_t jh_unknown[392]; /* Apparently unused and all zeros */
+ uint32_t jh_dcrc; /* CRC checksum of the payload */
+ uint32_t jh_hcrc; /* CRC checksum of the header */
+};
+
+/*
+ * JCG uses a modified uImage header that replaces the last four bytes
+ * of the image name with the length of the kernel in the image.
+ */
+#define IH_MAGIC 0x27051956 /* Image Magic Number */
+#define IH_NMLEN 28 /* Image Name Length */
+
+struct uimage_header {
+ uint32_t ih_magic; /* Image Header Magic Number */
+ uint32_t ih_hcrc; /* Image Header CRC Checksum */
+ uint32_t ih_time; /* Image Creation Timestamp */
+ uint32_t ih_size; /* Image Data Size */
+ uint32_t ih_load; /* Data Load Address */
+ uint32_t ih_ep; /* Entry Point Address */
+ uint32_t ih_dcrc; /* Image Data CRC Checksum */
+ uint8_t ih_os; /* Operating System */
+ uint8_t ih_arch; /* CPU architecture */
+ uint8_t ih_type; /* Image Type */
+ uint8_t ih_comp; /* Compression Type */
+ uint8_t ih_name[IH_NMLEN];/* Image Name */
+ uint32_t ih_fsoff; /* Offset of the file system
+ partition from the start of
+ the header */
+};
+
+/*
+ * Open the named file and return its size and file descriptor.
+ * Exit in case of errors.
+ */
+int
+opensize(char *name, size_t *size)
+{
+ struct stat s;
+ int fd = open(name, O_RDONLY);
+ if (fd < 0) {
+ err(1, "cannot open \"%s\"", name);
+ }
+ if (fstat(fd, &s) == -1) {
+ err(1, "cannot stat \"%s\"", name);
+ }
+ *size = s.st_size;
+ return fd;
+}
+
+static time_t source_date_epoch = -1;
+static void set_source_date_epoch() {
+ char *env = getenv("SOURCE_DATE_EPOCH");
+ char *endptr = env;
+ errno = 0;
+ if (env && *env) {
+ source_date_epoch = strtoull(env, &endptr, 10);
+ if (errno || (endptr && *endptr != '\0')) {
+ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
+ exit(1);
+ }
+ }
+}
+
+/*
+ * Write the JCG header
+ */
+void
+mkjcgheader(struct jcg_header *h, size_t psize, char *version)
+{
+ uLong crc;
+ uint16_t major = 0, minor = 0;
+ void *payload = (void *)h + sizeof(*h);
+ time_t t;
+
+ if (source_date_epoch != -1) {
+ t = source_date_epoch;
+ } else if ((time(&t) == (time_t)(-1))) {
+ err(1, "time call failed");
+ }
+
+ if (version != NULL) {
+ if (sscanf(version, "%hu.%hu", &major, &minor) != 2) {
+ err(1, "cannot parse version \"%s\"", version);
+ }
+ }
+
+ memset(h, 0, sizeof(*h));
+ h->jh_magic = htonl(JH_MAGIC);
+ h->jh_type = htonl(1);
+ h->jh_time = htonl(t);
+ h->jh_major = htons(major);
+ h->jh_minor = htons(minor);
+
+ /* CRC over JCG payload (uImage) */
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, payload, psize);
+ h->jh_dcrc = htonl(crc);
+
+ /* CRC over JCG header */
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, (void *)h, sizeof(*h));
+ h->jh_hcrc = htonl(crc);
+}
+
+/*
+ * Write the uImage header
+ */
+void
+mkuheader(struct uimage_header *h, size_t ksize, size_t fsize)
+{
+ uLong crc;
+ void *payload = (void *)h + sizeof(*h);
+
+ // printf("mkuheader: %p, %zd, %zd\n", h, ksize, fsize);
+ memset(h, 0, sizeof(*h));
+ h->ih_magic = htonl(IH_MAGIC);
+ h->ih_time = htonl(time(NULL));
+ h->ih_size = htonl(ksize + fsize);
+ h->ih_load = htonl(0x80000000);
+ h->ih_ep = htonl(0x80292000);
+ h->ih_os = 0x05;
+ h->ih_arch = 0x05;
+ h->ih_type = 0x02;
+ h->ih_comp = 0x03;
+ h->ih_fsoff = htonl(sizeof(*h) + ksize);
+ strcpy((char *)h->ih_name, "Linux Kernel Image");
+
+ /* CRC over uImage payload (kernel and file system) */
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, payload, ntohl(h->ih_size));
+ h->ih_dcrc = htonl(crc);
+ printf("CRC1: %08lx\n", crc);
+
+ /* CRC over uImage header */
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, (void *)h, sizeof(*h));
+ h->ih_hcrc = htonl(crc);
+ printf("CRC2: %08lx\n", crc);
+}
+
+/*
+ * Calculate a "patch" value and write it into the last four bytes of
+ * buf, so that the CRC32 checksum of the whole buffer is dcrc.
+ *
+ * Based on: SAR-PR-2006-05: Reversing CRC – Theory and Practice.
+ * Martin Stigge, Henryk Plötz, Wolf Müller, Jens-Peter Redlich.
+ * http://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2006-05
+ */
+void
+craftcrc(uint32_t dcrc, uint8_t *buf, size_t len)
+{
+ int i;
+ uint32_t a;
+ uint32_t patch = 0;
+ uint32_t crc = crc32(0L, Z_NULL, 0);
+
+ a = ~dcrc;
+ for (i = 0; i < 32; i++) {
+ if (patch & 1) {
+ patch = (patch >> 1) ^ 0xedb88320L;
+ } else {
+ patch >>= 1;
+ }
+ if (a & 1) {
+ patch ^= 0x5b358fd3L;
+ }
+ a >>= 1;
+ }
+ patch ^= ~crc32(crc, buf, len - 4);
+ for (i = 0; i < 4; i++) {
+ buf[len - 4 + i] = patch & 0xff;
+ patch >>= 8;
+ }
+ /* Verify that we actually get the desired result */
+ crc = crc32(0L, Z_NULL, 0);
+ crc = crc32(crc, buf, len);
+ if (crc != dcrc) {
+ errx(1, "CRC patching is broken: wanted %08x, but got %08x.",
+ dcrc, crc);
+ }
+}
+
+void
+usage() {
+ fprintf(stderr, "Usage:\n"
+ "jcgimage -o outfile -u uImage [-v version]\n"
+ "jcgimage -o outfile -k kernel -f rootfs [-v version]\n");
+ exit(1);
+}
+
+#define MODE_UNKNOWN 0
+#define MODE_UIMAGE 1
+#define MODE_KR 2
+
+/* The output image must not be larger than 4MiB - 5*64kiB */
+#define MAXSIZE (size_t)(4 * 1024 * 1024 - 5 * 64 * 1024)
+
+int
+main(int argc, char **argv)
+{
+ struct jcg_header *jh;
+ struct uimage_header *uh;
+ int c;
+ char *imagefile = NULL;
+ char *file1 = NULL;
+ char *file2 = NULL;
+ char *version = NULL;
+ int mode = MODE_UNKNOWN;
+ int fdo, fd1, fd2;
+ size_t size1, size2, sizeu, sizeo, off1, off2;
+ void *map;
+
+ /* Make sure the headers have the right size */
+ assert(sizeof(struct jcg_header) == 512);
+ assert(sizeof(struct uimage_header) == 64);
+ set_source_date_epoch();
+
+ while ((c = getopt(argc, argv, "o:k:f:u:v:h")) != -1) {
+ switch (c) {
+ case 'o':
+ imagefile = optarg;
+ break;
+ case 'k':
+ if (mode == MODE_UIMAGE) {
+ errx(1,"-k cannot be combined with -u");
+ }
+ mode = MODE_KR;
+ file1 = optarg;
+ break;
+ case 'f':
+ if (mode == MODE_UIMAGE) {
+ errx(1,"-f cannot be combined with -u");
+ }
+ mode = MODE_KR;
+ file2 = optarg;
+ break;
+ case 'u':
+ if (mode == MODE_KR) {
+ errx(1,"-u cannot be combined with -k and -r");
+ }
+ mode = MODE_UIMAGE;
+ file1 = optarg;
+ break;
+ case 'v':
+ version = optarg;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+ if (optind != argc) {
+ errx(1, "illegal arg \"%s\"", argv[optind]);
+ }
+ if (imagefile == NULL) {
+ errx(1, "no output file specified");
+ }
+ if (mode == MODE_UNKNOWN) {
+ errx(1, "specify either -u or -k and -r");
+ }
+ if (mode == MODE_KR) {
+ if (file1 == NULL || file2 == NULL) {
+ errx(1,"need -k and -r");
+ }
+ fd2 = opensize(file2, &size2);
+ }
+ fd1 = opensize(file1, &size1);
+ if (mode == MODE_UIMAGE) {
+ off1 = sizeof(*jh);
+ sizeu = size1 + 4;
+ sizeo = sizeof(*jh) + sizeu;
+ } else {
+ off1 = sizeof(*jh) + sizeof(*uh);
+ off2 = sizeof(*jh) + sizeof(*uh) + size1;
+ sizeu = sizeof(*uh) + size1 + size2;
+ sizeo = sizeof(*jh) + sizeu;
+ }
+
+ if (sizeo > MAXSIZE) {
+ errx(1,"payload too large: %zd > %zd\n", sizeo, MAXSIZE);
+ }
+
+ fdo = open(imagefile, O_RDWR | O_CREAT | O_TRUNC, 00644);
+ if (fdo < 0) {
+ err(1, "cannot open \"%s\"", imagefile);
+ }
+
+ if (ftruncate(fdo, sizeo) == -1) {
+ err(1, "cannot grow \"%s\" to %zd bytes", imagefile, sizeo);
+ }
+ map = mmap(NULL, sizeo, PROT_READ|PROT_WRITE, MAP_SHARED, fdo, 0);
+ uh = map + sizeof(*jh);
+ if (map == MAP_FAILED) {
+ err(1, "cannot mmap \"%s\"", imagefile);
+ }
+
+ if (read(fd1, map + off1, size1) != size1) {
+ err(1, "cannot copy %s", file1);
+ }
+
+ if (mode == MODE_KR) {
+ if (read(fd2, map+off2, size2) != size2) {
+ err(1, "cannot copy %s", file2);
+ }
+ mkuheader(uh, size1, size2);
+ } else if (mode == MODE_UIMAGE) {
+ craftcrc(ntohl(uh->ih_dcrc), (void*)uh + sizeof(*uh),
+ sizeu - sizeof(*uh));
+ }
+ mkjcgheader(map, sizeu, version);
+ munmap(map, sizeo);
+ close(fdo);
+ return 0;
+}
diff --git a/tools/firmware-utils/src/lzma2eva.c b/tools/firmware-utils/src/lzma2eva.c
index 0bc13fa4f34..1d7e3648899 100644
--- a/tools/firmware-utils/src/lzma2eva.c
+++ b/tools/firmware-utils/src/lzma2eva.c
@@ -48,7 +48,7 @@ main(int argc, char *argv[])
const char *infile, *outfile;
FILE *in, *out;
- static const uint8_t buf[4096];
+ static uint8_t buf[4096];
size_t elems;
uint8_t properties;
diff --git a/tools/firmware-utils/src/md5.c b/tools/firmware-utils/src/md5.c
index 20397603834..52d96accd30 100644
--- a/tools/firmware-utils/src/md5.c
+++ b/tools/firmware-utils/src/md5.c
@@ -1,307 +1,296 @@
-
-
/*
- ***********************************************************************
- ** md5.c -- the source code for MD5 routines **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
- ** Created: 2/17/90 RLR **
- ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
- ***********************************************************************
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's. No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible. Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
*/
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
- ** **
- ** License to copy and use this software is granted provided that **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message- **
- ** Digest Algorithm" in all material mentioning or referencing this **
- ** software or this function. **
- ** **
- ** License is also granted to make and use derivative works **
- ** provided that such works are identified as "derived from the RSA **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
- ** material mentioning or referencing the derived work. **
- ** **
- ** RSA Data Security, Inc. makes no representations concerning **
- ** either the merchantability of this software or the suitability **
- ** of this software for any particular purpose. It is provided "as **
- ** is" without express or implied warranty of any kind. **
- ** **
- ** These notices must be retained in any copies of any part of this **
- ** documentation and/or software. **
- ***********************************************************************
- */
+#ifndef HAVE_OPENSSL
#include <string.h>
+
#include "md5.h"
/*
- ***********************************************************************
- ** Message-digest routines: **
- ** To form the message digest for a message M **
- ** (1) Initialize a context buffer mdContext using MD5_Init **
- ** (2) Call MD5_Update on mdContext and M **
- ** (3) Call MD5_Final on mdContext **
- ** The message digest is now in mdContext->digest[0...15] **
- ***********************************************************************
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) (((x) ^ (y)) ^ (z))
+#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
*/
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
-/* forward declaration */
-static void Transform ();
-
-static unsigned char PADDING[64] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* F, G, H and I are basic MD5 functions */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s, ac) \
- {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) \
- {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) \
- {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) \
- {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-#ifdef __STDC__
-#define UL(x) x##U
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+ (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
#else
-#define UL(x) x
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD5_u32plus)ptr[(n) * 4] | \
+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
#endif
-/* The routine MD5_Init initializes the message-digest context
- mdContext. All fields are set to zero.
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There are no alignment requirements.
*/
-void MD5_Init (mdContext)
-MD5_CTX *mdContext;
+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
- mdContext->i[0] = mdContext->i[1] = (UINT4)0;
-
- /* Load magic initialization constants.
- */
- mdContext->buf[0] = (UINT4)0x67452301;
- mdContext->buf[1] = (UINT4)0xefcdab89;
- mdContext->buf[2] = (UINT4)0x98badcfe;
- mdContext->buf[3] = (UINT4)0x10325476;
+ const unsigned char *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = (const unsigned char *)data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while (size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
}
-/* The routine MD5Update updates the message-digest context to
- account for the presence of each of the characters inBuf[0..inLen-1]
- in the message whose digest is being computed.
- */
-void MD5_Update (mdContext, inBuf, inLen)
-MD5_CTX *mdContext;
-unsigned char *inBuf;
-unsigned int inLen;
+void MD5_Init(MD5_CTX *ctx)
{
- UINT4 in[16];
- int mdi;
- unsigned int i, ii;
-
- /* compute number of bytes mod 64 */
- mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
- /* update number of bits */
- if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
- mdContext->i[1]++;
- mdContext->i[0] += ((UINT4)inLen << 3);
- mdContext->i[1] += ((UINT4)inLen >> 29);
-
- while (inLen--) {
- /* add new character to buffer, increment mdi */
- mdContext->in[mdi++] = *inBuf++;
-
- /* transform if necessary */
- if (mdi == 0x40) {
- for (i = 0, ii = 0; i < 16; i++, ii += 4)
- in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
- (((UINT4)mdContext->in[ii+2]) << 16) |
- (((UINT4)mdContext->in[ii+1]) << 8) |
- ((UINT4)mdContext->in[ii]);
- Transform (mdContext->buf, in);
- mdi = 0;
- }
- }
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
}
-/* The routine MD5Final terminates the message-digest computation and
- ends with the desired message digest in mdContext->digest[0...15].
- */
-void MD5_Final (hash, mdContext)
-unsigned char hash[];
-MD5_CTX *mdContext;
+void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
- UINT4 in[16];
- int mdi;
- unsigned int i, ii;
- unsigned int padLen;
-
- /* save number of bits */
- in[14] = mdContext->i[0];
- in[15] = mdContext->i[1];
-
- /* compute number of bytes mod 64 */
- mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
-
- /* pad out to 56 mod 64 */
- padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
- MD5_Update (mdContext, PADDING, padLen);
-
- /* append length in bits and transform */
- for (i = 0, ii = 0; i < 14; i++, ii += 4)
- in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
- (((UINT4)mdContext->in[ii+2]) << 16) |
- (((UINT4)mdContext->in[ii+1]) << 8) |
- ((UINT4)mdContext->in[ii]);
- Transform (mdContext->buf, in);
-
- /* store buffer in digest */
- for (i = 0, ii = 0; i < 4; i++, ii += 4) {
- mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
- mdContext->digest[ii+1] =
- (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
- mdContext->digest[ii+2] =
- (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
- mdContext->digest[ii+3] =
- (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
- }
- memcpy(hash, mdContext->digest, 16);
+ MD5_u32plus saved_lo;
+ unsigned long used, available;
+
+ saved_lo = ctx->lo;
+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if (used) {
+ available = 64 - used;
+
+ if (size < available) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, available);
+ data = (const unsigned char *)data + available;
+ size -= available;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if (size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
}
-/* Basic MD5 step. Transforms buf based on in.
- */
-static void Transform (buf, in)
-UINT4 *buf;
-UINT4 *in;
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
- UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-
- /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
- FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
- FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
- FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
- FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
- FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
- FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
- FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
- FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
- FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
- FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
- FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
- FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
- FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
- FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
- FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
- FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
-
- /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
- GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
- GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
- GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
- GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
- GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
- GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
- GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
- GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
- GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
- GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
- GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
- GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
- GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
- GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
- GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
- GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
-
- /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
- HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
- HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
- HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
- HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
- HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
- HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
- HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
- HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
- HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
- HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
- HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
- HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
- HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
- HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
- HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
- HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
-
- /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
- II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
- II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
- II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
- II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
- II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
- II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
- II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
- II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
- II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
- II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
- II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
- II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
- II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
- II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
- II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
- II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
-
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
+ unsigned long used, available;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ available = 64 - used;
+
+ if (available < 8) {
+ memset(&ctx->buffer[used], 0, available);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ available = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, available - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = ctx->lo;
+ ctx->buffer[57] = ctx->lo >> 8;
+ ctx->buffer[58] = ctx->lo >> 16;
+ ctx->buffer[59] = ctx->lo >> 24;
+ ctx->buffer[60] = ctx->hi;
+ ctx->buffer[61] = ctx->hi >> 8;
+ ctx->buffer[62] = ctx->hi >> 16;
+ ctx->buffer[63] = ctx->hi >> 24;
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = ctx->a;
+ result[1] = ctx->a >> 8;
+ result[2] = ctx->a >> 16;
+ result[3] = ctx->a >> 24;
+ result[4] = ctx->b;
+ result[5] = ctx->b >> 8;
+ result[6] = ctx->b >> 16;
+ result[7] = ctx->b >> 24;
+ result[8] = ctx->c;
+ result[9] = ctx->c >> 8;
+ result[10] = ctx->c >> 16;
+ result[11] = ctx->c >> 24;
+ result[12] = ctx->d;
+ result[13] = ctx->d >> 8;
+ result[14] = ctx->d >> 16;
+ result[15] = ctx->d >> 24;
+
+ memset(ctx, 0, sizeof(*ctx));
}
-/*
- ***********************************************************************
- ** End of md5.c **
- ******************************** (cut) ********************************
- */
+#endif
diff --git a/tools/firmware-utils/src/md5.h b/tools/firmware-utils/src/md5.h
index f7a0c964183..2da44bf355a 100644
--- a/tools/firmware-utils/src/md5.h
+++ b/tools/firmware-utils/src/md5.h
@@ -1,65 +1,45 @@
/*
- ***********************************************************************
- ** md5.h -- header file for implementation of MD5 **
- ** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
- ** Created: 2/17/90 RLR **
- ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
- ** Revised (for MD5): RLR 4/27/91 **
- ** -- G modified to have y&~z instead of y&z **
- ** -- FF, GG, HH modified to add in last register done **
- ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
- ** -- distinct additive constant for each step **
- ** -- round 4 added, working mod 7 **
- ***********************************************************************
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001. No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See md5.c for more information.
*/
-/*
- ***********************************************************************
- ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
- ** **
- ** License to copy and use this software is granted provided that **
- ** it is identified as the "RSA Data Security, Inc. MD5 Message- **
- ** Digest Algorithm" in all material mentioning or referencing this **
- ** software or this function. **
- ** **
- ** License is also granted to make and use derivative works **
- ** provided that such works are identified as "derived from the RSA **
- ** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
- ** material mentioning or referencing the derived work. **
- ** **
- ** RSA Data Security, Inc. makes no representations concerning **
- ** either the merchantability of this software or the suitability **
- ** of this software for any particular purpose. It is provided "as **
- ** is" without express or implied warranty of any kind. **
- ** **
- ** These notices must be retained in any copies of any part of this **
- ** documentation and/or software. **
- ***********************************************************************
- */
+#ifdef HAVE_OPENSSL
+#include <openssl/md5.h>
+#elif !defined(_MD5_H)
+#define _MD5_H
-#ifndef __MD5_INCLUDE__
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
-/* typedef a 32-bit type */
-#ifdef _LP64
-typedef unsigned int UINT4;
-typedef int INT4;
-#else
-typedef unsigned long UINT4;
-typedef long INT4;
-#endif
-#define _UINT4_T
-
-/* Data structure for MD5 (Message-Digest) computation */
typedef struct {
- UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
- UINT4 buf[4]; /* scratch buffer */
- unsigned char in[64]; /* input buffer */
- unsigned char digest[16]; /* actual digest after MD5Final call */
+ MD5_u32plus lo, hi;
+ MD5_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD5_u32plus block[16];
} MD5_CTX;
-void MD5_Init ();
-void MD5_Update ();
-void MD5_Final ();
+extern void MD5_Init(MD5_CTX *ctx);
+extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
-#define __MD5_INCLUDE__
-#endif /* __MD5_INCLUDE__ */
+#endif
diff --git a/tools/firmware-utils/src/mkbrnimg.c b/tools/firmware-utils/src/mkbrnimg.c
index fff92c4ef66..b7a73ff59d2 100644
--- a/tools/firmware-utils/src/mkbrnimg.c
+++ b/tools/firmware-utils/src/mkbrnimg.c
@@ -32,9 +32,14 @@
static uint32_t crc32[1<<BPB];
+static char *output_file = "default-brnImage";
+static uint32_t magic = 0x12345678;
+static char *signature = "BRNDTW502";
+static uint32_t crc32_poly = 0x2083b8ed;
+
static void init_crc32()
{
- const uint32_t poly = ntohl(0x2083b8ed);
+ const uint32_t poly = ntohl(crc32_poly);
int n;
for (n = 0; n < 1<<BPB; n++) {
@@ -61,21 +66,17 @@ static void usage(const char *) __attribute__ (( __noreturn__ ));
static void usage(const char *mess)
{
fprintf(stderr, "Error: %s\n", mess);
- fprintf(stderr, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] kernel_file [additional files]\n");
+ fprintf(stderr, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] [-p crc32 poly] kernel_file [additional files]\n");
fprintf(stderr, "\n");
exit(1);
}
-static char *output_file = "default-brnImage";
-static uint32_t magic = 0x12345678;
-static char *signature = "BRNDTW502";
-
static void parseopts(int *argc, char ***argv)
{
char *endptr;
int res;
- while ((res = getopt(*argc, *argv, "o:m:s:")) != -1) {
+ while ((res = getopt(*argc, *argv, "o:m:s:p:")) != -1) {
switch (res) {
default:
usage("Unknown option");
@@ -91,6 +92,11 @@ static void parseopts(int *argc, char ***argv)
case 's':
signature = optarg;
break;
+ case 'p':
+ crc32_poly = strtoul(optarg, &endptr, 0);
+ if (endptr == optarg || *endptr != 0)
+ usage("'crc32 poly' must be a decimal or hexadecimal 32-bit value");
+ break;
}
}
*argc -= optind;
@@ -136,7 +142,7 @@ static void appendfile(int outfd, char *path, int kernel) {
// write padding
padded_len = ((len + sizeof(footer) + sizeof(padding) - 1) & ~(sizeof(padding) - 1)) - sizeof(footer);
- fprintf(stderr, "len=%08x padded_len=%08x\n", len, padded_len);
+ fprintf(stderr, "len=%08zx padded_len=%08zx\n", len, padded_len);
write(outfd, padding, padded_len - len);
// write footer
diff --git a/tools/firmware-utils/src/mkbuffaloimg.c b/tools/firmware-utils/src/mkbuffaloimg.c
new file mode 100644
index 00000000000..364dda005b0
--- /dev/null
+++ b/tools/firmware-utils/src/mkbuffaloimg.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2016 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * Based on mkdniimg.c
+ *
+ * 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>
+
+#define DNI_HDR_LEN 128
+
+/*
+ * Globals
+ */
+static char *ifname;
+static char *progname;
+static char *ofname;
+static char *version = "0.00_0.00";
+static char *region = "JP";
+static char *rootfs_size;
+static char *kernel_size;
+
+static char *board_id;
+/*
+ * 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 ": %s\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -B <board> create image for the board specified with <board>\n"
+" -i <file> read input from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -v <version> set image version to <version>\n"
+" -r <region> set image region to <region>\n"
+" -R <rootfs_size> set RootfsSize to <rootfs_size>\n"
+" -K <kernel_size> set KernelSize to <kernel_size>\n"
+" -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+int main(int argc, char *argv[])
+{
+ int res = EXIT_FAILURE;
+ int buflen;
+ int err;
+ struct stat st;
+ char *buf;
+ int i;
+ uint8_t csum;
+
+ FILE *outfile, *infile;
+
+ progname = basename(argv[0]);
+
+ while ( 1 ) {
+ int c;
+
+ c = getopt(argc, argv, "B:i:o:v:r:R:K:h");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ board_id = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 'v':
+ version = optarg;
+ break;
+ case 'r':
+ region = optarg;
+ break;
+ case 'R':
+ rootfs_size = optarg;
+ break;
+ case 'K':
+ kernel_size = optarg;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (board_id == NULL) {
+ ERR("no board specified");
+ goto err;
+ }
+
+ if (rootfs_size == NULL) {
+ ERR("no rootfs_size specified");
+ goto err;
+ }
+
+ if (kernel_size == NULL) {
+ ERR("no kernel_size specified");
+ goto err;
+ }
+
+ if (ifname == NULL) {
+ ERR("no input file specified");
+ goto err;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ goto err;
+ }
+
+ err = stat(ifname, &st);
+ if (err){
+ ERRS("stat failed on %s", ifname);
+ goto err;
+ }
+
+ buflen = st.st_size + DNI_HDR_LEN + 1;
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto err;
+ }
+
+ memset(buf, 0, DNI_HDR_LEN);
+ snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:%s\nregion:%s\n"
+ "RootfsSize:%s\nKernelSize:%s\nInfoHeadSize:128\n",
+ board_id, version, region, rootfs_size, kernel_size);
+ buf[DNI_HDR_LEN - 2] = 0x12;
+ buf[DNI_HDR_LEN - 1] = 0x32;
+
+ infile = fopen(ifname, "r");
+ if (infile == NULL) {
+ ERRS("could not open \"%s\" for reading", ifname);
+ goto err_free;
+ }
+
+ errno = 0;
+ fread(buf + DNI_HDR_LEN, st.st_size, 1, infile);
+ if (errno != 0) {
+ ERRS("unable to read from file %s", ifname);
+ goto err_close_in;
+ }
+
+ csum = 0;
+ for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++)
+ csum += buf[i];
+
+ csum = 0xff - csum;
+ buf[st.st_size + DNI_HDR_LEN] = csum;
+
+ outfile = fopen(ofname, "w");
+ if (outfile == NULL) {
+ ERRS("could not open \"%s\" for writing", ofname);
+ goto err_close_in;
+ }
+
+ errno = 0;
+ fwrite(buf, buflen, 1, outfile);
+ if (errno) {
+ ERRS("unable to write to file %s", ofname);
+ goto err_close_out;
+ }
+
+ res = EXIT_SUCCESS;
+
+ fflush(outfile);
+
+ err_close_out:
+ fclose(outfile);
+ if (res != EXIT_SUCCESS) {
+ unlink(ofname);
+ }
+
+ err_close_in:
+ fclose(infile);
+
+ err_free:
+ free(buf);
+
+ err:
+ return res;
+}
diff --git a/tools/firmware-utils/src/mkcameofw.c b/tools/firmware-utils/src/mkcameofw.c
new file mode 100644
index 00000000000..e0da4baf330
--- /dev/null
+++ b/tools/firmware-utils/src/mkcameofw.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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>
+
+#define MAX_MODEL_LEN 20
+#define MAX_SIGNATURE_LEN 30
+#define MAX_REGION_LEN 4
+#define MAX_VERSION_LEN 12
+
+#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+
+struct file_info {
+ char *file_name; /* name of the file */
+ uint32_t file_size; /* length of the file */
+ uint32_t write_size;
+};
+
+struct img_header {
+ uint32_t checksum;
+ uint32_t image_size;
+ uint32_t kernel_size;
+ char model[MAX_MODEL_LEN];
+ char signature[MAX_SIGNATURE_LEN];
+ char region[MAX_REGION_LEN];
+ char version[MAX_VERSION_LEN];
+ unsigned char header_len;
+ unsigned char is_tgz;
+ unsigned char pad[4];
+} __attribute__ ((packed));
+
+/*
+ * Globals
+ */
+static char *ofname;
+static char *progname;
+
+static char *model;
+static char *signature;
+static char *region = "DEF";
+static char *version;
+static struct file_info kernel_info;
+static struct file_info rootfs_info;
+static uint32_t kernel_size;
+static uint32_t image_size;
+static int combined;
+
+/*
+ * 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 " (%s)\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
+} while (0)
+
+static void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -k <file> read kernel image from the file <file>\n"
+" -c use the kernel image as a combined image\n"
+" -M <model> set model to <model>\n"
+" -o <file> write output to the file <file>\n"
+" -r <file> read rootfs image from the file <file>\n"
+" -S <signature> set image signature to <signature>\n"
+" -R <region> set image region to <region>\n"
+" -V <version> set image version to <version>\n"
+" -I <size> set image size to <size>\n"
+" -K <size> set kernel size to <size>\n"
+" -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+int
+str2u32(char *arg, uint32_t *val)
+{
+ char *err = NULL;
+ uint32_t t;
+
+ errno=0;
+ t = strtoul(arg, &err, 0);
+ if (errno || (err==arg) || ((err != NULL) && *err)) {
+ return -1;
+ }
+
+ *val = t;
+ return 0;
+}
+
+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;
+ fdata->write_size = fdata->file_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;
+
+#define CHKSTR(_name, _msg) \
+ do { \
+ if (_name == NULL) { \
+ ERR("no %s specified", _msg); \
+ return -1; \
+ } \
+ } while (0)
+
+#define CHKSTRLEN(_name, _msg) \
+ do { \
+ int field_len; \
+ CHKSTR(_name, _msg); \
+ field_len = FIELD_SIZEOF(struct img_header, _name) - 1; \
+ if (strlen(_name) > field_len) { \
+ ERR("%s is too long, max length is %d", \
+ _msg, field_len); \
+ return -1; \
+ } \
+ } while (0)
+
+ CHKSTRLEN(model, "model");
+ CHKSTRLEN(signature, "signature");
+ CHKSTRLEN(region, "region");
+ CHKSTRLEN(version, "version");
+ CHKSTR(ofname, "output file");
+ CHKSTR(kernel_info.file_name, "kernel image");
+
+ ret = get_file_stat(&kernel_info);
+ if (ret)
+ return ret;
+
+ if (combined) {
+ if (!kernel_size) {
+ ERR("kernel size must be specified for combined images");
+ return -1; \
+ }
+
+ if (!image_size)
+ image_size = kernel_info.file_size;
+
+ if (kernel_info.file_size > image_size) {
+ ERR("kernel image is too big");
+ return -1;
+ }
+
+ kernel_info.write_size = image_size;
+ } else {
+ CHKSTR(rootfs_info.file_name, "rootfs image");
+
+ ret = get_file_stat(&rootfs_info);
+ if (ret)
+ return ret;
+
+ if (kernel_size) {
+ /* override kernel size */
+ kernel_info.write_size = kernel_size;
+ }
+
+ if (image_size) {
+ if (image_size < kernel_info.write_size)
+ kernel_info.write_size = image_size;
+
+ /* override rootfs size */
+ rootfs_info.write_size = image_size - kernel_info.write_size;
+ }
+
+ if (kernel_info.file_size > kernel_info.write_size) {
+ ERR("kernel image is too big");
+ return -1;
+ }
+
+ if (rootfs_info.file_size > rootfs_info.write_size) {
+ ERR("rootfs image is too big");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+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 uint32_t get_csum(unsigned char *p, uint32_t len)
+{
+ uint32_t csum = 0;
+
+ while (len--)
+ csum += *p++;
+
+ return csum;
+}
+
+static int build_fw(void)
+{
+ int buflen;
+ char *buf;
+ char *p;
+ uint32_t csum;
+ struct img_header *hdr;
+ int ret = EXIT_FAILURE;
+
+ buflen = sizeof(struct img_header) +
+ kernel_info.write_size + rootfs_info.write_size;
+
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ memset(buf, 0, buflen);
+
+ p = buf + sizeof(struct img_header);
+
+ /* read kernel data */
+ ret = read_to_buf(&kernel_info, p);
+ if (ret)
+ goto out_free_buf;
+
+ if (!combined) {
+ p += kernel_info.write_size;
+
+ /* read rootfs data */
+ ret = read_to_buf(&rootfs_info, p);
+ if (ret)
+ goto out_free_buf;
+ }
+
+ csum = get_csum((unsigned char *)(buf + sizeof(struct img_header)),
+ buflen - sizeof(struct img_header));
+
+ /* fill firmware header */
+ hdr = (struct img_header *) buf;
+
+ hdr->checksum = htonl(csum);
+ hdr->image_size = htonl(buflen - sizeof(struct img_header));
+ if (!combined)
+ hdr->kernel_size = htonl(kernel_info.write_size);
+ else
+ hdr->kernel_size = htonl(kernel_size);
+ hdr->header_len = sizeof(struct img_header);
+ strncpy(hdr->model, model, sizeof(hdr->model));
+ strncpy(hdr->signature, signature, sizeof(hdr->signature));
+ strncpy(hdr->version, version, sizeof(hdr->version));
+ strncpy(hdr->region, region, sizeof(hdr->region));
+
+ ret = write_fw(buf, buflen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+out_free_buf:
+ free(buf);
+out:
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "M:S:V:R:k:K:I:r:o:hc");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'M':
+ model = optarg;
+ break;
+ case 'S':
+ signature = optarg;
+ break;
+ case 'V':
+ version = optarg;
+ break;
+ case 'R':
+ region = optarg;
+ break;
+ case 'k':
+ kernel_info.file_name = optarg;
+ break;
+ case 'K':
+ if (str2u32(optarg, &kernel_size)) {
+ ERR("%s is invalid '%s'",
+ "kernel size", optarg);
+ goto out;
+ }
+ break;
+ case 'I':
+ if (str2u32(optarg, &image_size)) {
+ ERR("%s is invalid '%s'",
+ "image size", optarg);
+ goto out;
+ }
+ break;
+ case 'r':
+ rootfs_info.file_name = optarg;
+ break;
+ case 'c':
+ combined = 1;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret)
+ goto out;
+
+ ret = build_fw();
+
+out:
+ return ret;
+}
+
diff --git a/tools/firmware-utils/src/mkcasfw.c b/tools/firmware-utils/src/mkcasfw.c
index 626e77d4c49..5655bf1894c 100644
--- a/tools/firmware-utils/src/mkcasfw.c
+++ b/tools/firmware-utils/src/mkcasfw.c
@@ -258,7 +258,7 @@ static struct board_info boards[] = {
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
@@ -708,7 +708,7 @@ image_writeout(FILE *outfile, struct image_desc *desc)
/* write padding data if neccesary */
padlen = desc->out_size - desc->file_size;
- DBG(1,"padding desc, length=%d", padlen);
+ DBG(1,"padding desc, length=%zu", padlen);
res = write_out_padding(outfile, padlen, desc->padc, &css);
desc->csum = csum_get(&css);
@@ -985,11 +985,11 @@ main(int argc, char *argv[])
res = ERR_FATAL;
if (keep_invalid_images == 0) {
- WARN("generation of invalid images disabled", ofname);
+ WARN("generation of invalid images \"%s\" disabled", ofname);
goto out;
}
- WARN("generating invalid image", ofname);
+ WARN("generating invalid image: \"%s\"", ofname);
}
outfile = fopen(ofname, "w");
diff --git a/tools/firmware-utils/src/mkchkimg.c b/tools/firmware-utils/src/mkchkimg.c
index e152f7d4685..0fe01f07079 100644
--- a/tools/firmware-utils/src/mkchkimg.c
+++ b/tools/firmware-utils/src/mkchkimg.c
@@ -31,6 +31,20 @@
#define MAX_BOARD_ID_LEN (64)
+/*
+ * Note on the reserved field of the chk_header:
+ * OFW naming scheme is typically: DEVICENAME-VA.B.C.D_E.F.G.chk, with A-G
+ * between 0 and 255. For instance: EX3700_EX3800-V1.0.0.58_1.0.38.chk
+ * The reserved field works like this:
+ * reserved[0]: region code. 1 for WW (WorldWide) and 2 for NA (North America)
+ * reserved[1]: A
+ * reserved[2]: B
+ * reserved[3]: C
+ * reserved[4]: D
+ * reserved[5]: E
+ * reserved[6]: F
+ * reserved[7]: G
+ */
struct chk_header {
uint32_t magic;
uint32_t header_len;
@@ -248,10 +262,10 @@ main (int argc, char * argv[])
hdr->reserved[1] = 1; /* Major */
hdr->reserved[2] = 1; /* Minor */
hdr->reserved[3] = 99; /* Build */
- hdr->reserved[4] = 0; /* Unknown t1 ? was 1 */
- hdr->reserved[5] = 0; /* Unknonw t2 ? was 0 */
- hdr->reserved[6] = 0; /* Unknonw t3 ? was 1 */
- hdr->reserved[7] = 0; /* Unused ? */
+ hdr->reserved[4] = 0;
+ hdr->reserved[5] = 0;
+ hdr->reserved[6] = 0;
+ hdr->reserved[7] = 0;
message (" Board Id: %s", board_id);
message (" Region: %s", region == 1 ? "World Wide (WW)"
: (region == 2 ? "North America (NA)" : "Unknown"));
diff --git a/tools/firmware-utils/src/mkcsysimg.c b/tools/firmware-utils/src/mkcsysimg.c
index 4f2352a60e7..77fbbaa57fa 100644
--- a/tools/firmware-utils/src/mkcsysimg.c
+++ b/tools/firmware-utils/src/mkcsysimg.c
@@ -160,6 +160,7 @@ static struct board_info boards[] = {
BOARD_ADM("BR-6114WG", "Edimax BR-6114WG", 2, SIG_BR6114WG),
BOARD_ADM("BR-6524K", "Edimax BR-6524K", 2, SIG_BR6524K),
BOARD_ADM("BR-6524KP", "Edimax BR-6524KP", 2, SIG_BR6524KP),
+ BOARD_ADM("BR-6524N", "Edimax BR-6524N", 2, SIG_BR6524N),
BOARD_ADM("BR-6524WG", "Edimax BR-6524WG", 4, SIG_BR6524WG),
BOARD_ADM("BR-6524WP", "Edimax BR-6524WP", 4, SIG_BR6524WP),
BOARD_ADM("BR-6541K", "Edimax BR-6541K", 2, SIG_BR6541K),
@@ -198,7 +199,7 @@ static struct board_info boards[] = {
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", progname, ## __VA_ARGS__ \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", progname, ## __VA_ARGS__ \
, strerror(save)); \
} while (0)
@@ -646,7 +647,7 @@ block_writeout_data(FILE *outfile, struct csys_block *block)
/* write padding data if neccesary */
padlen = block->size_avail - block->file_size;
- DBG(1,"padding block, length=%d", padlen);
+ DBG(1,"padding block, length=%zu", padlen);
res = write_out_padding(outfile, padlen, block->padc, block->css);
return res;
@@ -1121,11 +1122,11 @@ main(int argc, char *argv[])
res = ERR_FATAL;
if (keep_invalid_images == 0) {
- WARN("generation of invalid images disabled", ofname);
+ WARN("generation of invalid images \"%s\" disabled", ofname);
goto out;
}
- WARN("generating invalid image", ofname);
+ WARN("generating invalid image: \"%s\"", ofname);
}
outfile = fopen(ofname, "w");
diff --git a/tools/firmware-utils/src/mkdapimg.c b/tools/firmware-utils/src/mkdapimg.c
new file mode 100644
index 00000000000..ed662d8ecc0
--- /dev/null
+++ b/tools/firmware-utils/src/mkdapimg.c
@@ -0,0 +1,226 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+
+#include <netinet/in.h> // htonl
+
+// Usage: mkdapimg [-p] [-m <model>] -s <sig> -i <input> -o <output>
+//
+// e.g.: mkdapimg -s RT3052-AP-DAP1350-3 -i sysupgarde.bin -o factory.bin
+//
+// If the model string <model> is not given, we will assume that
+// the leading characters upto the first "-" is the model.
+//
+// The "-p" (patch) option is used to patch the exisiting image with the
+// specified model and signature.
+// The "-x" (fix) option will recalculate the payload size and checksum
+// during the patch mode operation.
+
+// The img_hdr_struct was taken from the D-Link SDK:
+// DAP-1350_A1_FW1.11NA_GPL/GPL_Source_Code/Uboot/DAP-1350/httpd/header.h
+
+#define MAX_MODEL_NAME_LEN 20
+#define MAX_SIG_LEN 30
+#define MAX_REGION_LEN 4
+#define MAX_VERSION_LEN 12
+
+struct img_hdr_struct {
+ uint32_t checksum;
+ char model[MAX_MODEL_NAME_LEN];
+ char sig[MAX_SIG_LEN];
+ uint8_t partition;
+ uint8_t hdr_len;
+ uint8_t rsv1;
+ uint8_t rsv2;
+ uint32_t flash_byte_cnt;
+} imghdr ;
+
+char *progname;
+
+void
+perrexit(int code, char *msg)
+{
+ fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
+ exit(code);
+}
+
+void
+usage()
+{
+ fprintf(stderr, "usage: %s [-p] [-m model] [-r region] [-v version] -s signature -i input -o output\n", progname);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ char model[MAX_MODEL_NAME_LEN+1];
+ char signature[MAX_SIG_LEN+1];
+ char region[MAX_REGION_LEN+1];
+ char version[MAX_VERSION_LEN+1];
+ int patchmode = 0;
+ int fixmode = 0;
+ int have_regionversion = 0;
+
+ FILE *ifile, *ofile;
+ int c;
+ uint32_t cksum;
+ uint32_t bcnt;
+
+ progname = basename(av[0]);
+ memset(model, 0, sizeof(model));
+ memset(signature, 0, sizeof(signature));
+ memset(region, 0, sizeof(region));
+ memset(version, 0, sizeof(version));
+
+ while ( 1 ) {
+ int c;
+
+ c = getopt(ac, av, "pxm:r:v:s:i:o:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'p':
+ patchmode = 1;
+ break;
+ case 'x':
+ fixmode = 1;
+ break;
+ case 'm':
+ if (strlen(optarg) > MAX_MODEL_NAME_LEN) {
+ fprintf(stderr, "%s: model name exceeds %d chars\n",
+ progname, MAX_MODEL_NAME_LEN);
+ exit(1);
+ }
+ strcpy(model, optarg);
+ break;
+ case 'r':
+ if (strlen(optarg) > MAX_REGION_LEN) {
+ fprintf(stderr, "%s: region exceeds %d chars\n",
+ progname, MAX_REGION_LEN);
+ exit(1);
+ }
+ have_regionversion = 1;
+ strcpy(region, optarg);
+ break;
+ case 'v':
+ if (strlen(optarg) > MAX_VERSION_LEN) {
+ fprintf(stderr, "%s: version exceeds %d chars\n",
+ progname, MAX_VERSION_LEN);
+ exit(1);
+ }
+ have_regionversion = 1;
+ strcpy(version, optarg);
+ break;
+ case 's':
+ if (strlen(optarg) > MAX_SIG_LEN) {
+ fprintf(stderr, "%s: signature exceeds %d chars\n",
+ progname, MAX_SIG_LEN);
+ exit(1);
+ }
+ strcpy(signature, optarg);
+ break;
+ case 'i':
+ if ((ifile = fopen(optarg, "r")) == NULL)
+ perrexit(1, optarg);
+ break;
+ case 'o':
+ if ((ofile = fopen(optarg, "w")) == NULL)
+ perrexit(1, optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (signature[0] == 0 || ifile == NULL || ofile == NULL) {
+ usage();
+ }
+
+ if (model[0] == 0) {
+ char *p = strchr(signature, '-');
+ if (p == NULL) {
+ fprintf(stderr, "%s: model name unknown\n", progname);
+ exit(1);
+ }
+ if (p - signature > MAX_MODEL_NAME_LEN) {
+ *p = 0;
+ fprintf(stderr, "%s: auto model name failed, string %s too long\n", progname, signature);
+ exit(1);
+ }
+ strncpy(model, signature, p - signature);
+ }
+
+ if (patchmode) {
+ if (fread(&imghdr, sizeof(imghdr), 1, ifile) < 0)
+ perrexit(2, "fread on input");
+ }
+
+ for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++)
+ cksum += c & 0xff;
+
+ if (fseek(ifile, patchmode ? sizeof(imghdr) : 0, SEEK_SET) < 0)
+ perrexit(2, "fseek on input");
+
+ if (patchmode == 0) {
+ // Fill in the header
+ memset(&imghdr, 0, sizeof(imghdr));
+ imghdr.checksum = htonl(cksum);
+ imghdr.partition = 0 ; // don't care?
+ imghdr.hdr_len = sizeof(imghdr);
+ if (have_regionversion) {
+ imghdr.hdr_len += MAX_REGION_LEN;
+ imghdr.hdr_len += MAX_VERSION_LEN;
+ }
+ imghdr.flash_byte_cnt = htonl(bcnt);
+ } else {
+ if (ntohl(imghdr.checksum) != cksum) {
+ fprintf(stderr, "%s: patch mode, checksum mismatch\n",
+ progname);
+ if (fixmode) {
+ fprintf(stderr, "%s: fixing\n", progname);
+ imghdr.checksum = htonl(cksum);
+ } else
+ exit(3);
+ } else if (ntohl(imghdr.flash_byte_cnt) != bcnt) {
+ fprintf(stderr, "%s: patch mode, size mismatch\n",
+ progname);
+ if (fixmode) {
+ fprintf(stderr, "%s: fixing\n", progname);
+ imghdr.flash_byte_cnt = htonl(bcnt);
+ } else
+ exit(3);
+ }
+ }
+
+ strncpy(imghdr.model, model, MAX_MODEL_NAME_LEN);
+ strncpy(imghdr.sig, signature, MAX_SIG_LEN);
+
+ if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
+ perrexit(2, "fwrite header on output");
+ if (have_regionversion) {
+ if (fwrite(&region, MAX_REGION_LEN, 1, ofile) < 0)
+ perrexit(2, "fwrite header on output");
+ if (fwrite(&version, MAX_VERSION_LEN, 1, ofile) < 0)
+ perrexit(2, "fwrite header on output");
+ }
+
+ while ((c = fgetc(ifile)) != EOF) {
+ if (fputc(c, ofile) == EOF)
+ perrexit(2, "fputc on output");
+ }
+
+ if (ferror(ifile))
+ perrexit(2, "fgetc on input");
+
+
+ fclose(ofile);
+ fclose(ifile);
+}
diff --git a/tools/firmware-utils/src/mkdapimg2.c b/tools/firmware-utils/src/mkdapimg2.c
new file mode 100644
index 00000000000..aef003c280c
--- /dev/null
+++ b/tools/firmware-utils/src/mkdapimg2.c
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ *
+ * (C) Nicolò Veronese <nicveronese@gmail.com>
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+
+#include <netinet/in.h> // htonl
+
+// Usage: mkdapimg2 -s signature [-v version] [-r region]
+// [-k uImage block size] -i <input> -o <output>
+//
+// NOTE: The kernel block size is used to know the offset of the rootfs
+// in the image file.
+//
+// The system writes in the uImage partition until the end of uImage
+// is reached, after that, the system jumps to the offset specified with the -k
+// parameter and begin writing at the beginning of the rootfs MTD partition.
+//
+// If the -k parameter is the size of the original uImage partition, the system
+// continue writing in the rootfs partition starting from the last block
+// that has been wrote. (This is useful if the new kernel size is
+// different from the original one)
+//
+// Example:
+// ------------------------------------------
+// Creating 7 MTD partitions on "ath-nor0":
+// 0x000000000000-0x000000010000 : "u-boot"
+// 0x000000010000-0x000000020000 : "ART"
+// 0x000000020000-0x000000030000 : "MP"
+// 0x000000030000-0x000000040000 : "config"
+// 0x000000040000-0x000000120000 : "uImage"
+// 0x000000120000-0x000000800000 : "rootfs"
+// 0x000000040000-0x000000800000 : "firmware"
+// ------------------------------------------
+//
+// 0x000000120000-0x000000040000 = 0xE0000 -> 917504
+//
+// e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default
+// -k 917504 -i sysupgarde.bin -o factory.bin
+//
+//
+// The img_hdr_struct was taken from the D-Link SDK:
+// DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch
+
+#define MAX_SIGN_LEN 32
+#define MAX_FW_VER_LEN 16
+#define MAX_REG_LEN 8
+
+struct img_hdr_struct {
+ uint32_t hdr_len;
+ uint32_t checksum;
+ uint32_t total_size;
+ uint32_t kernel_size;
+ char signature[MAX_SIGN_LEN];
+ char fw_ver[MAX_FW_VER_LEN];
+ char fw_reg[MAX_REG_LEN];
+} imghdr ;
+
+char *progname;
+
+void
+perrexit(int code, char *msg)
+{
+ fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
+ exit(code);
+}
+
+void
+usage()
+{
+ fprintf(stderr, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname);
+ exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+ char signature[MAX_SIGN_LEN];
+ char version[MAX_FW_VER_LEN];
+ char region[MAX_REG_LEN];
+ int kernel = 0;
+
+ FILE *ifile, *ofile;
+ int c;
+
+ uint32_t cksum;
+ uint32_t bcnt;
+
+ progname = basename(av[0]);
+
+ memset(signature, 0, sizeof(signature));
+ memset(version, 0, sizeof(version));
+ memset(region, 0, sizeof(region));
+
+ while ( 1 ) {
+ char *ptr;
+ int c;
+
+ c = getopt(ac, av, "s:v:r:k:i:o:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 's':
+ if (strlen(optarg) > MAX_SIGN_LEN + 1) {
+ fprintf(stderr, "%s: signature exceeds %d chars\n",
+ progname, MAX_SIGN_LEN);
+ exit(1);
+ }
+ strcpy(signature, optarg);
+ break;
+ case 'v':
+ if (strlen(optarg) > MAX_FW_VER_LEN + 1) {
+ fprintf(stderr, "%s: version exceeds %d chars\n",
+ progname, MAX_FW_VER_LEN);
+ exit(1);
+ }
+ strcpy(version, optarg);
+ break;
+ case 'r':
+ if (strlen(optarg) > MAX_REG_LEN + 1) {
+ fprintf(stderr, "%s: region exceeds %d chars\n",
+ progname, MAX_REG_LEN);
+ exit(1);
+ }
+ strcpy(region, optarg);
+ break;
+ case 'k':
+ kernel = strtoul(optarg, &ptr, 0);
+ if(ptr[0] == 'k'){
+ kernel *= 1000;
+ }
+ break;
+ case 'i':
+ if ((ifile = fopen(optarg, "r")) == NULL)
+ perrexit(1, optarg);
+ break;
+ case 'o':
+ if ((ofile = fopen(optarg, "w")) == NULL)
+ perrexit(1, optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (signature[0] == 0 || ifile == NULL || ofile == NULL) {
+ usage();
+ exit(1);
+ }
+
+ for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++)
+ cksum += c & 0xff;
+
+ if (fseek(ifile, 0, SEEK_SET) < 0)
+ perrexit(2, "fseek on input");
+
+ // Fill in the header
+ memset(&imghdr, 0, sizeof(imghdr));
+ imghdr.hdr_len = sizeof(imghdr);
+ imghdr.checksum = htonl(cksum);
+ imghdr.total_size = htonl(bcnt);
+ imghdr.kernel_size = htonl(kernel);
+
+ strncpy(imghdr.signature, signature, MAX_SIGN_LEN);
+ strncpy(imghdr.fw_ver, version, MAX_FW_VER_LEN);
+ strncpy(imghdr.fw_reg, region, MAX_REG_LEN);
+
+ if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
+ perrexit(2, "fwrite header on output");
+
+ while ((c = fgetc(ifile)) != EOF) {
+ if (fputc(c, ofile) == EOF)
+ perrexit(2, "fputc on output");
+ }
+
+ if (ferror(ifile))
+ perrexit(2, "fgetc on input");
+
+ fclose(ofile);
+ fclose(ifile);
+
+ fprintf(stderr, "imgHdr.hdr_len = %lu\n", sizeof(imghdr));
+ fprintf(stderr, "imgHdr.checksum = 0x%08x\n", cksum);
+ fprintf(stderr, "imgHdr.total_size = 0x%08x\n", bcnt);
+ fprintf(stderr, "imgHdr.kernel_size = 0x%08x\n", kernel);
+ fprintf(stderr, "imgHdr.header = %s\n", signature);
+ fprintf(stderr, "imgHdr.fw_ver = %s\n", version);
+ fprintf(stderr, "imgHdr.fw_reg = %s\n", region);
+
+ return 0;
+}
diff --git a/tools/firmware-utils/src/mkdcs932.c b/tools/firmware-utils/src/mkdcs932.c
new file mode 100644
index 00000000000..28c67aa3b30
--- /dev/null
+++ b/tools/firmware-utils/src/mkdcs932.c
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ * (C) John Crispin <blogic@openwrt.org>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main(int argc, char **argv)
+{
+ uint32_t t = 0, sum = 0x55aa55aa;
+ int fd;
+
+ if ((argc != 2) || ((fd = open(argv[1], O_RDWR)) == -1)) {
+ fprintf(stderr, "Usage: %s input_file\n", *argv);
+ return -EINVAL;
+ }
+
+ lseek(fd, -4, SEEK_END);
+ write(fd, &t, 4);
+ lseek(fd, 0, SEEK_SET);
+
+ while (read(fd, &t, 4) > 0)
+ sum -= t;
+
+ lseek(fd, -4, SEEK_END);
+ write(fd, &sum, 4);
+ close(fd);
+
+ return 0;
+}
diff --git a/tools/firmware-utils/src/mkdhpimg.c b/tools/firmware-utils/src/mkdhpimg.c
new file mode 100644
index 00000000000..e61d0425043
--- /dev/null
+++ b/tools/firmware-utils/src/mkdhpimg.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016 FUKAUMI Naoki <naobsd@gmail.com>
+ *
+ * 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 <sys/stat.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "buffalo-lib.h"
+
+#define DHP_HEADER_SIZE 20
+
+static char *progname;
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "usage: %s <in> <out>\n", progname);
+ exit(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat in_st;
+ size_t size;
+ uint32_t crc;
+ int in, out;
+ uint8_t *buf;
+
+ progname = argv[0];
+
+ if (argc != 3)
+ usage();
+
+ if ((in = open(argv[1], O_RDONLY)) == -1)
+ err(EXIT_FAILURE, "%s", argv[1]);
+
+ if (fstat(in, &in_st) == -1)
+ err(EXIT_FAILURE, "%s", argv[1]);
+
+ size = DHP_HEADER_SIZE + in_st.st_size;
+
+ if ((buf = malloc(size)) == NULL)
+ err(EXIT_FAILURE, "malloc");
+
+ memset(buf, 0, DHP_HEADER_SIZE);
+ buf[0x0] = 0x62;
+ buf[0x1] = 0x67;
+ buf[0x2] = 0x6e;
+ buf[0xb] = 0xb1;
+ buf[0xc] = (size >> 24) & 0xff;
+ buf[0xd] = (size >> 16) & 0xff;
+ buf[0xe] = (size >> 8) & 0xff;
+ buf[0xf] = size & 0xff;
+
+ read(in, &buf[DHP_HEADER_SIZE], in_st.st_size);
+ close(in);
+
+ crc = buffalo_crc(buf, size);
+ buf[0x10] = (crc >> 24) & 0xff;
+ buf[0x11] = (crc >> 16) & 0xff;
+ buf[0x12] = (crc >> 8) & 0xff;
+ buf[0x13] = crc & 0xff;
+
+ if ((out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
+ err(EXIT_FAILURE, "%s", argv[2]);
+ write(out, buf, size);
+ close(out);
+
+ free(buf);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.c b/tools/firmware-utils/src/mkdlinkfw-lib.c
new file mode 100644
index 00000000000..fcab8562319
--- /dev/null
+++ b/tools/firmware-utils/src/mkdlinkfw-lib.c
@@ -0,0 +1,172 @@
+/*
+ * mkdlinkfw
+ *
+ * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com>
+ *
+ * This tool is based on mktplinkfw.
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * 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 as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#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 <stdbool.h>
+#include <endian.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <zlib.h> /*for crc32 */
+
+#include "mkdlinkfw-lib.h"
+
+extern char *progname;
+
+static unsigned char jffs2_eof_mark[4] = { 0xde, 0xad, 0xc0, 0xde };
+
+uint32_t jboot_timestamp(void)
+{
+ time_t rawtime;
+ time(&rawtime);
+ return (((uint32_t) rawtime) - TIMESTAMP_MAGIC) >> 2;
+}
+
+uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size)
+{
+ uint32_t counter = start_val;
+ uint16_t *ptr = data;
+
+ while (size > 1) {
+ counter += *ptr;
+ ++ptr;
+ while (counter >> 16)
+ counter = (uint16_t) counter + (counter >> 16);
+ size -= 2;
+ }
+ if (size > 0) {
+ counter += *(uint8_t *) ptr;
+ counter -= 0xFF;
+ }
+ while (counter >> 16)
+ counter = (uint16_t) counter + (counter >> 16);
+ return counter;
+}
+
+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;
+}
+
+int read_to_buf(const 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;
+}
+
+int pad_jffs2(char *buf, int currlen, int maxlen)
+{
+ int len;
+ uint32_t pad_mask;
+
+ len = currlen;
+ pad_mask = (4 * 1024) | (64 * 1024); /* EOF at 4KB and at 64KB */
+ while ((len < maxlen) && (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;
+}
+
+int write_fw(const char *ofname, const 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;
+}
diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.h b/tools/firmware-utils/src/mkdlinkfw-lib.h
new file mode 100644
index 00000000000..d61124cb636
--- /dev/null
+++ b/tools/firmware-utils/src/mkdlinkfw-lib.h
@@ -0,0 +1,83 @@
+/*
+ * mkdlinkfw
+ *
+ * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com>
+ *
+ * This tool is based on mktplinkfw.
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * 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 as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef mkdlinkfw_lib_h
+#define mkdlinkfw_lib_h
+
+#define AUH_MAGIC "DLK"
+#define AUH_SIZE 80
+#define AUH_LVPS 0x01
+#define AUH_HDR_ID 0x4842
+#define AUH_HDR_VER 0x02
+#define AUH_SEC_ID 0x04
+#define AUH_INFO_TYPE 0x04
+
+#define STAG_SIZE 16
+#define STAG_ID 0x04
+#define STAG_MAGIC 0x2B24
+#define STAG_CMARK_FACTORY 0xFF
+
+#define SCH2_SIZE 40
+#define SCH2_MAGIC 0x2124
+#define SCH2_VER 0x02
+
+#define FLAT 0
+#define JZ 1
+#define GZIP 2
+#define LZMA 3
+
+#define RAM_ENTRY_ADDR 0x80000000
+#define RAM_LOAD_ADDR 0x80000000
+#define JBOOT_SIZE 0x10000
+
+#define ALL_HEADERS_SIZE (AUH_SIZE + STAG_SIZE + SCH2_SIZE)
+#define MAX_HEADER_COUNTER 10
+#define TIMESTAMP_MAGIC 0x35016f00L
+
+#define FACTORY 0
+#define SYSUPGRADE 1
+
+#define ALIGN(x, a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
+
+#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 ": %s\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__); \
+} while (0)
+
+struct file_info {
+ char *file_name; /* name of the file */
+ uint32_t file_size; /* length of the file */
+};
+
+uint32_t jboot_timestamp(void);
+uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size);
+int get_file_stat(struct file_info *fdata);
+int read_to_buf(const struct file_info *fdata, char *buf);
+int pad_jffs2(char *buf, int currlen, int maxlen);
+int write_fw(const char *ofname, const char *data, int len);
+
+#endif /* mkdlinkfw_lib_h */
diff --git a/tools/firmware-utils/src/mkdlinkfw.c b/tools/firmware-utils/src/mkdlinkfw.c
new file mode 100644
index 00000000000..87605004fe9
--- /dev/null
+++ b/tools/firmware-utils/src/mkdlinkfw.c
@@ -0,0 +1,665 @@
+/*
+ * mkdlinkfw
+ *
+ * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com>
+ *
+ * This tool is based on mktplinkfw.
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * 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 as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#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 <stdbool.h>
+#include <endian.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <zlib.h> /*for crc32 */
+
+#include "mkdlinkfw-lib.h"
+
+/* ARM update header 2.0
+ * used only in factory images to erase and flash selected area
+ */
+struct auh_header {
+ uint8_t rom_id[12]; /* 12-bit rom-id unique per router type */
+ uint16_t derange; /* used for scramble header */
+ uint16_t image_checksum; /* jboot_checksum of flashed data */
+
+ uint32_t space1; /* zeros */
+ uint32_t space2; /* zeros */
+ uint16_t space3; /* zerosu */
+ uint8_t lpvs; /* must be 0x01 */
+ uint8_t mbz; /* bust be 0 */
+ uint32_t time_stamp; /* timestamp calculated in jboot way */
+
+ uint32_t erase_start; /* erase start address */
+ uint32_t erase_length; /* erase length address */
+ uint32_t data_offset; /* data start address */
+ uint32_t data_length; /* data length address */
+
+ uint32_t space4; /* zeros */
+ uint32_t space5; /* zeros */
+ uint32_t space6; /* zeros */
+ uint32_t space7; /* zeros */
+
+ uint16_t header_id; /* magic 0x4842 */
+ uint16_t header_version; /* 0x02 for 2.0 */
+ uint16_t space8; /* zeros */
+ uint8_t section_id; /* section id */
+ uint8_t image_info_type; /* (?) 0x04 in factory images */
+ uint32_t image_info_offset; /* (?) zeros in factory images */
+ uint16_t family_member; /* unique per router type */
+ uint16_t header_checksum; /* negated jboot_checksum of header data */
+};
+
+struct stag_header { /* used only of sch2 wrapped kernel data */
+ uint8_t cmark; /* in factory 0xFF ,in sysuograde must be the same as id */
+ uint8_t id; /* 0x04 */
+ uint16_t magic; /* magic 0x2B24 */
+ uint32_t time_stamp; /* timestamp calculated in jboot way */
+ uint32_t image_length; /* lentgh of kernel + sch2 header */
+ uint16_t image_checksum; /* negated jboot_checksum of sch2 + kernel */
+ uint16_t tag_checksum; /* negated jboot_checksum of stag header data */
+};
+
+struct sch2_header { /* used only in kernel partitions */
+ uint16_t magic; /* magic 0x2124 */
+ uint8_t cp_type; /* 0x00 for flat, 0x01 for jz, 0x02 for gzip, 0x03 for lzma */
+ uint8_t version; /* 0x02 for sch2 */
+ uint32_t ram_addr; /* ram entry address */
+ uint32_t image_len; /* kernel image length */
+ uint32_t image_crc32; /* kernel image crc */
+ uint32_t start_addr; /* ram start address */
+ uint32_t rootfs_addr; /* rootfs flash address */
+ uint32_t rootfs_len; /* rootfls length */
+ uint32_t rootfs_crc32; /* rootfs crc32 */
+ uint32_t header_crc32; /* sch2 header crc32, durring calculation this area is replaced by zero */
+ uint16_t header_length; /* sch2 header length: 0x28 */
+ uint16_t cmd_line_length; /* cmd line length, known zeros */
+};
+
+/* globals */
+static struct file_info inspect_info;
+struct file_info kernel_info;
+struct file_info rootfs_info;
+struct file_info image_info;
+
+char *ofname;
+char *progname;
+uint32_t firmware_size;
+uint16_t family_member;
+char *rom_id[12] = { 0 };
+
+char image_type;
+int add_jffs2_eof;
+
+static void usage(int status)
+{
+ fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stderr,
+ "\n"
+ "Options:\n"
+ " -i <file> inspect given firmware file <file>\n"
+ " -f set family member id (hexval prefixed with 0x)\n"
+ " -F <file> read image and convert it to FACTORY\n"
+ " -k <file> read kernel image from the file <file>\n"
+ " -r <file> read rootfs image from the file <file>\n"
+ " -o <file> write output to the file <file>\n"
+ " -s <size> set firmware partition size\n"
+ " -m <version> set rom id to <version> (12-bit string val: \"DLK*********\")\n"
+ " -h show this screen\n");
+
+ exit(status);
+}
+
+void print_auh_header(struct auh_header *printed_header)
+{
+ printf("\trom_id: %s\n"
+ "\tderange: 0x%04X\n"
+ "\timage_checksum: 0x%04X\n"
+ "\tspace1: 0x%08X\n"
+ "\tspace2: 0x%08X\n"
+ "\tspace3: 0x%04X\n"
+ "\tlpvs: 0x%02X\n"
+ "\tmbz: 0x%02X\n"
+ "\ttime_stamp: 0x%08X\n"
+ "\terase_start: 0x%08X\n"
+ "\terase_length: 0x%08X\n"
+ "\tdata_offset: 0x%08X\n"
+ "\tdata_length: 0x%08X\n"
+ "\tspace4: 0x%08X\n"
+ "\tspace5: 0x%08X\n"
+ "\tspace6: 0x%08X\n"
+ "\tspace7: 0x%08X\n"
+ "\theader_id: 0x%04X\n"
+ "\theader_version: 0x%02X\n"
+ "\tspace8: 0x%04X\n"
+ "\tsection_id: 0x%02X\n"
+ "\timage_info_type: 0x%02X\n"
+ "\timage_info_offset 0x%08X\n"
+ "\tfamily_member: 0x%04X\n"
+ "\theader_checksum: 0x%04X\n",
+ printed_header->rom_id,
+ printed_header->derange,
+ printed_header->image_checksum,
+ printed_header->space1,
+ printed_header->space2,
+ printed_header->space3,
+ printed_header->lpvs,
+ printed_header->mbz,
+ printed_header->time_stamp,
+ printed_header->erase_start,
+ printed_header->erase_length,
+ printed_header->data_offset,
+ printed_header->data_length,
+ printed_header->space4,
+ printed_header->space5,
+ printed_header->space6,
+ printed_header->space7,
+ printed_header->header_id,
+ printed_header->header_version,
+ printed_header->space8,
+ printed_header->section_id,
+ printed_header->image_info_type,
+ printed_header->image_info_offset,
+ printed_header->family_member, printed_header->header_checksum);
+}
+
+void print_stag_header(struct stag_header *printed_header)
+{
+ printf("\tcmark: 0x%02X\n"
+ "\tid: 0x%02X\n"
+ "\tmagic: 0x%04X\n"
+ "\ttime_stamp: 0x%08X\n"
+ "\timage_length: 0x%04X\n"
+ "\timage_checksum: 0x%04X\n"
+ "\ttag_checksum: 0x%04X\n",
+ printed_header->cmark,
+ printed_header->id,
+ printed_header->magic,
+ printed_header->time_stamp,
+ printed_header->image_length,
+ printed_header->image_checksum, printed_header->tag_checksum);
+}
+
+void print_sch2_header(struct sch2_header *printed_header)
+{
+ printf("\tmagic: 0x%04X\n"
+ "\tcp_type: 0x%02X\n"
+ "\tversion: 0x%02X\n"
+ "\tram_addr: 0x%08X\n"
+ "\timage_len: 0x%08X\n"
+ "\timage_crc32: 0x%08X\n"
+ "\tstart_addr: 0x%08X\n"
+ "\trootfs_addr: 0x%08X\n"
+ "\trootfs_len: 0x%08X\n"
+ "\trootfs_crc32: 0x%08X\n"
+ "\theader_crc32: 0x%08X\n"
+ "\theader_length: 0x%04X\n"
+ "\tcmd_line_length: 0x%04X\n",
+ printed_header->magic,
+ printed_header->cp_type,
+ printed_header->version,
+ printed_header->ram_addr,
+ printed_header->image_len,
+ printed_header->image_crc32,
+ printed_header->start_addr,
+ printed_header->rootfs_addr,
+ printed_header->rootfs_len,
+ printed_header->rootfs_crc32,
+ printed_header->header_crc32,
+ printed_header->header_length, printed_header->cmd_line_length);
+}
+
+static int find_auh_headers(char *buf)
+{
+ char *tmp_buf = buf;
+ struct auh_header *tmp_header[MAX_HEADER_COUNTER];
+ int header_counter = 0;
+
+ int ret = EXIT_FAILURE;
+
+ while (tmp_buf - buf <= inspect_info.file_size - AUH_SIZE) {
+ if (!memcmp(tmp_buf, AUH_MAGIC, 3)) {
+ if (((struct auh_header *)tmp_buf)->header_checksum ==
+ (uint16_t) ~jboot_checksum(0, (uint16_t *) tmp_buf,
+ AUH_SIZE - 2)) {
+ uint16_t checksum = 0;
+ printf("Find proper AUH header at: 0x%lX!\n",
+ tmp_buf - buf);
+ tmp_header[header_counter] =
+ (struct auh_header *)tmp_buf;
+ checksum =
+ jboot_checksum(0, (uint16_t *) ((char *)
+ tmp_header
+ [header_counter]
+ + AUH_SIZE),
+ tmp_header
+ [header_counter]->data_length);
+ if (tmp_header[header_counter]->image_checksum
+ == checksum)
+ printf("Image checksum ok.\n");
+ else
+ ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", tmp_header[header_counter]->image_checksum, checksum);
+ header_counter++;
+ if (header_counter > MAX_HEADER_COUNTER)
+ break;
+ }
+ }
+ tmp_buf++;
+ }
+
+ if (header_counter == 0)
+ ERR("Can't find proper AUH header!\n");
+ else if (header_counter > MAX_HEADER_COUNTER)
+ ERR("To many AUH headers!\n");
+ else {
+ for (int i = 0; i < header_counter; i++) {
+ printf("AUH %d:\n", i);
+ print_auh_header(tmp_header[i]);
+ }
+
+ ret = EXIT_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int check_stag_header(char *buf, struct stag_header *header)
+{
+
+ int ret = EXIT_FAILURE;
+
+ uint8_t cmark_tmp = header->cmark;
+ header->cmark = header->id;
+
+ if (header->tag_checksum ==
+ (uint16_t) ~jboot_checksum(0, (uint16_t *) header,
+ STAG_SIZE - 2)) {
+ uint16_t checksum = 0;
+ printf("Find proper STAG header at: 0x%lX!\n",
+ (char *)header - buf);
+ checksum =
+ jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE),
+ header->image_length);
+ if (header->image_checksum == checksum) {
+ printf("Image checksum ok.\n");
+ header->cmark = cmark_tmp;
+ print_stag_header(header);
+ ret = EXIT_SUCCESS;
+ } else
+ ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_checksum, checksum);
+ } else
+ ERR("STAG header checksum incorrect!");
+
+ header->cmark = cmark_tmp;
+ return ret;
+}
+
+static int check_sch2_header(char *buf, struct sch2_header *header)
+{
+
+ int ret = EXIT_FAILURE;
+
+ uint32_t crc32_tmp = header->header_crc32;
+ header->header_crc32 = 0;
+
+ if (crc32_tmp == crc32(0, (uint8_t *) header, header->header_length)) {
+ uint32_t crc32_val;
+ printf("Find proper SCH2 header at: 0x%lX!\n",
+ (char *)header - buf);
+
+ crc32_val =
+ crc32(0, (uint8_t *) header + header->header_length,
+ header->image_len);
+ if (header->image_crc32 == crc32_val) {
+ printf("Kernel checksum ok.\n");
+
+ header->header_crc32 = crc32_tmp;
+ print_sch2_header(header);
+ ret = EXIT_SUCCESS;
+ } else
+ ERR("Kernel checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_crc32, crc32_val);
+
+ } else
+ ERR("SCH2 header checksum incorrect!");
+
+ header->header_crc32 = crc32_tmp;
+ return ret;
+}
+
+static int inspect_fw(void)
+{
+ char *buf;
+ struct stag_header *stag_header_kernel;
+ struct sch2_header *sch2_header_kernel;
+ 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;
+
+ ret = find_auh_headers(buf);
+ if (ret)
+ goto out_free_buf;
+
+ stag_header_kernel = (struct stag_header *)(buf + AUH_SIZE);
+
+ ret = check_stag_header(buf, stag_header_kernel);
+ if (ret)
+ goto out_free_buf;
+
+ sch2_header_kernel = (struct sch2_header *)(buf + AUH_SIZE + STAG_SIZE);
+
+ ret = check_sch2_header(buf, sch2_header_kernel);
+ if (ret)
+ goto out_free_buf;
+
+ out_free_buf:
+ free(buf);
+ 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;
+ }
+
+ return 0;
+}
+
+int fill_sch2(struct sch2_header *header, char *kernel_ptr, char *rootfs_ptr)
+{
+
+ header->magic = SCH2_MAGIC;
+ header->cp_type = LZMA;
+ header->version = SCH2_VER;
+ header->ram_addr = RAM_LOAD_ADDR;
+ header->image_len = kernel_info.file_size;
+ header->image_crc32 = crc32(0, (uint8_t *) kernel_ptr, kernel_info.file_size);
+ header->start_addr = RAM_ENTRY_ADDR;
+ header->rootfs_addr =
+ JBOOT_SIZE + STAG_SIZE + SCH2_SIZE + kernel_info.file_size;
+ header->rootfs_len = rootfs_info.file_size;
+ header->rootfs_crc32 = crc32(0, (uint8_t *) rootfs_ptr, rootfs_info.file_size);
+ header->header_crc32 = 0;
+ header->header_length = SCH2_SIZE;
+ header->cmd_line_length = 0;
+
+ header->header_crc32 = crc32(0, (uint8_t *) header, header->header_length);
+
+ return EXIT_SUCCESS;
+}
+
+int fill_stag(struct stag_header *header, uint32_t length)
+{
+ header->cmark = STAG_ID;
+ header->id = STAG_ID;
+ header->magic = STAG_MAGIC;
+ header->time_stamp = jboot_timestamp();
+ header->image_length = length + SCH2_SIZE;
+ header->image_checksum =
+ jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE),
+ header->image_length);
+ header->tag_checksum =
+ ~jboot_checksum(0, (uint16_t *) header, STAG_SIZE - 2);
+
+ if (image_type == FACTORY)
+ header->cmark = STAG_CMARK_FACTORY;
+
+ return EXIT_SUCCESS;
+};
+
+int fill_auh(struct auh_header *header, uint32_t length)
+{
+ memcpy(header->rom_id, rom_id, 12);
+ header->derange = 0;
+ header->image_checksum =
+ jboot_checksum(0, (uint16_t *) ((char *)header + AUH_SIZE), length);
+ header->space1 = 0;
+ header->space2 = 0;
+ header->space3 = 0;
+ header->lpvs = AUH_LVPS;
+ header->mbz = 0;
+ header->time_stamp = jboot_timestamp();
+ header->erase_start = JBOOT_SIZE;
+ header->erase_length = firmware_size;
+ header->data_offset = JBOOT_SIZE;
+ header->data_length = length;
+ header->space4 = 0;
+ header->space5 = 0;
+ header->space6 = 0;
+ header->space7 = 0;
+ header->header_id = AUH_HDR_ID;
+ header->header_version = AUH_HDR_VER;
+ header->space8 = 0;
+ header->section_id = AUH_SEC_ID;
+ header->image_info_type = AUH_INFO_TYPE;
+ header->image_info_offset = 0;
+ header->family_member = family_member;
+ header->header_checksum =
+ ~jboot_checksum(0, (uint16_t *) header, AUH_SIZE - 2);
+
+ return EXIT_SUCCESS;
+}
+
+int build_fw(void)
+{
+ char *buf;
+ char *kernel_ptr;
+ char *rootfs_ptr;
+ int ret = EXIT_FAILURE;
+ int writelen;
+
+ struct stag_header *stag_header_kernel;
+ struct sch2_header *sch2_header_kernel;
+
+ if (!kernel_info.file_name | !rootfs_info.file_name)
+ goto out;
+
+ ret = get_file_stat(&kernel_info);
+ if (ret)
+ goto out;
+ ret = get_file_stat(&rootfs_info);
+ if (ret)
+ goto out;
+
+ buf = malloc(firmware_size);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ if (rootfs_info.file_size + kernel_info.file_size + ALL_HEADERS_SIZE >
+ firmware_size) {
+ ERR("data is bigger than firmware_size!\n");
+ goto out;
+ }
+
+ memset(buf, 0xff, firmware_size);
+
+ stag_header_kernel = (struct stag_header *)buf;
+
+ sch2_header_kernel =
+ (struct sch2_header *)((char *)stag_header_kernel + STAG_SIZE);
+ kernel_ptr = (char *)sch2_header_kernel + SCH2_SIZE;
+
+ ret = read_to_buf(&kernel_info, kernel_ptr);
+ if (ret)
+ goto out_free_buf;
+
+ rootfs_ptr = kernel_ptr + kernel_info.file_size;
+
+ ret = read_to_buf(&rootfs_info, rootfs_ptr);
+ if (ret)
+ goto out_free_buf;
+
+ writelen = rootfs_ptr + rootfs_info.file_size - buf;
+
+ fill_sch2(sch2_header_kernel, kernel_ptr, rootfs_ptr);
+ fill_stag(stag_header_kernel, kernel_info.file_size);
+
+ ret = write_fw(ofname, buf, writelen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+ out_free_buf:
+ free(buf);
+ out:
+ return ret;
+}
+
+int wrap_fw(void)
+{
+ char *buf;
+ char *image_ptr;
+ int ret = EXIT_FAILURE;
+ int writelen;
+
+ struct auh_header *auh_header_kernel;
+
+ if (!image_info.file_name)
+ goto out;
+
+ ret = get_file_stat(&image_info);
+ if (ret)
+ goto out;
+
+ buf = malloc(firmware_size);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ if (image_info.file_size + AUH_SIZE >
+ firmware_size) {
+ ERR("data is bigger than firmware_size!\n");
+ goto out;
+ }
+ if (!family_member) {
+ ERR("No family_member!\n");
+ goto out;
+ }
+ if (!(rom_id[0])) {
+ ERR("No rom_id!\n");
+ goto out;
+ }
+ memset(buf, 0xff, firmware_size);
+
+ image_ptr = (char *)(buf + AUH_SIZE);
+
+ ret = read_to_buf(&image_info, image_ptr);
+ if (ret)
+ goto out_free_buf;
+
+ writelen = image_ptr + image_info.file_size - buf;
+
+ auh_header_kernel = (struct auh_header *)buf;
+ fill_auh(auh_header_kernel, writelen - AUH_SIZE);
+
+ ret = write_fw(ofname, buf, writelen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+ out_free_buf:
+ free(buf);
+ out:
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+
+ progname = basename(argv[0]);
+ image_type = SYSUPGRADE;
+ family_member = 0;
+ firmware_size = 0;
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "f:F:i:hk:m:o:r:s:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'f':
+ sscanf(optarg, "0x%hx", &family_member);
+ break;
+ case 'F':
+ image_info.file_name = optarg;
+ image_type = FACTORY;
+ break;
+ case 'i':
+ inspect_info.file_name = optarg;
+ break;
+ case 'k':
+ kernel_info.file_name = optarg;
+ break;
+ case 'm':
+ if (strlen(optarg) == 12)
+ memcpy(rom_id, optarg, 12);
+ break;
+ case 'r':
+ rootfs_info.file_name = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 's':
+ sscanf(optarg, "0x%x", &firmware_size);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret)
+ goto out;
+
+ if (!inspect_info.file_name) {
+ if (image_type == FACTORY)
+ ret = wrap_fw();
+ else
+ ret = build_fw();
+ }
+ else
+ ret = inspect_fw();
+
+ out:
+ return ret;
+
+}
diff --git a/tools/firmware-utils/src/mkdniimg.c b/tools/firmware-utils/src/mkdniimg.c
index 7230f09d492..852b07dd9f6 100644
--- a/tools/firmware-utils/src/mkdniimg.c
+++ b/tools/firmware-utils/src/mkdniimg.c
@@ -43,7 +43,7 @@ static char *board_id;
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
diff --git a/tools/firmware-utils/src/mkfwimage.c b/tools/firmware-utils/src/mkfwimage.c
index a527014b551..d8d5239cc55 100644
--- a/tools/firmware-utils/src/mkfwimage.c
+++ b/tools/firmware-utils/src/mkfwimage.c
@@ -61,7 +61,7 @@ fw_layout_t fw_layout_data[] = {
.name = "RSPRO",
.kern_start = 0xbf030000,
.kern_entry = 0x80060000,
- .firmware_max_length= 0x00B00000,
+ .firmware_max_length= 0x00F00000,
},
{
.name = "LS-SR71",
@@ -79,6 +79,12 @@ fw_layout_t fw_layout_data[] = {
.name = "XM",
.kern_start = 0x9f050000,
.kern_entry = 0x80002000,
+ .firmware_max_length= 0x00760000,
+ },
+ {
+ .name = "UBDEV01",
+ .kern_start = 0x9f050000,
+ .kern_entry = 0x80002000,
.firmware_max_length= 0x006A0000,
},
{ .name = "",
@@ -104,8 +110,6 @@ typedef struct part_data {
#define OPTIONS "B:hv:m:o:r:k:"
-static int debug = 0;
-
typedef struct image_info {
char magic[16];
char version[256];
@@ -236,9 +240,9 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c
fw_layout_t* p;
p = &fw_layout_data[0];
- while ((strlen(p->name) != 0) && (strncmp(p->name, board_name, sizeof(board_name)) != 0))
+ while (*p->name && (strcmp(p->name, board_name) != 0))
p++;
- if (p->name == NULL) {
+ if (!*p->name) {
printf("BUG! Unable to find default fw layout!\n");
exit(-1);
}
@@ -247,7 +251,7 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c
strcpy(kernel->partition_name, "kernel");
kernel->partition_index = 1;
kernel->partition_baseaddr = p->kern_start;
- if ( (kernel->partition_length = filelength(kernelfile)) < 0) return (-1);
+ if ( (kernel->partition_length = filelength(kernelfile)) == (u_int32_t)-1) return (-1);
kernel->partition_memaddr = p->kern_entry;
kernel->partition_entryaddr = p->kern_entry;
strncpy(kernel->filename, kernelfile, sizeof(kernel->filename));
@@ -263,8 +267,8 @@ static int create_image_layout(const char* kernelfile, const char* rootfsfile, c
rootfs->partition_entryaddr = 0x00000000;
strncpy(rootfs->filename, rootfsfile, sizeof(rootfs->filename));
-printf("kernel: %d 0x%08x\n", kernel->partition_length, kernel->partition_baseaddr);
-printf("root: %d 0x%08x\n", rootfs->partition_length, rootfs->partition_baseaddr);
+ printf("kernel: %d 0x%08x\n", kernel->partition_length, kernel->partition_baseaddr);
+ printf("root: %d 0x%08x\n", rootfs->partition_length, rootfs->partition_baseaddr);
im->part_count = 2;
return 0;
diff --git a/tools/firmware-utils/src/mkfwimage2.c b/tools/firmware-utils/src/mkfwimage2.c
index ee09abba1ae..89a98051b43 100644
--- a/tools/firmware-utils/src/mkfwimage2.c
+++ b/tools/firmware-utils/src/mkfwimage2.c
@@ -197,6 +197,10 @@ int str2u32(char *arg, u_int32_t *val)
return 0;
}
+#ifndef STRINGIFY
+#define STRINGIFY2(X) #X
+#define STRINGIFY(X) STRINGIFY2(X)
+#endif
static int image_layout_add_partition(const char *part_desc)
{
part_data_t *d;
@@ -212,7 +216,7 @@ static int image_layout_add_partition(const char *part_desc)
}
d = &im.parts[im.part_count];
- t = sscanf(part_desc, "%15[a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%256s",
+ t = sscanf(part_desc, "%15[-0-9a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%"STRINGIFY(PATH_MAX)"s",
d->partition_name,
offset,
length,
diff --git a/tools/firmware-utils/src/mkheader_gemtek.c b/tools/firmware-utils/src/mkheader_gemtek.c
new file mode 100644
index 00000000000..9e618efbadd
--- /dev/null
+++ b/tools/firmware-utils/src/mkheader_gemtek.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2014 Claudio Leite <leitec@staticky.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Builds a proper flash image for routers using some Gemtek
+ * OEM boards. These include the Airlink101 AR725W, the
+ * Asante SmartHub 600 (AWRT-600N), and Linksys WRT100/110.
+ *
+ * The resulting image is compatible with the factory firmware
+ * web upgrade and TFTP interface.
+ *
+ * To build:
+ * gcc -O2 -o mkheader_gemtek mkheader_gemtek.c -lz
+ *
+ * Claudio Leite <leitec@staticky.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <zlib.h> /* for crc32() */
+
+/*
+ * The header is in little-endian format. In case
+ * we are on a BE host, we need to swap binary
+ * values.
+ */
+#ifdef __APPLE__
+# include <libkern/OSByteOrder.h>
+# define le32 OSSwapHostToLittleInt32
+#else
+# if defined(__linux__)
+# include <endian.h>
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define CPU_BIG_ENDIAN
+# endif
+# else
+# include <sys/endian.h> /* BSD's should have this */
+# if _BYTE_ORDER == _BIG_ENDIAN
+# define CPU_BIG_ENDIAN
+# endif
+# endif
+# ifdef CPU_BIG_ENDIAN
+# define le32(x) (((x & 0xff000000) >> 24) | \
+ ((x & 0x00ff0000) >> 8) | \
+ ((x & 0x0000ff00) << 8) | \
+ ((x & 0x000000ff) << 24))
+# else
+# define le32(x) (x)
+# endif
+#endif
+
+struct gemtek_header {
+ uint8_t magic[4];
+ uint8_t version[4];
+ uint32_t product_id;
+ uint32_t imagesz;
+ uint32_t checksum;
+ uint32_t fast_checksum;
+ uint8_t build[4];
+ uint8_t lang[4];
+};
+
+#define HDRLEN sizeof(struct gemtek_header)
+
+struct machines {
+ char *desc;
+ char *id;
+ uint32_t maxsize;
+ struct gemtek_header header;
+};
+
+struct machines mach_def[] = {
+ {"Airlink101 AR725W", "ar725w", 0x340000,
+ {"GMTK", "1003", le32(0x03000001), 0, 0,
+ 0, "01\0\0", "EN\0\0"}},
+ {"Asante AWRT-600N", "awrt600n", 0x340000,
+ {"A600", "1005", le32(0x03000001), 0, 0,
+ 0, "01\0\0", "EN\0\0"}},
+ {"Linksys WRT100", "wrt100", 0x320000,
+ {"GMTK", "1007", le32(0x03040001), 0, 0,
+ 0, "2\0\0\0", "EN\0\0"}},
+ {"Linksys WRT110", "wrt110", 0x320000,
+ {"GMTK", "1007", le32(0x03040001), 0, 0,
+ 0, "2\0\0\0", "EN\0\0"}},
+ {0}
+};
+
+int
+main(int argc, char *argv[])
+{
+ unsigned long res, flen;
+ struct gemtek_header my_hdr;
+ FILE *f, *f_out;
+ int image_type = -1, index;
+ uint8_t *buf;
+ uint32_t crc;
+
+ if (argc < 3) {
+ fprintf(stderr, "mkheader_gemtek <uImage> <webflash image> [machine ID]\n");
+ fprintf(stderr, " where [machine ID] is one of:\n");
+ for (index = 0; mach_def[index].desc != 0; index++) {
+ fprintf(stderr, " %-10s %s", mach_def[index].id, mach_def[index].desc);
+ if (index == 0)
+ fprintf(stderr, " (default)\n");
+ else
+ fprintf(stderr, "\n");
+ }
+
+ exit(-1);
+ }
+
+ if (argc == 4) {
+ for(index = 0; mach_def[index].id != 0; index++) {
+ if(strcmp(mach_def[index].id, argv[3]) == 0) {
+ image_type = index;
+ break;
+ }
+ }
+
+ if(image_type == -1) {
+ fprintf(stderr, "\nERROR: invalid machine type\n");
+ exit(-1);
+ }
+ } else
+ image_type = 0;
+
+ printf("Opening %s...\n", argv[1]);
+
+ f = fopen(argv[1], "r");
+ if(!f) {
+ fprintf(stderr, "\nERROR: couldn't open input image\n");
+ exit(-1);
+ }
+
+ fseek(f, 0, SEEK_END);
+ flen = (unsigned long) ftell(f);
+
+ printf(" %lu (0x%lX) bytes long\n", flen, flen);
+
+ if (flen > mach_def[image_type].maxsize) {
+ fprintf(stderr, "\nERROR: image exceeds maximum compatible size\n");
+ goto f_error;
+ }
+
+ buf = malloc(flen + HDRLEN);
+ if (!buf) {
+ fprintf(stderr, "\nERROR: couldn't allocate buffer\n");
+ goto f_error;
+ }
+ rewind(f);
+ res = fread(buf + HDRLEN, 1, flen, f);
+ if (res != flen) {
+ perror("Couldn't read entire file: fread()");
+ goto f_error;
+ }
+ fclose(f);
+
+ printf("\nCreating %s...\n", argv[2]);
+
+ memcpy(&my_hdr, &mach_def[image_type].header, HDRLEN);
+
+ printf(" Using %s magic\n", mach_def[image_type].desc);
+
+ my_hdr.imagesz = le32(flen + HDRLEN);
+ memcpy(my_hdr.lang, "EN", 2);
+
+ memcpy(buf, &my_hdr, HDRLEN);
+
+ crc = crc32(0, buf, flen + HDRLEN);
+ printf(" CRC32: %08X\n", crc);
+
+ my_hdr.checksum = le32(crc);
+ memcpy(buf, &my_hdr, HDRLEN);
+
+ printf(" Writing...\n");
+
+ f_out = fopen(argv[2], "w");
+ if(!f_out) {
+ fprintf(stderr, "\nERROR: couldn't open output image\n");
+ exit(-1);
+ }
+
+ fwrite(buf, 1, flen + HDRLEN, f_out);
+
+ fclose(f_out);
+
+ free(buf);
+ return 0;
+
+f_error:
+ fclose(f);
+ exit(-1);
+}
diff --git a/tools/firmware-utils/src/mkhilinkfw.c b/tools/firmware-utils/src/mkhilinkfw.c
new file mode 100644
index 00000000000..55908e5caa7
--- /dev/null
+++ b/tools/firmware-utils/src/mkhilinkfw.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2013 Jeff Kent <jeff@jkent.net>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This tool encrypts and decrypts uImage formatted firmware for Hilink
+ * HLK-RM04 wireless modules. It will also truncate a dump of mtd6 and make
+ * it an image suitable for flashing via the stock firmware upgrade page.
+ *
+ * Build instructions:
+ * gcc -lcrypto hlkcrypt.c -o hlkcrypt
+ */
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <openssl/des.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define DES_KEY "H@L9K*(3"
+
+#ifndef min
+#define min(a,b) \
+ ({ __typeof__ (a) _a = (a); \
+ __typeof__ (b) _b = (b); \
+ _a < _b ? _a : _b; })
+#endif
+
+#define IH_MAGIC 0x27051956
+#define IH_NMLEN 32
+typedef struct image_header {
+ uint32_t ih_magic; /* Image Header Magic Number */
+ uint32_t ih_hcrc; /* Image Header CRC Checksum */
+ uint32_t ih_time; /* Image Creation Timestamp */
+ uint32_t ih_size; /* Image Data Size */
+ uint32_t ih_load; /* Data Load Address */
+ uint32_t ih_ep; /* Entry Point Address */
+ uint32_t ih_dcrc; /* Image Data CRC Checksum */
+ uint8_t ih_os; /* Operating System */
+ uint8_t ih_arch; /* CPU architecture */
+ uint8_t ih_type; /* Image Type */
+ uint8_t ih_comp; /* Compression Type */
+ uint8_t ih_name[IH_NMLEN]; /* Image Name */
+} image_header_t;
+
+static int temp_fd = -1;
+static DES_key_schedule schedule;
+
+static void show_usage(const char *arg0);
+static void exit_cleanup(void);
+static void copy_file(int src, int dst);
+static void do_encrypt(void *p, off_t len);
+static void do_decrypt(void *p, off_t len);
+
+
+int main(int argc, char **argv)
+{
+ int encrypt_opt = 0;
+ int decrypt_opt = 0;
+ int input_opt = 0;
+ int output_opt = 0;
+ char *input_filename = NULL;
+ char *output_filename = NULL;
+
+ int input_fd;
+ int output_fd;
+ off_t file_len;
+ char *p;
+ char buf[sizeof(image_header_t) + 3];
+ image_header_t *header;
+
+ while (1) {
+ static struct option long_options[] = {
+ {"encrypt", no_argument, 0, 'e'},
+ {"decrypt", no_argument, 0, 'd'},
+ {"input", required_argument, 0, 'i'},
+ {"output", required_argument, 0, 'o'},
+ {0, 0, 0, 0 }
+ };
+ int option_index = 0;
+ int c = getopt_long(argc, argv, "dei:o:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'd':
+ decrypt_opt++;
+ if (decrypt_opt > 1) {
+ fprintf(stderr, "%s: decrypt may only be specified once\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+ break;
+
+ case 'e':
+ encrypt_opt++;
+ if (encrypt_opt > 1) {
+ fprintf(stderr, "%s: encrypt may only be specified once\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+ break;
+
+ case 'i':
+ input_opt++;
+ if (input_opt > 1) {
+ fprintf(stderr, "%s: only one input file may be specified\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+ if (strcmp("-", optarg) != 0) {
+ input_filename = optarg;
+ }
+ break;
+
+ case 'o':
+ output_opt++;
+ if (output_opt > 1) {
+ fprintf(stderr, "%s: only one output file may be specified\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+ if (strcmp("-", optarg) != 0) {
+ output_filename = optarg;
+ }
+ break;
+
+ case '?':
+ exit(-1);
+
+ default:
+ abort();
+ }
+ }
+
+ if (decrypt_opt && encrypt_opt) {
+ fprintf(stderr, "%s: decrypt and encrypt may not be used together\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+
+ if (!decrypt_opt && !encrypt_opt) {
+ fprintf(stderr, "%s: neither decrypt or encrypt were specified\n",
+ argv[0]);
+ show_usage(argv[0]);
+ }
+
+ temp_fd = fileno(tmpfile());
+ if (temp_fd < 0) {
+ fprintf(stderr, "Can't create temporary file\n");
+ exit(EXIT_FAILURE);
+ }
+
+ atexit(exit_cleanup);
+ DES_set_key_unchecked((const_DES_cblock *)DES_KEY, &schedule);
+
+ if (input_filename) {
+ input_fd = open(input_filename, O_RDONLY);
+ if (input_fd < 0) {
+ fprintf(stderr, "Can't open %s for reading: %s\n", input_filename,
+ strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ copy_file(input_fd, temp_fd);
+ close(input_fd);
+ }
+ else {
+ copy_file(STDIN_FILENO, temp_fd);
+ }
+
+ file_len = lseek(temp_fd, 0, SEEK_CUR);
+ if (file_len < 64) {
+ fprintf(stderr, "Not enough data\n");
+ exit(EXIT_FAILURE);
+ }
+
+ p = mmap(0, file_len, PROT_READ|PROT_WRITE, MAP_SHARED, temp_fd, 0);
+ if (p == MAP_FAILED) {
+ fprintf(stderr, "mmap failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (encrypt_opt) {
+ header = (image_header_t *)p;
+ off_t len = min(file_len,
+ ntohl(header->ih_size) + sizeof(image_header_t));
+ if (ntohl(header->ih_magic) != IH_MAGIC) {
+ fprintf(stderr, "Header magic incorrect: "
+ "expected 0x%08X, got 0x%08X\n",
+ IH_MAGIC, ntohl(header->ih_magic));
+ munmap(p, file_len);
+ exit(EXIT_FAILURE);
+ }
+ do_encrypt(p, len);
+ munmap(p, file_len);
+ if (len != file_len) {
+ if (ftruncate(temp_fd, len) < 0) {
+ fprintf(stderr, "ftruncate failed: %s\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ if (decrypt_opt) {
+ off_t header_len = min(file_len, sizeof(image_header_t) + 3);
+ memcpy(buf, p, header_len);
+ do_decrypt(buf, header_len);
+ header = (image_header_t *)buf;
+ if (ntohl(header->ih_magic) != IH_MAGIC) {
+ fprintf(stderr, "Header magic incorrect: "
+ "expected 0x%08X, got 0x%08X\n",
+ IH_MAGIC, ntohl(header->ih_magic));
+ exit(EXIT_FAILURE);
+ }
+ do_decrypt(p, file_len);
+ munmap(p, file_len);
+ }
+
+ lseek(temp_fd, 0, SEEK_SET);
+ if (output_filename) {
+ output_fd = creat(output_filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (output_fd < 0) {
+ fprintf(stderr, "Can't open %s for writing: %s\n",
+ output_filename, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ copy_file(temp_fd, output_fd);
+ close(output_fd);
+ }
+ else {
+ copy_file(temp_fd, STDOUT_FILENO);
+ }
+
+ exit(EXIT_SUCCESS);
+ return 0;
+}
+
+static void show_usage(const char *arg0)
+{
+ fprintf(stderr, "usage: %s -d|-e [-i FILE] [-o FILE]\n\n", arg0);
+ fprintf(stderr, "%-15s %s\n", "-d, --decrypt", "decrypt data");
+ fprintf(stderr, "%-15s %s\n", "-e, --encrypt", "encrypt data");
+ fprintf(stderr, "%-15s %s\n", "-i, --input", "intput file (defaults to stdin)");
+ fprintf(stderr, "%-15s %s\n", "-o, --output", "output file (defaults to stdout)");
+ exit(-1);
+}
+
+static void exit_cleanup(void)
+{
+ if (temp_fd >= 0) {
+ close(temp_fd);
+ }
+}
+
+static void copy_file(int src, int dst)
+{
+ char buf[4096];
+ ssize_t size;
+
+ while ((size = read(src, buf, 4096)) > 0) {
+ write(dst, buf, size);
+ }
+}
+
+static void do_encrypt(void *p, off_t len)
+{
+ DES_cblock *pblock;
+ int num_blocks;
+
+ num_blocks = len / 8;
+ pblock = (DES_cblock *) p;
+ while (num_blocks--) {
+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT);
+ pblock++;
+ }
+
+ num_blocks = (len - 3) / 8;
+ pblock = (DES_cblock *) (p + 3);
+ while (num_blocks--) {
+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT);
+ pblock++;
+ }
+}
+
+static void do_decrypt(void *p, off_t len)
+{
+ DES_cblock *pblock;
+ int num_blocks;
+
+ num_blocks = (len - 3) / 8;
+ pblock = (DES_cblock *) (p + 3);
+ while (num_blocks--) {
+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT);
+ pblock++;
+ }
+
+ num_blocks = len / 8;
+ pblock = (DES_cblock *) p;
+ while (num_blocks--) {
+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT);
+ pblock++;
+ }
+}
diff --git a/tools/firmware-utils/src/mkmerakifw-old.c b/tools/firmware-utils/src/mkmerakifw-old.c
new file mode 100644
index 00000000000..05317c2a5b4
--- /dev/null
+++ b/tools/firmware-utils/src/mkmerakifw-old.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com>
+ * Copyright (C) 2016 Christian Lamparter <chunkeey@googlemail.com>
+ *
+ * The format of the header this tool generates was first documented by
+ * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the
+ * same purpose. I have created this reimplementation at his request. The
+ * original script can be found at:
+ * <https://github.com/riptidewave93/meraki-partbuilder>
+ *
+ * Support for the old header format, which is used by the Cisco Z1 AP
+ * has been reverse engineered from the nandloader's nand_load_bk function.
+ * The original code is part of Cisco's GPL code and can be found at:
+ * <https://github.com/riptidewave93/meraki-linux>
+ *
+ * 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 <stdbool.h>
+#include <string.h>
+#include <libgen.h>
+#include <endian.h>
+#include <getopt.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#define PADDING_BYTE 0xff
+
+#define HDR_LENGTH 0x00000020
+#define HDR_OFF_MAGIC1 0
+#define HDR_OFF_LOAD_ADDR 4
+#define HDR_OFF_IMAGELEN 8
+#define HDR_OFF_ENTRY 12
+#define HDR_OFF_CHECKSUM 16
+#define HDR_OFF_FILLER0 20
+#define HDR_OFF_FILLER1 24
+#define HDR_OFF_FILLER2 28
+
+struct board_info {
+ char *id;
+ char *description;
+ uint32_t magic;
+ uint32_t imagelen;
+ uint32_t load_addr;
+ uint32_t entry;
+};
+
+/*
+ * Globals
+ */
+static char *progname;
+static bool strip_padding;
+
+static char *board_id;
+static const struct board_info *board;
+
+static const struct board_info boards[] = {
+ {
+ .id = "z1",
+ .description = "Meraki Z1 Access Point",
+ .magic = 0x4d495053,
+ .imagelen = 0x007e0000,
+ .load_addr = 0x80060000,
+ .entry = 0x80060000
+ }, {
+ /* 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)
+
+static const struct board_info *find_board(const char *id)
+{
+ const struct board_info *ret;
+ const 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 void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+ const 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"
+" -i <file> read kernel image from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -s strip padding from the end of the image\n"
+" -h show this screen\n"
+ );
+
+ fprintf(stream, "\nBoards:\n");
+ for (board = boards; board->id != NULL; board++)
+ fprintf(stream, " %-16s%s\n", board->id, board->description);
+
+ exit(status);
+}
+
+static void writel(unsigned char *buf, size_t offset, uint32_t value)
+{
+ value = htonl(value);
+ memcpy(buf + offset, &value, sizeof(uint32_t));
+}
+
+static const uint32_t crc32_table[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+};
+
+static inline uint32_t crc32_accumulate_8(const uint32_t crc, const uint8_t ch)
+{
+ return crc32_table[(crc ^ ch) & 0xff] ^ (crc >> 8);
+}
+
+static void crc32_csum(uint8_t *buf, const size_t len)
+{
+ uint32_t crc;
+ size_t i;
+
+ crc = ~0;
+ for (i = 0; i < len; i += 4) {
+ crc = crc32_accumulate_8(crc, buf[i + 3]);
+ crc = crc32_accumulate_8(crc, buf[i + 2]);
+ crc = crc32_accumulate_8(crc, buf[i + 1]);
+ crc = crc32_accumulate_8(crc, buf[i]);
+ }
+ crc = ~crc;
+
+ writel(buf, HDR_OFF_CHECKSUM, crc);
+}
+
+
+static int meraki_build_hdr(const struct board_info *board, const size_t klen,
+ FILE *out, FILE *in)
+{
+ unsigned char *kernel;
+ unsigned char *buf;
+ size_t buflen;
+ size_t kspace;
+
+ size_t rc;
+ buflen = board->imagelen;
+ kspace = buflen - HDR_LENGTH;
+
+ if (klen > kspace) {
+ ERR("kernel file is too big - max size: 0x%08lX\n", kspace);
+ return EXIT_FAILURE;
+ }
+
+ /* If requested, resize buffer to remove padding */
+ if (strip_padding)
+ buflen = klen + HDR_LENGTH;
+
+ /* Allocate and initialize buffer for final image */
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ ERRS("no memory for buffer: %s\n");
+ return EXIT_FAILURE;
+ }
+ memset(buf, PADDING_BYTE, buflen);
+
+ /* Load kernel */
+ 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_FILLER0, 0);
+ writel(buf, HDR_OFF_FILLER1, 0);
+ writel(buf, HDR_OFF_FILLER2, 0);
+
+ /* Write load and kernel entry point address */
+ writel(buf, HDR_OFF_LOAD_ADDR, board->load_addr);
+ writel(buf, HDR_OFF_ENTRY, board->entry);
+
+ /* Write header and image length */
+ writel(buf, HDR_OFF_IMAGELEN, klen);
+
+ /* this gets replaced later, after the checksum has been calculated */
+ writel(buf, HDR_OFF_CHECKSUM, 0);
+
+ /* Write checksum */
+ crc32_csum(buf, klen + HDR_LENGTH);
+
+ rc = fwrite(buf, buflen, 1, out);
+
+ free(buf);
+
+ return rc == 1 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ char *ofname = NULL, *ifname = NULL;
+ FILE *out, *in;
+ size_t klen;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "B:i:o:sh");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ board_id = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 's':
+ strip_padding = true;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (board_id == NULL) {
+ ERR("no board specified");
+ goto err;
+ }
+
+ board = find_board(board_id);
+ if (board == NULL) {
+ ERR("unknown board \"%s\"", board_id);
+ goto err;
+ }
+
+ if (ifname == NULL) {
+ ERR("no input file specified");
+ goto err;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ goto err;
+ }
+
+ in = fopen(ifname, "r");
+ if (in == NULL) {
+ ERRS("could not open \"%s\" for reading: %s", ifname);
+ goto err;
+ }
+
+ /* Get kernel length */
+ fseek(in, 0, SEEK_END);
+ klen = ftell(in);
+ rewind(in);
+
+ out = fopen(ofname, "w");
+ if (out == NULL) {
+ ERRS("could not open \"%s\" for writing: %s", ofname);
+ goto err_close_in;
+ }
+
+ ret = meraki_build_hdr(board, klen, out, in);
+ fclose(out);
+
+err_close_in:
+ fclose(in);
+
+err:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/mkmerakifw.c b/tools/firmware-utils/src/mkmerakifw.c
new file mode 100644
index 00000000000..1a50f1658f7
--- /dev/null
+++ b/tools/firmware-utils/src/mkmerakifw.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com>
+ *
+ * The format of the header this tool generates was first documented by
+ * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the
+ * same purpose. I have created this reimplementation at his request. The
+ * original script can be found at:
+ * <https://github.com/riptidewave93/meraki-partbuilder>
+ *
+ * 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 <stdbool.h>
+#include <string.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include "sha1.h"
+
+#define PADDING_BYTE 0xff
+
+#define HDR_LENGTH 0x00000400
+#define HDR_OFF_MAGIC1 0
+#define HDR_OFF_HDRLEN 4
+#define HDR_OFF_IMAGELEN 8
+#define HDR_OFF_CHECKSUM 12
+#define HDR_OFF_MAGIC2 32
+#define HDR_OFF_MAGIC3 36
+#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 {
+ uint32_t magic1;
+ uint32_t magic2;
+ uint32_t magic3;
+ uint32_t imagelen;
+ union {
+ unsigned char statichash[20];
+ struct {
+ uint32_t kernel_offset;
+ uint32_t ramdisk_offset;
+ uint32_t fdt_offset;
+ uint32_t unknown_offset;
+ } mx60;
+ } u;
+ char *id;
+ char *description;
+};
+
+/*
+ * Globals
+ */
+static char *progname;
+
+static char *board_id;
+static const struct board_info *board;
+
+static const struct board_info boards[] = {
+ {
+ .id = "mr18",
+ .description = "Meraki MR18 Access Point",
+ .magic1 = 0x8e73ed8a,
+ .magic2 = 0x8e73ed8a,
+ .imagelen = 0x00800000,
+ .u.statichash = {0xda, 0x39, 0xa3, 0xee, 0x5e,
+ 0x6b, 0x4b, 0x0d, 0x32, 0x55,
+ 0xbf, 0xef, 0x95, 0x60, 0x18,
+ 0x90, 0xaf, 0xd8, 0x07, 0x09},
+ }, {
+ .id = "mr24",
+ .description = "Meraki MR24 Access Point",
+ .magic1 = 0x8e73ed8a,
+ .magic2 = 0x8e73ed8a,
+ .imagelen = 0x00800000,
+ .u.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 ?
+ */
+ .u.mx60 = {
+ .kernel_offset = 0x10000,
+ .ramdisk_offset = 0x3FFC00,
+ .fdt_offset = 0x0400,
+ .unknown_offset = 0x0400,
+ },
+ }, {
+ /* 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)
+
+static const struct board_info *find_board(const char *id)
+{
+ const struct board_info *ret;
+ const 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 void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+ const 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"
+" -i <file> read kernel image from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -s strip padding from the end of the image\n"
+" -h show this screen\n"
+ );
+
+ fprintf(stream, "\nBoards:\n");
+ for (board = boards; board->id != NULL; board++)
+ fprintf(stream, " %-16s%s\n", board->id, board->description);
+
+ exit(status);
+}
+
+void writel(unsigned char *buf, size_t offset, uint32_t value)
+{
+ value = htonl(value);
+ memcpy(buf + offset, &value, sizeof(uint32_t));
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ long klen;
+ size_t kspace;
+ unsigned char *kernel;
+ size_t buflen;
+ unsigned char *buf;
+ bool strip_padding = false;
+ char *ofname = NULL, *ifname = NULL;
+ FILE *out, *in;
+
+ progname = basename(argv[0]);
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "B:i:o:sh");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ board_id = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 's':
+ strip_padding = true;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (board_id == NULL) {
+ ERR("no board specified");
+ goto err;
+ }
+
+ board = find_board(board_id);
+ if (board == NULL) {
+ ERR("unknown board \"%s\"", board_id);
+ goto err;
+ }
+
+ if (ifname == NULL) {
+ ERR("no input file specified");
+ goto err;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ goto err;
+ }
+
+ in = fopen(ifname, "r");
+ if (in == NULL) {
+ ERRS("could not open \"%s\" for reading: %s", ifname);
+ goto err;
+ }
+
+ buflen = board->imagelen;
+ kspace = buflen - HDR_LENGTH;
+
+ /* Get kernel length */
+ fseek(in, 0, SEEK_END);
+ klen = ftell(in);
+ rewind(in);
+
+ if (klen > kspace) {
+ ERR("file \"%s\" is too big - max size: 0x%08lX\n",
+ ifname, kspace);
+ goto err_close_in;
+ }
+
+ /* If requested, resize buffer to remove padding */
+ if (strip_padding)
+ buflen = klen + HDR_LENGTH;
+
+ /* Allocate and initialize buffer for final image */
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ ERRS("no memory for buffer: %s\n");
+ goto err_close_in;
+ }
+ memset(buf, PADDING_BYTE, buflen);
+
+ /* Load kernel */
+ kernel = buf + HDR_LENGTH;
+ fread(kernel, klen, 1, in);
+
+ /* 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);
+ writel(buf, HDR_OFF_IMAGELEN, klen);
+
+ /* Write checksum and static hash */
+ sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM);
+
+ switch (board->magic2) {
+ case 0xa1f0beef:
+ writel(buf, HDR_OFF_KERNEL_OFFSET, board->u.mx60.kernel_offset);
+ writel(buf, HDR_OFF_RAMDISK_OFFSET, board->u.mx60.ramdisk_offset);
+ writel(buf, HDR_OFF_FDT_OFFSET, board->u.mx60.fdt_offset),
+ writel(buf, HDR_OFF_UNKNOWN_OFFSET, board->u.mx60.unknown_offset);
+ break;
+
+ case 0x8e73ed8a:
+ memcpy(buf + HDR_OFF_STATICHASH, board->u.statichash, 20);
+ break;
+ }
+
+ /* Save finished image */
+ out = fopen(ofname, "w");
+ if (out == NULL) {
+ ERRS("could not open \"%s\" for writing: %s", ofname);
+ goto err_free;
+ }
+ fwrite(buf, buflen, 1, out);
+
+ ret = EXIT_SUCCESS;
+
+ fclose(out);
+
+err_free:
+ free(buf);
+
+err_close_in:
+ fclose(in);
+
+err:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/mkplanexfw.c b/tools/firmware-utils/src/mkplanexfw.c
index 1bdccb7c026..0b71f80438f 100644
--- a/tools/firmware-utils/src/mkplanexfw.c
+++ b/tools/firmware-utils/src/mkplanexfw.c
@@ -82,7 +82,7 @@ static struct board_info boards[] = {
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
diff --git a/tools/firmware-utils/src/mkporayfw.c b/tools/firmware-utils/src/mkporayfw.c
new file mode 100644
index 00000000000..6ec4f320d93
--- /dev/null
+++ b/tools/firmware-utils/src/mkporayfw.c
@@ -0,0 +1,791 @@
+/*
+ * Builder/viewer/extractor utility for Poray firmware image files
+ *
+ * Copyright (C) 2013 Michel Stempin <michel.stempin@wanadoo.fr>
+ * Copyright (C) 2013 Felix Kaechele <felix@fetzig.org>
+ * Copyright (C) 2013 <admin@openschemes.com>
+ *
+ * This tool is based on:
+ * TP-Link firmware upgrade tool.
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Itself 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>
+#include <libgen.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+# define HOST_TO_BE32(x) (x)
+# define BE32_TO_HOST(x) (x)
+# define HOST_TO_LE32(x) bswap_32(x)
+# define LE32_TO_HOST(x) bswap_32(x)
+#else
+# define HOST_TO_BE32(x) bswap_32(x)
+# define BE32_TO_HOST(x) bswap_32(x)
+# define HOST_TO_LE32(x) (x)
+# define LE32_TO_HOST(x) (x)
+#endif
+
+/* Fixed header flags */
+#define HEADER_FLAGS 0x020e0000
+
+/* Recognized Hardware ID magic */
+#define HWID_HAME_MPR_A1_L8 0x32473352
+#define HWID_PORAY_R50B 0x31353033
+#define HWID_PORAY_R50D 0x33353033
+#define HWID_PORAY_R50E 0x34353033
+#define HWID_PORAY_M3 0x31353335
+#define HWID_PORAY_M4 0x32353335
+#define HWID_PORAY_Q3 0x33353335
+#define HWID_PORAY_X5_X6 0x35353335
+#define HWID_PORAY_X8 0x36353335
+#define HWID_PORAY_X1 0x38353335
+#define HWID_NEXX_WT1520 0x30353332
+#define HWID_NEXX_WT3020 0x30323033
+#define HWID_A5_V11 0x32473352
+
+/* Recognized XOR obfuscation keys */
+#define KEY_HAME 0
+#define KEY_PORAY_1 1
+#define KEY_PORAY_2 2
+#define KEY_PORAY_3 3
+#define KEY_PORAY_4 4
+#define KEY_NEXX_1 5
+#define KEY_NEXX_2 6
+#define KEY_A5_V11 7
+
+/* XOR key length */
+#define KEY_LEN 15
+
+struct file_info {
+ char *file_name; /* Name of the file */
+ uint32_t file_size; /* Length of the file */
+};
+
+struct fw_header {
+ uint32_t hw_id; /* Hardware id */
+ uint32_t firmware_len; /* Firmware data length */
+ uint32_t flags; /* Header flags */
+ uint8_t pad[16];
+} __attribute__ ((packed));
+
+struct flash_layout {
+ char *id;
+ uint32_t fw_max_len;
+};
+
+struct board_info {
+ char *id;
+ uint32_t hw_id;
+ char *layout_id;
+ uint32_t key;
+};
+
+/*
+ * Globals
+ */
+static char *ofname;
+static char *progname;
+
+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 struct file_info firmware_info;
+static uint32_t firmware_len = 0;
+
+static int inspect = 0;
+static int extract = 0;
+
+static uint8_t key[][KEY_LEN] = {
+ {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x12, 0x03, 0x08},
+ {0x89, 0x6B, 0x5A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7},
+ {0xC9, 0x1C, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7},
+ {0x19, 0x1B, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7},
+ {0x79, 0x7B, 0x7A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7},
+ {0x19, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6},
+ {0x39, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6},
+ {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x20, 0x11, 0x08},
+};
+
+static struct flash_layout layouts[] = {
+ {
+ .id = "4M",
+ .fw_max_len = 0x3c0000,
+ }, {
+ .id = "8M",
+ .fw_max_len = 0x7c0000,
+ }, {
+ /* terminating entry */
+ }
+};
+
+static struct board_info boards[] = {
+ {
+ .id = "A5-V11",
+ .hw_id = HWID_A5_V11,
+ .layout_id = "4M",
+ .key = KEY_A5_V11,
+ }, {
+ .id = "MPR-A1",
+ .hw_id = HWID_HAME_MPR_A1_L8,
+ .layout_id = "4M",
+ .key = KEY_HAME,
+ }, {
+ .id = "MPR-L8",
+ .hw_id = HWID_HAME_MPR_A1_L8,
+ .layout_id = "4M",
+ .key = KEY_HAME,
+ }, {
+ .id = "R50B",
+ .hw_id = HWID_PORAY_R50B,
+ .layout_id = "4M",
+ .key = KEY_PORAY_2,
+ }, {
+ .id = "R50D",
+ .hw_id = HWID_PORAY_R50D,
+ .layout_id = "4M",
+ .key = KEY_PORAY_3,
+ }, {
+ .id = "R50E",
+ .hw_id = HWID_PORAY_R50E,
+ .layout_id = "4M",
+ .key = KEY_PORAY_4,
+ }, {
+ .id = "M3",
+ .hw_id = HWID_PORAY_M3,
+ .layout_id = "4M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "M4",
+ .hw_id = HWID_PORAY_M4,
+ .layout_id = "4M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "Q3",
+ .hw_id = HWID_PORAY_Q3,
+ .layout_id = "4M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "X5 or X6",
+ .hw_id = HWID_PORAY_X5_X6,
+ .layout_id = "8M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "X5",
+ .hw_id = HWID_PORAY_X5_X6,
+ .layout_id = "8M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "X6",
+ .hw_id = HWID_PORAY_X5_X6,
+ .layout_id = "8M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "X8",
+ .hw_id = HWID_PORAY_X8,
+ .layout_id = "8M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "X1",
+ .hw_id = HWID_PORAY_X1,
+ .layout_id = "8M",
+ .key = KEY_PORAY_1,
+ }, {
+ .id = "WT1520",
+ .hw_id = HWID_NEXX_WT1520,
+ .layout_id = "4M",
+ .key = KEY_NEXX_1,
+ }, {
+ .id = "WT1520",
+ .hw_id = HWID_NEXX_WT1520,
+ .layout_id = "8M",
+ .key = KEY_NEXX_1,
+ }, {
+ .id = "WT3020",
+ .hw_id = HWID_NEXX_WT3020,
+ .layout_id = "4M",
+ .key = KEY_NEXX_2,
+ }, {
+ .id = "WT3020",
+ .hw_id = HWID_NEXX_WT3020,
+ .layout_id = "8M",
+ .key = KEY_NEXX_2,
+ }, {
+
+
+
+
+ /* 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 ":%s\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
+} while (0)
+
+/*
+ * Find a board by its name
+ */
+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;
+}
+
+/*
+ * Find a board by its hardware ID
+ */
+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;
+}
+
+/*
+ * Find a Flash memory layout by its name
+ */
+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;
+}
+
+/*
+ * Display usage
+ */
+static void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -B <board> create image for the board specified with <board>\n"
+" -H <hwid> use hardware id specified with <hwid>\n"
+" -F <id> use flash layout specified with <id>\n"
+" -f <file> read firmware image from the file <file>\n"
+" -o <file> write output to the file <file>\n"
+" -i inspect given firmware file (requires -f)\n"
+" -x extract combined kernel and rootfs while inspecting (implies -i)\n"
+" -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+/*
+ * Get file statistics
+ */
+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;
+}
+
+/*
+ * Read file into buffer
+ */
+static int read_to_buf(struct file_info *fdata, uint8_t *buf)
+{
+ FILE *f;
+ int ret = EXIT_FAILURE;
+
+ f = fopen(fdata->file_name, "rb");
+ 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;
+}
+
+/*
+ * Check command line options
+ */
+static int check_options(void)
+{
+ int ret;
+
+ if (firmware_info.file_name == NULL) {
+ ERR("no firmware image specified");
+ return -1;
+ }
+
+ ret = get_file_stat(&firmware_info);
+ if (ret)
+ return ret;
+
+ if (inspect)
+ return 0;
+
+ 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;
+ } else {
+ hw_id = strtoul(opt_hw_id, NULL, 0);
+ board = find_board_by_hwid(hw_id);
+ if (layout_id == NULL) {
+ layout_id = board->layout_id;
+ }
+ }
+
+ layout = find_layout(layout_id);
+ if (layout == NULL) {
+ ERR("unknown flash layout \"%s\"", layout_id);
+ return -1;
+ }
+
+ firmware_len = firmware_info.file_size;
+
+ if (firmware_info.file_size >
+ layout->fw_max_len - sizeof (struct fw_header)) {
+ ERR("firmware image is too big");
+ return -1;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Fill in firmware header
+ */
+static void fill_header(uint8_t *buf)
+{
+ struct fw_header *hdr = (struct fw_header *) buf;
+
+ memset(hdr, 0, sizeof (struct fw_header));
+ hdr->hw_id = HOST_TO_LE32(hw_id);
+ hdr->firmware_len = HOST_TO_LE32(firmware_len);
+ hdr->flags = HOST_TO_LE32(HEADER_FLAGS);
+}
+
+/*
+ * Compute firmware checksum
+ */
+static uint16_t checksum_fw(uint8_t *data, int len)
+{
+ int i;
+ int32_t checksum = 0;
+
+ for (i = 0; i < len - 1; i += 2) {
+ checksum += (data[i + 1] << 8) | data[i];
+ }
+ if (i < len) {
+ checksum += data[i];
+ }
+ checksum = checksum + (checksum >> 16) + 0xffff;
+ checksum = ~(checksum + (checksum >> 16)) & 0xffff;
+ return (uint16_t) checksum;
+}
+
+/*
+ * (De)obfuscate firmware using an XOR operation with a fixed length key
+ */
+static void xor_fw(uint8_t *data, int len)
+{
+ int i;
+
+ for (i = 0; i <= len; i++) {
+ data[i] ^= key[board->key][i % KEY_LEN];
+ }
+}
+
+/*
+ * Write firmware to file
+ */
+static int write_fw(uint8_t *data, int len)
+{
+ FILE *f;
+ int ret = EXIT_FAILURE;
+
+ f = fopen(ofname, "wb");
+ 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;
+}
+
+/*
+ * Build firmware file
+ */
+static int build_fw(void)
+{
+ int buflen;
+ uint8_t *buf, *p;
+ int ret = EXIT_FAILURE;
+ int writelen = 0;
+ uint16_t checksum;
+
+ buflen = layout->fw_max_len;
+
+ buf = (uint8_t *) 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(&firmware_info, p);
+ if (ret) {
+ goto out_free_buf;
+ }
+ writelen = sizeof (struct fw_header) + firmware_len + 2;
+
+ /* Fill in header */
+ fill_header(buf);
+
+ /* Compute firmware checksum */
+ checksum = checksum_fw(buf + sizeof (struct fw_header), firmware_len);
+
+ /* Cannot use network order function because checksum is not word-aligned */
+ buf[writelen - 1] = checksum >> 8;
+ buf[writelen - 2] = checksum & 0xff;
+
+ /* XOR obfuscate firmware */
+ xor_fw(buf + sizeof (struct fw_header), firmware_len + 2);
+
+ /* Write firmware file */
+ 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_pchecksum(char *label,
+ uint16_t val, uint16_t expval)
+{
+ printf("%-23s: 0x%04x ", label, val);
+ if (val == expval) {
+ printf("(ok)\n");
+ } else {
+ printf("(expected: 0x%04x)\n", expval);
+ }
+}
+
+static int inspect_fw(void)
+{
+ uint8_t *buf;
+ struct fw_header *hdr;
+ int ret = EXIT_FAILURE;
+ uint16_t computed_checksum, file_checksum;
+
+ buf = (uint8_t *) malloc(firmware_info.file_size);
+ if (!buf) {
+ ERR("no memory for buffer!\n");
+ goto out;
+ }
+
+ ret = read_to_buf(&firmware_info, buf);
+ if (ret) {
+ goto out_free_buf;
+ }
+ hdr = (struct fw_header *)buf;
+
+ inspect_fw_pstr("File name", firmware_info.file_name);
+ inspect_fw_phexdec("File size", firmware_info.file_size);
+
+ printf("\n");
+
+ inspect_fw_phexdec("Header size", sizeof (struct fw_header));
+ board = find_board_by_hwid(LE32_TO_HOST(hdr->hw_id));
+ if (board) {
+ layout = find_layout(board->layout_id);
+ inspect_fw_phexpost("Hardware ID",
+ LE32_TO_HOST( hdr->hw_id), board->id);
+ } else {
+ inspect_fw_phexpost("Hardware ID",
+ LE32_TO_HOST(hdr->hw_id), "unknown");
+ }
+ inspect_fw_phexdec("Firmware data length",
+ LE32_TO_HOST(hdr->firmware_len));
+
+ inspect_fw_phexexp("Flags",
+ LE32_TO_HOST(hdr->flags), HEADER_FLAGS);
+ printf("\n");
+
+ /* XOR unobfuscate firmware */
+ xor_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len) + 2);
+
+ /* Compute firmware checksum */
+ computed_checksum = checksum_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len));
+
+ /* Cannot use network order function because checksum is not word-aligned */
+ file_checksum = (buf[firmware_info.file_size - 1] << 8) | buf[firmware_info.file_size - 2];
+ inspect_fw_pchecksum("Firmware checksum", computed_checksum, file_checksum);
+
+ /* Verify checksum */
+ if (computed_checksum != file_checksum) {
+ ret = -1;
+ ERR("checksums do not match");
+ goto out_free_buf;
+ }
+
+ printf("\n");
+
+ if (extract) {
+ FILE *fp;
+ char *filename;
+
+ if (ofname == NULL) {
+ filename = malloc(strlen(firmware_info.file_name) + 10);
+ sprintf(filename, "%s-firmware", firmware_info.file_name);
+ } else {
+ filename = ofname;
+ }
+ printf("Extracting firmware to \"%s\"...\n", filename);
+ fp = fopen(filename, "wb");
+ if (fp) {
+ if (!fwrite(buf + sizeof (struct fw_header),
+ LE32_TO_HOST(hdr->firmware_len), 1, fp)) {
+ ERRS("error in fwrite(): %s", strerror(errno));
+ }
+ fclose(fp);
+ } else {
+ ERRS("error in fopen(): %s", strerror(errno));
+ }
+ if (ofname == NULL) {
+ free(filename);
+ }
+ printf("\n");
+ }
+
+ out_free_buf:
+ free(buf);
+ out:
+ return ret;
+}
+
+/*
+ * Main entry point
+ */
+int main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+
+ progname = basename(argv[0]);
+
+ int c;
+
+ while ((c = getopt(argc, argv, "B:H:F:f:o:ixh")) != -1) {
+ switch (c) {
+ case 'B':
+ board_id = optarg;
+ break;
+ case 'H':
+ opt_hw_id = optarg;
+ break;
+ case 'F':
+ layout_id = optarg;
+ break;
+ case 'f':
+ firmware_info.file_name = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 'i':
+ inspect = 1;
+ break;
+ case 'x':
+ inspect = 1;
+ extract = 1;
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ ret = check_options();
+ if (ret) {
+ goto out;
+ }
+ if (!inspect) {
+ ret = build_fw();
+ } else {
+ ret = inspect_fw();
+ }
+
+ out:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/mkrtn56uimg.c b/tools/firmware-utils/src/mkrtn56uimg.c
new file mode 100644
index 00000000000..92aaf314a17
--- /dev/null
+++ b/tools/firmware-utils/src/mkrtn56uimg.c
@@ -0,0 +1,293 @@
+/*
+ *
+ * Copyright (C) 2014 OpenWrt.org
+ * Copyright (C) 2014 Mikko Hissa <mikko.hissa@werzek.com>
+ *
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <zlib.h>
+
+#define IH_MAGIC 0x27051956
+#define IH_NMLEN 32
+#define IH_PRODLEN 23
+
+#define IH_TYPE_INVALID 0
+#define IH_TYPE_STANDALONE 1
+#define IH_TYPE_KERNEL 2
+#define IH_TYPE_RAMDISK 3
+#define IH_TYPE_MULTI 4
+#define IH_TYPE_FIRMWARE 5
+#define IH_TYPE_SCRIPT 6
+#define IH_TYPE_FILESYSTEM 7
+
+/*
+ * Compression Types
+ */
+#define IH_COMP_NONE 0
+#define IH_COMP_GZIP 1
+#define IH_COMP_BZIP2 2
+#define IH_COMP_LZMA 3
+
+typedef struct {
+ uint8_t major;
+ uint8_t minor;
+} version_t;
+
+typedef struct {
+ version_t kernel;
+ version_t fs;
+ uint8_t productid[IH_PRODLEN];
+ uint8_t sub_fs;
+ uint32_t ih_ksz;
+} asus_t;
+
+typedef struct image_header {
+ uint32_t ih_magic;
+ uint32_t ih_hcrc;
+ uint32_t ih_time;
+ uint32_t ih_size;
+ uint32_t ih_load;
+ uint32_t ih_ep;
+ uint32_t ih_dcrc;
+ uint8_t ih_os;
+ uint8_t ih_arch;
+ uint8_t ih_type;
+ uint8_t ih_comp;
+ union {
+ uint8_t ih_name[IH_NMLEN];
+ asus_t asus;
+ } tail;
+} image_header_t;
+
+typedef struct squashfs_sb {
+ uint32_t s_magic;
+ uint32_t pad0[9];
+ uint64_t bytes_used;
+} squashfs_sb_t;
+
+typedef enum {
+ NONE, FACTORY, SYSUPGRADE,
+} op_mode_t;
+
+void
+calc_crc(image_header_t *hdr, void *data, uint32_t len)
+{
+ /*
+ * Calculate payload checksum
+ */
+ hdr->ih_dcrc = htonl(crc32(0, (Bytef *)data, len));
+ hdr->ih_size = htonl(len);
+ /*
+ * Calculate header checksum
+ */
+ hdr->ih_hcrc = 0;
+ hdr->ih_hcrc = htonl(crc32(0, (Bytef *)hdr, sizeof(image_header_t)));
+}
+
+
+static void
+usage(const char *progname, int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+ int i;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream, "\n"
+ "Options:\n"
+ " -f <file> generate a factory flash image <file>\n"
+ " -s <file> generate a sysupgrade flash image <file>\n"
+ " -h show this screen\n");
+ exit(status);
+}
+
+int
+process_image(char *progname, char *filename, op_mode_t opmode)
+{
+ int fd, len;
+ void *data, *ptr;
+ char namebuf[IH_NMLEN];
+ struct stat sbuf;
+ uint32_t checksum, offset_kernel, offset_sqfs, offset_end,
+ offset_sec_header, offset_eb, offset_image_end;
+ squashfs_sb_t *sqs;
+ image_header_t *hdr;
+
+ if ((fd = open(filename, O_RDWR, 0666)) < 0) {
+ fprintf (stderr, "%s: Can't open %s: %s\n",
+ progname, filename, strerror(errno));
+ return (EXIT_FAILURE);
+ }
+
+ if (fstat(fd, &sbuf) < 0) {
+ fprintf (stderr, "%s: Can't stat %s: %s\n",
+ progname, filename, strerror(errno));
+ return (EXIT_FAILURE);
+ }
+
+ if ((unsigned)sbuf.st_size < sizeof(image_header_t)) {
+ fprintf (stderr,
+ "%s: Bad size: \"%s\" is no valid image\n",
+ progname, filename);
+ return (EXIT_FAILURE);
+ }
+
+ ptr = (void *)mmap(0, sbuf.st_size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ fd, 0);
+
+ if ((caddr_t)ptr == (caddr_t)-1) {
+ fprintf (stderr, "%s: Can't read %s: %s\n",
+ progname, filename, strerror(errno));
+ return (EXIT_FAILURE);
+ }
+
+ hdr = ptr;
+
+ if (ntohl(hdr->ih_magic) != IH_MAGIC) {
+ fprintf (stderr,
+ "%s: Bad Magic Number: \"%s\" is no valid image\n",
+ progname, filename);
+ return (EXIT_FAILURE);
+ }
+
+ if (opmode == FACTORY) {
+ strncpy(namebuf, hdr->tail.ih_name, IH_NMLEN);
+ hdr->tail.asus.kernel.major = 0;
+ hdr->tail.asus.kernel.minor = 0;
+ hdr->tail.asus.fs.major = 0;
+ hdr->tail.asus.fs.minor = 0;
+ strncpy((char *)&hdr->tail.asus.productid, "RT-N56U", IH_PRODLEN);
+ }
+
+ if (hdr->tail.asus.ih_ksz == 0)
+ hdr->tail.asus.ih_ksz = htonl(ntohl(hdr->ih_size) + sizeof(image_header_t));
+
+ offset_kernel = sizeof(image_header_t);
+ offset_sqfs = ntohl(hdr->tail.asus.ih_ksz);
+ sqs = ptr + offset_sqfs;
+ offset_sec_header = offset_sqfs + sqs->bytes_used;
+
+ /*
+ * Reserve space for the second header.
+ */
+ offset_end = offset_sec_header + sizeof(image_header_t);
+ offset_eb = ((offset_end>>16)+1)<<16;
+
+ if (opmode == FACTORY)
+ offset_image_end = offset_eb + 4;
+ else
+ offset_image_end = sbuf.st_size;
+ /*
+ * Move the second header at the end of the image.
+ */
+ offset_end = offset_sec_header;
+ offset_sec_header = offset_eb - sizeof(image_header_t);
+
+ /*
+ * Remove jffs2 markers between squashfs and eb boundary.
+ */
+ if (opmode == FACTORY)
+ memset(ptr+offset_end, 0xff ,offset_eb - offset_end);
+
+ /*
+ * Grow the image if needed.
+ */
+ if (offset_image_end > sbuf.st_size) {
+ (void) munmap((void *)ptr, sbuf.st_size);
+ ftruncate(fd, offset_image_end);
+ ptr = (void *)mmap(0, offset_image_end,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ fd, 0);
+ /*
+ * jffs2 marker
+ */
+ if (opmode == FACTORY) {
+ *(uint8_t *)(ptr+offset_image_end-4) = 0xde;
+ *(uint8_t *)(ptr+offset_image_end-3) = 0xad;
+ *(uint8_t *)(ptr+offset_image_end-2) = 0xc0;
+ *(uint8_t *)(ptr+offset_image_end-1) = 0xde;
+ }
+ }
+
+ /*
+ * Calculate checksums for the second header to be used after flashing.
+ */
+ if (opmode == FACTORY) {
+ hdr = ptr+offset_sec_header;
+ memcpy(hdr, ptr, sizeof(image_header_t));
+ strncpy(hdr->tail.ih_name, namebuf, IH_NMLEN);
+ calc_crc(hdr, ptr+offset_kernel, offset_sqfs - offset_kernel);
+ calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_image_end - offset_kernel);
+ } else {
+ calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_sqfs - offset_kernel);
+ }
+
+ if (sbuf.st_size > offset_image_end)
+ (void) munmap((void *)ptr, sbuf.st_size);
+ else
+ (void) munmap((void *)ptr, offset_image_end);
+
+ ftruncate(fd, offset_image_end);
+ (void) close (fd);
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char **argv)
+{
+ int opt;
+ char *filename, *progname;
+ op_mode_t opmode = NONE;
+
+ progname = argv[0];
+
+ while ((opt = getopt(argc, argv,":s:f:h?")) != -1) {
+ switch (opt) {
+ case 's':
+ opmode = SYSUPGRADE;
+ filename = optarg;
+ break;
+ case 'f':
+ opmode = FACTORY;
+ filename = optarg;
+ break;
+ case 'h':
+ opmode = NONE;
+ default:
+ usage(progname, EXIT_FAILURE);
+ opmode = NONE;
+ }
+ }
+
+ if(filename == NULL)
+ opmode = NONE;
+
+ switch (opmode) {
+ case NONE:
+ usage(progname, EXIT_FAILURE);
+ break;
+ case FACTORY:
+ case SYSUPGRADE:
+ return process_image(progname, filename, opmode);
+ break;
+ }
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/tools/firmware-utils/src/mksenaofw.c b/tools/firmware-utils/src/mksenaofw.c
new file mode 100644
index 00000000000..0f10ebdfbeb
--- /dev/null
+++ b/tools/firmware-utils/src/mksenaofw.c
@@ -0,0 +1,420 @@
+/*
+ *
+ * Copyright (C) 2012 OpenWrt.org
+ * Copyright (C) 2012 Mikko Hissa <mikko.hissa@uta.fi>
+ *
+ * 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 <string.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include "md5.h"
+
+#define HDR_LEN 0x60
+#define BUF_SIZE 0x200
+#define VERSION_SIZE 0x10
+#define MD5_SIZE 0x10
+#define PAD_SIZE 0x20
+
+#define DEFAULT_BLOCK_SIZE 65535
+
+#define DEFAULT_HEAD_VALUE 0x0
+#define DEFAULT_VERSION "123"
+#define DEFAULT_MAGIC 0x12345678
+
+typedef struct {
+ uint32_t head;
+ uint32_t vendor_id;
+ uint32_t product_id;
+ uint8_t version[VERSION_SIZE];
+ uint32_t firmware_type;
+ uint32_t filesize;
+ uint32_t zero;
+ uint8_t md5sum[MD5_SIZE];
+ uint8_t pad[PAD_SIZE];
+ uint32_t chksum;
+ uint32_t magic;
+} img_header;
+
+typedef struct {
+ uint8_t id;
+ char * name;
+} firmware_type;
+
+typedef enum {
+ NONE, ENCODE, DECODE
+} op_mode;
+
+static firmware_type FIRMWARE_TYPES[] = {
+ { 0x01, "bootloader" },
+ { 0x02, "kernel" },
+ { 0x03, "kernelapp" },
+ { 0x04, "apps" },
+ /* The types below this line vary by manufacturer */
+ { 0x05, "littleapps (D-Link)/factoryapps (EnGenius)" },
+ { 0x06, "sounds (D-Link)/littleapps (EnGenius)" },
+ { 0x07, "userconfig (D-Link)/appdata (EnGenius)" },
+ { 0x08, "userconfig (EnGenius)"},
+ { 0x09, "odmapps (EnGenius)"},
+ { 0x0a, "factoryapps (D-Link)" },
+ { 0x0b, "odmapps (D-Link)" },
+ { 0x0c, "langpack (D-Link)" }
+};
+
+static long get_file_size(const char *filename)
+{
+ FILE *fp_file;
+ long result;
+
+ fp_file = fopen(filename, "r");
+ if (!fp_file)
+ return -1;
+ fseek(fp_file, 0, SEEK_END);
+ result = ftell(fp_file);
+ fclose(fp_file);
+ return result;
+}
+
+static int header_checksum(void *data, int len)
+{
+ int i;
+ int sum;
+
+ sum = 0;
+ if (data != NULL && len >= 0) {
+ for (i = 0; i < len; ++i)
+ sum += *(unsigned char *) (data + i);
+ return sum;
+ }
+
+ return -1;
+}
+
+static int md5_file(const char *filename, uint8_t *dst)
+{
+ FILE *fp_src;
+ MD5_CTX ctx;
+ char buf[BUF_SIZE];
+ size_t bytes_read;
+
+ MD5_Init(&ctx);
+
+ fp_src = fopen(filename, "r+b");
+ if (!fp_src) {
+ return -1;
+ }
+ while (!feof(fp_src)) {
+ bytes_read = fread(&buf, 1, BUF_SIZE, fp_src);
+ MD5_Update(&ctx, &buf, bytes_read);
+ }
+ fclose(fp_src);
+
+ MD5_Final(dst, &ctx);
+
+ return 0;
+}
+
+static int encode_image(const char *input_file_name,
+ const char *output_file_name, img_header *header, int block_size)
+{
+ char buf[BUF_SIZE];
+ size_t bytes_read;
+ size_t pad_len = 0;
+ size_t bytes_avail;
+
+ FILE *fp_input;
+ FILE *fp_output;
+
+ int i;
+ long magic;
+
+ fp_input = fopen(input_file_name, "r+b");
+ if (!fp_input) {
+ fprintf(stderr, "Cannot open %s !!\n", input_file_name);
+ return -1;
+ }
+
+ fp_output = fopen(output_file_name, "w+b");
+ if (!fp_output) {
+ fprintf(stderr, "Cannot open %s !!\n", output_file_name);
+ fclose(fp_input);
+ return -1;
+ }
+
+ header->filesize = get_file_size(input_file_name);
+ if (!header->filesize) {
+ fprintf(stderr, "File %s open/size error!\n", input_file_name);
+ fclose(fp_input);
+ fclose(fp_output);
+ return -1;
+ }
+ /*
+ * Zero padding
+ */
+ if (block_size > 0) {
+ pad_len = block_size - (header->filesize % block_size);
+ }
+
+ if (md5_file(input_file_name, (uint8_t *) &header->md5sum) < 0) {
+ fprintf(stderr, "MD5 failed on file %s\n", input_file_name);
+ fclose(fp_input);
+ fclose(fp_output);
+ return -1;
+ }
+ header->zero = 0;
+ header->chksum = header_checksum(header, HDR_LEN);
+ header->head = htonl(header->head);
+ header->vendor_id = htonl(header->vendor_id);
+ header->product_id = htonl(header->product_id);
+ header->firmware_type = htonl(header->firmware_type);
+ header->filesize = htonl(header->filesize);
+ header->chksum = htonl(header->chksum);
+ magic = header->magic;
+ header->magic = htonl(header->magic);
+
+ fwrite(header, HDR_LEN, 1, fp_output);
+
+ while (!feof(fp_input) || pad_len > 0) {
+
+ if (!feof(fp_input))
+ bytes_read = fread(&buf, 1, BUF_SIZE, fp_input);
+ else
+ bytes_read = 0;
+
+ /*
+ * No more bytes read, start padding
+ */
+ if (bytes_read < BUF_SIZE && pad_len > 0) {
+ bytes_avail = BUF_SIZE - bytes_read;
+ memset( &buf[bytes_read], 0, bytes_avail);
+ bytes_read += bytes_avail < pad_len ? bytes_avail : pad_len;
+ pad_len -= bytes_avail < pad_len ? bytes_avail : pad_len;
+ }
+
+ for (i = 0; i < bytes_read; i++)
+ buf[i] ^= magic >> (i % 8) & 0xff;
+ fwrite(&buf, bytes_read, 1, fp_output);
+ }
+
+ fclose(fp_input);
+ fclose(fp_output);
+ return 1;
+}
+
+int decode_image(const char *input_file_name, const char *output_file_name)
+{
+ img_header header;
+ char buf[BUF_SIZE];
+
+ FILE *fp_input;
+ FILE *fp_output;
+ unsigned int i;
+
+ size_t bytes_read;
+ size_t bytes_written;
+
+ fp_input = fopen(input_file_name, "r+b");
+ if (!fp_input) {
+ fprintf(stderr, "Cannot open %s !!\n", input_file_name);
+ fclose(fp_input);
+ return -1;
+ }
+
+ fp_output = fopen(output_file_name, "w+b");
+ if (!fp_output) {
+ fprintf(stderr, "Cannot open %s !!\n", output_file_name);
+ fclose(fp_output);
+ return -1;
+ }
+
+ if (fread(&header, 1, HDR_LEN, fp_input) != HDR_LEN) {
+ fprintf(stderr, "Incorrect header size!!");
+ fclose(fp_input);
+ fclose(fp_output);
+ return -1;
+ }
+
+ header.head = ntohl(header.head);
+ header.vendor_id = ntohl(header.vendor_id);
+ header.product_id = ntohl(header.product_id);
+ header.firmware_type = ntohl(header.firmware_type);
+ header.filesize = ntohl(header.filesize);
+ header.chksum = ntohl(header.chksum);
+ header.magic = ntohl(header.magic);
+
+ bytes_written = 0;
+ while (!feof(fp_input)) {
+
+ bytes_read = fread(&buf, 1, BUF_SIZE, fp_input);
+ for (i = 0; i < bytes_read; i++)
+ buf[i] ^= header.magic >> (i % 8) & 0xff;
+
+ /*
+ * Handle padded source file
+ */
+ if (bytes_written + bytes_read > header.filesize) {
+ bytes_read = header.filesize - bytes_written;
+ if (bytes_read > 0)
+ fwrite(&buf, bytes_read, 1, fp_output);
+ break;
+ }
+
+ fwrite(&buf, bytes_read, 1, fp_output);
+ bytes_written += bytes_read;
+ }
+
+ fclose(fp_input);
+ fclose(fp_output);
+
+ return 1;
+}
+
+static void usage(const char *progname, int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+ int i;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream, "\n"
+ "Options:\n"
+ " -e <file> encode image file <file>\n"
+ " -d <file> decode image file <file>\n"
+ " -o <file> write output to the file <file>\n"
+ " -t <type> set image type to <type>\n"
+ " valid image <type> values:\n");
+ for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type); i++) {
+ fprintf(stream, " %-5i= %s\n", FIRMWARE_TYPES[i].id,
+ FIRMWARE_TYPES[i].name);
+ }
+ fprintf(stream, " -v <version> set image version to <version>\n"
+ " -r <vendor> set image vendor id to <vendor>\n"
+ " -p <product> set image product id to <product>\n"
+ " -m <magic> set encoding magic <magic>\n"
+ " -z enable image padding to <blocksize>\n"
+ " -b <blocksize> set image <blocksize>, defaults to %u\n"
+ " -h show this screen\n", DEFAULT_BLOCK_SIZE);
+ exit(status);
+}
+
+int main(int argc, char *argv[])
+{
+ int opt;
+ char *input_file, *output_file, *progname = NULL;
+ op_mode mode = NONE;
+ int tmp, i, pad = 0;
+ int block_size;
+ img_header header;
+
+ block_size = DEFAULT_BLOCK_SIZE;
+ progname = basename(argv[0]);
+
+ memset(&header, 0, sizeof( img_header ));
+ header.magic = DEFAULT_MAGIC;
+ header.head = DEFAULT_HEAD_VALUE;
+ strncpy( (char*)&header.version, DEFAULT_VERSION, VERSION_SIZE - 1);
+
+ while ((opt = getopt(argc, argv, ":o:e:d:t:v:r:p:m:b:h?z")) != -1) {
+ switch (opt) {
+ case 'e':
+ input_file = optarg;
+ mode = ENCODE;
+ break;
+ case 'd':
+ input_file = optarg;
+ mode = DECODE;
+ break;
+ case 'o':
+ output_file = optarg;
+ break;
+ case 't':
+ tmp = strtol(optarg, 0, 10);
+ for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type);
+ i++) {
+ if (FIRMWARE_TYPES[i].id == tmp) {
+ header.firmware_type = FIRMWARE_TYPES[i].id;
+ break;
+ }
+ }
+ if (header.firmware_type == 0) {
+ fprintf(stderr, "Invalid firmware type \"0\"!\n");
+ usage(progname, EXIT_FAILURE);
+ }
+ break;
+ case 'v':
+ strncpy( (char*)&header.version, optarg,
+ VERSION_SIZE - 1);
+ break;
+ case 'r':
+ header.vendor_id = strtol(optarg, 0, 0);
+ break;
+ case 'p':
+ header.product_id = strtol(optarg, 0, 0);
+ break;
+ case 'm':
+ header.magic = strtoul(optarg, 0, 16);
+ break;
+ case 'z':
+ pad = 1;
+ break;
+ case 'b':
+ block_size = strtol(optarg, 0, 10);
+ break;
+ case 'h':
+ usage(progname, EXIT_SUCCESS);
+ break;
+ case ':':
+ fprintf(stderr, "Option -%c requires an operand\n", optopt);
+ usage(progname, EXIT_FAILURE);
+ break;
+ case '?':
+ fprintf(stderr, "Unrecognized option: -%c\n", optopt);
+ usage(progname, EXIT_FAILURE);
+ break;
+ default:
+ usage(progname, EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* Check required arguments */
+ if (mode == NONE) {
+ fprintf(stderr, "A mode must be defined\n");
+ usage(progname, EXIT_FAILURE);
+ }
+
+ if (input_file == NULL || output_file == NULL) {
+ fprintf(stderr, "Input and output files must be defined\n");
+ usage(progname, EXIT_FAILURE);
+ }
+
+ if (mode == DECODE) {
+ if (decode_image(input_file, output_file) < 0)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+ }
+
+ if (header.firmware_type == 0) {
+ fprintf(stderr, "Firmware type must be defined\n");
+ usage(progname, EXIT_FAILURE);
+ }
+
+ if (header.vendor_id == 0 || header.product_id == 0) {
+ fprintf(stderr, "Vendor ID and Product ID must be defined and non-zero\n");
+ usage(progname, EXIT_FAILURE);
+ }
+
+ if (encode_image(input_file, output_file, &header, pad ? block_size : 0) < 0)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/firmware-utils/src/mksercommfw.c b/tools/firmware-utils/src/mksercommfw.c
new file mode 100644
index 00000000000..7f31d4f4c79
--- /dev/null
+++ b/tools/firmware-utils/src/mksercommfw.c
@@ -0,0 +1,255 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+/* #define DEBUG 1 */
+
+/*
+ * Fw Header Layout for Netgear / Sercomm devices
+ * */
+static const char *magic = "sErCoMm"; /* 7 */
+/* 7-11: version control/download control ? */
+unsigned char version[4] = {0x00, 0x01, 0x00, 0x00};
+char *hwID = ""; /* 11-43 , ASCII/HEX */
+char *hwVer = ""; /* 44-57 , ASCII/HEX */
+char *swVer = ""; /* 58-62 , ASCII/HEX */
+/* magic again. */
+
+#define HEADER_SIZE 71
+
+/* null bytes until 511 */
+u_int32_t checksum = 0xFF; /* checksum */
+/* 512 onwards -> ZIP containing rootfs with the same Header */
+
+
+/* appended on rootfs for the Header. */
+const int footer_size = 128;
+
+struct file_info {
+ char *file_name; /* name of the file */
+ char *file_data; /* data of the file in memory */
+ u_int32_t file_size; /* length of the file */
+};
+
+u_int8_t getCheckSum(char *data, int len)
+{
+
+ int32_t previous = 0;
+ u_int32_t new = 0;
+
+ for (u_int32_t i = 0; i < len; i++) {
+ new = (data[i] + previous) % 256;
+ previous = new | previous & -256;
+ }
+ return (u_int8_t) new;
+}
+
+void *bufferFile(struct file_info *finfo, int dontload)
+{
+ int fs = 0;
+ FILE *f = NULL;
+
+#ifdef DEBUG
+ printf("Opening file: %s\n", finfo->file_name);
+#endif
+ f = fopen(finfo->file_name, "rb");
+ if (f == NULL) {
+ perror("Error");
+ exit(1);
+ }
+
+ fseek(f, 0L, SEEK_END);
+ fs = ftell(f);
+ rewind(f);
+
+#ifdef DEBUG
+ printf("Filesize: %i .\n", fs);
+#endif
+
+ finfo->file_size = fs;
+
+ if (dontload) {
+ return 0;
+ }
+
+ char *data = malloc(fs);
+ finfo->file_data = data;
+
+ int read = fread(data, fs, 1, f);
+
+ if (read != 1) {
+ printf("Error reading file %s.", finfo->file_name);
+ exit(1);
+ }
+
+#ifdef DEBUG
+ printf("File: read successfully %i bytes.\n", read*fs);
+#endif
+ fclose(f);
+}
+
+void *writeFile(struct file_info *finfo)
+{
+
+#ifdef DEBUG
+ printf("Writing file: %s.\n", finfo->file_name);
+#endif
+
+ FILE *fout = fopen(finfo->file_name, "w");
+
+ if (!fwrite(finfo->file_data, finfo->file_size, 1, fout)) {
+ printf("Wanted to write, but something went wrong.\n");
+ fclose(fout);
+ exit(1);
+ }
+ fclose(fout);
+}
+
+void *rmFile(struct file_info *finfo)
+{
+ remove(finfo->file_name);
+ free(finfo->file_data);
+ finfo->file_size = 0;
+}
+
+void *usage(char *argv[])
+{
+ printf("Usage: %s <sysupgradefile> <kernel_offset> <HWID> <HWVER> <SWID>\n"
+ "All are positional arguments ... \n"
+ " sysupgradefile: File with the kernel uimage at 0\n"
+ " kernel_offset: Offset in Hex where the kernel is located\n"
+ " HWID: Hardware ID, ASCII\n"
+ " HWVER: Hardware Version, ASCII\n"
+ " SWID: Software Version, Hex\n"
+ " \n"
+ " ", argv[0]);
+}
+
+int main(int argc, char *argv[])
+{
+ printf("Building fw image for sercomm devices.\n");
+
+ if (argc == 2) {
+ struct file_info myfile = {argv[1], 0, 0};
+ bufferFile(&myfile, 0);
+ char chksum = getCheckSum(myfile.file_data, myfile.file_size);
+ printf("Checksum for File: %X.\n", chksum);
+ return 0;
+ }
+
+ if (argc != 6) {
+ usage(argv);
+ return 1;
+ }
+
+ /* Args */
+
+ struct file_info sysupgrade = {argv[1], 0, 0};
+ bufferFile(&sysupgrade, 0);
+
+ int kernel_offset = 0x90000; /* offset for the kernel inside the rootfs, default val */
+ sscanf(argv[2], "%X", &kernel_offset);
+#ifdef DEBUG
+ printf("Kernel_offset: at %X/%i bytes.\n", kernel_offset, kernel_offset);
+#endif
+ char *hwID = argv[3];
+ char *hwVer = argv[4];
+ u_int32_t swVer = 0;
+ sscanf(argv[5],"%4X",&swVer);
+ swVer = bswap_32(swVer);
+
+ char *rootfsname = malloc(2*strlen(sysupgrade.file_name) + 8);
+ sprintf(rootfsname, "%s.rootfs", sysupgrade.file_name);
+
+ char *zipfsname = malloc(2*strlen(rootfsname) + 5);
+ sprintf(zipfsname, "%s.zip", rootfsname);
+ /* / Args */
+
+#ifdef DEBUG
+ printf("Building header: %s %s %2X %s.\n", hwID , hwVer, swVer, magic);
+#endif
+ /* Construct the firmware header/magic */
+ struct file_info header = {0, 0, 0};
+ header.file_size = HEADER_SIZE;
+ header.file_data = malloc(HEADER_SIZE);
+ bzero(header.file_data, header.file_size);
+
+ char *tg = header.file_data;
+ strcpy(tg, magic);
+ memcpy(tg+7, version, 4*sizeof(char));
+ strcpy(tg+11, hwID);
+ strcpy(tg+45, hwVer);
+ memcpy(tg+55, &swVer,sizeof(u_int32_t));
+ strcpy(tg+63, magic);
+
+#ifdef DEBUG
+ printf("Header done, now creating rootfs.");
+#endif
+ /* Construct a rootfs */
+ struct file_info rootfs = {0, 0, 0};
+ rootfs.file_size = sysupgrade.file_size + kernel_offset + footer_size;
+ rootfs.file_data = malloc(rootfs.file_size);
+ bzero(rootfs.file_data, rootfs.file_size);
+ rootfs.file_name = rootfsname;
+
+ /* copy Owrt image to Kernel location */
+ memcpy(rootfs.file_data+kernel_offset, sysupgrade.file_data, sysupgrade.file_size);
+
+ /* 22 added to get away from sysup image, no other reason.
+ * updater searches for magic anyway */
+ tg = rootfs.file_data + kernel_offset + sysupgrade.file_size+22;
+
+ memcpy(tg, header.file_data, header.file_size);
+ writeFile(&rootfs);
+
+#ifdef DEBUG
+ printf("Preparing to zip.\n");
+#endif
+ /* now that we got the rootfs, repeat the whole thing again(sorta):
+ * 1. zip the rootfs */
+ char *zipper = malloc(5 + 2*strlen(rootfs.file_name) + 4);
+ sprintf(zipper, "%s %s %s", "zip ", zipfsname, rootfs.file_name);
+ int ret = system(zipper);
+
+ /* clear rootfs file */
+ rmFile(&rootfs);
+
+ /* and load zipped fs */
+ struct file_info zippedfs = {zipfsname, 0, 0};
+ bufferFile(&zippedfs, 0);
+
+#ifdef DEBUG
+ printf("Creating Image.\n");
+#endif
+
+ /* 2. create new file 512+rootfs size */
+ struct file_info image = {argv[1], 0, 0};
+ image.file_data = malloc(zippedfs.file_size + 512);
+ image.file_size = zippedfs.file_size + 512;
+
+ /* 3. copy zipfile at loc 512 */
+ memcpy(image.file_data+512, zippedfs.file_data, zippedfs.file_size);
+ rmFile(&zippedfs);
+
+ /* 4. add header to file */
+ memcpy(image.file_data, header.file_data, header.file_size);
+
+ /* 5. do a checksum run, and compute checksum */
+ char chksum = getCheckSum(image.file_data, image.file_size);
+#ifdef DEBUG
+ printf("Checksum for Image: %X.\n", chksum);
+#endif
+
+ /* 6. write the checksum invert into byte 511 to bring it to 0 */
+ chksum = (chksum ^ 0xFF) + 1;
+ memcpy(image.file_data+511, &chksum, 1);
+
+ chksum = getCheckSum(image.file_data, image.file_size);
+#ifdef DEBUG
+ printf("Checksum for after fix: %X.\n", chksum);
+#endif
+ /* 7. pray that the updater will accept the file */
+ writeFile(&image);
+ return 0;
+}
diff --git a/tools/firmware-utils/src/mktplinkfw-lib.c b/tools/firmware-utils/src/mktplinkfw-lib.c
new file mode 100644
index 00000000000..e3213274c19
--- /dev/null
+++ b/tools/firmware-utils/src/mktplinkfw-lib.c
@@ -0,0 +1,265 @@
+/*
+ * 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 <stdbool.h>
+#include <endian.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "mktplinkfw-lib.h"
+#include "md5.h"
+
+extern char *ofname;
+extern char *progname;
+extern uint32_t kernel_len;
+extern struct file_info kernel_info;
+extern struct file_info rootfs_info;
+extern struct flash_layout *layout;
+extern uint32_t rootfs_ofs;
+extern uint32_t rootfs_align;
+extern int combined;
+extern int strip_padding;
+extern int add_jffs2_eof;
+
+static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
+
+void fill_header(char *buf, int len);
+
+struct flash_layout *find_layout(struct flash_layout *layouts, const 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;
+}
+
+void get_md5(const char *data, int size, uint8_t *md5)
+{
+ MD5_CTX ctx;
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, data, size);
+ MD5_Final(md5, &ctx);
+}
+
+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;
+}
+
+int read_to_buf(const 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 pad_jffs2(char *buf, int currlen, int maxlen)
+{
+ int len;
+ uint32_t pad_mask;
+
+ len = currlen;
+ pad_mask = (4 * 1024) | (64 * 1024); /* EOF at 4KB and at 64KB */
+ while ((len < maxlen) && (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;
+}
+
+int write_fw(const char *ofname, const 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;
+}
+
+/* Helper functions to inspect_fw() representing different output formats */
+inline void inspect_fw_pstr(const char *label, const char *str)
+{
+ printf("%-23s: %s\n", label, str);
+}
+
+inline void inspect_fw_phex(const char *label, uint32_t val)
+{
+ printf("%-23s: 0x%08x\n", label, val);
+}
+
+inline void inspect_fw_phexdec(const char *label, uint32_t val)
+{
+ printf("%-23s: 0x%08x / %8u bytes\n", label, val, val);
+}
+
+inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text)
+{
+ int i;
+
+ printf("%-23s:", label);
+ for (i=0; i<MD5SUM_LEN; i++)
+ printf(" %02x", val[i]);
+ printf(" %s\n", text);
+}
+
+// header_size = sizeof(struct fw_header)
+int build_fw(size_t header_size)
+{
+ int buflen;
+ char *buf;
+ char *p;
+ int ret = EXIT_FAILURE;
+ int writelen = 0;
+
+ writelen = header_size + kernel_len;
+
+ if (combined)
+ buflen = writelen;
+ else
+ buflen = layout->fw_max_len;
+
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto out;
+ }
+
+ memset(buf, 0xff, buflen);
+ p = buf + header_size;
+ ret = read_to_buf(&kernel_info, p);
+ if (ret)
+ goto out_free_buf;
+
+ if (!combined) {
+ p = buf + rootfs_ofs;
+
+ ret = read_to_buf(&rootfs_info, p);
+ if (ret)
+ goto out_free_buf;
+
+ writelen = rootfs_ofs + rootfs_info.file_size;
+
+ if (add_jffs2_eof)
+ writelen = pad_jffs2(buf, writelen, layout->fw_max_len);
+ }
+
+ if (!strip_padding)
+ writelen = buflen;
+
+ fill_header(buf, writelen);
+ ret = write_fw(ofname, buf, writelen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+out_free_buf:
+ free(buf);
+out:
+ return ret;
+}
diff --git a/tools/firmware-utils/src/mktplinkfw-lib.h b/tools/firmware-utils/src/mktplinkfw-lib.h
new file mode 100644
index 00000000000..31e6d0b1e6b
--- /dev/null
+++ b/tools/firmware-utils/src/mktplinkfw-lib.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+
+
+#ifndef mktplinkfw_lib_h
+#define mktplinkfw_lib_h
+
+#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
+#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
+
+#define MD5SUM_LEN 16
+
+/*
+ * 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 ": %s\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define DBG(fmt, ...) do { \
+ fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \
+} while (0)
+
+
+struct file_info {
+ char *file_name; /* name of the file */
+ uint32_t file_size; /* length of the file */
+};
+
+struct flash_layout {
+ char *id;
+ uint32_t fw_max_len;
+ uint32_t kernel_la;
+ uint32_t kernel_ep;
+ uint32_t rootfs_ofs;
+};
+
+struct flash_layout *find_layout(struct flash_layout *layouts, const char *id);
+void get_md5(const char *data, int size, uint8_t *md5);
+int get_file_stat(struct file_info *fdata);
+int read_to_buf(const struct file_info *fdata, char *buf);
+int write_fw(const char *ofname, const char *data, int len);
+inline void inspect_fw_pstr(const char *label, const char *str);
+inline void inspect_fw_phex(const char *label, uint32_t val);
+inline void inspect_fw_phexdec(const char *label, uint32_t val);
+inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text);
+int build_fw(size_t header_size);
+
+#endif /* mktplinkfw_lib_h */
diff --git a/tools/firmware-utils/src/mktplinkfw.c b/tools/firmware-utils/src/mktplinkfw.c
index f8fa2f14b40..ce2acc20c93 100644
--- a/tools/firmware-utils/src/mktplinkfw.c
+++ b/tools/firmware-utils/src/mktplinkfw.c
@@ -19,6 +19,8 @@
#include <libgen.h>
#include <getopt.h> /* for getopt() */
#include <stdarg.h>
+#include <stdbool.h>
+#include <endian.h>
#include <errno.h>
#include <sys/stat.h>
@@ -26,37 +28,10 @@
#include <netinet/in.h>
#include "md5.h"
-
-#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
+#include "mktplinkfw-lib.h"
#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 */
-};
+#define HEADER_VERSION_V2 0x02000000
struct fw_header {
uint32_t version; /* header version */
@@ -64,7 +39,7 @@ struct fw_header {
char fw_version[36];
uint32_t hw_id; /* hardware id */
uint32_t hw_rev; /* hardware revision */
- uint32_t unk1;
+ uint32_t region_code; /* region code */
uint8_t md5sum1[MD5SUM_LEN];
uint32_t unk2;
uint8_t md5sum2[MD5SUM_LEN];
@@ -78,62 +53,68 @@ struct fw_header {
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];
+ uint16_t ver_hi;
+ uint16_t ver_mid;
+ uint16_t ver_lo;
+ uint8_t pad[130];
+ char region_str1[32];
+ char region_str2[32];
+ uint8_t pad2[160];
} __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 fw_region {
+ char name[4];
+ uint32_t code;
};
-struct board_info {
- char *id;
- uint32_t hw_id;
- uint32_t hw_rev;
- char *layout_id;
-};
/*
* Globals
*/
-static char *ofname;
-static char *progname;
+char *ofname;
+char *progname;
static char *vendor = "TP-LINK Technologies";
static char *version = "ver. 1.0";
+static char *fw_ver = "0.0.0";
+static uint32_t hdr_ver = HEADER_VERSION_V1;
-static char *board_id;
-static struct board_info *board;
static char *layout_id;
-static struct flash_layout *layout;
+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 opt_hdr_ver = 1;
+static char *country;
+static const struct fw_region *region;
+static int fw_ver_lo;
+static int fw_ver_mid;
+static int fw_ver_hi;
+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;
+uint32_t kernel_len = 0;
+struct file_info rootfs_info;
+uint32_t rootfs_ofs = 0;
+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};
+int combined;
+int strip_padding;
+int add_jffs2_eof;
+static uint32_t fw_max_len;
+static uint32_t reserved_space;
static struct file_info inspect_info;
static int extract = 0;
+static bool endian_swap = false;
+static bool rootfs_ofs_calc = false;
-char md5salt_normal[MD5SUM_LEN] = {
+static const 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] = {
+static const char md5salt_boot[MD5SUM_LEN] = {
0x8c, 0xef, 0x33, 0x5b, 0xd5, 0xc5, 0xce, 0xfa,
0xa7, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42,
};
@@ -164,268 +145,85 @@ static struct flash_layout layouts[] = {
.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 = "16M",
+ .fw_max_len = 0xf80000,
+ .kernel_la = 0x80060000,
+ .kernel_ep = 0x80060000,
+ .rootfs_ofs = 0x140000,
}, {
- .id = "TL-WR2543Nv1",
- .hw_id = HWID_TL_WR2543N_V1,
- .hw_rev = 1,
- .layout_id = "8Mlzma",
+ .id = "16Mlzma",
+ .fw_max_len = 0xf80000,
+ .kernel_la = 0x80060000,
+ .kernel_ep = 0x80060000,
+ .rootfs_ofs = 0x100000,
}, {
- .id = "TL-WR703Nv1",
- .hw_id = HWID_TL_WR703N_V1,
- .hw_rev = 1,
- .layout_id = "4Mlzma",
+ .id = "16Mppc",
+ .fw_max_len = 0xf80000,
+ .kernel_la = 0x00000000 ,
+ .kernel_ep = 0xc0000000,
+ .rootfs_ofs = 0x2a0000,
}, {
/* 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 const struct fw_region regions[] = {
+ /* Default region (universal) uses code 0 as well */
+ {"US", 1},
+ {"EU", 0},
+ {"BR", 0},
+};
-static struct board_info *find_board_by_hwid(uint32_t hw_id)
-{
- struct board_info *board;
+static const struct fw_region * find_region(const char *country) {
+ size_t i;
- for (board = boards; board->id != NULL; board++) {
- if (hw_id == board->hw_id)
- return board;
- };
+ for (i = 0; i < ARRAY_SIZE(regions); i++) {
+ if (strcasecmp(regions[i].name, country) == 0)
+ return &regions[i];
+ }
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,
+ fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stderr,
"\n"
"Options:\n"
-" -B <board> create image for the board specified with <board>\n"
" -c use combined kernel image\n"
+" -e swap endianness in kernel load address and entry point\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"
+" -W <hwrev> use hardware revision specified with <hwrev>\n"
+" -C <country> set region code to <country>\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 calculate rootfs offset for combined images\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"
+" -v <version> set firmware version to <version>\n"
+" -m <version> set header version to <version>\n"
" -i <file> inspect given firmware file <file>\n"
" -x extract kernel and rootfs while inspecting (requires -i)\n"
+" -X <size> reserve <size> bytes in the firmware image (hexval prefixed with 0x)\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;
+ int exceed_bytes;
if (inspect_info.file_name) {
ret = get_file_stat(&inspect_info);
@@ -438,48 +236,55 @@ static int check_options(void)
return -1;
}
- if (board_id == NULL && opt_hw_id == NULL) {
- ERR("either board or hardware id must be specified");
+ if (opt_hw_id == NULL) {
+ ERR("hardware id not specified");
+ return -1;
+ }
+ hw_id = strtoul(opt_hw_id, NULL, 0);
+
+ if (!combined && layout_id == NULL) {
+ ERR("flash layout is not specified");
return -1;
}
- if (board_id) {
- board = find_board(board_id);
- if (board == NULL) {
- ERR("unknown/unsupported board id \"%s\"", board_id);
+ if (opt_hw_rev)
+ hw_rev = strtoul(opt_hw_rev, NULL, 0);
+ else
+ hw_rev = 1;
+
+ if (country) {
+ region = find_region(country);
+ if (!region) {
+ ERR("unknown region code \"%s\"", country);
return -1;
}
- if (layout_id == NULL)
- layout_id = board->layout_id;
+ }
- hw_id = board->hw_id;
- hw_rev = board->hw_rev;
+ if (combined) {
+ if (!kernel_la || !kernel_ep) {
+ ERR("kernel loading address and entry point must be specified for combined image");
+ return -1;
+ }
} else {
- if (layout_id == NULL) {
- ERR("flash layout is not specified");
+ layout = find_layout(layouts, layout_id);
+ if (layout == NULL) {
+ ERR("unknown flash layout \"%s\"", layout_id);
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;
- }
+ if (!kernel_la)
+ kernel_la = layout->kernel_la;
+ if (!kernel_ep)
+ kernel_ep = layout->kernel_ep;
+ if (!rootfs_ofs)
+ rootfs_ofs = layout->rootfs_ofs;
- layout = find_layout(layout_id);
- if (layout == NULL) {
- ERR("unknown flash layout \"%s\"", layout_id);
- return -1;
+ if (reserved_space > layout->fw_max_len) {
+ ERR("reserved space is not valid");
+ 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;
@@ -491,13 +296,9 @@ static int check_options(void)
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 (!combined) {
+ fw_max_len = layout->fw_max_len - reserved_space;
+
if (rootfs_info.file_name == NULL) {
ERR("no rootfs image specified");
return -1;
@@ -509,26 +310,26 @@ static int check_options(void)
if (rootfs_align) {
kernel_len += sizeof(struct fw_header);
- kernel_len = ALIGN(kernel_len, rootfs_align);
+ rootfs_ofs = ALIGN(kernel_len, rootfs_align);
kernel_len -= sizeof(struct fw_header);
- DBG("kernel length aligned to %u", kernel_len);
+ DBG("rootfs offset aligned to 0x%u", rootfs_ofs);
- if (kernel_len + rootfs_info.file_size >
- layout->fw_max_len - sizeof(struct fw_header)) {
- ERR("images are too big");
+ exceed_bytes = kernel_len + rootfs_info.file_size - (fw_max_len - sizeof(struct fw_header));
+ if (exceed_bytes > 0) {
+ ERR("images are too big by %i bytes", exceed_bytes);
return -1;
}
} else {
- if (kernel_info.file_size >
- rootfs_ofs - sizeof(struct fw_header)) {
- ERR("kernel image is too big");
+ exceed_bytes = kernel_info.file_size - (rootfs_ofs - sizeof(struct fw_header));
+ if (exceed_bytes > 0) {
+ ERR("kernel image is too big by %i bytes", exceed_bytes);
return -1;
}
- if (rootfs_info.file_size >
- (layout->fw_max_len - rootfs_ofs)) {
- ERR("rootfs image is too big");
+ exceed_bytes = rootfs_info.file_size - (fw_max_len - rootfs_ofs);
+ if (exceed_bytes > 0) {
+ ERR("rootfs image is too big by %i bytes", exceed_bytes);
return -1;
}
}
@@ -539,227 +340,79 @@ static int check_options(void)
return -1;
}
+ ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo);
+ if (ret != 3) {
+ ERR("invalid firmware version '%s'", fw_ver);
+ return -1;
+ }
+
+ if (opt_hdr_ver == 1) {
+ hdr_ver = HEADER_VERSION_V1;
+ } else if (opt_hdr_ver == 2) {
+ hdr_ver = HEADER_VERSION_V2;
+ } else {
+ ERR("invalid header version '%u'", opt_hdr_ver);
+ return -1;
+ }
+
return 0;
}
-static void fill_header(char *buf, int len)
+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);
+ hdr->version = htonl(hdr_ver);
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) {
+ if (boot_info.file_size == 0)
+ memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1));
+ else
+ memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1));
+
+ hdr->fw_length = htonl(layout->fw_max_len);
hdr->rootfs_ofs = htonl(rootfs_ofs);
hdr->rootfs_len = htonl(rootfs_info.file_size);
}
- get_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);
+ if (combined && rootfs_ofs_calc) {
+ hdr->rootfs_ofs = htonl(sizeof(struct fw_header) + kernel_len);
}
- 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;
+ hdr->ver_hi = htons(fw_ver_hi);
+ hdr->ver_mid = htons(fw_ver_mid);
+ hdr->ver_lo = htons(fw_ver_lo);
+
+ if (region) {
+ hdr->region_code = htonl(region->code);
+ snprintf(
+ hdr->region_str1, sizeof(hdr->region_str1), "00000000;%02X%02X%02X%02X;",
+ region->name[0], region->name[1], region->name[2], region->name[3]
+ );
+ snprintf(
+ hdr->region_str2, sizeof(hdr->region_str2), "%02X%02X%02X%02X",
+ region->name[0], region->name[1], region->name[2], region->name[3]
+ );
}
- 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 (endian_swap) {
+ hdr->kernel_la = bswap_32(hdr->kernel_la);
+ hdr->kernel_ep = bswap_32(hdr->kernel_ep);
}
- 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);
+ if (!combined)
+ get_md5(buf, len, hdr->md5sum1);
}
static int inspect_fw(void)
@@ -767,7 +420,6 @@ 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);
@@ -784,16 +436,14 @@ static int inspect_fw(void)
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");
+ if ((ntohl(hdr->version) != HEADER_VERSION_V1) &&
+ (ntohl(hdr->version) != HEADER_VERSION_V2)) {
+ ERR("file does not seem to have V1/V2 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));
@@ -818,19 +468,9 @@ static int inspect_fw(void)
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));
- }
+ inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id));
+ inspect_fw_phex("Hardware Revision", ntohl(hdr->hw_rev));
+ inspect_fw_phex("Region code", ntohl(hdr->region_code));
printf("\n");
@@ -838,24 +478,12 @@ static int inspect_fw(void)
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_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",
@@ -911,16 +539,13 @@ static int inspect_fw(void)
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");
+ c = getopt(argc, argv, "a:H:E:F:L:m:V:N:W:C:ci:k:r:R:o:OxX:ehsjv:");
if (c == -1)
break;
@@ -928,9 +553,6 @@ int main(int argc, char *argv[])
case 'a':
sscanf(optarg, "0x%x", &rootfs_align);
break;
- case 'B':
- board_id = optarg;
- break;
case 'H':
opt_hw_id = optarg;
break;
@@ -943,12 +565,21 @@ int main(int argc, char *argv[])
case 'W':
opt_hw_rev = optarg;
break;
+ case 'C':
+ country = optarg;
+ break;
case 'L':
sscanf(optarg, "0x%x", &kernel_la);
break;
+ case 'm':
+ sscanf(optarg, "%u", &opt_hdr_ver);
+ break;
case 'V':
version = optarg;
break;
+ case 'v':
+ fw_ver = optarg;
+ break;
case 'N':
vendor = optarg;
break;
@@ -967,6 +598,9 @@ int main(int argc, char *argv[])
case 'o':
ofname = optarg;
break;
+ case 'O':
+ rootfs_ofs_calc = 1;
+ break;
case 's':
strip_padding = 1;
break;
@@ -979,9 +613,15 @@ int main(int argc, char *argv[])
case 'x':
extract = 1;
break;
+ case 'e':
+ endian_swap = true;
+ break;
case 'h':
usage(EXIT_SUCCESS);
break;
+ case 'X':
+ sscanf(optarg, "0x%x", &reserved_space);
+ break;
default:
usage(EXIT_FAILURE);
break;
@@ -993,11 +633,10 @@ int main(int argc, char *argv[])
goto out;
if (!inspect_info.file_name)
- ret = build_fw();
+ ret = build_fw(sizeof(struct fw_header));
else
ret = inspect_fw();
out:
return ret;
}
-
diff --git a/tools/firmware-utils/src/mktplinkfw2.c b/tools/firmware-utils/src/mktplinkfw2.c
new file mode 100644
index 00000000000..dead49e7af8
--- /dev/null
+++ b/tools/firmware-utils/src/mktplinkfw2.c
@@ -0,0 +1,628 @@
+/*
+ * 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 <stdbool.h>
+#include <endian.h>
+#include <sys/stat.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "md5.h"
+#include "mktplinkfw-lib.h"
+
+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 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));
+
+#define FLAG_LE_KERNEL_LA_EP 0x00000001 /* Little-endian used for kernel load address & entry point */
+
+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;
+ uint32_t flags;
+};
+
+/*
+ * Globals
+ */
+char *ofname;
+char *progname;
+static char *vendor = "TP-LINK Technologies";
+static char *version = "ver. 1.0";
+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 struct board_info *board;
+static char *layout_id;
+struct flash_layout *layout;
+static char *opt_hw_id;
+static char *opt_hw_rev;
+static char *opt_hw_ver_add;
+static int fw_ver_lo;
+static int fw_ver_mid;
+static int fw_ver_hi;
+static int sver_lo;
+static int sver_hi;
+struct file_info kernel_info;
+static uint32_t kernel_la = 0;
+static uint32_t kernel_ep = 0;
+uint32_t kernel_len = 0;
+struct file_info rootfs_info;
+uint32_t rootfs_ofs = 0;
+uint32_t rootfs_align;
+static struct file_info boot_info;
+int combined;
+int strip_padding;
+int add_jffs2_eof;
+
+static struct file_info inspect_info;
+static int extract = 0;
+
+char md5salt_normal[MD5SUM_LEN] = {
+ 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb,
+ 0xdc, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x37,
+};
+
+char md5salt_boot[MD5SUM_LEN] = {
+ 0x8c, 0xef, 0x33, 0x5f, 0xd5, 0xc5, 0xce, 0xfa,
+ 0xac, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42,
+};
+
+static struct flash_layout layouts[] = {
+ {
+ .id = "4Mmtk",
+ .fw_max_len = 0x3d0000,
+ .kernel_la = 0x80000000,
+ .kernel_ep = 0x80000000,
+ .rootfs_ofs = 0x140000,
+ }, {
+ .id = "8Mltq",
+ .fw_max_len = 0x7a0000,
+ .kernel_la = 0x80002000,
+ .kernel_ep = 0x80002000,
+ .rootfs_ofs = 0x140000,
+ }, {
+ .id = "16Mltq",
+ .fw_max_len = 0xf90000,
+ .kernel_la = 0x80002000,
+ .kernel_ep = 0x800061b0,
+ .rootfs_ofs = 0x140000,
+ }, {
+ .id = "8Mmtk",
+ .fw_max_len = 0x7a0000,
+ .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 */
+ }
+};
+
+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"
+" -c use combined kernel image\n"
+" -e swap endianness in kernel load address and entry point\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"
+" -W <hwrev> use hardware revision specified with <hwrev>\n"
+" -w <hwveradd> use additional hardware version specified with <hwveradd>\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"
+" -T <version> set header version to <version>\n"
+" -V <version> set image version to <version>\n"
+" -v <version> set firmware version to <version>\n"
+" -y <version> set secondary 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 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 (opt_hw_id == NULL) {
+ ERR("hardware id must be specified");
+ return -1;
+ }
+
+ board = &custom_board;
+
+ if (layout_id == NULL) {
+ ERR("flash layout is not specified");
+ return -1;
+ }
+
+ board->hw_id = strtoul(opt_hw_id, NULL, 0);
+
+ board->hw_rev = 1;
+ board->hw_ver_add = 0;
+
+ if (opt_hw_rev)
+ board->hw_rev = strtoul(opt_hw_rev, NULL, 0);
+ if (opt_hw_ver_add)
+ board->hw_ver_add = strtoul(opt_hw_ver_add, NULL, 0);
+
+ layout = find_layout(layouts, 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);
+ rootfs_ofs = ALIGN(kernel_len, rootfs_align);
+ kernel_len -= sizeof(struct fw_header);
+
+ DBG("rootfs offset aligned to 0x%u", rootfs_ofs);
+
+ 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;
+ }
+
+ ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo);
+ if (ret != 3) {
+ ERR("invalid firmware version '%s'", fw_ver);
+ return -1;
+ }
+
+ ret = sscanf(sver, "%d.%d", &sver_hi, &sver_lo);
+ if (ret != 2) {
+ ERR("invalid secondary version '%s'", sver);
+ return -1;
+ }
+
+ return 0;
+}
+
+void fill_header(char *buf, int len)
+{
+ struct fw_header *hdr = (struct fw_header *)buf;
+ unsigned ver_len;
+
+ memset(hdr, '\xff', sizeof(struct fw_header));
+
+ hdr->version = htonl(bswap_32(hdr_ver));
+ ver_len = strlen(version);
+ if (ver_len > (sizeof(hdr->fw_version) - 1))
+ ver_len = sizeof(hdr->fw_version) - 1;
+
+ memcpy(hdr->fw_version, version, ver_len);
+ hdr->fw_version[ver_len] = 0;
+
+ 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));
+ hdr->boot_ofs = htonl(0);
+ hdr->boot_len = htonl(0);
+ } else {
+ memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1));
+ hdr->boot_ofs = htonl(rootfs_ofs + rootfs_info.file_size);
+ hdr->boot_len = htonl(rootfs_info.file_size);
+ }
+
+ 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);
+ }
+
+ hdr->boot_ofs = htonl(0);
+ hdr->boot_len = htonl(boot_info.file_size);
+
+ hdr->unk2 = htonl(0);
+ hdr->unk3 = htonl(0xffffffff);
+ hdr->unk4 = htons(0x55aa);
+ hdr->unk5 = 0xa5;
+
+ hdr->sver_hi = sver_hi;
+ hdr->sver_lo = sver_lo;
+
+ hdr->ver_hi = fw_ver_hi;
+ hdr->ver_mid = fw_ver_mid;
+ hdr->ver_lo = fw_ver_lo;
+
+ if (board->flags & FLAG_LE_KERNEL_LA_EP) {
+ hdr->kernel_la = bswap_32(hdr->kernel_la);
+ hdr->kernel_ep = bswap_32(hdr->kernel_ep);
+ }
+
+ get_md5(buf, len, hdr->md5sum1);
+}
+
+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;
+
+ board = &custom_board;
+
+ if (board->flags & FLAG_LE_KERNEL_LA_EP) {
+ hdr->kernel_la = bswap_32(hdr->kernel_la);
+ hdr->kernel_ep = bswap_32(hdr->kernel_ep);
+ }
+
+ inspect_fw_pstr("File name", inspect_info.file_name);
+ inspect_fw_phexdec("File size", inspect_info.file_size);
+
+ switch(bswap_32(ntohl(hdr->version))) {
+ case 2:
+ case 3:
+ break;
+ default:
+ ERR("file does not seem to have V2/V3 header!\n");
+ goto out_free_buf;
+ }
+
+ inspect_fw_phexdec("Version 2 Header size", sizeof(struct fw_header));
+
+ 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));
+ get_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) != 0xffffffff)
+ inspect_fw_phexdec("Unknown value 3", hdr->unk3);
+
+ if (ntohs(hdr->unk4) != 0x55aa)
+ inspect_fw_phexdec("Unknown value 4", hdr->unk4);
+
+ if (hdr->unk5 != 0xa5)
+ inspect_fw_phexdec("Unknown value 5", hdr->unk5);
+
+ printf("\n");
+
+ inspect_fw_pstr("Firmware version", hdr->fw_version);
+ inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id));
+ 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",
+ hdr->ver_hi, hdr->ver_mid, hdr->ver_lo,
+ hdr->sver_hi, hdr->sver_lo);
+
+ printf("\n");
+
+ inspect_fw_phexdec("Kernel data offset",
+ ntohl(hdr->kernel_ofs));
+ inspect_fw_phexdec("Kernel data length",
+ ntohl(hdr->kernel_len));
+ 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;
+
+ progname = basename(argv[0]);
+
+ while ( 1 ) {
+ int c;
+
+ c = getopt(argc, argv, "a:H:E:F:L:V:N:W:w:ci:k:r:R:o:xhsjv:y:T:e");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'a':
+ sscanf(optarg, "0x%x", &rootfs_align);
+ 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 'w':
+ opt_hw_ver_add = optarg;
+ break;
+ case 'L':
+ sscanf(optarg, "0x%x", &kernel_la);
+ break;
+ case 'V':
+ version = optarg;
+ break;
+ case 'v':
+ fw_ver = optarg;
+ break;
+ case 'y':
+ sver = 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 'T':
+ hdr_ver = atoi(optarg);
+ break;
+ case 'e':
+ custom_board.flags = FLAG_LE_KERNEL_LA_EP;
+ 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(sizeof(struct fw_header));
+ else
+ ret = inspect_fw();
+
+ out:
+ return ret;
+}
+
diff --git a/tools/firmware-utils/src/mkwrggimg.c b/tools/firmware-utils/src/mkwrggimg.c
new file mode 100644
index 00000000000..9995b9a13d8
--- /dev/null
+++ b/tools/firmware-utils/src/mkwrggimg.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be>
+ *
+ * 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.
+ *
+ */
+
+#define _ANSI_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "md5.h"
+
+#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 ", %s\n", \
+ progname, ## __VA_ARGS__, strerror(save)); \
+} while (0)
+
+#define WRGG03_MAGIC 0x20080321
+
+struct wrgg03_header {
+ char signature[32];
+ uint32_t magic1;
+ uint32_t magic2;
+ char version[16];
+ char model[16];
+ uint32_t flag[2];
+ uint32_t reserve[2];
+ char buildno[16];
+ uint32_t size;
+ uint32_t offset;
+ char devname[32];
+ char digest[16];
+} __attribute__ ((packed));
+
+static char *progname;
+static char *ifname;
+static char *ofname;
+static char *signature;
+static char *version;
+static char *model;
+static uint32_t flag = 0;
+static uint32_t reserve = 0;
+static char *buildno;
+static uint32_t offset;
+static char *devname;
+static int big_endian;
+
+void usage(int status)
+{
+ FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
+
+ fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stream,
+"\n"
+"Options:\n"
+" -b create image in big endian format\n"
+" -B <buildno> build number\n"
+" -i <file> read input from the file <file>\n"
+" -d <name> set device name to <name>\n"
+" -m <model> model name\n"
+" -o <file> write output to the file <file>\n"
+" -O <offset> set offset to <offset>\n"
+" -s <sig> set image signature to <sig>\n"
+" -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+static void put_u32(void *data, uint32_t val, int swap)
+{
+ unsigned char *p = data;
+
+ if (swap) {
+ p[0] = (val >> 24) & 0xff;
+ p[1] = (val >> 16) & 0xff;
+ p[2] = (val >> 8) & 0xff;
+ p[3] = val & 0xff;
+ } else {
+ p[3] = (val >> 24) & 0xff;
+ p[2] = (val >> 16) & 0xff;
+ p[1] = (val >> 8) & 0xff;
+ p[0] = val & 0xff;
+ }
+}
+
+static void get_digest(struct wrgg03_header *header, char *data, int size)
+{
+ MD5_CTX ctx;
+
+ MD5_Init(&ctx);
+
+ MD5_Update(&ctx, (char *)&header->offset, sizeof(header->offset));
+ MD5_Update(&ctx, (char *)&header->devname, sizeof(header->devname));
+ MD5_Update(&ctx, data, size);
+
+ MD5_Final(header->digest, &ctx);
+}
+
+int main(int argc, char *argv[])
+{
+ struct wrgg03_header *header;
+ char *buf;
+ struct stat st;
+ int buflen;
+ int err;
+ int res = EXIT_FAILURE;
+
+ FILE *outfile, *infile;
+
+ progname = basename(argv[0]);
+
+ while ( 1 ) {
+ int c;
+
+ c = getopt(argc, argv, "bd:i:m:o:s:v:B:O:h");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'b':
+ big_endian = 1;
+ break;
+ case 'B':
+ buildno = optarg;
+ break;
+ case 'd':
+ devname = optarg;
+ break;
+ case 'i':
+ ifname = optarg;
+ break;
+ case 'm':
+ model = optarg;
+ break;
+ case 'o':
+ ofname = optarg;
+ break;
+ case 's':
+ signature = optarg;
+ break;
+ case 'v':
+ version = optarg;
+ break;
+ case 'O':
+ offset = strtoul(optarg, NULL, 0);
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ break;
+
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (signature == NULL) {
+ ERR("no signature specified");
+ goto err;
+ }
+
+ if (ifname == NULL) {
+ ERR("no input file specified");
+ goto err;
+ }
+
+ if (ofname == NULL) {
+ ERR("no output file specified");
+ goto err;
+ }
+
+ if (devname == NULL) {
+ ERR("no device name specified");
+ goto err;
+ }
+
+ if (model == NULL) {
+ ERR("no model name specified");
+ goto err;
+ }
+
+ if (buildno == NULL) {
+ ERR("no build number specified");
+ goto err;
+ }
+
+ if (version == NULL) {
+ ERR("no version specified");
+ goto err;
+ }
+
+ err = stat(ifname, &st);
+ if (err){
+ ERRS("stat failed on %s", ifname);
+ goto err;
+ }
+
+ buflen = st.st_size + sizeof(struct wrgg03_header);
+ buf = malloc(buflen);
+ if (!buf) {
+ ERR("no memory for buffer\n");
+ goto err;
+ }
+
+ infile = fopen(ifname, "r");
+ if (infile == NULL) {
+ ERRS("could not open \"%s\" for reading", ifname);
+ goto err_free;
+ }
+
+ errno = 0;
+ fread(buf + sizeof(struct wrgg03_header), st.st_size, 1, infile);
+ if (errno != 0) {
+ ERRS("unable to read from file %s", ifname);
+ goto close_in;
+ }
+
+ header = (struct wrgg03_header *) buf;
+ memset(header, '\0', sizeof(struct wrgg03_header));
+
+ strncpy(header->signature, signature, sizeof(header->signature));
+ put_u32(&header->magic1, WRGG03_MAGIC, 0);
+ put_u32(&header->magic2, WRGG03_MAGIC, 0);
+ strncpy(header->version, version, sizeof(header->version));
+ strncpy(header->model, model, sizeof(header->model));
+ put_u32(&header->flag, flag, 0);
+ put_u32(&header->reserve, reserve, 0);
+ strncpy(header->buildno, buildno, sizeof(header->buildno));
+ put_u32(&header->size, st.st_size, big_endian);
+ put_u32(&header->offset, offset, big_endian);
+ strncpy(header->devname, devname, sizeof(header->devname));
+
+ get_digest(header, buf + sizeof(struct wrgg03_header), st.st_size);
+
+ outfile = fopen(ofname, "w");
+ if (outfile == NULL) {
+ ERRS("could not open \"%s\" for writing", ofname);
+ goto close_in;
+ }
+
+ errno = 0;
+ fwrite(buf, buflen, 1, outfile);
+ if (errno) {
+ ERRS("unable to write to file %s", ofname);
+ goto close_out;
+ }
+
+ fflush(outfile);
+
+ res = EXIT_SUCCESS;
+
+close_out:
+ fclose(outfile);
+ if (res != EXIT_SUCCESS)
+ unlink(ofname);
+close_in:
+ fclose(infile);
+err_free:
+ free(buf);
+err:
+ return res;
+}
diff --git a/tools/firmware-utils/src/mkzcfw.c b/tools/firmware-utils/src/mkzcfw.c
index 7674e706c99..2326f1ff5c5 100644
--- a/tools/firmware-utils/src/mkzcfw.c
+++ b/tools/firmware-utils/src/mkzcfw.c
@@ -100,7 +100,7 @@ static struct board_info boards[] = {
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
diff --git a/tools/firmware-utils/src/mkzynfw.c b/tools/firmware-utils/src/mkzynfw.c
index 36c176f4325..ccbabfe7f20 100644
--- a/tools/firmware-utils/src/mkzynfw.c
+++ b/tools/firmware-utils/src/mkzynfw.c
@@ -27,6 +27,7 @@
#if defined(__CYGWIN__)
# include <byteswap.h>
#endif
+#include <inttypes.h>
#include "zynos.h"
@@ -687,7 +688,7 @@ write_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css)
FILE *f;
int res;
- DBG(2, "writing out file, name=%s, len=%d",
+ DBG(2, "writing out file, name=%s, len=%zu",
name, len);
errno = 0;
@@ -988,7 +989,7 @@ calc_block_offsets(int type, uint32_t *offset)
uint32_t avail;
int i, res;
- DBG(1,"calculating block offsets, starting with %lu",
+ DBG(1,"calculating block offsets, starting with %" PRIu32,
*offset);
res = 0;
diff --git a/tools/firmware-utils/src/nand_ecc.c b/tools/firmware-utils/src/nand_ecc.c
index b1e9305158c..58fb6ce0db4 100644
--- a/tools/firmware-utils/src/nand_ecc.c
+++ b/tools/firmware-utils/src/nand_ecc.c
@@ -2,7 +2,7 @@
* calculate ecc code for nand flash
*
* Copyright (C) 2008 yajin <yajin@vm-kernel.org>
- * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
diff --git a/tools/firmware-utils/src/osbridge-crc.c b/tools/firmware-utils/src/osbridge-crc.c
index f2e3920a48c..5fd236a0746 100644
--- a/tools/firmware-utils/src/osbridge-crc.c
+++ b/tools/firmware-utils/src/osbridge-crc.c
@@ -51,7 +51,7 @@ static char *ofname;
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
diff --git a/tools/firmware-utils/src/oseama.c b/tools/firmware-utils/src/oseama.c
new file mode 100644
index 00000000000..4434b11162e
--- /dev/null
+++ b/tools/firmware-utils/src/oseama.c
@@ -0,0 +1,556 @@
+/*
+ * oseama
+ *
+ * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "md5.h"
+
+#if !defined(__BYTE_ORDER)
+#error "Unknown byte order"
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_be32(x) bswap_32(x)
+#define be32_to_cpu(x) bswap_32(x)
+#define cpu_to_be16(x) bswap_16(x)
+#define be16_to_cpu(x) bswap_16(x)
+#else
+#error "Unsupported endianness"
+#endif
+
+#define SEAMA_MAGIC 0x5ea3a417
+
+struct seama_seal_header {
+ uint32_t magic;
+ uint16_t reserved;
+ uint16_t metasize;
+ uint32_t imagesize;
+} __attribute__ ((packed));
+
+struct seama_entity_header {
+ uint32_t magic;
+ uint16_t reserved;
+ uint16_t metasize;
+ uint32_t imagesize;
+ uint8_t md5[16];
+} __attribute__ ((packed));
+
+char *seama_path;
+int entity_idx = -1;
+char *out_path;
+
+static inline size_t oseama_min(size_t x, size_t y) {
+ return x < y ? x : y;
+}
+
+/**************************************************
+ * Info
+ **************************************************/
+
+static void oseama_info_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "e:")) != -1) {
+ switch (c) {
+ case 'e':
+ entity_idx = atoi(optarg);
+ break;
+ }
+ }
+}
+
+static int oseama_info_entities(FILE *seama) {
+ struct seama_entity_header hdr;
+ size_t bytes, metasize, imagesize;
+ uint8_t buf[1024];
+ char *end, *tmp;
+ int i = 0;
+ int err = 0;
+
+ while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) {
+ if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
+ fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_out;
+ }
+ metasize = be16_to_cpu(hdr.metasize);
+ imagesize = be32_to_cpu(hdr.imagesize);
+
+ if (entity_idx >= 0 && i != entity_idx) {
+ fseek(seama, metasize + imagesize, SEEK_CUR);
+ i++;
+ continue;
+ }
+
+ if (metasize >= sizeof(buf)) {
+ fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%zd B)\n", sizeof(buf), metasize);
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ if (entity_idx < 0)
+ printf("\n");
+ printf("Entity offset:\t%ld\n", ftell(seama) - sizeof(hdr));
+ printf("Entity size:\t%zd\n", sizeof(hdr) + metasize + imagesize);
+ printf("Meta size:\t%zd\n", metasize);
+ printf("Image size:\t%zd\n", imagesize);
+
+ bytes = fread(buf, 1, metasize, seama);
+ if (bytes != metasize) {
+ fprintf(stderr, "Couldn't read %zd B of meta\n", metasize);
+ err = -EIO;
+ goto err_out;
+ }
+
+ end = (char *)&buf[metasize - 1];
+ *end = '\0';
+ for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) {
+ printf("Meta entry:\t%s\n", tmp);
+ }
+
+ fseek(seama, imagesize, SEEK_CUR);
+ i++;
+ }
+
+err_out:
+ return err;
+}
+
+static int oseama_info(int argc, char **argv) {
+ FILE *seama;
+ struct seama_seal_header hdr;
+ size_t bytes;
+ uint16_t metasize;
+ uint32_t imagesize;
+ uint8_t buf[1024];
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No Seama file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ seama_path = argv[2];
+
+ optind = 3;
+ oseama_info_parse_options(argc, argv);
+
+ seama = fopen(seama_path, "r");
+ if (!seama) {
+ fprintf(stderr, "Couldn't open %s\n", seama_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ bytes = fread(&hdr, 1, sizeof(hdr), seama);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", seama_path);
+ err = -EIO;
+ goto err_close;
+ }
+ metasize = be16_to_cpu(hdr.metasize);
+ imagesize = be32_to_cpu(hdr.imagesize);
+
+ if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
+ fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ if (metasize >= sizeof(buf)) {
+ fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%d B)\n", sizeof(buf), metasize);
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ if (imagesize) {
+ fprintf(stderr, "Invalid Seama image size: 0x%08x (should be 0)\n", imagesize);
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ bytes = fread(buf, 1, metasize, seama);
+ if (bytes != metasize) {
+ fprintf(stderr, "Couldn't read %d B of meta\n", metasize);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (entity_idx < 0) {
+ char *end, *tmp;
+
+ printf("Meta size:\t%d\n", metasize);
+ printf("Image size:\t%d\n", imagesize);
+
+ end = (char *)&buf[metasize - 1];
+ *end = '\0';
+ for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) {
+ printf("Meta entry:\t%s\n", tmp);
+ }
+ }
+
+ oseama_info_entities(seama);
+
+err_close:
+ fclose(seama);
+out:
+ return err;
+}
+
+/**************************************************
+ * Create
+ **************************************************/
+
+static ssize_t oseama_entity_append_file(FILE *seama, const char *in_path) {
+ FILE *in;
+ size_t bytes;
+ ssize_t length = 0;
+ uint8_t buf[128];
+
+ in = fopen(in_path, "r");
+ if (!in) {
+ fprintf(stderr, "Couldn't open %s\n", in_path);
+ return -EACCES;
+ }
+
+ while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (fwrite(buf, 1, bytes, seama) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, seama_path);
+ length = -EIO;
+ break;
+ }
+ length += bytes;
+ }
+
+ fclose(in);
+
+ return length;
+}
+
+static ssize_t oseama_entity_append_zeros(FILE *seama, size_t length) {
+ uint8_t *buf;
+
+ buf = malloc(length);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, length);
+
+ if (fwrite(buf, 1, length, seama) != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, seama_path);
+ return -EIO;
+ }
+
+ return length;
+}
+
+static ssize_t oseama_entity_align(FILE *seama, size_t curr_offset, size_t alignment) {
+ if (curr_offset & (alignment - 1)) {
+ size_t length = alignment - (curr_offset % alignment);
+
+ return oseama_entity_append_zeros(seama, length);
+ }
+
+ return 0;
+}
+
+static int oseama_entity_write_hdr(FILE *seama, size_t metasize, size_t imagesize) {
+ struct seama_entity_header hdr = {};
+ uint8_t buf[128];
+ size_t length = imagesize;
+ size_t bytes;
+ MD5_CTX ctx;
+
+ fseek(seama, sizeof(hdr) + metasize, SEEK_SET);
+ MD5_Init(&ctx);
+ while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) {
+ MD5_Update(&ctx, buf, bytes);
+ length -= bytes;
+ }
+ MD5_Final(hdr.md5, &ctx);
+
+ hdr.magic = cpu_to_be32(SEAMA_MAGIC);
+ hdr.metasize = cpu_to_be16(metasize);
+ hdr.imagesize = cpu_to_be32(imagesize);
+
+ fseek(seama, 0, SEEK_SET);
+ bytes = fwrite(&hdr, 1, sizeof(hdr), seama);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't write Seama entity header to %s\n", seama_path);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int oseama_entity(int argc, char **argv) {
+ FILE *seama;
+ ssize_t sbytes;
+ size_t curr_offset = sizeof(struct seama_entity_header);
+ size_t metasize = 0, imagesize = 0;
+ int c;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No Seama file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ seama_path = argv[2];
+
+ seama = fopen(seama_path, "w+");
+ if (!seama) {
+ fprintf(stderr, "Couldn't open %s\n", seama_path);
+ err = -EACCES;
+ goto out;
+ }
+ fseek(seama, curr_offset, SEEK_SET);
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "m:f:b:")) != -1) {
+ switch (c) {
+ case 'm':
+ sbytes = fwrite(optarg, 1, strlen(optarg) + 1, seama);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to write meta %s\n", optarg);
+ } else {
+ curr_offset += sbytes;
+ metasize += sbytes;
+ }
+
+ sbytes = oseama_entity_align(seama, curr_offset, 4);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append zeros\n");
+ } else {
+ curr_offset += sbytes;
+ metasize += sbytes;
+ }
+
+ break;
+ case 'f':
+ case 'b':
+ break;
+ }
+ }
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "m:f:b:")) != -1) {
+ switch (c) {
+ case 'm':
+ break;
+ case 'f':
+ sbytes = oseama_entity_append_file(seama, optarg);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append file %s\n", optarg);
+ } else {
+ curr_offset += sbytes;
+ imagesize += sbytes;
+ }
+ break;
+ case 'b':
+ sbytes = strtol(optarg, NULL, 0) - curr_offset;
+ if (sbytes < 0) {
+ fprintf(stderr, "Current Seama entity length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0));
+ } else {
+ sbytes = oseama_entity_append_zeros(seama, sbytes);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append zeros\n");
+ } else {
+ curr_offset += sbytes;
+ imagesize += sbytes;
+ }
+ }
+ break;
+ }
+ if (err)
+ break;
+ }
+
+ oseama_entity_write_hdr(seama, metasize, imagesize);
+
+ fclose(seama);
+out:
+ return err;
+}
+
+/**************************************************
+ * Extract
+ **************************************************/
+
+static void oseama_extract_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "e:o:")) != -1) {
+ switch (c) {
+ case 'e':
+ entity_idx = atoi(optarg);
+ break;
+ case 'o':
+ out_path = optarg;
+ break;
+ }
+ }
+}
+
+static int oseama_extract_entity(FILE *seama, FILE *out) {
+ struct seama_entity_header hdr;
+ size_t bytes, metasize, imagesize, length;
+ uint8_t buf[1024];
+ int i = 0;
+ int err = 0;
+
+ while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) {
+ if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) {
+ fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ break;
+ }
+ metasize = be16_to_cpu(hdr.metasize);
+ imagesize = be32_to_cpu(hdr.imagesize);
+
+ if (i != entity_idx) {
+ fseek(seama, metasize + imagesize, SEEK_CUR);
+ i++;
+ continue;
+ }
+
+ fseek(seama, -sizeof(hdr), SEEK_CUR);
+
+ length = sizeof(hdr) + metasize + imagesize;
+ while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) {
+ if (fwrite(buf, 1, bytes, out) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path);
+ err = -EIO;
+ break;
+ }
+ length -= bytes;
+ }
+
+ if (length) {
+ fprintf(stderr, "Couldn't extract whole entity %d from %s (%zu B left)\n", entity_idx, seama_path, length);
+ err = -EIO;
+ break;
+ }
+
+ break;
+ }
+
+ return err;
+}
+
+static int oseama_extract(int argc, char **argv) {
+ FILE *seama;
+ FILE *out;
+ struct seama_seal_header hdr;
+ size_t bytes;
+ uint16_t metasize;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No Seama file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ seama_path = argv[2];
+
+ optind = 3;
+ oseama_extract_parse_options(argc, argv);
+ if (entity_idx < 0) {
+ fprintf(stderr, "No entity specified\n");
+ err = -EINVAL;
+ goto out;
+ } else if (!out_path) {
+ fprintf(stderr, "No output file specified\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ seama = fopen(seama_path, "r");
+ if (!seama) {
+ fprintf(stderr, "Couldn't open %s\n", seama_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ out = fopen(out_path, "w");
+ if (!out) {
+ fprintf(stderr, "Couldn't open %s\n", out_path);
+ err = -EACCES;
+ goto err_close_seama;
+ }
+
+ bytes = fread(&hdr, 1, sizeof(hdr), seama);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", seama_path);
+ err = -EIO;
+ goto err_close_out;
+ }
+ metasize = be16_to_cpu(hdr.metasize);
+
+ fseek(seama, metasize, SEEK_CUR);
+
+ oseama_extract_entity(seama, out);
+
+err_close_out:
+ fclose(out);
+err_close_seama:
+ fclose(seama);
+out:
+ return err;
+}
+
+/**************************************************
+ * Start
+ **************************************************/
+
+static void usage() {
+ printf("Usage:\n");
+ printf("\n");
+ printf("Info about Seama seal (container):\n");
+ printf("\toseama info <file> [options]\n");
+ printf("\t-e\t\t\t\tprint info about specified entity only\n");
+ printf("\n");
+ printf("Create Seama entity:\n");
+ printf("\toseama entity <file> [options]\n");
+ printf("\t-m meta\t\t\t\tmeta into to put in header\n");
+ printf("\t-f file\t\t\t\tappend content from file\n");
+ printf("\t-b offset\t\t\tappend zeros till reaching absolute offset\n");
+ printf("\n");
+ printf("Extract from Seama seal (container):\n");
+ printf("\toseama extract <file> [options]\n");
+ printf("\t-e\t\t\t\tindex of entity to extract\n");
+ printf("\t-o file\t\t\t\toutput file\n");
+}
+
+int main(int argc, char **argv) {
+ if (argc > 1) {
+ if (!strcmp(argv[1], "info"))
+ return oseama_info(argc, argv);
+ else if (!strcmp(argv[1], "entity"))
+ return oseama_entity(argc, argv);
+ else if (!strcmp(argv[1], "extract"))
+ return oseama_extract(argc, argv);
+ }
+
+ usage();
+ return 0;
+}
diff --git a/tools/firmware-utils/src/otrx.c b/tools/firmware-utils/src/otrx.c
new file mode 100644
index 00000000000..223e032f2b5
--- /dev/null
+++ b/tools/firmware-utils/src/otrx.c
@@ -0,0 +1,592 @@
+/*
+ * otrx
+ *
+ * Copyright (C) 2015-2017 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if !defined(__BYTE_ORDER)
+#error "Unknown byte order"
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_le32(x) bswap_32(x)
+#define le32_to_cpu(x) bswap_32(x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#else
+#error "Unsupported endianness"
+#endif
+
+#define TRX_MAGIC 0x30524448
+#define TRX_FLAGS_OFFSET 12
+#define TRX_MAX_PARTS 3
+
+struct trx_header {
+ uint32_t magic;
+ uint32_t length;
+ uint32_t crc32;
+ uint16_t flags;
+ uint16_t version;
+ uint32_t offset[3];
+};
+
+char *trx_path;
+size_t trx_offset = 0;
+char *partition[TRX_MAX_PARTS] = {};
+
+static inline size_t otrx_min(size_t x, size_t y) {
+ return x < y ? x : y;
+}
+
+/**************************************************
+ * CRC32
+ **************************************************/
+
+static const uint32_t crc32_tbl[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+};
+
+uint32_t otrx_crc32(uint32_t crc, uint8_t *buf, size_t len) {
+ while (len) {
+ crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ buf++;
+ len--;
+ }
+
+ return crc;
+}
+
+/**************************************************
+ * Check
+ **************************************************/
+
+static void otrx_check_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "o:")) != -1) {
+ switch (c) {
+ case 'o':
+ trx_offset = atoi(optarg);
+ break;
+ }
+ }
+}
+
+static int otrx_check(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr;
+ size_t bytes, length;
+ uint8_t buf[1024];
+ uint32_t crc32;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ optind = 3;
+ otrx_check_parse_options(argc, argv);
+
+ trx = fopen(trx_path, "r");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ fseek(trx, trx_offset, SEEK_SET);
+ bytes = fread(&hdr, 1, sizeof(hdr), trx);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (le32_to_cpu(hdr.magic) != TRX_MAGIC) {
+ fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ length = le32_to_cpu(hdr.length);
+ if (length < sizeof(hdr)) {
+ fprintf(stderr, "Length read from TRX too low (%zu B)\n", length);
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ crc32 = 0xffffffff;
+ fseek(trx, trx_offset + TRX_FLAGS_OFFSET, SEEK_SET);
+ length -= TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) {
+ crc32 = otrx_crc32(crc32, buf, bytes);
+ length -= bytes;
+ }
+
+ if (length) {
+ fprintf(stderr, "Couldn't read last %zd B of data from %s\n", length, trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (crc32 != le32_to_cpu(hdr.crc32)) {
+ fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(hdr.crc32));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ printf("Found a valid TRX version %d\n", le32_to_cpu(hdr.version));
+
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Create
+ **************************************************/
+
+static ssize_t otrx_create_append_file(FILE *trx, const char *in_path) {
+ FILE *in;
+ size_t bytes;
+ ssize_t length = 0;
+ uint8_t buf[1024];
+
+ in = fopen(in_path, "r");
+ if (!in) {
+ fprintf(stderr, "Couldn't open %s\n", in_path);
+ return -EACCES;
+ }
+
+ while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (fwrite(buf, 1, bytes, trx) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, trx_path);
+ length = -EIO;
+ break;
+ }
+ length += bytes;
+ }
+
+ fclose(in);
+
+ return length;
+}
+
+static ssize_t otrx_create_append_zeros(FILE *trx, size_t length) {
+ uint8_t *buf;
+
+ buf = malloc(length);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, length);
+
+ if (fwrite(buf, 1, length, trx) != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, trx_path);
+ free(buf);
+ return -EIO;
+ }
+
+ free(buf);
+
+ return length;
+}
+
+static ssize_t otrx_create_align(FILE *trx, size_t curr_offset, size_t alignment) {
+ if (curr_offset & (alignment - 1)) {
+ size_t length = alignment - (curr_offset % alignment);
+ return otrx_create_append_zeros(trx, length);
+ }
+
+ return 0;
+}
+
+static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) {
+ size_t bytes, length;
+ uint8_t buf[1024];
+ uint32_t crc32;
+
+ hdr->magic = cpu_to_le32(TRX_MAGIC);
+ hdr->version = 1;
+
+ fseek(trx, 0, SEEK_SET);
+ bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
+ if (bytes != sizeof(struct trx_header)) {
+ fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
+ return -EIO;
+ }
+
+ length = le32_to_cpu(hdr->length);
+
+ crc32 = 0xffffffff;
+ fseek(trx, TRX_FLAGS_OFFSET, SEEK_SET);
+ length -= TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) {
+ crc32 = otrx_crc32(crc32, buf, bytes);
+ length -= bytes;
+ }
+ hdr->crc32 = cpu_to_le32(crc32);
+
+ fseek(trx, 0, SEEK_SET);
+ bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
+ if (bytes != sizeof(struct trx_header)) {
+ fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int otrx_create(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr = {};
+ ssize_t sbytes;
+ size_t curr_idx = 0;
+ size_t curr_offset = sizeof(hdr);
+ int c;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ trx = fopen(trx_path, "w+");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+ fseek(trx, curr_offset, SEEK_SET);
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "f:A:a:b:")) != -1) {
+ switch (c) {
+ case 'f':
+ if (curr_idx >= TRX_MAX_PARTS) {
+ err = -ENOSPC;
+ fprintf(stderr, "Reached TRX partitions limit, no place for %s\n", optarg);
+ goto err_close;
+ }
+
+ sbytes = otrx_create_append_file(trx, optarg);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append file %s\n", optarg);
+ } else {
+ hdr.offset[curr_idx++] = curr_offset;
+ curr_offset += sbytes;
+ }
+
+ sbytes = otrx_create_align(trx, curr_offset, 4);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+
+ break;
+ case 'A':
+ sbytes = otrx_create_append_file(trx, optarg);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append file %s\n", optarg);
+ } else {
+ curr_offset += sbytes;
+ }
+
+ sbytes = otrx_create_align(trx, curr_offset, 4);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+ break;
+ case 'a':
+ sbytes = otrx_create_align(trx, curr_offset, strtol(optarg, NULL, 0));
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+ break;
+ case 'b':
+ sbytes = strtol(optarg, NULL, 0) - curr_offset;
+ if (sbytes < 0) {
+ fprintf(stderr, "Current TRX length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0));
+ } else {
+ sbytes = otrx_create_append_zeros(trx, sbytes);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+ }
+ break;
+ }
+ if (err)
+ break;
+ }
+
+ sbytes = otrx_create_align(trx, curr_offset, 0x1000);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+
+ hdr.length = curr_offset;
+ otrx_create_write_hdr(trx, &hdr);
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Extract
+ **************************************************/
+
+static void otrx_extract_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "c:e:o:1:2:3:")) != -1) {
+ switch (c) {
+ case 'o':
+ trx_offset = atoi(optarg);
+ break;
+ case '1':
+ partition[0] = optarg;
+ break;
+ case '2':
+ partition[1] = optarg;
+ break;
+ case '3':
+ partition[2] = optarg;
+ break;
+ }
+ }
+}
+
+static int otrx_extract_copy(FILE *trx, size_t offset, size_t length, char *out_path) {
+ FILE *out;
+ size_t bytes;
+ uint8_t *buf;
+ int err = 0;
+
+ out = fopen(out_path, "w");
+ if (!out) {
+ fprintf(stderr, "Couldn't open %s\n", out_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ buf = malloc(length);
+ if (!buf) {
+ fprintf(stderr, "Couldn't alloc %zu B buffer\n", length);
+ err = -ENOMEM;
+ goto err_close;
+ }
+
+ fseek(trx, offset, SEEK_SET);
+ bytes = fread(buf, 1, length, trx);
+ if (bytes != length) {
+ fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path);
+ err = -ENOMEM;
+ goto err_free_buf;
+ };
+
+ bytes = fwrite(buf, 1, length, out);
+ if (bytes != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, out_path);
+ err = -ENOMEM;
+ goto err_free_buf;
+ }
+
+ printf("Extracted 0x%zx bytes into %s\n", length, out_path);
+
+err_free_buf:
+ free(buf);
+err_close:
+ fclose(out);
+out:
+ return err;
+}
+
+static int otrx_extract(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr;
+ size_t bytes;
+ int i;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ optind = 3;
+ otrx_extract_parse_options(argc, argv);
+
+ trx = fopen(trx_path, "r");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ fseek(trx, trx_offset, SEEK_SET);
+ bytes = fread(&hdr, 1, sizeof(hdr), trx);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (le32_to_cpu(hdr.magic) != TRX_MAGIC) {
+ fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ for (i = 0; i < TRX_MAX_PARTS; i++) {
+ size_t length;
+
+ if (!partition[i])
+ continue;
+ if (!hdr.offset[i]) {
+ printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]);
+ continue;
+ }
+
+ if (i + 1 >= TRX_MAX_PARTS || !hdr.offset[i + 1])
+ length = le32_to_cpu(hdr.length) - le32_to_cpu(hdr.offset[i]);
+ else
+ length = le32_to_cpu(hdr.offset[i + 1]) - le32_to_cpu(hdr.offset[i]);
+
+ otrx_extract_copy(trx, trx_offset + le32_to_cpu(hdr.offset[i]), length, partition[i]);
+ }
+
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Start
+ **************************************************/
+
+static void usage() {
+ printf("Usage:\n");
+ printf("\n");
+ printf("Checking TRX file:\n");
+ printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n");
+ printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
+ printf("\n");
+ printf("Creating new TRX file:\n");
+ printf("\totrx create <file> [options] [partitions]\n");
+ printf("\t-f file\t\t\t\t[partition] start new partition with content copied from file\n");
+ printf("\t-A file\t\t\t\t[partition] append current partition with content copied from file\n");
+ printf("\t-a alignment\t\t\t[partition] align current partition\n");
+ printf("\t-b offset\t\t\t[partition] append zeros to partition till reaching absolute offset\n");
+ printf("\n");
+ printf("Extracting from TRX file:\n");
+ printf("\totrx extract <file> [options]\textract partitions from TRX file\n");
+ printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
+ printf("\t-1 file\t\t\t\tfile to extract 1st partition to (optional)\n");
+ printf("\t-2 file\t\t\t\tfile to extract 2nd partition to (optional)\n");
+ printf("\t-3 file\t\t\t\tfile to extract 3rd partition to (optional)\n");
+}
+
+int main(int argc, char **argv) {
+ if (argc > 1) {
+ if (!strcmp(argv[1], "check"))
+ return otrx_check(argc, argv);
+ else if (!strcmp(argv[1], "create"))
+ return otrx_create(argc, argv);
+ else if (!strcmp(argv[1], "extract"))
+ return otrx_extract(argc, argv);
+ }
+
+ usage();
+ return 0;
+}
diff --git a/tools/firmware-utils/src/pc1crypt.c b/tools/firmware-utils/src/pc1crypt.c
index 9c2eb83f666..fe41b3dab5c 100644
--- a/tools/firmware-utils/src/pc1crypt.c
+++ b/tools/firmware-utils/src/pc1crypt.c
@@ -208,7 +208,7 @@ static int decrypt;
#define ERRS(fmt, ...) do { \
int save = errno; \
fflush(0); \
- fprintf(stderr, "[%s] *** error: " fmt "\n", \
+ fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
progname, ## __VA_ARGS__, strerror(save)); \
} while (0)
diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c
index d94aabb5fcf..13e0eda6222 100644
--- a/tools/firmware-utils/src/ptgen.c
+++ b/tools/firmware-utils/src/ptgen.c
@@ -1,6 +1,6 @@
-/*
+/*
* ptgen - partition table generator
- * Copyright (C) 2006 by Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006 by Felix Fietkau <nbd@nbd.name>
*
* uses parts of afdisk
* Copyright (C) 2002 by David Roetzel <david@roetzel.de>
@@ -9,12 +9,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
@@ -26,25 +26,27 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
#include <ctype.h>
#include <fcntl.h>
+#include <stdint.h>
#if __BYTE_ORDER == __BIG_ENDIAN
-#define cpu_to_le16(x) bswap_16(x)
+#define cpu_to_le32(x) bswap_32(x)
#elif __BYTE_ORDER == __LITTLE_ENDIAN
-#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
#else
#error unknown endianness!
#endif
/* Partition table entry */
-struct pte {
- unsigned char active;
- unsigned char chs_start[3];
- unsigned char type;
- unsigned char chs_end[3];
- unsigned int start;
- unsigned int length;
+struct pte {
+ uint8_t active;
+ uint8_t chs_start[3];
+ uint8_t type;
+ uint8_t chs_end[3];
+ uint32_t start;
+ uint32_t length;
};
struct partinfo {
@@ -56,29 +58,31 @@ int verbose = 0;
int active = 1;
int heads = -1;
int sectors = -1;
+int kb_align = 0;
struct partinfo parts[4];
char *filename = NULL;
-/*
+/*
* parse the size argument, which is either
* a simple number (K assumed) or
* K, M or G
*
* returns the size in KByte
*/
-static long to_kbytes(const char *string) {
+static long to_kbytes(const char *string)
+{
int exp = 0;
long result;
char *end;
result = strtoul(string, &end, 0);
switch (tolower(*end)) {
- case 'k' :
- case '\0' : exp = 0; break;
- case 'm' : exp = 1; break;
- case 'g' : exp = 2; break;
- default: return 0;
+ case 'k' :
+ case '\0' : exp = 0; break;
+ case 'm' : exp = 1; break;
+ case 'g' : exp = 2; break;
+ default: return 0;
}
if (*end)
@@ -90,13 +94,16 @@ static long to_kbytes(const char *string) {
}
/* result: number + 1024^(exp) */
- return result * ((2 << ((10 * exp) - 1)) ?: 1);
+ if (exp == 0)
+ return result;
+ return result * (2 << ((10 * exp) - 1));
}
/* convert the sector number into a CHS value for the partition table */
-static void to_chs(long sect, unsigned char chs[3]) {
+static void to_chs(long sect, unsigned char chs[3])
+{
int c,h,s;
-
+
s = (sect % sectors) + 1;
sect = sect / sectors;
h = sect % heads;
@@ -111,17 +118,23 @@ static void to_chs(long sect, unsigned char chs[3]) {
}
/* round the sector number up to the next cylinder */
-static inline unsigned long round_to_cyl(long sect) {
+static inline unsigned long round_to_cyl(long sect)
+{
int cyl_size = heads * sectors;
- return sect + cyl_size - (sect % cyl_size);
+ return sect + cyl_size - (sect % cyl_size);
+}
+
+/* round the sector number up to the kb_align boundary */
+static inline unsigned long round_to_kb(long sect) {
+ return ((sect - 1) / kb_align + 1) * kb_align;
}
/* check the partition sizes and write the partition table */
-static int gen_ptable(int nr)
+static int gen_ptable(uint32_t signature, int nr)
{
struct pte pte[4];
- unsigned long sect = 0;
+ unsigned long sect = 0;
int i, fd, ret = -1, start, len;
memset(pte, 0, sizeof(struct pte) * 4);
@@ -130,17 +143,27 @@ static int gen_ptable(int nr)
fprintf(stderr, "Invalid size in partition %d!\n", i);
return -1;
}
+
pte[i].active = ((i + 1) == active) ? 0x80 : 0;
pte[i].type = parts[i].type;
- pte[i].start = cpu_to_le16(start = sect + sectors);
- sect = round_to_cyl(start + parts[i].size * 2);
- pte[i].length = cpu_to_le16(len = sect - start);
+
+ start = sect + sectors;
+ if (kb_align != 0)
+ start = round_to_kb(start);
+ pte[i].start = cpu_to_le32(start);
+
+ sect = start + parts[i].size * 2;
+ if (kb_align == 0)
+ sect = round_to_cyl(sect);
+ pte[i].length = cpu_to_le32(len = sect - start);
+
to_chs(start, pte[i].chs_start);
to_chs(start + len - 1, pte[i].chs_end);
+
if (verbose)
- fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long) start * 512, ((long) start + (long) len) * 512, (long) len * 512);
- printf("%ld\n", ((long) start * 512));
- printf("%ld\n", ((long) len * 512));
+ fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", i, (long)start * 512, ((long)start + (long)len) * 512, (long)len * 512);
+ printf("%ld\n", (long)start * 512);
+ printf("%ld\n", (long)len * 512);
}
if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
@@ -148,6 +171,12 @@ static int gen_ptable(int nr)
return -1;
}
+ lseek(fd, 440, SEEK_SET);
+ if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) {
+ fprintf(stderr, "write failed.\n");
+ goto fail;
+ }
+
lseek(fd, 446, SEEK_SET);
if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) {
fprintf(stderr, "write failed.\n");
@@ -158,7 +187,7 @@ static int gen_ptable(int nr)
fprintf(stderr, "write failed.\n");
goto fail;
}
-
+
ret = 0;
fail:
close(fd);
@@ -167,8 +196,8 @@ fail:
static void usage(char *prog)
{
- fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [[-t <type>] -p <size>...] \n", prog);
- exit(1);
+ fprintf(stderr, "Usage: %s [-v] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [-l <align kB>] [[-t <type>] -p <size>...] \n", prog);
+ exit(EXIT_FAILURE);
}
int main (int argc, char **argv)
@@ -176,8 +205,9 @@ int main (int argc, char **argv)
char type = 0x83;
int ch;
int part = 0;
+ uint32_t signature = 0x5452574F; /* 'OWRT' */
- while ((ch = getopt(argc, argv, "h:s:p:a:t:o:v")) != -1) {
+ while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vl:S:")) != -1) {
switch (ch) {
case 'o':
filename = optarg;
@@ -186,35 +216,41 @@ int main (int argc, char **argv)
verbose++;
break;
case 'h':
- heads = (int) strtoul(optarg, NULL, 0);
+ heads = (int)strtoul(optarg, NULL, 0);
break;
case 's':
- sectors = (int) strtoul(optarg, NULL, 0);
+ sectors = (int)strtoul(optarg, NULL, 0);
break;
case 'p':
if (part > 3) {
fprintf(stderr, "Too many partitions\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
parts[part].size = to_kbytes(optarg);
parts[part++].type = type;
break;
case 't':
- type = (char) strtoul(optarg, NULL, 16);
+ type = (char)strtoul(optarg, NULL, 16);
break;
case 'a':
- active = (int) strtoul(optarg, NULL, 0);
+ active = (int)strtoul(optarg, NULL, 0);
if ((active < 0) || (active > 4))
active = 0;
break;
+ case 'l':
+ kb_align = (int)strtoul(optarg, NULL, 0) * 2;
+ break;
+ case 'S':
+ signature = strtoul(optarg, NULL, 0);
+ break;
case '?':
default:
usage(argv[0]);
}
}
argc -= optind;
- if (argc || (heads <= 0) || (sectors <= 0) || !filename)
+ if (argc || (heads <= 0) || (sectors <= 0) || !filename)
usage(argv[0]);
-
- return gen_ptable(part);
+
+ return gen_ptable(signature, part) ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/tools/firmware-utils/src/seama.c b/tools/firmware-utils/src/seama.c
new file mode 100644
index 00000000000..05aee8e76aa
--- /dev/null
+++ b/tools/firmware-utils/src/seama.c
@@ -0,0 +1,529 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2008, Alpha Networks, Inc.
+ * Created by David Hsieh <david_hsieh@alphanetworks.com>
+ * All right reserved.
+ *
+ * (SEA)ttle i(MA)ge is the image which used in project seattle.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+#include "md5.h"
+#include "seama.h"
+
+#define PROGNAME "seama"
+#define VERSION "0.20"
+#define MAX_SEAMA_META_SIZE 1024
+#define MAX_META 128
+#define MAX_IMAGE 128
+
+extern int optind;
+extern char * optarg;
+
+static int o_verbose = 0; /* verbose mode. */
+static char * o_dump = NULL; /* Seama file to dump. */
+static char * o_seal = NULL; /* Seal the input images when file name exist. */
+static char * o_extract = NULL; /* Extract the seama file. */
+static char * o_images[MAX_IMAGE];/* The image files to pack or seal */
+static int o_isize = 0; /* number of images */
+static char * o_meta[MAX_META]; /* meta data array */
+static int o_msize = 0; /* size of meta array */
+
+static void verbose(const char * format, ...)
+{
+ va_list marker;
+ if (o_verbose)
+ {
+ va_start(marker, format);
+ vfprintf(stdout, format, marker);
+ va_end(marker);
+ }
+}
+
+static void cleanup_exit(int exit_code)
+{
+ verbose("%s: exit with code %d\n", PROGNAME, exit_code);
+ exit(exit_code);
+}
+
+static void show_usage(int exit_code)
+{
+ printf( PROGNAME " version " VERSION "\n"
+ "usage: " PROGNAME " [OPTIONS]\n"
+ " -h show this help message.\n"
+ " -v verbose mode.\n"
+ " -m {META data} META data.\n"
+ " -d {file} dump the info of the seama file.\n"
+ " -i {input file} image file name.\n"
+ " -s {file} Seal the images to the seama file.\n"
+ " -x {seama file} Extract the seama file.\n"
+ "\n"
+ " SEAMA can pack the input file (with -i) into a seama file.\n"
+ " ex: seama -i target.file\n"
+ " SEAMA can also seal multiple seama files into a single seama file.\n"
+ " ex: seama -s final.file -i taget1.seama -i target2.seama\n"
+ " To extract the raw image from SEAMA, you need to specify the meta.\n"
+ " The first image match the specified meta will be extract to\n"
+ " the output file which was specified with '-x'.\n"
+ " ex: seama -x output -i seama.image -m file=sealpac\n"
+ );
+ cleanup_exit(exit_code);
+}
+
+static int parse_args(int argc, char * argv[])
+{
+ int opt;
+
+ while ((opt = getopt(argc, argv, "hvd:s:i:m:x:")) > 0)
+ {
+ switch (opt)
+ {
+ default: show_usage(-1); break;
+ case 'h': show_usage(0); break;
+ case 'v': o_verbose++; break;
+ case 'd': o_dump = optarg; break;
+ case 's': o_seal = optarg; break;
+ case 'x': o_extract = optarg; break;
+ case 'i':
+ if (o_isize < MAX_IMAGE) o_images[o_isize++] = optarg;
+ else printf("Exceed the maximum acceptable image files.!\n");
+ break;
+ case 'm':
+ if (o_msize < MAX_META) o_meta[o_msize++] = optarg;
+ else printf("Exceed the maximum acceptable META data.!\n");
+ break;
+ }
+ }
+ return 0;
+}
+
+/*******************************************************************/
+
+static size_t calculate_digest(FILE * fh, size_t size, uint8_t * digest)
+{
+ MD5_CTX ctx;
+ size_t bytes_left, bytes_read, i;
+ uint8_t buf[MAX_SEAMA_META_SIZE];
+
+ bytes_left = size ? size : sizeof(buf);
+ bytes_read = 0;
+
+ MD5_Init(&ctx);
+ while (!feof(fh) && !ferror(fh) && bytes_left > 0)
+ {
+ i = bytes_left < sizeof(buf) ? bytes_left : sizeof(buf);
+ i = fread(buf, sizeof(char), i, fh);
+ if (i > 0)
+ {
+ MD5_Update(&ctx, buf, i);
+ bytes_read += i;
+ }
+ if (size) bytes_left -= i;
+ }
+ MD5_Final(digest, &ctx);
+ return bytes_read;
+}
+
+#define READ_BUFF_SIZE 8*1024
+static size_t copy_file(FILE * to, FILE * from)
+{
+ size_t i, fsize = 0;
+ uint8_t buf[READ_BUFF_SIZE];
+
+ while (!feof(from) && !ferror(from))
+ {
+ i = fread(buf, sizeof(uint8_t), READ_BUFF_SIZE, from);
+ if (i > 0)
+ {
+ fsize += i;
+ fwrite(buf, sizeof(uint8_t), i, to);
+ }
+ }
+ return fsize;
+}
+
+static int verify_seama(const char * fname, int msg)
+{
+ FILE * fh = NULL;
+ struct stat st;
+ seamahdr_t shdr;
+ uint8_t checksum[16];
+ uint8_t digest[16];
+ uint8_t buf[MAX_SEAMA_META_SIZE];
+ size_t msize, isize, i;
+ int ret = -1;
+
+#define ERRBREAK(fmt, args...) { if (msg) printf(fmt, ##args); break; }
+
+ do
+ {
+ if (stat(fname, &st) < 0) ERRBREAK("Unable to get the info of '%s'\n",fname);
+ if ((fh = fopen(fname, "r+"))==NULL) ERRBREAK("Unable to open '%s' for reading!\n",fname);
+
+ /* Dump SEAMA header */
+ if (msg) printf("FILE - %s (%d bytes)\n", fname, (int)st.st_size);
+
+ /* SEAMA */
+ while (!feof(fh) && !ferror(fh))
+ {
+ /* read header */
+ if (fread(&shdr, sizeof(shdr), 1, fh) != 1) break;
+
+ /* Check the magic number */
+ if (shdr.magic != htonl(SEAMA_MAGIC)) ERRBREAK("Invalid SEAMA magic. Probably no more SEAMA!\n");
+
+ /* Get the size */
+ isize = ntohl(shdr.size);
+ msize = ntohs(shdr.metasize);
+
+ /* The checksum exist only if size is greater than zero. */
+ if (isize > 0)
+ {
+ if (fread(checksum, sizeof(checksum), 1, fh) != 1)
+ ERRBREAK("Error reading checksum !\n");
+ }
+
+ /* Check the META size. */
+ if (msize > sizeof(buf)) ERRBREAK("META data in SEAMA header is too large!\n");
+
+ /* Read META data. */
+ if (fread(buf, sizeof(char), msize, fh) != msize)
+ ERRBREAK("Unable to read SEAMA META data!\n");
+
+ /* dump header */
+ if (msg)
+ {
+ printf("SEAMA ==========================================\n");
+ printf(" magic : %08x\n", ntohl(shdr.magic));
+ printf(" meta size : %zu bytes\n", msize);
+ for (i=0; i<msize; i+=(strlen((const char *)&buf[i])+1))
+ printf(" meta data : %s\n", &buf[i]);
+ printf(" image size : %zu bytes\n", isize);
+ }
+
+ /* verify checksum */
+ if (isize > 0)
+ {
+ if (msg)
+ {
+ printf(" checksum : ");
+ for (i=0; i<16; i++) printf("%02X", checksum[i]);
+ printf("\n");
+ }
+
+ /* Calculate the checksum */
+ calculate_digest(fh, isize, digest);
+ if (msg)
+ {
+ printf(" digest : ");
+ for (i=0; i<16; i++) printf("%02X", digest[i]);
+ printf("\n");
+ }
+
+ if (memcmp(checksum, digest, 16)!=0) ERRBREAK("!!ERROR!! checksum error !!\n");
+ ret = 0;
+ }
+ }
+ if (msg) printf("================================================\n");
+ } while (0);
+ if (fh) fclose(fh);
+ return ret;
+}
+
+static size_t write_seama_header(FILE * fh, char * meta[], size_t msize, size_t size)
+{
+ seamahdr_t shdr;
+ size_t i;
+ uint16_t metasize = 0;
+
+ /* Calculate the META size */
+ for (i=0; i<msize; i++) metasize += (strlen(meta[i]) + 1);
+ //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm
+ metasize = ((metasize+3)/4)*4;
+ verbose("SEAMA META : %d bytes\n", metasize);
+
+ /* Fill up the header, all the data endian should be network byte order. */
+ shdr.magic = htonl(SEAMA_MAGIC);
+ shdr.reserved = 0;
+ shdr.metasize = htons(metasize);
+ shdr.size = htonl(size);
+
+ /* Write the header */
+ return fwrite(&shdr, sizeof(seamahdr_t), 1, fh);
+}
+
+static size_t write_checksum(FILE * fh, uint8_t * checksum)
+{
+ return fwrite(checksum, sizeof(uint8_t), 16, fh);
+}
+
+static size_t write_meta_data(FILE * fh, char * meta[], size_t size)
+{
+ size_t i,j;
+ size_t ret = 0;
+
+ for (i=0; i<size; i++)
+ {
+ verbose("SEAMA META data : %s\n", meta[i]);
+ j = fwrite(meta[i], sizeof(char), strlen(meta[i])+1, fh);
+ if (j != strlen(meta[i])+1) return 0;
+ ret += j;
+ }
+ //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm
+ j = ((ret+3)/4)*4;
+ for ( ; ret < j; ret++)
+ fwrite("", sizeof(char), 1, fh);
+
+ return ret;
+}
+
+/*******************************************************************/
+
+static void dump_seama(const char * fname)
+{
+ verify_seama(fname, 1);
+}
+
+static void seal_files(const char * file)
+{
+ FILE * fh;
+ FILE * ifh;
+ size_t i;
+
+ /* Each image should be seama. */
+ for (i = 0; i < o_isize; i++)
+ {
+ if (verify_seama(o_images[i], 0) < 0)
+ {
+ printf("'%s' is not a seama file !\n",o_images[i]);
+ return;
+ }
+ }
+
+ /* Open file for write */
+ fh = fopen(file, "w+");
+ if (fh)
+ {
+ /* Write the header. */
+ write_seama_header(fh, o_meta, o_msize, 0);
+ write_meta_data(fh, o_meta, o_msize);
+
+ /* Write image files */
+ for (i=0; i<o_isize; i++)
+ {
+ ifh = fopen(o_images[i], "r+");
+ if (ifh)
+ {
+ copy_file(fh, ifh);
+ fclose(ifh);
+ }
+ }
+
+ fclose(fh);
+ }
+}
+
+static void pack_files(void)
+{
+ FILE * fh;
+ FILE * ifh;
+ size_t i, fsize;
+ char filename[512];
+ uint8_t digest[16];
+
+ for (i=0; i<o_isize; i++)
+ {
+ /* Open the input file. */
+ ifh = fopen(o_images[i], "r+");
+ if (ifh)
+ {
+ fsize = calculate_digest(ifh, 0, digest);
+ verbose("file size (%s) : %d\n", o_images[i], fsize);
+ rewind(ifh);
+
+ /* Open the output file. */
+ sprintf(filename, "%s.seama", o_images[i]);
+ fh = fopen(filename, "w+");
+ if (fh)
+ {
+ write_seama_header(fh, o_meta, o_msize, fsize);
+ write_checksum(fh, digest);
+ write_meta_data(fh, o_meta, o_msize);
+ copy_file(fh, ifh);
+ fclose(fh);
+ }
+ fclose(ifh);
+ }
+ else
+ {
+ printf("Unable to open image file '%s'\n",o_images[i]);
+ }
+ }
+}
+
+/**************************************************************************/
+
+static int match_meta(const char * meta, size_t size)
+{
+ size_t i, j;
+ int match;
+
+ for (i = 0; i < o_msize; i++)
+ {
+ for (match = 0, j = 0; j < size; j += (strlen(&meta[j])+1))
+ if (strcmp(&meta[j], o_meta[i])==0) { match++; break; }
+ if (!match) return 0;
+ }
+ return 1;
+}
+
+
+static void extract_file(const char * output)
+{
+ FILE * ifh = NULL;
+ FILE * ofh = NULL;
+ size_t msize, isize, i, m;
+ seamahdr_t shdr;
+ uint8_t buf[MAX_SEAMA_META_SIZE];
+ int done = 0;
+
+ /* We need meta for searching the target image. */
+ if (o_msize == 0)
+ {
+ printf("SEAMA: need meta for searching image.\n");
+ return;
+ }
+
+ /* Walk through each input file */
+ for (i = 0; i < o_isize; i++)
+ {
+ /* verify the input file */
+ if (verify_seama(o_images[i], 0) < 0)
+ {
+ printf("SEAMA: '%s' is not a seama file !\n", o_images[i]);
+ continue;
+ }
+ /* open the input file */
+ ifh = fopen(o_images[i], "r");
+ if (!ifh) continue;
+ /* read file */
+ while (!feof(ifh) && !ferror(ifh))
+ {
+ /* read header */
+ fread(&shdr, sizeof(shdr), 1, ifh);
+ if (shdr.magic != htonl(SEAMA_MAGIC)) break;
+ /* Get the size */
+ isize = ntohl(shdr.size);
+ msize = ntohs(shdr.metasize);
+ if (isize == 0)
+ {
+ while (msize > 0)
+ {
+ m = fread(buf, sizeof(char), (msize < MAX_SEAMA_META_SIZE) ? msize : MAX_SEAMA_META_SIZE, ifh);
+ if (m <= 0) break;
+ msize -= m;
+ }
+ continue;
+ }
+ /* read checksum */
+ fread(buf, sizeof(char), 16, ifh);
+ if (msize > 0)
+ {
+ /* read META */
+ fread(buf, sizeof(char), msize, ifh);
+ if (match_meta((const char *)buf, msize))
+ {
+ printf("SEAMA: found image @ '%s', image size: %zu\n", o_images[i], isize);
+ /* open output file */
+ ofh = fopen(output, "w");
+ if (!ofh) printf("SEAMA: unable to open '%s' for writting.\n",output);
+ else
+ {
+ while (isize > 0)
+ {
+ m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh);
+ if (m <= 0) break;
+ fwrite(buf, sizeof(char), m, ofh);
+ isize -= m;
+ }
+ fclose(ofh);
+ }
+ done++;
+ break;
+ }
+ }
+ while (isize > 0)
+ {
+ m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh);
+ if (m <= 0) break;
+ isize -= m;
+ }
+ }
+ /* close the file. */
+ fclose(ifh);
+ if (done) break;
+ }
+ return;
+}
+
+/*******************************************************************/
+#ifdef RGBIN_BOX
+int seama_main(int argc, char * argv[], char * env[])
+#else
+int main(int argc, char * argv[], char * env[])
+#endif
+{
+ verbose("SEAMA version " VERSION "\n");
+
+ /* parse the arguments */
+ if (parse_args(argc, argv) < 0) show_usage(9);
+
+ /* Do the works */
+ if (o_dump) dump_seama(o_dump);
+ else if (o_seal) seal_files(o_seal);
+ else if (o_extract) extract_file(o_extract);
+ else pack_files();
+
+ cleanup_exit(0);
+ return 0;
+}
diff --git a/tools/firmware-utils/src/seama.h b/tools/firmware-utils/src/seama.h
new file mode 100644
index 00000000000..02683b6e98d
--- /dev/null
+++ b/tools/firmware-utils/src/seama.h
@@ -0,0 +1,108 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * (SEA)ttle i(MA)ge is the image which used in project seattle.
+ *
+ * Created by David Hsieh <david_hsieh@alphanetworks.com>
+ * Copyright (C) 2008-2009 Alpha Networks, Inc.
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either'
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library is distributed in the hope that it will be useful,'
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, write to the Free
+ * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ */
+
+#ifndef __SEAMA_HEADER_FILE__
+#define __SEAMA_HEADER_FILE__
+
+#include <stdint.h>
+
+#define SEAMA_MAGIC 0x5EA3A417
+
+/*
+ * SEAMA looks like the following map.
+ * All the data of the header should be in network byte order.
+ *
+ * +-------------+-------------+------------
+ * | SEAMA magic | ^
+ * +-------------+-------------+ |
+ * | reserved | meta size | |
+ * +-------------+-------------+ header
+ * | image size (0 bytes) | |
+ * +-------------+-------------+ |
+ * ~ Meta data ~ v
+ * +-------------+-------------+------------
+ * | SEAMA magic | ^ ^
+ * +-------------+-------------+ | |
+ * | reserved | meta size | | |
+ * +-------------+-------------+ | |
+ * | image size | | |
+ * +-------------+-------------+ header |
+ * | | | |
+ * | 16 bytes of MD5 digest | | |
+ * | | | |
+ * | | | |
+ * +-------------+-------------+ | |
+ * ~ Meta data ~ v |
+ * +-------------+-------------+------- |
+ * | | |
+ * | Image of the 1st entity | |
+ * ~ ~ 1st entity
+ * | | |
+ * | | v
+ * +-------------+-------------+-------------
+ * | SEAMA magic | ^ ^
+ * +-------------+-------------+ | |
+ * | reserved | meta size | | |
+ * +-------------+-------------+ | |
+ * | image size | | |
+ * +-------------+-------------+ header |
+ * | | | |
+ * | 16 bytes of MD5 digest | | |
+ * | | | |
+ * | | | |
+ * +-------------+-------------+ | |
+ * ~ Meta data ~ v |
+ * +-------------+-------------+------- |
+ * | | |
+ * | Image of the 2nd entity | |
+ * ~ ~ 2nd entity
+ * | | |
+ * | | v
+ * +-------------+-------------+-------------
+ */
+
+
+/*
+ * SEAMA header
+ *
+ * |<-------- 32 bits -------->|
+ * +-------------+-------------+
+ * | SEAMA magic |
+ * +-------------+-------------+
+ * | reserved | meta size |
+ * +-------------+-------------+
+ * | image size |
+ * +-------------+-------------+
+ */
+/* seama header */
+typedef struct seama_hdr seamahdr_t;
+struct seama_hdr
+{
+ uint32_t magic; /* should always be SEAMA_MAGIC. */
+ uint16_t reserved; /* reserved for */
+ uint16_t metasize; /* size of the META data */
+ uint32_t size; /* size of the image */
+} __attribute__ ((packed));
+
+
+#endif
diff --git a/tools/firmware-utils/src/spw303v.c b/tools/firmware-utils/src/spw303v.c
index ae34a1ebddc..684532d7e11 100644
--- a/tools/firmware-utils/src/spw303v.c
+++ b/tools/firmware-utils/src/spw303v.c
@@ -18,11 +18,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
-#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
diff --git a/tools/firmware-utils/src/srec2bin.c b/tools/firmware-utils/src/srec2bin.c
index 1cffbaed969..5cc71bda220 100644
--- a/tools/firmware-utils/src/srec2bin.c
+++ b/tools/firmware-utils/src/srec2bin.c
@@ -513,7 +513,7 @@ int srec2bin(int argc,char *argv[],int verbose)
return(1);
}
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
{
debug = TRUE;
debug = FALSE;
diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c
new file mode 100644
index 00000000000..78092bc535c
--- /dev/null
+++ b/tools/firmware-utils/src/tplink-safeloader.c
@@ -0,0 +1,2084 @@
+/*
+ Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/*
+ tplink-safeloader
+
+ Image generation tool for the TP-LINK SafeLoader as seen on
+ TP-LINK Pharos devices (CPE210/220/510/520)
+*/
+
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+
+#include "md5.h"
+
+
+#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
+
+
+#define MAX_PARTITIONS 32
+
+/** An image partition table entry */
+struct image_partition_entry {
+ const char *name;
+ size_t size;
+ uint8_t *data;
+};
+
+/** A flash partition table entry */
+struct flash_partition_entry {
+ char *name;
+ uint32_t base;
+ uint32_t size;
+};
+
+/** Firmware layout description */
+struct device_info {
+ const char *id;
+ const char *vendor;
+ const char *support_list;
+ char support_trail;
+ const char *soft_ver;
+ struct flash_partition_entry partitions[MAX_PARTITIONS+1];
+ const char *first_sysupgrade_partition;
+ const char *last_sysupgrade_partition;
+};
+
+/** The content of the soft-version structure */
+struct __attribute__((__packed__)) soft_version {
+ uint32_t magic;
+ uint32_t zero;
+ uint8_t pad1;
+ uint8_t version_major;
+ uint8_t version_minor;
+ uint8_t version_patch;
+ uint8_t year_hi;
+ uint8_t year_lo;
+ uint8_t month;
+ uint8_t day;
+ uint32_t rev;
+ uint8_t pad2;
+};
+
+
+static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
+
+
+/**
+ Salt for the MD5 hash
+
+ Fortunately, TP-LINK seems to use the same salt for most devices which use
+ the new image format.
+*/
+static const uint8_t md5_salt[16] = {
+ 0x7a, 0x2b, 0x15, 0xed,
+ 0x9b, 0x98, 0x59, 0x6d,
+ 0xe5, 0x04, 0xab, 0x44,
+ 0xac, 0x2a, 0x9f, 0x4e,
+};
+
+
+/** Firmware layout table */
+static struct device_info boards[] = {
+ /** Firmware layout for the CPE210/220 */
+ {
+ .id = "CPE210",
+ .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
+ "CPE210(TP-LINK|US|N300-2):1.1\r\n"
+ "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
+ "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
+ "CPE220(TP-LINK|US|N300-2):1.1\r\n"
+ "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"product-info", 0x31100, 0x00100},
+ {"signature", 0x32000, 0x00400},
+ {"os-image", 0x40000, 0x1c0000},
+ {"file-system", 0x200000, 0x5b0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
+ {"user-config", 0x7c0000, 0x10000},
+ {"default-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "support-list",
+ },
+
+ /** Firmware layout for the CPE210 V2 */
+ {
+ .id = "CPE210V2",
+ .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
+ "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
+ "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
+ "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
+ "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
+ "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
+ "CPE210(TP-LINK|US|N300-2):2.0\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"product-info", 0x31100, 0x00100},
+ {"device-info", 0x31400, 0x00400},
+ {"signature", 0x32000, 0x00400},
+ {"device-id", 0x33000, 0x00100},
+ {"os-image", 0x40000, 0x1c0000},
+ {"file-system", 0x200000, 0x5b0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x01000},
+ {"user-config", 0x7c0000, 0x10000},
+ {"default-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "support-list",
+ },
+
+ /** Firmware layout for the CPE510/520 */
+ {
+ .id = "CPE510",
+ .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
+ "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
+ "CPE510(TP-LINK|US|N300-5):1.1\r\n"
+ "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
+ "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
+ "CPE520(TP-LINK|US|N300-5):1.1\r\n"
+ "CPE520(TP-LINK|EU|N300-5):1.1\r\n"
+ "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
+ "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
+ "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
+ "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
+ "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
+ "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
+ "CPE510(TP-LINK|US|N300-5):2.0\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"product-info", 0x31100, 0x00100},
+ {"signature", 0x32000, 0x00400},
+ {"os-image", 0x40000, 0x1c0000},
+ {"file-system", 0x200000, 0x5b0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
+ {"user-config", 0x7c0000, 0x10000},
+ {"default-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "support-list",
+ },
+
+ {
+ .id = "WBS210",
+ .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
+ "WBS210(TP-LINK|US|N300-2):1.20\r\n"
+ "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"product-info", 0x31100, 0x00100},
+ {"signature", 0x32000, 0x00400},
+ {"os-image", 0x40000, 0x1c0000},
+ {"file-system", 0x200000, 0x5b0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
+ {"user-config", 0x7c0000, 0x10000},
+ {"default-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "support-list",
+ },
+
+ {
+ .id = "WBS510",
+ .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
+ "WBS510(TP-LINK|US|N300-5):1.20\r\n"
+ "WBS510(TP-LINK|EU|N300-5):1.20\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"product-info", 0x31100, 0x00100},
+ {"signature", 0x32000, 0x00400},
+ {"os-image", 0x40000, 0x1c0000},
+ {"file-system", 0x200000, 0x5b0000},
+ {"soft-version", 0x7b0000, 0x00100},
+ {"support-list", 0x7b1000, 0x00400},
+ {"user-config", 0x7c0000, 0x10000},
+ {"default-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "support-list",
+ },
+
+ /** Firmware layout for the C2600 */
+ {
+ .id = "C2600",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /**
+ We use a bigger os-image partition than the stock images (and thus
+ smaller file-system), as our kernel doesn't fit in the stock firmware's
+ 2 MB os-image since kernel 4.14.
+ */
+ .partitions = {
+ {"SBL1", 0x00000, 0x20000},
+ {"MIBIB", 0x20000, 0x20000},
+ {"SBL2", 0x40000, 0x20000},
+ {"SBL3", 0x60000, 0x30000},
+ {"DDRCONFIG", 0x90000, 0x10000},
+ {"SSD", 0xa0000, 0x10000},
+ {"TZ", 0xb0000, 0x30000},
+ {"RPM", 0xe0000, 0x20000},
+ {"fs-uboot", 0x100000, 0x70000},
+ {"uboot-env", 0x170000, 0x40000},
+ {"radio", 0x1b0000, 0x40000},
+ {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
+ {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
+ {"default-mac", 0x1ef0000, 0x00200},
+ {"pin", 0x1ef0200, 0x00200},
+ {"product-info", 0x1ef0400, 0x0fc00},
+ {"partition-table", 0x1f00000, 0x10000},
+ {"soft-version", 0x1f10000, 0x10000},
+ {"support-list", 0x1f20000, 0x10000},
+ {"profile", 0x1f30000, 0x10000},
+ {"default-config", 0x1f40000, 0x10000},
+ {"user-config", 0x1f50000, 0x40000},
+ {"qos-db", 0x1f90000, 0x40000},
+ {"usb-config", 0x1fd0000, 0x10000},
+ {"log", 0x1fe0000, 0x20000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the C25v1 */
+ {
+ .id = "ARCHER-C25-V1",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
+ "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
+ "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ /**
+ We use a bigger os-image partition than the stock images (and thus
+ smaller file-system), as our kernel doesn't fit in the stock firmware's
+ 1MB os-image.
+ */
+ .partitions = {
+ {"factory-boot", 0x00000, 0x20000},
+ {"fs-uboot", 0x20000, 0x10000},
+ {"os-image", 0x30000, 0x180000}, /* Stock: base 0x30000 size 0x100000 */
+ {"file-system", 0x1b0000, 0x620000}, /* Stock: base 0x130000 size 0x6a0000 */
+ {"user-config", 0x7d0000, 0x04000},
+ {"default-mac", 0x7e0000, 0x00100},
+ {"device-id", 0x7e0100, 0x00100},
+ {"extra-para", 0x7e0200, 0x00100},
+ {"pin", 0x7e0300, 0x00100},
+ {"support-list", 0x7e0400, 0x00400},
+ {"soft-version", 0x7e0800, 0x00400},
+ {"product-info", 0x7e0c00, 0x01400},
+ {"partition-table", 0x7e2000, 0x01000},
+ {"profile", 0x7e3000, 0x01000},
+ {"default-config", 0x7e4000, 0x04000},
+ {"merge-config", 0x7ec000, 0x02000},
+ {"qos-db", 0x7ee000, 0x02000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C58v1 */
+ {
+ .id = "ARCHER-C58-V1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
+ "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x10000},
+ {"default-mac", 0x10000, 0x00200},
+ {"pin", 0x10200, 0x00200},
+ {"product-info", 0x10400, 0x00100},
+ {"partition-table", 0x10500, 0x00800},
+ {"soft-version", 0x11300, 0x00200},
+ {"support-list", 0x11500, 0x00100},
+ {"device-id", 0x11600, 0x00100},
+ {"profile", 0x11700, 0x03900},
+ {"default-config", 0x15000, 0x04000},
+ {"user-config", 0x19000, 0x04000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0x648000},
+ {"certyficate", 0x7e8000, 0x08000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C59v1 */
+ {
+ .id = "ARCHER-C59-V1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
+ "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
+ "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x10000},
+ {"default-mac", 0x10000, 0x00200},
+ {"pin", 0x10200, 0x00200},
+ {"device-id", 0x10400, 0x00100},
+ {"product-info", 0x10500, 0x0fb00},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0xcb0000},
+ {"partition-table", 0xe50000, 0x10000},
+ {"soft-version", 0xe60000, 0x10000},
+ {"support-list", 0xe70000, 0x10000},
+ {"profile", 0xe80000, 0x10000},
+ {"default-config", 0xe90000, 0x10000},
+ {"user-config", 0xea0000, 0x40000},
+ {"usb-config", 0xee0000, 0x10000},
+ {"certificate", 0xef0000, 0x10000},
+ {"qos-db", 0xf00000, 0x40000},
+ {"log", 0xfe0000, 0x10000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C59v2 */
+ {
+ .id = "ARCHER-C59-V2",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
+ "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
+ "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:2.0.0 Build 20161206 rel.7303\n",
+
+ /** We're using a dynamic kernel/rootfs split here */
+ .partitions = {
+ {"factory-boot", 0x00000, 0x20000},
+ {"fs-uboot", 0x20000, 0x10000},
+ {"default-mac", 0x30000, 0x00200},
+ {"pin", 0x30200, 0x00200},
+ {"device-id", 0x30400, 0x00100},
+ {"product-info", 0x30500, 0x0fb00},
+ {"firmware", 0x40000, 0xe10000},
+ {"partition-table", 0xe50000, 0x10000},
+ {"soft-version", 0xe60000, 0x10000},
+ {"support-list", 0xe70000, 0x10000},
+ {"profile", 0xe80000, 0x10000},
+ {"default-config", 0xe90000, 0x10000},
+ {"user-config", 0xea0000, 0x40000},
+ {"usb-config", 0xee0000, 0x10000},
+ {"certificate", 0xef0000, 0x10000},
+ {"extra-para", 0xf00000, 0x10000},
+ {"qos-db", 0xf10000, 0x30000},
+ {"log", 0xfe0000, 0x10000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C60v1 */
+ {
+ .id = "ARCHER-C60-V1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
+ "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x10000},
+ {"default-mac", 0x10000, 0x00200},
+ {"pin", 0x10200, 0x00200},
+ {"product-info", 0x10400, 0x00100},
+ {"partition-table", 0x10500, 0x00800},
+ {"soft-version", 0x11300, 0x00200},
+ {"support-list", 0x11500, 0x00100},
+ {"device-id", 0x11600, 0x00100},
+ {"profile", 0x11700, 0x03900},
+ {"default-config", 0x15000, 0x04000},
+ {"user-config", 0x19000, 0x04000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0x648000},
+ {"certyficate", 0x7e8000, 0x08000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C60v2 */
+ {
+ .id = "ARCHER-C60-V2",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
+ "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
+ "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:2.0.0\n",
+
+ .partitions = {
+ {"factory-boot", 0x00000, 0x1fb00},
+ {"default-mac", 0x1fb00, 0x00200},
+ {"pin", 0x1fd00, 0x00100},
+ {"product-info", 0x1fe00, 0x00100},
+ {"device-id", 0x1ff00, 0x00100},
+ {"fs-uboot", 0x20000, 0x10000},
+ {"os-image", 0x30000, 0x180000},
+ {"file-system", 0x1b0000, 0x620000},
+ {"soft-version", 0x7d9500, 0x00100},
+ {"support-list", 0x7d9600, 0x00100},
+ {"extra-para", 0x7d9700, 0x00100},
+ {"profile", 0x7d9800, 0x03000},
+ {"default-config", 0x7dc800, 0x03000},
+ {"partition-table", 0x7df800, 0x00800},
+ {"user-config", 0x7e0000, 0x0c000},
+ {"certificate", 0x7ec000, 0x04000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C5 */
+ {
+ .id = "ARCHER-C5-V2",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
+ "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
+ "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x40000},
+ {"os-image", 0x40000, 0x200000},
+ {"file-system", 0x240000, 0xc00000},
+ {"default-mac", 0xe40000, 0x00200},
+ {"pin", 0xe40200, 0x00200},
+ {"product-info", 0xe40400, 0x00200},
+ {"partition-table", 0xe50000, 0x10000},
+ {"soft-version", 0xe60000, 0x00200},
+ {"support-list", 0xe61000, 0x0f000},
+ {"profile", 0xe70000, 0x10000},
+ {"default-config", 0xe80000, 0x10000},
+ {"user-config", 0xe90000, 0x50000},
+ {"log", 0xee0000, 0x100000},
+ {"radio_bk", 0xfe0000, 0x10000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the C7 */
+ {
+ .id = "ARCHER-C7-V4",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
+ "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ /**
+ We use a bigger os-image partition than the stock images (and thus
+ smaller file-system), as our kernel doesn't fit in the stock firmware's
+ 1MB os-image.
+ */
+ .partitions = {
+ {"factory-boot", 0x00000, 0x20000},
+ {"fs-uboot", 0x20000, 0x20000},
+ {"os-image", 0x40000, 0x180000}, /* Stock: base 0x40000 size 0x120000 */
+ {"file-system", 0x1c0000, 0xd40000}, /* Stock: base 0x160000 size 0xda0000 */
+ {"default-mac", 0xf00000, 0x00200},
+ {"pin", 0xf00200, 0x00200},
+ {"device-id", 0xf00400, 0x00100},
+ {"product-info", 0xf00500, 0x0fb00},
+ {"soft-version", 0xf10000, 0x00100},
+ {"extra-para", 0xf11000, 0x01000},
+ {"support-list", 0xf12000, 0x0a000},
+ {"profile", 0xf1c000, 0x04000},
+ {"default-config", 0xf20000, 0x10000},
+ {"user-config", 0xf30000, 0x40000},
+ {"qos-db", 0xf70000, 0x40000},
+ {"certificate", 0xfb0000, 0x10000},
+ {"partition-table", 0xfc0000, 0x10000},
+ {"log", 0xfd0000, 0x20000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C7 v5*/
+ {
+ .id = "ARCHER-C7-V5",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
+ "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n",
+
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+
+ /**
+ We use a bigger os-image partition than the stock images (and thus
+ smaller file-system), as our kernel doesn't fit in the stock firmware's
+ 1MB os-image.
+ */
+ .partitions = {
+ {"factory-boot", 0x00000, 0x20000},
+ {"fs-uboot", 0x20000, 0x20000},
+ {"partition-table", 0x40000, 0x10000},
+ {"radio", 0x50000, 0x10000},
+ {"default-mac", 0x60000, 0x00200},
+ {"pin", 0x60200, 0x00200},
+ {"device-id", 0x60400, 0x00100},
+ {"product-info", 0x60500, 0x0fb00},
+ {"soft-version", 0x70000, 0x01000},
+ {"extra-para", 0x71000, 0x01000},
+ {"support-list", 0x72000, 0x0a000},
+ {"profile", 0x7c000, 0x04000},
+ {"user-config", 0x80000, 0x40000},
+
+
+ {"os-image", 0xc0000, 0x180000}, /* Stock: base 0xc0000 size 0x120000 */
+ {"file-system", 0x240000, 0xd80000}, /* Stock: base 0x1e0000 size 0xde0000 */
+
+ {"log", 0xfc0000, 0x20000},
+ {"certificate", 0xfe0000, 0x10000},
+ {"default-config", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the C9 */
+ {
+ .id = "ARCHERC9",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:ArcherC9,"
+ "product_ver:1.0.0,"
+ "special_id:00000000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x40000},
+ {"os-image", 0x40000, 0x200000},
+ {"file-system", 0x240000, 0xc00000},
+ {"default-mac", 0xe40000, 0x00200},
+ {"pin", 0xe40200, 0x00200},
+ {"product-info", 0xe40400, 0x00200},
+ {"partition-table", 0xe50000, 0x10000},
+ {"soft-version", 0xe60000, 0x00200},
+ {"support-list", 0xe61000, 0x0f000},
+ {"profile", 0xe70000, 0x10000},
+ {"default-config", 0xe80000, 0x10000},
+ {"user-config", 0xe90000, 0x50000},
+ {"log", 0xee0000, 0x100000},
+ {"radio_bk", 0xfe0000, 0x10000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the EAP120 */
+ {
+ .id = "EAP120",
+ .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
+ .support_list =
+ "SupportList:\r\n"
+ "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
+ .support_trail = '\xff',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"partition-table", 0x20000, 0x02000},
+ {"default-mac", 0x30000, 0x00020},
+ {"support-list", 0x31000, 0x00100},
+ {"product-info", 0x31100, 0x00100},
+ {"soft-version", 0x32000, 0x00100},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0x600000},
+ {"user-config", 0x7c0000, 0x10000},
+ {"backup-config", 0x7d0000, 0x10000},
+ {"log", 0x7e0000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the TL-WA850RE v2 */
+ {
+ .id = "TLWA850REV2",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
+ "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /**
+ 576KB were moved from file-system to os-image
+ in comparison to the stock image
+ */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x150000},
+ {"file-system", 0x170000, 0x240000},
+ {"partition-table", 0x3b0000, 0x02000},
+ {"default-mac", 0x3c0000, 0x00020},
+ {"pin", 0x3c0100, 0x00020},
+ {"product-info", 0x3c1000, 0x01000},
+ {"soft-version", 0x3c2000, 0x00100},
+ {"support-list", 0x3c3000, 0x01000},
+ {"profile", 0x3c4000, 0x08000},
+ {"user-config", 0x3d0000, 0x10000},
+ {"default-config", 0x3e0000, 0x10000},
+ {"radio", 0x3f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the TL-WA855RE v1 */
+ {
+ .id = "TLWA855REV1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
+ "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x150000},
+ {"file-system", 0x170000, 0x240000},
+ {"partition-table", 0x3b0000, 0x02000},
+ {"default-mac", 0x3c0000, 0x00020},
+ {"pin", 0x3c0100, 0x00020},
+ {"product-info", 0x3c1000, 0x01000},
+ {"soft-version", 0x3c2000, 0x00100},
+ {"support-list", 0x3c3000, 0x01000},
+ {"profile", 0x3c4000, 0x08000},
+ {"user-config", 0x3d0000, 0x10000},
+ {"default-config", 0x3e0000, 0x10000},
+ {"radio", 0x3f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the TL-WR1043 v5 */
+ {
+ .id = "TLWR1043NV5",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
+ "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
+ .support_trail = '\x00',
+ .soft_ver = "soft_ver:1.0.0\n",
+ .partitions = {
+ {"factory-boot", 0x00000, 0x20000},
+ {"fs-uboot", 0x20000, 0x20000},
+ {"os-image", 0x40000, 0x180000},
+ {"file-system", 0x1c0000, 0xd40000},
+ {"default-mac", 0xf00000, 0x00200},
+ {"pin", 0xf00200, 0x00200},
+ {"device-id", 0xf00400, 0x00100},
+ {"product-info", 0xf00500, 0x0fb00},
+ {"soft-version", 0xf10000, 0x01000},
+ {"extra-para", 0xf11000, 0x01000},
+ {"support-list", 0xf12000, 0x0a000},
+ {"profile", 0xf1c000, 0x04000},
+ {"default-config", 0xf20000, 0x10000},
+ {"user-config", 0xf30000, 0x40000},
+ {"qos-db", 0xf70000, 0x40000},
+ {"certificate", 0xfb0000, 0x10000},
+ {"partition-table", 0xfc0000, 0x10000},
+ {"log", 0xfd0000, 0x20000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the TL-WR1043 v4 */
+ {
+ .id = "TLWR1043NDV4",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /* We're using a dynamic kernel/rootfs split here */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"firmware", 0x20000, 0xf30000},
+ {"default-mac", 0xf50000, 0x00200},
+ {"pin", 0xf50200, 0x00200},
+ {"product-info", 0xf50400, 0x0fc00},
+ {"soft-version", 0xf60000, 0x0b000},
+ {"support-list", 0xf6b000, 0x04000},
+ {"profile", 0xf70000, 0x04000},
+ {"default-config", 0xf74000, 0x0b000},
+ {"user-config", 0xf80000, 0x40000},
+ {"partition-table", 0xfc0000, 0x10000},
+ {"log", 0xfd0000, 0x20000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the TL-WR902AC v1 */
+ {
+ .id = "TL-WR902AC-V1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
+ "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /**
+ 384KB were moved from file-system to os-image
+ in comparison to the stock image
+ */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0x5b0000},
+ {"default-mac", 0x750000, 0x00200},
+ {"pin", 0x750200, 0x00200},
+ {"product-info", 0x750400, 0x0fc00},
+ {"soft-version", 0x760000, 0x0b000},
+ {"support-list", 0x76b000, 0x04000},
+ {"profile", 0x770000, 0x04000},
+ {"default-config", 0x774000, 0x0b000},
+ {"user-config", 0x780000, 0x40000},
+ {"partition-table", 0x7c0000, 0x10000},
+ {"log", 0x7d0000, 0x20000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the TL-WR942N V1 */
+ {
+ .id = "TLWR942NV1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0xca0000},
+ {"default-mac", 0xe40000, 0x00200},
+ {"pin", 0xe40200, 0x00200},
+ {"product-info", 0xe40400, 0x0fc00},
+ {"partition-table", 0xe50000, 0x10000},
+ {"soft-version", 0xe60000, 0x10000},
+ {"support-list", 0xe70000, 0x10000},
+ {"profile", 0xe80000, 0x10000},
+ {"default-config", 0xe90000, 0x10000},
+ {"user-config", 0xea0000, 0x40000},
+ {"qos-db", 0xee0000, 0x40000},
+ {"certificate", 0xf20000, 0x10000},
+ {"usb-config", 0xfb0000, 0x10000},
+ {"log", 0xfc0000, 0x20000},
+ {"radio-bk", 0xfe0000, 0x10000},
+ {"radio", 0xff0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system",
+ },
+
+ /** Firmware layout for the RE350 v1 */
+ {
+ .id = "RE350-V1",
+ .vendor = "",
+ .support_list =
+ "SupportList:\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
+ "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /** We're using a dynamic kernel/rootfs split here */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"firmware", 0x20000, 0x5e0000},
+ {"partition-table", 0x600000, 0x02000},
+ {"default-mac", 0x610000, 0x00020},
+ {"pin", 0x610100, 0x00020},
+ {"product-info", 0x611100, 0x01000},
+ {"soft-version", 0x620000, 0x01000},
+ {"support-list", 0x621000, 0x01000},
+ {"profile", 0x622000, 0x08000},
+ {"user-config", 0x630000, 0x10000},
+ {"default-config", 0x640000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the RE355 */
+ {
+ .id = "RE355",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
+ "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /**
+ The flash partition table for RE355;
+ it is almost the same as the one used by the stock images,
+ 576KB were moved from file-system to os-image.
+ */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0x460000},
+ {"partition-table", 0x600000, 0x02000},
+ {"default-mac", 0x610000, 0x00020},
+ {"pin", 0x610100, 0x00020},
+ {"product-info", 0x611100, 0x01000},
+ {"soft-version", 0x620000, 0x01000},
+ {"support-list", 0x621000, 0x01000},
+ {"profile", 0x622000, 0x08000},
+ {"user-config", 0x630000, 0x10000},
+ {"default-config", 0x640000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the RE450 */
+ {
+ .id = "RE450",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
+ "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /**
+ The flash partition table for RE450;
+ it is almost the same as the one used by the stock images,
+ 576KB were moved from file-system to os-image.
+ */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"os-image", 0x20000, 0x180000},
+ {"file-system", 0x1a0000, 0x460000},
+ {"partition-table", 0x600000, 0x02000},
+ {"default-mac", 0x610000, 0x00020},
+ {"pin", 0x610100, 0x00020},
+ {"product-info", 0x611100, 0x01000},
+ {"soft-version", 0x620000, 0x01000},
+ {"support-list", 0x621000, 0x01000},
+ {"profile", 0x622000, 0x08000},
+ {"user-config", 0x630000, 0x10000},
+ {"default-config", 0x640000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ /** Firmware layout for the RE450 v2 */
+ {
+ .id = "RE450-V2",
+ .vendor = "",
+ .support_list =
+ "SupportList:\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
+ "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
+ .support_trail = '\x00',
+ .soft_ver = NULL,
+
+ /* We're using a dynamic kernel/rootfs split here */
+ .partitions = {
+ {"fs-uboot", 0x00000, 0x20000},
+ {"firmware", 0x20000, 0x5e0000},
+ {"partition-table", 0x600000, 0x02000},
+ {"default-mac", 0x610000, 0x00020},
+ {"pin", 0x610100, 0x00020},
+ {"product-info", 0x611100, 0x01000},
+ {"soft-version", 0x620000, 0x01000},
+ {"support-list", 0x621000, 0x01000},
+ {"profile", 0x622000, 0x08000},
+ {"user-config", 0x630000, 0x10000},
+ {"default-config", 0x640000, 0x10000},
+ {"radio", 0x7f0000, 0x10000},
+
+ {NULL, 0, 0}
+ },
+
+ .first_sysupgrade_partition = "os-image",
+ .last_sysupgrade_partition = "file-system"
+ },
+
+ {}
+};
+
+#define error(_ret, _errno, _str, ...) \
+ do { \
+ fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
+ strerror(_errno)); \
+ if (_ret) \
+ exit(_ret); \
+ } while (0)
+
+
+/** Stores a uint32 as big endian */
+static inline void put32(uint8_t *buf, uint32_t val) {
+ buf[0] = val >> 24;
+ buf[1] = val >> 16;
+ buf[2] = val >> 8;
+ buf[3] = val;
+}
+
+/** Allocates a new image partition */
+static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
+ struct image_partition_entry entry = {name, len, malloc(len)};
+ if (!entry.data)
+ error(1, errno, "malloc");
+
+ return entry;
+}
+
+/** Frees an image partition */
+static void free_image_partition(struct image_partition_entry entry) {
+ free(entry.data);
+}
+
+static time_t source_date_epoch = -1;
+static void set_source_date_epoch() {
+ char *env = getenv("SOURCE_DATE_EPOCH");
+ char *endptr = env;
+ errno = 0;
+ if (env && *env) {
+ source_date_epoch = strtoull(env, &endptr, 10);
+ if (errno || (endptr && *endptr != '\0')) {
+ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
+ exit(1);
+ }
+ }
+}
+
+/** Generates the partition-table partition */
+static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
+ struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
+
+ char *s = (char *)entry.data, *end = (char *)(s+entry.size);
+
+ *(s++) = 0x00;
+ *(s++) = 0x04;
+ *(s++) = 0x00;
+ *(s++) = 0x00;
+
+ size_t i;
+ for (i = 0; p[i].name; i++) {
+ size_t len = end-s;
+ size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size);
+
+ if (w > len-1)
+ error(1, 0, "flash partition table overflow?");
+
+ s += w;
+ }
+
+ s++;
+
+ memset(s, 0xff, end-s);
+
+ return entry;
+}
+
+
+/** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
+static inline uint8_t bcd(uint8_t v) {
+ return 0x10 * (v/10) + v%10;
+}
+
+
+/** Generates the soft-version partition */
+static struct image_partition_entry make_soft_version(uint32_t rev) {
+ struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version));
+ struct soft_version *s = (struct soft_version *)entry.data;
+
+ time_t t;
+
+ if (source_date_epoch != -1)
+ t = source_date_epoch;
+ else if (time(&t) == (time_t)(-1))
+ error(1, errno, "time");
+
+ struct tm *tm = localtime(&t);
+
+ s->magic = htonl(0x0000000c);
+ s->zero = 0;
+ s->pad1 = 0xff;
+
+ s->version_major = 0;
+ s->version_minor = 0;
+ s->version_patch = 0;
+
+ s->year_hi = bcd((1900+tm->tm_year)/100);
+ s->year_lo = bcd(tm->tm_year%100);
+ s->month = bcd(tm->tm_mon+1);
+ s->day = bcd(tm->tm_mday);
+ s->rev = htonl(rev);
+
+ s->pad2 = 0xff;
+
+ return entry;
+}
+
+static struct image_partition_entry make_soft_version_from_string(const char *soft_ver) {
+ /** String length _including_ the terminating zero byte */
+ uint32_t ver_len = strlen(soft_ver) + 1;
+ /** Partition contains 64 bit header, the version string, and one additional null byte */
+ size_t partition_len = 2*sizeof(uint32_t) + ver_len + 1;
+ struct image_partition_entry entry = alloc_image_partition("soft-version", partition_len);
+
+ uint32_t *len = (uint32_t *)entry.data;
+ len[0] = htonl(ver_len);
+ len[1] = 0;
+ memcpy(&len[2], soft_ver, ver_len);
+
+ entry.data[partition_len - 1] = 0;
+
+ return entry;
+}
+
+/** Generates the support-list partition */
+static struct image_partition_entry make_support_list(struct device_info *info) {
+ size_t len = strlen(info->support_list);
+ struct image_partition_entry entry = alloc_image_partition("support-list", len + 9);
+
+ put32(entry.data, len);
+ memset(entry.data+4, 0, 4);
+ memcpy(entry.data+8, info->support_list, len);
+ entry.data[len+8] = info->support_trail;
+
+ return entry;
+}
+
+/** Creates a new image partition with an arbitrary name from a file */
+static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof, struct flash_partition_entry *file_system_partition) {
+ struct stat statbuf;
+
+ if (stat(filename, &statbuf) < 0)
+ error(1, errno, "unable to stat file `%s'", filename);
+
+ size_t len = statbuf.st_size;
+
+ if (add_jffs2_eof)
+ if (file_system_partition)
+ len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
+ else
+ len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
+
+ struct image_partition_entry entry = alloc_image_partition(part_name, len);
+
+ FILE *file = fopen(filename, "rb");
+ if (!file)
+ error(1, errno, "unable to open file `%s'", filename);
+
+ if (fread(entry.data, statbuf.st_size, 1, file) != 1)
+ error(1, errno, "unable to read file `%s'", filename);
+
+ if (add_jffs2_eof) {
+ uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
+
+ memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
+ memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
+ }
+
+ fclose(file);
+
+ return entry;
+}
+
+/** Creates a new image partition from arbitrary data */
+static struct image_partition_entry put_data(const char *part_name, const char *datain, size_t len) {
+
+ struct image_partition_entry entry = alloc_image_partition(part_name, len);
+
+ memcpy(entry.data, datain, len);
+
+ return entry;
+}
+
+/**
+ Copies a list of image partitions into an image buffer and generates the image partition table while doing so
+
+ Example image partition table:
+
+ fwup-ptn partition-table base 0x00800 size 0x00800
+ fwup-ptn os-image base 0x01000 size 0x113b45
+ fwup-ptn file-system base 0x114b45 size 0x1d0004
+ fwup-ptn support-list base 0x2e4b49 size 0x000d1
+
+ Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
+ the end of the partition table is marked with a zero byte.
+
+ The firmware image must contain at least the partition-table and support-list partitions
+ to be accepted. There aren't any alignment constraints for the image partitions.
+
+ The partition-table partition contains the actual flash layout; partitions
+ from the image partition table are mapped to the corresponding flash partitions during
+ the firmware upgrade. The support-list partition contains a list of devices supported by
+ the firmware image.
+
+ The base offsets in the firmware partition table are relative to the end
+ of the vendor information block, so the partition-table partition will
+ actually start at offset 0x1814 of the image.
+
+ I think partition-table must be the first partition in the firmware image.
+*/
+static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
+ size_t i, j;
+ char *image_pt = (char *)buffer, *end = image_pt + 0x800;
+
+ size_t base = 0x800;
+ for (i = 0; parts[i].name; i++) {
+ for (j = 0; flash_parts[j].name; j++) {
+ if (!strcmp(flash_parts[j].name, parts[i].name)) {
+ if (parts[i].size > flash_parts[j].size)
+ error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
+ break;
+ }
+ }
+
+ assert(flash_parts[j].name);
+
+ memcpy(buffer + base, parts[i].data, parts[i].size);
+
+ size_t len = end-image_pt;
+ size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size);
+
+ if (w > len-1)
+ error(1, 0, "image partition table overflow?");
+
+ image_pt += w;
+
+ base += parts[i].size;
+ }
+}
+
+/** Generates and writes the image MD5 checksum */
+static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
+ MD5_CTX ctx;
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
+ MD5_Update(&ctx, buffer, len);
+ MD5_Final(md5, &ctx);
+}
+
+
+/**
+ Generates the firmware image in factory format
+
+ Image format:
+
+ Bytes (hex) Usage
+ ----------- -----
+ 0000-0003 Image size (4 bytes, big endian)
+ 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
+ 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
+ 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
+ (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
+ 1014-1813 Image partition table (2048 bytes, padded with 0xff)
+ 1814-xxxx Firmware partitions
+*/
+static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
+ *len = 0x1814;
+
+ size_t i;
+ for (i = 0; parts[i].name; i++)
+ *len += parts[i].size;
+
+ uint8_t *image = malloc(*len);
+ if (!image)
+ error(1, errno, "malloc");
+
+ memset(image, 0xff, *len);
+ put32(image, *len);
+
+ if (info->vendor) {
+ size_t vendor_len = strlen(info->vendor);
+ put32(image+0x14, vendor_len);
+ memcpy(image+0x18, info->vendor, vendor_len);
+ }
+
+ put_partitions(image + 0x1014, info->partitions, parts);
+ put_md5(image+0x04, image+0x14, *len-0x14);
+
+ return image;
+}
+
+/**
+ Generates the firmware image in sysupgrade format
+
+ This makes some assumptions about the provided flash and image partition tables and
+ should be generalized when TP-LINK starts building its safeloader into hardware with
+ different flash layouts.
+*/
+static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
+ size_t i, j;
+ size_t flash_first_partition_index = 0;
+ size_t flash_last_partition_index = 0;
+ const struct flash_partition_entry *flash_first_partition = NULL;
+ const struct flash_partition_entry *flash_last_partition = NULL;
+ const struct image_partition_entry *image_last_partition = NULL;
+
+ /** Find first and last partitions */
+ for (i = 0; info->partitions[i].name; i++) {
+ if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
+ flash_first_partition = &info->partitions[i];
+ flash_first_partition_index = i;
+ } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
+ flash_last_partition = &info->partitions[i];
+ flash_last_partition_index = i;
+ }
+ }
+
+ assert(flash_first_partition && flash_last_partition);
+ assert(flash_first_partition_index < flash_last_partition_index);
+
+ /** Find last partition from image to calculate needed size */
+ for (i = 0; image_parts[i].name; i++) {
+ if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
+ image_last_partition = &image_parts[i];
+ break;
+ }
+ }
+
+ assert(image_last_partition);
+
+ *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
+
+ uint8_t *image = malloc(*len);
+ if (!image)
+ error(1, errno, "malloc");
+
+ memset(image, 0xff, *len);
+
+ for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
+ for (j = 0; image_parts[j].name; j++) {
+ if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
+ if (image_parts[j].size > info->partitions[i].size)
+ error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
+ memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
+ break;
+ }
+
+ assert(image_parts[j].name);
+ }
+ }
+
+ return image;
+}
+
+/** Generates an image according to a given layout and writes it to a file */
+static void build_image(const char *output,
+ const char *kernel_image,
+ const char *rootfs_image,
+ uint32_t rev,
+ bool add_jffs2_eof,
+ bool sysupgrade,
+ struct device_info *info) {
+
+ size_t i;
+
+ struct image_partition_entry parts[7] = {};
+
+ struct flash_partition_entry *firmware_partition = NULL;
+ struct flash_partition_entry *os_image_partition = NULL;
+ struct flash_partition_entry *file_system_partition = NULL;
+ size_t firmware_partition_index = 0;
+
+ for (i = 0; info->partitions[i].name; i++) {
+ if (!strcmp(info->partitions[i].name, "firmware"))
+ {
+ firmware_partition = &info->partitions[i];
+ firmware_partition_index = i;
+ }
+ }
+
+ if (firmware_partition)
+ {
+ os_image_partition = &info->partitions[firmware_partition_index];
+ file_system_partition = &info->partitions[firmware_partition_index + 1];
+
+ struct stat kernel;
+ if (stat(kernel_image, &kernel) < 0)
+ error(1, errno, "unable to stat file `%s'", kernel_image);
+
+ if (kernel.st_size > firmware_partition->size)
+ error(1, 0, "kernel overflowed firmware partition\n");
+
+ for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
+ info->partitions[i+1] = info->partitions[i];
+
+ file_system_partition->name = "file-system";
+ file_system_partition->base = firmware_partition->base + kernel.st_size;
+
+ /* Align partition start to erase blocks for factory images only */
+ if (!sysupgrade)
+ file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
+
+ file_system_partition->size = firmware_partition->size - file_system_partition->base;
+
+ os_image_partition->name = "os-image";
+ os_image_partition->size = kernel.st_size;
+ }
+
+ parts[0] = make_partition_table(info->partitions);
+ if (info->soft_ver)
+ parts[1] = make_soft_version_from_string(info->soft_ver);
+ else
+ parts[1] = make_soft_version(rev);
+
+ parts[2] = make_support_list(info);
+ parts[3] = read_file("os-image", kernel_image, false, NULL);
+ parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition);
+
+ /* Some devices need the extra-para partition to accept the firmware */
+ if (strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
+ strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
+ strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
+ strcasecmp(info->id, "TLWR1043NV5") == 0) {
+ const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
+ parts[5] = put_data("extra-para", mdat, 11);
+ } else if (strcasecmp(info->id, "ARCHER-C7-V4") == 0 || strcasecmp(info->id, "ARCHER-C7-V5") == 0) {
+ const char mdat[11] = {0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x01, 0x00, 0x00};
+ parts[5] = put_data("extra-para", mdat, 11);
+ }
+
+ size_t len;
+ void *image;
+ if (sysupgrade)
+ image = generate_sysupgrade_image(info, parts, &len);
+ else
+ image = generate_factory_image(info, parts, &len);
+
+ FILE *file = fopen(output, "wb");
+ if (!file)
+ error(1, errno, "unable to open output file");
+
+ if (fwrite(image, len, 1, file) != 1)
+ error(1, 0, "unable to write output file");
+
+ fclose(file);
+
+ free(image);
+
+ for (i = 0; parts[i].name; i++)
+ free_image_partition(parts[i]);
+}
+
+/** Usage output */
+static void usage(const char *argv0) {
+ fprintf(stderr,
+ "Usage: %s [OPTIONS...]\n"
+ "\n"
+ "Options:\n"
+ " -h show this help\n"
+ "\n"
+ "Create a new image:\n"
+ " -B <board> create image for the board specified with <board>\n"
+ " -k <file> read kernel image from the file <file>\n"
+ " -r <file> read rootfs image from the file <file>\n"
+ " -o <file> write output to the file <file>\n"
+ " -V <rev> sets the revision number to <rev>\n"
+ " -j add jffs2 end-of-filesystem markers\n"
+ " -S create sysupgrade instead of factory image\n"
+ "Extract an old image:\n"
+ " -x <file> extract all oem firmware partition\n"
+ " -d <dir> destination to extract the firmware partition\n"
+ " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
+ argv0
+ );
+};
+
+
+static struct device_info *find_board(const char *id)
+{
+ struct device_info *board = NULL;
+
+ for (board = boards; board->id != NULL; board++)
+ if (strcasecmp(id, board->id) == 0)
+ return board;
+
+ return NULL;
+}
+
+static int add_flash_partition(
+ struct flash_partition_entry *part_list,
+ size_t max_entries,
+ const char *name,
+ unsigned long base,
+ unsigned long size)
+{
+ int ptr;
+ /* check if the list has a free entry */
+ for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
+ if (part_list->name == NULL &&
+ part_list->base == 0 &&
+ part_list->size == 0)
+ break;
+ }
+
+ if (ptr == max_entries) {
+ error(1, 0, "No free flash part entry available.");
+ }
+
+ part_list->name = calloc(1, strlen(name) + 1);
+ if (!part_list->name) {
+ error(1, 0, "Unable to allocate memory");
+ }
+
+ memcpy((char *)part_list->name, name, strlen(name));
+ part_list->base = base;
+ part_list->size = size;
+
+ return 0;
+}
+
+/** read the partition table into struct flash_partition_entry */
+static int read_partition_table(
+ FILE *file, long offset,
+ struct flash_partition_entry *entries, size_t max_entries,
+ int type)
+{
+ char buf[2048];
+ char *ptr, *end;
+ const char *parthdr = NULL;
+ const char *fwuphdr = "fwup-ptn";
+ const char *flashhdr = "partition";
+
+ /* TODO: search for the partition table */
+
+ switch(type) {
+ case 0:
+ parthdr = fwuphdr;
+ break;
+ case 1:
+ parthdr = flashhdr;
+ break;
+ default:
+ error(1, 0, "Invalid partition table");
+ }
+
+ if (fseek(file, offset, SEEK_SET) < 0)
+ error(1, errno, "Can not seek in the firmware");
+
+ if (fread(buf, 1, 2048, file) < 0)
+ error(1, errno, "Can not read fwup-ptn from the firmware");
+
+ buf[2047] = '\0';
+
+ /* look for the partition header */
+ if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
+ fprintf(stderr, "DEBUG: can not find fwuphdr\n");
+ return 1;
+ }
+
+ ptr = buf;
+ end = buf + sizeof(buf);
+ while ((ptr + strlen(parthdr)) < end &&
+ memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
+ char *end_part;
+ char *end_element;
+
+ char name[32] = { 0 };
+ int name_len = 0;
+ unsigned long base = 0;
+ unsigned long size = 0;
+
+ end_part = memchr(ptr, '\n', (end - ptr));
+ if (end_part == NULL) {
+ /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
+ break;
+ }
+
+ for (int i = 0; i <= 4; i++) {
+ if (end_part <= ptr)
+ break;
+
+ end_element = memchr(ptr, 0x20, (end_part - ptr));
+ if (end_element == NULL) {
+ error(1, errno, "Ignoring the rest of the partition entries.");
+ break;
+ }
+
+ switch (i) {
+ /* partition header */
+ case 0:
+ ptr = end_element + 1;
+ continue;
+ /* name */
+ case 1:
+ name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
+ strncpy(name, ptr, name_len);
+ name[name_len] = '\0';
+ ptr = end_element + 1;
+ continue;
+
+ /* string "base" */
+ case 2:
+ ptr = end_element + 1;
+ continue;
+
+ /* actual base */
+ case 3:
+ base = strtoul(ptr, NULL, 16);
+ ptr = end_element + 1;
+ continue;
+
+ /* string "size" */
+ case 4:
+ ptr = end_element + 1;
+ /* actual size. The last element doesn't have a sepeartor */
+ size = strtoul(ptr, NULL, 16);
+ /* the part ends with 0x09, 0x0d, 0x0a */
+ ptr = end_part + 1;
+ add_flash_partition(entries, max_entries, name, base, size);
+ continue;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void write_partition(
+ FILE *input_file,
+ size_t firmware_offset,
+ struct flash_partition_entry *entry,
+ FILE *output_file)
+{
+ char buf[4096];
+ size_t offset;
+
+ fseek(input_file, entry->base + firmware_offset, SEEK_SET);
+
+ for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
+ if (fread(buf, sizeof(buf), 1, input_file) < 0)
+ error(1, errno, "Can not read partition from input_file");
+
+ if (fwrite(buf, sizeof(buf), 1, output_file) < 0)
+ error(1, errno, "Can not write partition to output_file");
+ }
+ /* write last chunk smaller than buffer */
+ if (offset < entry->size) {
+ offset = entry->size - offset;
+ if (fread(buf, offset, 1, input_file) < 0)
+ error(1, errno, "Can not read partition from input_file");
+ if (fwrite(buf, offset, 1, output_file) < 0)
+ error(1, errno, "Can not write partition to output_file");
+ }
+}
+
+static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
+{
+ FILE *output_file;
+ char output[PATH_MAX];
+
+ snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
+ output_file = fopen(output, "wb+");
+ if (output_file == NULL) {
+ error(1, errno, "Can not open output file %s", output);
+ }
+
+ write_partition(input_file, firmware_offset, entry, output_file);
+
+ fclose(output_file);
+
+ return 0;
+}
+
+/** extract all partitions from the firmware file */
+static int extract_firmware(const char *input, const char *output_directory)
+{
+ struct flash_partition_entry entries[16] = { 0 };
+ size_t max_entries = 16;
+ size_t firmware_offset = 0x1014;
+ FILE *input_file;
+
+ struct stat statbuf;
+
+ /* check input file */
+ if (stat(input, &statbuf)) {
+ error(1, errno, "Can not read input firmware %s", input);
+ }
+
+ /* check if output directory exists */
+ if (stat(output_directory, &statbuf)) {
+ error(1, errno, "Failed to stat output directory %s", output_directory);
+ }
+
+ if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
+ error(1, errno, "Given output directory is not a directory %s", output_directory);
+ }
+
+ input_file = fopen(input, "rb");
+
+ if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) {
+ error(1, 0, "Error can not read the partition table (fwup-ptn)");
+ }
+
+ for (int i = 0; i < max_entries; i++) {
+ if (entries[i].name == NULL &&
+ entries[i].base == 0 &&
+ entries[i].size == 0)
+ continue;
+
+ extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory);
+ }
+
+ return 0;
+}
+
+static struct flash_partition_entry *find_partition(
+ struct flash_partition_entry *entries, size_t max_entries,
+ const char *name, const char *error_msg)
+{
+ for (int i = 0; i < max_entries; i++, entries++) {
+ if (strcmp(entries->name, name) == 0)
+ return entries;
+ }
+
+ error(1, 0, "%s", error_msg);
+ return NULL;
+}
+
+static void write_ff(FILE *output_file, size_t size)
+{
+ char buf[4096];
+ int offset;
+
+ memset(buf, 0xff, sizeof(buf));
+
+ for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
+ if (fwrite(buf, sizeof(buf), 1, output_file) < 0)
+ error(1, errno, "Can not write 0xff to output_file");
+ }
+
+ /* write last chunk smaller than buffer */
+ if (offset < size) {
+ offset = size - offset;
+ if (fwrite(buf, offset, 1, output_file) < 0)
+ error(1, errno, "Can not write partition to output_file");
+ }
+}
+
+static void convert_firmware(const char *input, const char *output)
+{
+ struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 };
+ struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 };
+ struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL;
+ struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL;
+ struct flash_partition_entry *fwup_partition_table = NULL;
+ size_t firmware_offset = 0x1014;
+ FILE *input_file, *output_file;
+
+ struct stat statbuf;
+
+ /* check input file */
+ if (stat(input, &statbuf)) {
+ error(1, errno, "Can not read input firmware %s", input);
+ }
+
+ input_file = fopen(input, "rb");
+ if (!input_file)
+ error(1, 0, "Can not open input firmware %s", input);
+
+ output_file = fopen(output, "wb");
+ if (!output_file)
+ error(1, 0, "Can not open output firmware %s", output);
+
+ if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) {
+ error(1, 0, "Error can not read the partition table (fwup-ptn)");
+ }
+
+ fwup_os_image = find_partition(fwup, MAX_PARTITIONS,
+ "os-image", "Error can not find os-image partition (fwup)");
+ fwup_file_system = find_partition(fwup, MAX_PARTITIONS,
+ "file-system", "Error can not find file-system partition (fwup)");
+ fwup_partition_table = find_partition(fwup, MAX_PARTITIONS,
+ "partition-table", "Error can not find partition-table partition");
+
+ /* the flash partition table has a 0x00000004 magic haeder */
+ if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0)
+ error(1, 0, "Error can not read the partition table (flash)");
+
+ flash_os_image = find_partition(flash, MAX_PARTITIONS,
+ "os-image", "Error can not find os-image partition (flash)");
+ flash_file_system = find_partition(flash, MAX_PARTITIONS,
+ "file-system", "Error can not find file-system partition (flash)");
+
+ /* write os_image to 0x0 */
+ write_partition(input_file, firmware_offset, fwup_os_image, output_file);
+ write_ff(output_file, flash_os_image->size - fwup_os_image->size);
+
+ /* write file-system behind os_image */
+ fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
+ write_partition(input_file, firmware_offset, fwup_file_system, output_file);
+ write_ff(output_file, flash_file_system->size - fwup_file_system->size);
+
+ fclose(output_file);
+ fclose(input_file);
+}
+
+int main(int argc, char *argv[]) {
+ const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
+ const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
+ bool add_jffs2_eof = false, sysupgrade = false;
+ unsigned rev = 0;
+ struct device_info *info;
+ set_source_date_epoch();
+
+ while (true) {
+ int c;
+
+ c = getopt(argc, argv, "B:k:r:o:V:jSh:x:d:z:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'B':
+ board = optarg;
+ break;
+
+ case 'k':
+ kernel_image = optarg;
+ break;
+
+ case 'r':
+ rootfs_image = optarg;
+ break;
+
+ case 'o':
+ output = optarg;
+ break;
+
+ case 'V':
+ sscanf(optarg, "r%u", &rev);
+ break;
+
+ case 'j':
+ add_jffs2_eof = true;
+ break;
+
+ case 'S':
+ sysupgrade = true;
+ break;
+
+ case 'h':
+ usage(argv[0]);
+ return 0;
+
+ case 'd':
+ output_directory = optarg;
+ break;
+
+ case 'x':
+ extract_image = optarg;
+ break;
+
+ case 'z':
+ convert_image = optarg;
+ break;
+
+ default:
+ usage(argv[0]);
+ return 1;
+ }
+ }
+
+ if (extract_image || output_directory) {
+ if (!extract_image)
+ error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
+ if (!output_directory)
+ error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
+ extract_firmware(extract_image, output_directory);
+ } else if (convert_image) {
+ if (!output)
+ error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
+ convert_firmware(convert_image, output);
+ } else {
+ if (!board)
+ error(1, 0, "no board has been specified");
+ if (!kernel_image)
+ error(1, 0, "no kernel image has been specified");
+ if (!rootfs_image)
+ error(1, 0, "no rootfs image has been specified");
+ if (!output)
+ error(1, 0, "no output filename has been specified");
+
+ info = find_board(board);
+
+ if (info == NULL)
+ error(1, 0, "unsupported board %s", board);
+
+ build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
+ }
+
+ return 0;
+}
diff --git a/tools/firmware-utils/src/trx.c b/tools/firmware-utils/src/trx.c
index 8e95d98d7ae..dc5bb672aeb 100644
--- a/tools/firmware-utils/src/trx.c
+++ b/tools/firmware-utils/src/trx.c
@@ -68,7 +68,7 @@ uint32_t crc32buf(char *buf, size_t len);
#define TRX_MAGIC 0x30524448 /* "HDR0" */
#define TRX_MAX_LEN 0x720000
-#define TRX_NO_HEADER 1 /* Do not write TRX header */
+#define TRX_NO_HEADER 1 /* Do not write TRX header */
struct trx_header {
uint32_t magic; /* "HDR0" */
@@ -100,7 +100,7 @@ int main(int argc, char **argv)
int c, i, append = 0;
size_t n;
ssize_t n2;
- uint32_t cur_len, fsmark=0;
+ uint32_t cur_len, fsmark=0, magic;
unsigned long maxlen = TRX_MAX_LEN;
struct trx_header *p;
char trx_version = 1;
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
in = NULL;
i = 0;
- while ((c = getopt(argc, argv, "-:2o:m:a:x:b:f:A:F:")) != -1) {
+ while ((c = getopt(argc, argv, "-:2o:m:a:x:b:f:A:F:M:")) != -1) {
switch (c) {
case '2':
/* take care that nothing was written to buf so far */
@@ -243,6 +243,15 @@ int main(int argc, char **argv)
}
break;
+ case 'M':
+ errno = 0;
+ magic = strtoul(optarg, &e, 0);
+ if (errno || (e == optarg) || *e) {
+ fprintf(stderr, "illegal numeric string\n");
+ usage();
+ }
+ p->magic = STORE32_LE(magic);
+ break;
default:
usage();
}
@@ -262,7 +271,7 @@ int main(int argc, char **argv)
cur_len += ROUND - n;
}
- /* for TRXv2 set bin-header Flags to 0xFF for CRC calculation like CFE does */
+ /* for TRXv2 set bin-header Flags to 0xFF for CRC calculation like CFE does */
if (trx_version == 2) {
if(cur_len - LOAD32_LE(p->offsets[3]) < sizeof(binheader)) {
fprintf(stderr, "TRXv2 binheader too small!\n");
@@ -273,11 +282,10 @@ int main(int argc, char **argv)
}
p->crc32 = crc32buf((char *) &p->flag_version,
- (fsmark)?fsmark:cur_len - offsetof(struct trx_header, flag_version));
+ ((fsmark)?fsmark:cur_len) - offsetof(struct trx_header, flag_version));
p->crc32 = STORE32_LE(p->crc32);
p->len = STORE32_LE((fsmark) ? fsmark : cur_len);
- p->len = STORE32_LE(p->len);
/* restore TRXv2 bin-header */
if (trx_version == 2) {
@@ -290,7 +298,7 @@ int main(int argc, char **argv)
}
fclose(out);
-
+
return EXIT_SUCCESS;
}
diff --git a/tools/firmware-utils/src/wndr3700.c b/tools/firmware-utils/src/wndr3700.c
deleted file mode 100644
index 97b5f1d4558..00000000000
--- a/tools/firmware-utils/src/wndr3700.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * wndr3700.c - partially based on OpenWrt's add_header.c
- *
- * Copyright (C) 2009 Anael Orlinski <naouel@naouel.org>
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
- * The add_header utility used by various vendors preprends the buf
- * image with a header containing a CRC32 value which is generated for the
- * model id + reserved space for CRC32 + buf, then replaces the reserved
- * area with the actual CRC32. This replacement tool mimics this behavior.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <inttypes.h>
-
-#define BPB 8 /* bits/byte */
-
-#define WNDR3700_MAGIC_LEN 4
-
-static uint32_t crc32[1<<BPB];
-static char *magic = "3700";
-
-static void init_crc32()
-{
- const uint32_t poly = ntohl(0x2083b8ed);
- int n;
-
- for (n = 0; n < 1<<BPB; n++) {
- uint32_t crc = n;
- int bit;
-
- for (bit = 0; bit < BPB; bit++)
- crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1);
- crc32[n] = crc;
- }
-}
-
-static uint32_t crc32buf(unsigned char *buf, size_t len)
-{
- uint32_t crc = 0xFFFFFFFF;
-
- for (; len; len--, buf++)
- crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB);
- return ~crc;
-}
-
-struct header {
- unsigned char magic[WNDR3700_MAGIC_LEN];
- uint32_t crc;
- unsigned char stuff[56];
-};
-
-static void usage(const char *) __attribute__ (( __noreturn__ ));
-
-static void usage(const char *mess)
-{
- fprintf(stderr, "Error: %s\n", mess);
- fprintf(stderr, "Usage: wndr3700 input_file output_file [magic]\n");
- fprintf(stderr, "\n");
- exit(1);
-}
-
-int main(int argc, char **argv)
-{
- off_t len; // of original buf
- off_t buflen; // of the output file
- int fd;
- void *input_file; // pointer to the input file (mmmapped)
- struct header header;
- unsigned char *buf; // pointer to prefix + copy of original buf
-
- // verify parameters
-
- if (argc < 3)
- usage("wrong number of arguments");
-
- if (argc > 3)
- magic = argv[3];
-
- if (strlen(magic) != WNDR3700_MAGIC_LEN) {
- fprintf(stderr, "Invalid magic: '%s'\n", magic);
- exit(1);
- }
-
- // mmap input_file
- if ((fd = open(argv[1], O_RDONLY)) < 0
- || (len = lseek(fd, 0, SEEK_END)) < 0
- || (input_file = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1)
- || close(fd) < 0)
- {
- fprintf(stderr, "Error loading file %s: %s\n", argv[1], strerror(errno));
- exit(1);
- }
-
- buflen = len;
-
- init_crc32();
-
- // preload header
- memcpy(&header, input_file, sizeof(header));
-
- memcpy(header.magic, magic, WNDR3700_MAGIC_LEN);
- header.crc = 0;
-
- // create a firmware image in memory and copy the input_file to it
- buf = malloc(buflen);
- memcpy(buf, input_file, len);
-
- // CRC of temporary header
- header.crc = htonl(crc32buf((unsigned char*)&header, sizeof(header)));
-
- memcpy(buf, &header, sizeof(header));
-
- // write the buf
- if ((fd = open(argv[2], O_CREAT|O_WRONLY|O_TRUNC,0644)) < 0
- || write(fd, buf, buflen) != buflen
- || close(fd) < 0)
- {
- fprintf(stderr, "Error storing file %s: %s\n", argv[2], strerror(errno));
- exit(2);
- }
-
- free(buf);
-
- munmap(input_file,len);
-
- return 0;
-}
diff --git a/tools/firmware-utils/src/wrt400n.c b/tools/firmware-utils/src/wrt400n.c
index a9a4908060c..1cf1debc893 100644
--- a/tools/firmware-utils/src/wrt400n.c
+++ b/tools/firmware-utils/src/wrt400n.c
@@ -7,12 +7,14 @@
*
* Author: Sandeep Mistry
*/
+#include <arpa/inet.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include "cyg_crc.h"
diff --git a/tools/firmware-utils/src/xorimage.c b/tools/firmware-utils/src/xorimage.c
index b5ab83fa7a6..ca6e43742a1 100644
--- a/tools/firmware-utils/src/xorimage.c
+++ b/tools/firmware-utils/src/xorimage.c
@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
-#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
diff --git a/tools/firmware-utils/src/zyimage.c b/tools/firmware-utils/src/zyimage.c
new file mode 100644
index 00000000000..6aacf2ff1bd
--- /dev/null
+++ b/tools/firmware-utils/src/zyimage.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 Soul Trace <S-trace@list.ru>
+ *
+ * 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.
+ *
+ */
+
+#define _POSIX_SOURCE
+#define _POSIX_C_SOURCE 199309L /* getopt */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+
+#define szbuf 32768
+
+u_int32_t crc_tab[256];
+
+u_int32_t chksum_crc32 (FILE *f)
+{
+ register unsigned long crc;
+ unsigned long i, j;
+ char *buffer = malloc(szbuf);
+ char *buf;
+
+ crc = 0xFFFFFFFF;
+ while (!feof(f))
+ {
+ j = fread(buffer, 1, szbuf, f);
+ buf = buffer;
+ for (i = 0; i < j; i++)
+ crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *buf++) & 0xFF];
+ }
+ free(buffer);
+ return crc;
+}
+
+void chksum_crc32gentab ()
+{
+ unsigned long crc, poly;
+ int i, j;
+
+ poly = 0xEDB88320L;
+ for (i = 0; i < 256; i++)
+ {
+ crc = i;
+ for (j = 8; j > 0; j--)
+ {
+ if (crc & 1)
+ crc = (crc >> 1) ^ poly;
+ else
+ crc >>= 1;
+ }
+ crc_tab[i] = crc;
+ }
+}
+
+void usage(char *progname)
+{
+ printf("Usage: %s [ -v Version ] [ -d Device_ID ] <input file>\n", progname);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ struct signature
+ {
+ const char magic[4];
+ unsigned int device_id;
+ char firmware_version[48];
+ unsigned int crc32;
+ }
+ sign =
+ {
+ { 'Z', 'N', 'B', 'G' },
+ 1,
+ { "V.1.0.0(1.0.0)" },
+ 0
+ };
+ FILE *f;
+ struct signature oldsign;
+ char *filename;
+ static const char *optString;
+ int opt;
+
+ if (argc < 1)
+ usage(argv[0]);
+
+ optString = "v:d:h";
+ opt = getopt( argc, argv, optString );
+ while( opt != -1 ) {
+ switch( opt ) {
+ case 'v':
+ if (optarg == NULL)
+ usage(argv[0]);
+ strncpy(sign.firmware_version, optarg, sizeof(sign.firmware_version)-1);
+ sign.firmware_version[sizeof(sign.firmware_version)-1]='\0'; /* Make sure that string is terminated correctly */
+ break;
+
+ case 'd':
+ sign.device_id = atoi(optarg);
+ if (sign.device_id == 0)
+ sign.device_id = (int)strtol(optarg, NULL, 16);
+ break;
+
+ case '?':
+ case 'h':
+ usage(argv[0]);
+ break;
+
+ default:
+ break;
+ }
+
+ opt = getopt( argc, argv, optString );
+ }
+
+ chksum_crc32gentab();
+
+ filename=argv[optind];
+ if (access(filename, W_OK) || access(filename, R_OK))
+ {
+ printf("Not open input file %s\n", filename);
+ exit(1);
+ }
+ f = fopen(argv[optind], "r+");
+ if (f != NULL)
+ {
+ fseek(f, sizeof(sign)*-1, SEEK_END);
+ fread(&oldsign, sizeof(oldsign), 1, f);
+
+ if (strncmp(oldsign.magic,"ZNBG", sizeof(oldsign.magic)) == 0 )
+ {
+ printf("Image is already signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", oldsign.device_id, oldsign.firmware_version, oldsign.crc32);
+ exit(0);
+ }
+
+ fseek(f, 0, SEEK_SET);
+ sign.crc32 = chksum_crc32(f);
+ fwrite(&sign, sizeof(sign), 1, f);
+ fclose(f);
+
+ printf("Image signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", sign.device_id, sign.firmware_version, sign.crc32);
+ }
+ return 0;
+}
diff --git a/tools/firmware-utils/src/zyxbcm.c b/tools/firmware-utils/src/zyxbcm.c
new file mode 100644
index 00000000000..1a2926bfd31
--- /dev/null
+++ b/tools/firmware-utils/src/zyxbcm.c
@@ -0,0 +1,259 @@
+/*
+ * zyxbcm.c - based on Jonas Gorski's spw303v.c
+ *
+ * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#define TAGVER_LEN 4 /* Length of Tag Version */
+#define SIG1_LEN 20 /* Company Signature 1 Length */
+#define SIG2_LEN 14 /* Company Signature 2 Lenght */
+#define BOARDID_LEN 16 /* Length of BoardId */
+#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
+#define CHIPID_LEN 6 /* Chip Id Length */
+#define IMAGE_LEN 10 /* Length of Length Field */
+#define ADDRESS_LEN 12 /* Length of Address field */
+#define DUALFLAG_LEN 2 /* Dual Image flag Length */
+#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
+#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
+#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
+#define ZYX_TAGINFO1_LEN 20 /* Length of vendor information field1 in tag */
+#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
+#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
+#define CRC_LEN 4 /* Length of CRC in bytes */
+
+#define IMAGETAG_CRC_START 0xFFFFFFFF
+
+struct bcm_tag {
+ char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag
+ char sig_1[SIG1_LEN]; // 4-23: Company Line 1
+ char sig_2[SIG2_LEN]; // 24-37: Company Line 2
+ char chipid[CHIPID_LEN]; // 38-43: Chip this image is for
+ char boardid[BOARDID_LEN]; // 44-59: Board name
+ char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE
+ char totalLength[IMAGE_LEN]; // 62-71: Total length of image
+ char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE
+ char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE
+ char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware)
+ char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing
+ char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel
+ char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel
+ char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present
+ char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present
+ char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this)
+ char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT)
+ char flashLayoutVer[FLASHLAYOUTVER_LEN]; // 192-195: Version flash layout
+ char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32
+ char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information
+ char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate)
+ char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition
+ char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition
+ char imageSequence[4]; // 228-231: Image sequence number
+ char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot
+ char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion
+ char reserved2[16]; // 240-255: Unused at present
+};
+
+struct zyxbcm_tag {
+ char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag
+ char sig_1[SIG1_LEN]; // 4-23: Company Line 1
+ char sig_2[SIG2_LEN]; // 24-37: Company Line 2
+ char chipid[CHIPID_LEN]; // 38-43: Chip this image is for
+ char boardid[BOARDID_LEN]; // 44-59: Board name
+ char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE
+ char totalLength[IMAGE_LEN]; // 62-71: Total length of image
+ char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE
+ char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE
+ char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware)
+ char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing
+ char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel
+ char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel
+ char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present
+ char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present
+ char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this)
+ char information1[ZYX_TAGINFO1_LEN]; // 162-181: Compilation and related information (not generated/used by OpenWRT)
+ char flashImageEnd[ADDRESS_LEN]; // 182-193: Address in memory of image end
+ char fskernelCRC[CRC_LEN]; // 194-197: kernel+rootfs CRC32
+ char reserved1[2]; // 198-199: Unused at present
+ char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information
+ char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate)
+ char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition
+ char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition
+ char imageSequence[4]; // 228-231: Image sequence number
+ char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot
+ char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion
+ char reserved2[16]; // 240-255: Unused at present
+};
+
+static uint32_t crc32tab[256] = {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+uint32_t crc32(uint32_t crc, uint8_t *data, size_t len)
+{
+ while (len--)
+ crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF];
+
+ return crc;
+}
+
+void fix_header(void *buf)
+{
+ struct bcm_tag *bcmtag = buf;
+ struct zyxbcm_tag *zyxtag = buf;
+ uint8_t fskernel_crc[CRC_LEN];
+ uint32_t crc;
+ uint64_t flash_start, rootfs_len, kernel_len;
+
+ /* Backup values */
+ flash_start = strtoul(bcmtag->flashImageStart, NULL, 10);
+ rootfs_len = strtoul(bcmtag->flashRootLength, NULL, 10);
+ kernel_len = strtoul(bcmtag->kernelLength, NULL, 10);
+ memcpy(fskernel_crc, bcmtag->fskernelCRC, CRC_LEN);
+
+ /* Clear values */
+ zyxtag->information1[ZYX_TAGINFO1_LEN - 1] = 0;
+ memset(zyxtag->flashImageEnd, 0, ADDRESS_LEN);
+ memset(zyxtag->fskernelCRC, 0, CRC_LEN);
+ memset(zyxtag->reserved1, 0, 2);
+
+ /* Replace values */
+ sprintf(zyxtag->flashImageEnd, "%lu", flash_start + rootfs_len + kernel_len);
+ memcpy(zyxtag->fskernelCRC, fskernel_crc, CRC_LEN);
+
+ /* Update tag crc */
+ crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236));
+ memcpy(zyxtag->headerCRC, &crc, 4);
+}
+
+void usage(void) __attribute__ (( __noreturn__ ));
+
+void usage(void)
+{
+ fprintf(stderr, "Usage: zyxbcm [-i <inputfile>] [-o <outputfile>]\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ char buf[1024]; /* keep this at 1k or adjust garbage calc below */
+ FILE *in = stdin, *out = stdout;
+ char *ifn = NULL, *ofn = NULL;
+ size_t n;
+ int c, first_block = 1;
+
+ while ((c = getopt(argc, argv, "i:o:h")) != -1) {
+ switch (c) {
+ case 'i':
+ ifn = optarg;
+ break;
+ case 'o':
+ ofn = optarg;
+ break;
+ case 'h':
+ default:
+ usage();
+ }
+ }
+
+ if (optind != argc || optind == 1) {
+ fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]);
+ usage();
+ }
+
+ if (ifn && !(in = fopen(ifn, "r"))) {
+ fprintf(stderr, "can not open \"%s\" for reading\n", ifn);
+ usage();
+ }
+
+ if (ofn && !(out = fopen(ofn, "w"))) {
+ fprintf(stderr, "can not open \"%s\" for writing\n", ofn);
+ usage();
+ }
+
+ while ((n = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (n < sizeof(buf)) {
+ if (ferror(in)) {
+ FREAD_ERROR:
+ fprintf(stderr, "fread error\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (first_block && n >= 256) {
+ fix_header(buf);
+ first_block = 0;
+ }
+
+ if (!fwrite(buf, n, 1, out)) {
+ FWRITE_ERROR:
+ fprintf(stderr, "fwrite error\n");
+ return EXIT_FAILURE;
+ }
+ }
+
+ if (ferror(in)) {
+ goto FREAD_ERROR;
+ }
+
+ if (fflush(out)) {
+ goto FWRITE_ERROR;
+ }
+
+ fclose(in);
+ fclose(out);
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/flex/Makefile b/tools/flex/Makefile
index 2fcc2c643fd..1eff81f3451 100644
--- a/tools/flex/Makefile
+++ b/tools/flex/Makefile
@@ -1,5 +1,5 @@
-#
-# Copyright (C) 2008 OpenWrt.org
+#
+# Copyright (C) 2008-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,15 +7,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=flex
-PKG_VERSION:=2.5.35
+PKG_CPE_ID:=cpe:/a:flex_project:flex
+PKG_VERSION:=2.6.4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/westes/flex/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=@SF/$(PKG_NAME)
-PKG_MD5SUM:=10714e50cea54dc7a227e3eddcd44d57
-PKG_CAT:=bzcat
+HOST_FIXUP:=autoreconf
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
+HOST_CONFIGURE_ARGS += --disable-shared
+
define Host/Clean
-$(MAKE) -C $(HOST_BUILD_DIR) uninstall
$(call Host/Clean/Default)
diff --git a/tools/flex/patches/100-disable-tests-docs.patch b/tools/flex/patches/100-disable-tests-docs.patch
new file mode 100644
index 00000000000..f7097f2127d
--- /dev/null
+++ b/tools/flex/patches/100-disable-tests-docs.patch
@@ -0,0 +1,13 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -43,10 +43,7 @@ EXTRA_DIST = \
+
+ SUBDIRS = \
+ src \
+- doc \
+- examples \
+ po \
+- tests \
+ tools
+
+ # Create the ChangeLog, but only if we're inside a git working directory
diff --git a/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch b/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch
new file mode 100644
index 00000000000..7c3645c4747
--- /dev/null
+++ b/tools/flex/patches/200-build-AC_USE_SYSTEM_EXTENSIONS-in-configure.ac.patch
@@ -0,0 +1,27 @@
+From 24fd0551333e7eded87b64dd36062da3df2f6380 Mon Sep 17 00:00:00 2001
+From: Explorer09 <explorer09@gmail.com>
+Date: Mon, 4 Sep 2017 10:47:33 +0800
+Subject: [PATCH] build: AC_USE_SYSTEM_EXTENSIONS in configure.ac.
+
+This would, e.g. define _GNU_SOURCE in config.h, enabling the
+reallocarray() prototype in glibc 2.26+ on Linux systems with that
+version of glibc.
+
+Fixes #241.
+---
+ configure.ac | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -25,8 +25,10 @@
+ # autoconf requirements and initialization
+
+ AC_INIT([the fast lexical analyser generator],[2.6.4],[flex-help@lists.sourceforge.net],[flex])
++AC_PREREQ([2.60])
+ AC_CONFIG_SRCDIR([src/scan.l])
+ AC_CONFIG_AUX_DIR([build-aux])
++AC_USE_SYSTEM_EXTENSIONS
+ LT_INIT
+ AM_INIT_AUTOMAKE([1.11.3 -Wno-portability foreign check-news std-options dist-lzip parallel-tests subdir-objects])
+ AC_CONFIG_HEADER([src/config.h])
diff --git a/tools/flock/Makefile b/tools/flock/Makefile
index 64a8655b831..9939d121169 100644
--- a/tools/flock/Makefile
+++ b/tools/flock/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2008 OpenWrt.org
+# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -10,6 +10,9 @@ PKG_NAME := flock
include $(INCLUDE_DIR)/host-build.mk
+HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
+
define Host/Compile
mkdir -p $(HOST_BUILD_DIR)
$(HOSTCC) $(HOST_CFLAGS) -o $(HOST_BUILD_DIR)/flock src/flock.c
diff --git a/tools/flock/src/flock.c b/tools/flock/src/flock.c
index 13baec46ca4..37ab0ea72da 100644
--- a/tools/flock/src/flock.c
+++ b/tools/flock/src/flock.c
@@ -39,6 +39,7 @@
#include <sys/file.h>
#include <sys/time.h>
#include <sys/wait.h>
+#include <fcntl.h>
#define PACKAGE_STRING "util-linux-ng 2.18"
#define _(x) (x)
@@ -132,6 +133,7 @@ int main(int argc, char *argv[])
int do_close = 0;
int err;
int status;
+ int open_flags = 0;
char *eon;
char **cmd_argv = NULL, *sh_c_argv[4];
const char *filename = NULL;
@@ -265,6 +267,21 @@ int main(int argc, char *argv[])
if ( timeout_expired )
exit(1); /* -w option set and failed to lock */
continue; /* otherwise try again */
+ case EBADF: /* since Linux 3.4 (commit 55725513) */
+ /* Probably NFSv4 where flock() is emulated by fcntl().
+ * Let's try to reopen in read-write mode.
+ */
+ if (!(open_flags & O_RDWR) &&
+ type != LOCK_SH &&
+ filename &&
+ access(filename, R_OK | W_OK) == 0) {
+
+ close(fd);
+ open_flags = O_RDWR;
+ fd = open(filename, open_flags);
+ break;
+ }
+ /* go through */
default: /* Other errors */
if ( filename )
fprintf(stderr, "%s: %s: %s\n", program, filename, strerror(err));
diff --git a/tools/genext2fs/Makefile b/tools/genext2fs/Makefile
index 1f69b2a6b6f..3a911df91a4 100644
--- a/tools/genext2fs/Makefile
+++ b/tools/genext2fs/Makefile
@@ -12,7 +12,7 @@ PKG_VERSION:=1.4.1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/genext2fs
-PKG_MD5SUM:=b7b6361bcce2cedff1ae437fadafe53b
+PKG_HASH:=404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc
include $(INCLUDE_DIR)/host-build.mk
@@ -36,6 +36,7 @@ HOST_CONFIGURE_ARGS = \
define Host/Compile
$(MAKE) -C $(HOST_BUILD_DIR) \
CFLAGS="$(HOST_CFLAGS)" \
+ LDFLAGS="$(HOST_LDFLAGS)" \
all
endef
diff --git a/tools/genext2fs/patches/100-c99_scanf.patch b/tools/genext2fs/patches/100-c99_scanf.patch
new file mode 100644
index 00000000000..e7aa17cc6fa
--- /dev/null
+++ b/tools/genext2fs/patches/100-c99_scanf.patch
@@ -0,0 +1,21 @@
+commit 3b8ca0ce9a0b58287a780747c90c449bdebfe464
+Author: Xavier Bestel <bestouff@users.sourceforge.net>
+Date: Mon Jan 14 08:52:44 2008 +0000
+
+ removed use of %as is scanf (GNU conflicts with C99) by Giacomo Catenazzi <cate@debian.org>
+
+diff --git a/genext2fs.c b/genext2fs.c
+index 070b270..f0d797d 100644
+--- a/genext2fs.c
++++ b/genext2fs.c
+@@ -286,7 +286,9 @@ typedef unsigned int uint32;
+ // older solaris. Note that this is still not very portable, in that
+ // the return value cannot be trusted.
+
+-#if SCANF_CAN_MALLOC
++#if 0 // SCANF_CAN_MALLOC
++// C99 define "a" for floating point, so you can have runtime surprise
++// according the library versions
+ # define SCANF_PREFIX "a"
+ # define SCANF_STRING(s) (&s)
+ #else
diff --git a/tools/genext2fs/patches/200-autoconf.patch b/tools/genext2fs/patches/200-autoconf.patch
new file mode 100644
index 00000000000..b3317bdd10a
--- /dev/null
+++ b/tools/genext2fs/patches/200-autoconf.patch
@@ -0,0 +1,13 @@
+Index: genext2fs/m4/ac_func_scanf_can_malloc.m4
+===================================================================
+--- genext2fs.orig/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:28:49.000000000 +0200
++++ genext2fs/m4/ac_func_scanf_can_malloc.m4 2011-09-03 21:29:41.000000000 +0200
+@@ -9,7 +9,7 @@
+ # --------------------------------------
+ AC_DEFUN([AC_FUNC_SCANF_CAN_MALLOC],
+ [ AC_CHECK_HEADERS([stdlib.h])
+- AC_CACHE_CHECK([whether scanf can malloc], [ac_scanf_can_malloc],
++ AC_CACHE_CHECK([whether scanf can malloc], [ac_cv_func_scanf_can_malloc],
+ [ AC_RUN_IFELSE(
+ [ AC_LANG_PROGRAM(
+ [
diff --git a/tools/genext2fs/patches/300-blocksize-creator.patch b/tools/genext2fs/patches/300-blocksize-creator.patch
new file mode 100644
index 00000000000..97a4836eeb2
--- /dev/null
+++ b/tools/genext2fs/patches/300-blocksize-creator.patch
@@ -0,0 +1,558 @@
+Index: genext2fs/genext2fs.c
+===================================================================
+--- genext2fs.orig/genext2fs.c 2011-09-03 14:21:17.000000000 +0200
++++ genext2fs/genext2fs.c 2011-09-03 14:21:17.000000000 +0200
+@@ -151,13 +151,24 @@
+
+ // block size
+
+-#define BLOCKSIZE 1024
++static int blocksize = 1024;
++
++#define BLOCKSIZE blocksize
+ #define BLOCKS_PER_GROUP 8192
+ #define INODES_PER_GROUP 8192
+ /* Percentage of blocks that are reserved.*/
+ #define RESERVED_BLOCKS 5/100
+ #define MAX_RESERVED_BLOCKS 25/100
+
++/* The default value for s_creator_os. */
++#if defined(__GNU__)
++# define CREATOR_OS 1 /* Hurd */
++#elif defined(__FreeBSD__)
++# define CREATOR_OS 3 /* FreeBSD */
++#else
++# define CREATOR_OS 0 /* Linux */
++#endif
++
+
+ // inode block size (why is it != BLOCKSIZE ?!?)
+ /* The field i_blocks in the ext2 inode stores the number of data blocks
+@@ -239,10 +250,10 @@
+ (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group)
+
+ // Get group block bitmap (bbm) given the group number
+-#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) )
++#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_block_bitmap) )
+
+ // Get group inode bitmap (ibm) given the group number
+-#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) )
++#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_inode_bitmap) )
+
+ // Given an inode number find the group it belongs to
+ #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group)
+@@ -532,7 +543,7 @@
+ char d_name[0];
+ } directory;
+
+-typedef uint8 block[BLOCKSIZE];
++typedef uint8 *block;
+
+ /* blockwalker fields:
+ The blockwalker is used to access all the blocks of a file (including
+@@ -571,16 +582,12 @@
+
+
+ /* Filesystem structure that support groups */
+-#if BLOCKSIZE == 1024
+ typedef struct
+ {
+- block zero; // The famous block 0
+- superblock sb; // The superblock
+- groupdescriptor gd[0]; // The group descriptors
++ uint8 zero[1024]; // Room for bootloader stuff
++ superblock sb; // The superblock, always at 1024
++ // group descriptors come next, see get_gd() below
+ } filesystem;
+-#else
+-#error UNHANDLED BLOCKSIZE
+-#endif
+
+ // now the endianness swap
+
+@@ -820,6 +827,14 @@
+ return (uint8*)fs + blk*BLOCKSIZE;
+ }
+
++// the group descriptors are aligned on the block size
++static inline groupdescriptor *
++get_gd(filesystem *fs, int no)
++{
++ int gdblk = (sizeof (filesystem) + BLOCKSIZE - 1) / BLOCKSIZE;
++ return ((groupdescriptor *) get_blk(fs, gdblk)) + no;
++}
++
+ // return a given inode from a filesystem
+ static inline inode *
+ get_nod(filesystem *fs, uint32 nod)
+@@ -829,7 +844,7 @@
+
+ offset = GRP_IBM_OFFSET(fs,nod);
+ grp = GRP_GROUP_OF_INODE(fs,nod);
+- itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table);
++ itab = (inode *)get_blk(fs, get_gd(fs,grp)->bg_inode_table);
+ return itab+offset-1;
+ }
+
+@@ -875,18 +890,18 @@
+
+ grp = GRP_GROUP_OF_INODE(fs,nod);
+ nbgroups = GRP_NBGROUPS(fs);
+- if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) {
++ if(!(bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0))) {
+ for(grp=0;grp<nbgroups && !bk;grp++)
+- bk=allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap),0);
++ bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0);
+ grp--;
+ }
+ if (!bk)
+ error_msg_and_die("couldn't allocate a block (no free space)");
+- if(!(fs->gd[grp].bg_free_blocks_count--))
++ if(!(get_gd(fs, grp)->bg_free_blocks_count--))
+ error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp);
+ if(!(fs->sb.s_free_blocks_count--))
+ error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
+- return fs->sb.s_blocks_per_group*grp + bk;
++ return fs->sb.s_first_data_block + fs->sb.s_blocks_per_group*grp + (bk-1);
+ }
+
+ // free a block
+@@ -897,8 +912,8 @@
+
+ grp = bk / fs->sb.s_blocks_per_group;
+ bk %= fs->sb.s_blocks_per_group;
+- deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk);
+- fs->gd[grp].bg_free_blocks_count++;
++ deallocate(GRP_GET_GROUP_BBM(fs, grp), bk);
++ get_gd(fs, grp)->bg_free_blocks_count++;
+ fs->sb.s_free_blocks_count++;
+ }
+
+@@ -918,16 +933,16 @@
+ /* We do it for all inodes. */
+ avefreei = fs->sb.s_free_inodes_count / nbgroups;
+ for(grp=0; grp<nbgroups; grp++) {
+- if (fs->gd[grp].bg_free_inodes_count < avefreei ||
+- fs->gd[grp].bg_free_inodes_count == 0)
++ if (get_gd(fs, grp)->bg_free_inodes_count < avefreei ||
++ get_gd(fs, grp)->bg_free_inodes_count == 0)
+ continue;
+ if (!best_group ||
+- fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count)
++ get_gd(fs, grp)->bg_free_blocks_count > get_gd(fs, best_group)->bg_free_blocks_count)
+ best_group = grp;
+ }
+- if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0)))
++ if (!(nod = allocate(GRP_GET_GROUP_IBM(fs, best_group), 0)))
+ error_msg_and_die("couldn't allocate an inode (no free inode)");
+- if(!(fs->gd[best_group].bg_free_inodes_count--))
++ if(!(get_gd(fs, best_group)->bg_free_inodes_count--))
+ error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)");
+ if(!(fs->sb.s_free_inodes_count--))
+ error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
+@@ -1390,7 +1405,7 @@
+ case FM_IFDIR:
+ add2dir(fs, nod, nod, ".");
+ add2dir(fs, nod, parent_nod, "..");
+- fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++;
++ get_gd(fs, GRP_GROUP_OF_INODE(fs,nod))->bg_used_dirs_count++;
+ break;
+ }
+ }
+@@ -1860,7 +1875,7 @@
+ swap_nod(nod);
+ }
+ for(i=0;i<GRP_NBGROUPS(fs);i++)
+- swap_gd(&(fs->gd[i]));
++ swap_gd(get_gd(fs, i));
+ swap_sb(&fs->sb);
+ }
+
+@@ -1870,7 +1885,7 @@
+ uint32 i;
+ swap_sb(&fs->sb);
+ for(i=0;i<GRP_NBGROUPS(fs);i++)
+- swap_gd(&(fs->gd[i]));
++ swap_gd(get_gd(fs, i));
+ for(i = 1; i < fs->sb.s_inodes_count; i++)
+ {
+ inode *nod = get_nod(fs, i);
+@@ -1895,7 +1910,8 @@
+
+ // initialize an empty filesystem
+ static filesystem *
+-init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp)
++init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
++ uint32 fs_timestamp, uint32 creator_os)
+ {
+ uint32 i;
+ filesystem *fs;
+@@ -1921,10 +1937,14 @@
+ */
+ min_nbgroups = (nbinodes + INODES_PER_GROUP - 1) / INODES_PER_GROUP;
+
++ /* On filesystems with 1k block size, the bootloader area uses a full
++ * block. For 2048 and up, the superblock can be fitted into block 0.
++ */
++ first_block = (BLOCKSIZE == 1024);
++
+ /* nbblocks is the total number of blocks in the filesystem.
+ * a block group can have no more than 8192 blocks.
+ */
+- first_block = (BLOCKSIZE == 1024);
+ nbgroups = (nbblocks - first_block + BLOCKS_PER_GROUP - 1) / BLOCKS_PER_GROUP;
+ if(nbgroups < min_nbgroups) nbgroups = min_nbgroups;
+ nbblocks_per_group = rndup((nbblocks - first_block + nbgroups - 1)/nbgroups, 8);
+@@ -1936,10 +1956,10 @@
+ gdsz = rndup(nbgroups*sizeof(groupdescriptor),BLOCKSIZE)/BLOCKSIZE;
+ itblsz = nbinodes_per_group * sizeof(inode)/BLOCKSIZE;
+ overhead_per_group = 3 /*sb,bbm,ibm*/ + gdsz + itblsz;
+- if((uint32)nbblocks - 1 < overhead_per_group * nbgroups)
+- error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page.");
+- free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/;
++ free_blocks = nbblocks - overhead_per_group*nbgroups - first_block;
+ free_blocks_per_group = nbblocks_per_group - overhead_per_group;
++ if(free_blocks < 0)
++ error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page.");
+
+ if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE)))
+ error_msg_and_die("not enough memory for filesystem");
+@@ -1959,28 +1979,31 @@
+ fs->sb.s_wtime = fs_timestamp;
+ fs->sb.s_magic = EXT2_MAGIC_NUMBER;
+ fs->sb.s_lastcheck = fs_timestamp;
++ fs->sb.s_creator_os = creator_os;
+
+ // set up groupdescriptors
+- for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1;
++ for(i=0, bbmpos=first_block+1+gdsz, ibmpos=bbmpos+1, itblpos=ibmpos+1;
+ i<nbgroups;
+ i++, bbmpos+=nbblocks_per_group, ibmpos+=nbblocks_per_group, itblpos+=nbblocks_per_group)
+ {
++ groupdescriptor *gd = get_gd(fs, i);
++
+ if(free_blocks > free_blocks_per_group) {
+- fs->gd[i].bg_free_blocks_count = free_blocks_per_group;
++ gd->bg_free_blocks_count = free_blocks_per_group;
+ free_blocks -= free_blocks_per_group;
+ } else {
+- fs->gd[i].bg_free_blocks_count = free_blocks;
++ gd->bg_free_blocks_count = free_blocks;
+ free_blocks = 0; // this is the last block group
+ }
+ if(i)
+- fs->gd[i].bg_free_inodes_count = nbinodes_per_group;
++ gd->bg_free_inodes_count = nbinodes_per_group;
+ else
+- fs->gd[i].bg_free_inodes_count = nbinodes_per_group -
++ gd->bg_free_inodes_count = nbinodes_per_group -
+ EXT2_FIRST_INO + 2;
+- fs->gd[i].bg_used_dirs_count = 0;
+- fs->gd[i].bg_block_bitmap = bbmpos;
+- fs->gd[i].bg_inode_bitmap = ibmpos;
+- fs->gd[i].bg_inode_table = itblpos;
++ gd->bg_used_dirs_count = 0;
++ gd->bg_block_bitmap = bbmpos;
++ gd->bg_inode_bitmap = ibmpos;
++ gd->bg_inode_table = itblpos;
+ }
+
+ /* Mark non-filesystem blocks and inodes as allocated */
+@@ -1988,9 +2011,9 @@
+ for(i = 0; i<nbgroups;i++) {
+
+ /* Block bitmap */
+- bbm = get_blk(fs,fs->gd[i].bg_block_bitmap);
++ bbm = GRP_GET_GROUP_BBM(fs, i);
+ //non-filesystem blocks
+- for(j = fs->gd[i].bg_free_blocks_count
++ for(j = get_gd(fs, i)->bg_free_blocks_count
+ + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++)
+ allocate(bbm, j);
+ //system blocks
+@@ -1998,7 +2021,7 @@
+ allocate(bbm, j);
+
+ /* Inode bitmap */
+- ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap);
++ ibm = GRP_GET_GROUP_IBM(fs, i);
+ //non-filesystem inodes
+ for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
+ allocate(ibm, j);
+@@ -2012,9 +2035,9 @@
+ // make root inode and directory
+ /* We have groups now. Add the root filesystem in group 0 */
+ /* Also increment the directory count for group 0 */
+- fs->gd[0].bg_free_inodes_count--;
+- fs->gd[0].bg_used_dirs_count = 1;
+- itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table);
++ get_gd(fs, 0)->bg_free_inodes_count--;
++ get_gd(fs, 0)->bg_used_dirs_count = 1;
++ itab0 = (inode *)get_blk(fs, get_gd(fs,0)->bg_inode_table);
+ itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH;
+ itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp;
+ itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp;
+@@ -2338,8 +2361,9 @@
+ for (i = 0; i < GRP_NBGROUPS(fs); i++) {
+ printf("Group No: %d\n", i+1);
+ printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n",
+- fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap,
+- fs->gd[i].bg_inode_table);
++ get_gd(fs, i)->bg_block_bitmap,
++ get_gd(fs, i)->bg_inode_bitmap,
++ get_gd(fs, i)->bg_inode_table);
+ printf("block bitmap allocation:\n");
+ print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group);
+ printf("inode bitmap allocation:\n");
+@@ -2421,10 +2445,12 @@
+ " -x, --starting-image <image>\n"
+ " -d, --root <directory>\n"
+ " -D, --devtable <file>\n"
++ " -B, --block-size <bytes>\n"
+ " -b, --size-in-blocks <blocks>\n"
+ " -i, --bytes-per-inode <bytes per inode>\n"
+ " -N, --number-of-inodes <number of inodes>\n"
+ " -m, --reserved-percentage <percentage of blocks to reserve>\n"
++ " -o, --creator-os <os> 'linux', 'hurd', 'freebsd' or a numerical value.\n"
+ " -g, --block-map <path> Generate a block map file for this path.\n"
+ " -e, --fill-value <value> Fill unallocated blocks with value.\n"
+ " -z, --allow-holes Allow files with holes.\n"
+@@ -2446,6 +2472,29 @@
+ extern char* optarg;
+ extern int optind, opterr, optopt;
+
++// parse the value for -o <os>
++int
++lookup_creator_os(const char *name)
++{
++ static const char *const creators[] =
++ {"linux", "hurd", "2", "freebsd", NULL};
++ char *endptr;
++ int i;
++
++ // numerical value ?
++ i = strtol(name, &endptr, 0);
++ if(name[0] && *endptr == '\0')
++ return i;
++
++ // symbolic name ?
++ for(i=0; creators[i]; i++)
++ if(strcasecmp(creators[i], name) == 0)
++ return i;
++
++ // whatever ?
++ return -1;
++}
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -2455,6 +2504,7 @@
+ float bytes_per_inode = -1;
+ float reserved_frac = -1;
+ int fs_timestamp = -1;
++ int creator_os = CREATOR_OS;
+ char * fsout = "-";
+ char * fsin = 0;
+ char * dopt[MAX_DOPT];
+@@ -2478,10 +2528,12 @@
+ { "starting-image", required_argument, NULL, 'x' },
+ { "root", required_argument, NULL, 'd' },
+ { "devtable", required_argument, NULL, 'D' },
++ { "block-size", required_argument, NULL, 'B' },
+ { "size-in-blocks", required_argument, NULL, 'b' },
+ { "bytes-per-inode", required_argument, NULL, 'i' },
+ { "number-of-inodes", required_argument, NULL, 'N' },
+ { "reserved-percentage", required_argument, NULL, 'm' },
++ { "creator-os", required_argument, NULL, 'o' },
+ { "block-map", required_argument, NULL, 'g' },
+ { "fill-value", required_argument, NULL, 'e' },
+ { "allow-holes", no_argument, NULL, 'z' },
+@@ -2497,11 +2549,11 @@
+
+ app_name = argv[0];
+
+- while((c = getopt_long(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) {
++ while((c = getopt_long(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv", longopts, NULL)) != EOF) {
+ #else
+ app_name = argv[0];
+
+- while((c = getopt(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv")) != EOF) {
++ while((c = getopt(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv")) != EOF) {
+ #endif /* HAVE_GETOPT_LONG */
+ switch(c)
+ {
+@@ -2512,6 +2564,9 @@
+ case 'D':
+ dopt[didx++] = optarg;
+ break;
++ case 'B':
++ blocksize = SI_atof(optarg);
++ break;
+ case 'b':
+ nbblocks = SI_atof(optarg);
+ break;
+@@ -2524,6 +2579,9 @@
+ case 'm':
+ reserved_frac = SI_atof(optarg) / 100;
+ break;
++ case 'o':
++ creator_os = lookup_creator_os(optarg);
++ break;
+ case 'g':
+ gopt[gidx++] = optarg;
+ break;
+@@ -2567,6 +2625,11 @@
+ error_msg_and_die("Not enough arguments. Try --help or else see the man page.");
+ fsout = argv[optind];
+
++ if(blocksize != 1024 && blocksize != 2048 && blocksize != 4096)
++ error_msg_and_die("Valid block sizes: 1024, 2048 or 4096.");
++ if(creator_os < 0)
++ error_msg_and_die("Creator OS unknown.");
++
+ hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s));
+ if (!hdlinks.hdl)
+ error_msg_and_die("Not enough memory");
+@@ -2611,7 +2674,8 @@
+ }
+ if(fs_timestamp == -1)
+ fs_timestamp = time(NULL);
+- fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp);
++ fs = init_fs(nbblocks, nbinodes, nbresrvd, holes,
++ fs_timestamp, creator_os);
+ }
+
+ populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);
+Index: genext2fs/test-gen.lib
+===================================================================
+--- genext2fs.orig/test-gen.lib 2011-09-03 13:40:35.000000000 +0200
++++ genext2fs/test-gen.lib 2011-09-03 14:21:17.000000000 +0200
+@@ -8,7 +8,7 @@
+ # Creates an image with a file of given size
+ # Usage: dgen file-size number-of-blocks
+ dgen () {
+- size=$1; blocks=$2
++ size=$1; blocks=$2; blocksz=$3;
+ rm -rf test
+ mkdir -p test
+ cd test
+@@ -20,7 +20,7 @@
+ chmod 777 file.$1
+ TZ=UTC-11 touch -t 200502070321.43 file.$1 .
+ cd ..
+- ./genext2fs -N 17 -b $blocks -d test -f -q ext2.img
++ ./genext2fs -B $blocksz -N 17 -b $blocks -d test -f -o Linux -q ext2.img
+ }
+
+ # fgen - Exercises the -f spec-file option of genext2fs
+@@ -31,7 +31,7 @@
+ mkdir -p test
+ cp $fname test
+ TZ=UTC-11 touch -t 200502070321.43 test/$fname
+- ./genext2fs -N 92 -b $blocks -D test/$fname -f ext2.img
++ ./genext2fs -N 92 -b $blocks -D test/$fname -f -o Linux ext2.img
+ }
+
+ # gen_cleanup - Remove the files generated by the above functions
+Index: genext2fs/test-mount.sh
+===================================================================
+--- genext2fs.orig/test-mount.sh 2011-09-03 13:40:35.000000000 +0200
++++ genext2fs/test-mount.sh 2011-09-03 14:21:17.000000000 +0200
+@@ -33,9 +33,9 @@
+ # and returns the command line with which to invoke dtest()
+ # Usage: dtest-mount file-size number-of-blocks
+ dtest_mount () {
+- size=$1; blocks=$2
+- echo Testing with file of size $size
+- dgen $size $blocks
++ size=$1; blocks=$2; blocksz=$3;
++ echo Testing $blocks blocks of $blocksz bytes with file of size $size
++ dgen $size $blocks $blocksz
+ /sbin/e2fsck -fn ext2.img || fail
+ mkdir -p mnt
+ mount -t ext2 -o ro,loop ext2.img mnt || fail
+@@ -44,7 +44,7 @@
+ awk '{print $5}'`" ] ; then
+ fail
+ fi
+- pass dtest $size $blocks
++ pass dtest $size $blocks $blocksz
+ }
+
+ # ftest-mount - Exercise the -f spec-file option of genext2fs
+@@ -75,13 +75,21 @@
+ pass ftest $fname $blocks
+ }
+
+-dtest_mount 0 4096
+-dtest_mount 0 8193
+-dtest_mount 0 8194
+-dtest_mount 1 4096
+-dtest_mount 12288 4096
+-dtest_mount 274432 4096
+-dtest_mount 8388608 9000
+-dtest_mount 16777216 20000
++dtest_mount 0 4096 1024
++dtest_mount 0 2048 2048
++dtest_mount 0 1024 4096
++dtest_mount 0 8193 1024
++dtest_mount 0 8194 1024
++dtest_mount 0 8193 4096
++dtest_mount 0 8194 2048
++dtest_mount 1 4096 1024
++dtest_mount 1 1024 4096
++dtest_mount 12288 4096 1024
++dtest_mount 274432 4096 1024
++dtest_mount 8388608 9000 1024
++dtest_mount 8388608 4500 2048
++dtest_mount 8388608 2250 4096
++dtest_mount 16777216 20000 1024
++dtest_mount 16777216 10000 2048
+
+ ftest_mount device_table.txt 4096
+Index: genext2fs/test.sh
+===================================================================
+--- genext2fs.orig/test.sh 2011-09-03 13:40:35.000000000 +0200
++++ genext2fs/test.sh 2011-09-03 14:21:17.000000000 +0200
+@@ -30,9 +30,9 @@
+ # Creates an image with a file of given size and verifies it
+ # Usage: dtest file-size number-of-blocks correct-checksum
+ dtest () {
+- size=$1; blocks=$2; checksum=$3
++ size=$1; blocks=$2; blocksz=$3; checksum=$4
+ echo Testing with file of size $size
+- dgen $size $blocks
++ dgen $size $blocks $blocksz
+ md5cmp $checksum
+ gen_cleanup
+ }
+@@ -53,12 +53,20 @@
+ # replace the following lines with the output of
+ # sudo sh test-mount.sh|grep test
+
+-dtest 0 4096 3bc6424b8fcd51a0de34ee59d91d5f16
+-dtest 0 8193 f174804f6b433b552706cbbfc60c416d
+-dtest 0 8194 4855a55d0cbdc44584634df49ebd5711
+-dtest 1 4096 09c569b6bfb45222c729c42d04d5451f
+-dtest 12288 4096 61febcbfbf32024ef99103fcdc282c39
+-dtest 274432 4096 0c517803552c55c1806e4220b0a0164f
+-dtest 8388608 9000 e0e5ea15bced10ab486d8135584b5d8e
+-dtest 16777216 20000 fdf636eb905ab4dc1bf76dce5ac5d209
++dtest 0 4096 1024 3bc6424b8fcd51a0de34ee59d91d5f16
++dtest 0 2048 2048 230afa16496df019878cc2370c661cdc
++dtest 0 1024 4096 ebff5eeb38b70f3f1cd081e60eb44561
++dtest 0 8193 1024 f174804f6b433b552706cbbfc60c416d
++dtest 0 8194 1024 4855a55d0cbdc44584634df49ebd5711
++dtest 0 8193 4096 c493679698418ec7e6552005e2d2a6d8
++dtest 0 8194 2048 ec13f328fa7543563f35f494bddc059c
++dtest 1 4096 1024 09c569b6bfb45222c729c42d04d5451f
++dtest 1 1024 4096 d318a326fdc907810ae9e6b0a20e9b06
++dtest 12288 4096 1024 61febcbfbf32024ef99103fcdc282c39
++dtest 274432 4096 1024 0c517803552c55c1806e4220b0a0164f
++dtest 8388608 9000 1024 e0e5ea15bced10ab486d8135584b5d8e
++dtest 8388608 4500 2048 39f4d537a72f5053fd6891721c59680d
++dtest 8388608 2250 4096 1d697fa4bc2cfffe02ac91edfadc40bf
++dtest 16777216 20000 1024 fdf636eb905ab4dc1bf76dce5ac5d209
++dtest 16777216 10000 2048 f9824a81ea5e74fdf469c097927c292b
+ ftest device_table.txt 4096 a0af06d944b11d2902dfd705484c64cc
diff --git a/tools/genext2fs/patches/400-byteswap_fix.patch b/tools/genext2fs/patches/400-byteswap_fix.patch
new file mode 100644
index 00000000000..7b3c00b5ee0
--- /dev/null
+++ b/tools/genext2fs/patches/400-byteswap_fix.patch
@@ -0,0 +1,44 @@
+Index: genext2fs/genext2fs.c
+===================================================================
+--- genext2fs.orig/genext2fs.c 2011-11-29 17:36:06.000000000 +0100
++++ genext2fs/genext2fs.c 2011-11-29 17:37:37.000000000 +0100
+@@ -1779,7 +1779,8 @@
+ assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
+ for(i = 0; i < BLOCKSIZE/4; i++)
+ if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
+- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])
++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
+ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
+ if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
+ return;
+@@ -1792,7 +1793,8 @@
+ (BLOCKSIZE/4)*(BLOCKSIZE/4) +
+ i*(BLOCKSIZE/4)*(BLOCKSIZE/4) +
+ j*(BLOCKSIZE/4)) )
+- swap_block(get_blk(fs,b2[j]));
++ if (b2[j])
++ swap_block(get_blk(fs,b2[j]));
+ else {
+ done = 1;
+ break;
+@@ -1825,7 +1827,8 @@
+ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
+ for(i = 0; i < BLOCKSIZE/4; i++)
+ if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
+- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
++ if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])
++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
+ if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
+ return;
+ /* Adding support for triple indirection */
+@@ -1839,7 +1842,8 @@
+ (BLOCKSIZE/4)*(BLOCKSIZE/4) +
+ i*(BLOCKSIZE/4)*(BLOCKSIZE/4) +
+ j*(BLOCKSIZE/4)) )
+- swap_block(get_blk(fs,b2[j]));
++ if (b2[j])
++ swap_block(get_blk(fs,b2[j]));
+ else {
+ done = 1;
+ break;
diff --git a/tools/gengetopt/Makefile b/tools/gengetopt/Makefile
new file mode 100644
index 00000000000..6d2b85e6582
--- /dev/null
+++ b/tools/gengetopt/Makefile
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licengengetopt under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gengetopt
+PKG_VERSION:=2.22.6
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
+PKG_HASH:=30b05a88604d71ef2a42a2ef26cd26df242b41f5b011ad03083143a31d9b01f7
+
+HOST_FIXUP := autoreconf
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/gengetopt $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/gengetopt
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/gengetopt/patches/100-dependency_fix.patch b/tools/gengetopt/patches/100-dependency_fix.patch
new file mode 100644
index 00000000000..69cb598b7d8
--- /dev/null
+++ b/tools/gengetopt/patches/100-dependency_fix.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -51,7 +51,7 @@ libgengetopt_la_LIBADD = $(top_builddir)
+ @LTLIBOBJS@ \
+ skels/libgen.la
+
+-LDADD = $(top_builddir)/src/libgengetopt.la
++LDADD = libgengetopt.la
+
+ EXTRA_DIST = parser.h argsdef.h gengetopt.h ggos.h gm.h gnugetopt.h \
+ cmdline.c cmdline.h \
diff --git a/tools/gengetopt/patches/200-no_docs_tests.patch b/tools/gengetopt/patches/200-no_docs_tests.patch
new file mode 100644
index 00000000000..d3930696ffe
--- /dev/null
+++ b/tools/gengetopt/patches/200-no_docs_tests.patch
@@ -0,0 +1,13 @@
+diff -urN gengetopt-2.22.6/Makefile.am gengetopt-2.22.6.new/Makefile.am
+--- gengetopt-2.22.6/Makefile.am 2012-11-02 06:26:54.000000000 -0700
++++ gengetopt-2.22.6.new/Makefile.am 2015-05-21 17:43:15.183083542 -0700
+@@ -18,6 +18,6 @@
+ ACLOCAL_AMFLAGS = -I m4 -I gl/m4
+
+ EXTRA_DIST = configure TODO LICENSE gl/m4/gnulib-cache.m4
+-SUBDIRS = gl src doc tests
++SUBDIRS = gl src
+
+-gengetoptdoc_DATA = ChangeLog COPYING NEWS THANKS INSTALL README LICENSE
+\ No newline at end of file
++gengetoptdoc_DATA = ChangeLog COPYING NEWS THANKS INSTALL README LICENSE
diff --git a/tools/gmp/Makefile b/tools/gmp/Makefile
index 1bee5f2b1f9..19dc8215f3f 100644
--- a/tools/gmp/Makefile
+++ b/tools/gmp/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 -2010 OpenWrt.org
+# Copyright (C) 2009-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,11 +7,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gmp
-PKG_VERSION:=5.0.1
+PKG_VERSION:=6.1.2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/gmp/
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=6bac6df75c192a13419dfd71d19240a7
+PKG_HASH:=87b565e89a9a684fe4ebeeddb8399dce2599f9c9049854ca8c0dfbdea0e21912
+
+HOST_FIXUP:=autoreconf
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
@@ -20,7 +24,12 @@ unexport CFLAGS
HOST_CONFIGURE_ARGS += \
--enable-static \
--disable-shared \
+ --disable-assembly \
--enable-cxx \
--enable-mpbsd
+ifeq ($(GNU_HOST_NAME),x86_64-linux-gnux32)
+HOST_CONFIGURE_ARGS += ABI=x32
+endif
+
$(eval $(call HostBuild))
diff --git a/tools/gmp/patches/000-OE-amd64.patch b/tools/gmp/patches/000-OE-amd64.patch
deleted file mode 100644
index 957a7224eac..00000000000
--- a/tools/gmp/patches/000-OE-amd64.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Index: gmp-5.0.1/longlong.h
-===================================================================
---- gmp-5.0.1.orig/longlong.h
-+++ gmp-5.0.1/longlong.h
-@@ -849,8 +849,10 @@ extern UWtype __MPN(udiv_qrnnd) _PROTO (
- count is only an int. */
- #define count_trailing_zeros(count, x) \
- do { \
-+ UDItype __cbtmp; \
- ASSERT ((x) != 0); \
-- __asm__ ("bsfq %1,%q0" : "=r" (count) : "rm" ((UDItype)(x))); \
-+ __asm__ ("bsfq %1,%0" : "=r" (__cbtmp) : "rm" ((UDItype)(x))); \
-+ (count) = __cbtmp; \
- } while (0)
- #endif /* x86_64 */
-
diff --git a/tools/gmp/patches/000-OE-configure.patch b/tools/gmp/patches/000-OE-configure.patch
deleted file mode 100644
index f89ce0770ee..00000000000
--- a/tools/gmp/patches/000-OE-configure.patch
+++ /dev/null
@@ -1,193 +0,0 @@
-diff -rdup gmp-5.0.1.oorig/acinclude.m4 gmp-5.0.1/acinclude.m4
---- gmp-5.0.1.oorig/acinclude.m4 2010-02-06 13:43:13.000000000 +0100
-+++ gmp-5.0.1/acinclude.m4 2010-02-08 17:19:44.000000000 +0100
-@@ -30,23 +30,23 @@ dnl a_out.exe - OpenVMS DEC C called
- dnl conftest.exe - various DOS compilers
-
-
--define(IA64_PATTERN,
-+define([IA64_PATTERN],
- [[ia64*-*-* | itanium-*-* | itanium2-*-*]])
-
- dnl Need to be careful not to match m6811, m6812, m68hc11 and m68hc12, all
- dnl of which config.sub accepts. (Though none of which are likely to work
- dnl with GMP.)
- dnl
--define(M68K_PATTERN,
-+define([M68K_PATTERN],
- [[m68k-*-* | m68[0-9][0-9][0-9]-*-*]])
-
--define(POWERPC64_PATTERN,
-+define([POWERPC64_PATTERN],
- [[powerpc64-*-* | powerpc64le-*-* | powerpc620-*-* | powerpc630-*-* | powerpc970-*-* | power[3-9]-*-*]])
-
--define(X86_PATTERN,
-+define([X86_PATTERN],
- [[i?86*-*-* | k[5-8]*-*-* | pentium*-*-* | athlon-*-* | viac3*-*-* | geode*-*-* | atom-*-*]])
-
--define(X86_64_PATTERN,
-+define([X86_64_PATTERN],
- [[athlon64-*-* | pentium4-*-* | atom-*-* | core2-*-* | corei-*-* | x86_64-*-* | nano-*-*]])
-
- dnl GMP_FAT_SUFFIX(DSTVAR, DIRECTORY)
-@@ -64,7 +64,7 @@ dnl x86 -> x86
- dnl x86/k6 -> k6
- dnl x86/k6/mmx -> k6_mmx
-
--define(GMP_FAT_SUFFIX,
-+define([GMP_FAT_SUFFIX],
- [[$1=`echo $2 | sed -e '/\//s:^[^/]*/::' -e 's:[\\/]:_:g'`]])
-
-
-@@ -73,7 +73,7 @@ dnl ----------------------------------
- dnl Emit code to remove any occurrence of ITEM from $LISTVAR. ITEM can be a
- dnl shell expression like $foo if desired.
-
--define(GMP_REMOVE_FROM_LIST,
-+define([GMP_REMOVE_FROM_LIST],
- [remove_from_list_tmp=
- for remove_from_list_i in $[][$1]; do
- if test $remove_from_list_i = [$2]; then :;
-@@ -89,12 +89,12 @@ dnl GMP_STRIP_PATH(subdir)
- dnl ----------------------
- dnl Strip entries */subdir from $path and $fat_path.
-
--define(GMP_STRIP_PATH,
-+define([GMP_STRIP_PATH],
- [GMP_STRIP_PATH_VAR(path, [$1])
- GMP_STRIP_PATH_VAR(fat_path, [$1])
- ])
-
--define(GMP_STRIP_PATH_VAR,
-+define([GMP_STRIP_PATH_VAR],
- [tmp_path=
- for i in $[][$1]; do
- case $i in
-@@ -115,7 +115,7 @@ dnl
- dnl Dummy value for GMP_LIMB_BITS is enough
- dnl for all current configure-time uses of gmp.h.
-
--define(GMP_INCLUDE_GMP_H,
-+define([GMP_INCLUDE_GMP_H],
- [[#define __GMP_WITHIN_CONFIGURE 1 /* ignore template stuff */
- #define GMP_NAIL_BITS $GMP_NAIL_BITS
- #define GMP_LIMB_BITS 123
-@@ -130,7 +130,7 @@ dnl Expand at autoconf time to the valu
- dnl FILE. The regexps here aren't very rugged, but are enough for gmp.
- dnl /dev/null as a parameter prevents a hang if $2 is accidentally omitted.
-
--define(GMP_HEADER_GETVAL,
-+define([GMP_HEADER_GETVAL],
- [patsubst(patsubst(
- esyscmd([grep "^#define $1 " $2 /dev/null 2>/dev/null]),
- [^.*$1[ ]+],[]),
-@@ -144,7 +144,7 @@ dnl The gmp version number, extracted f
- dnl autoconf time. Two digits like 3.0 if patchlevel <= 0, or three digits
- dnl like 3.0.1 if patchlevel > 0.
-
--define(GMP_VERSION,
-+define([GMP_VERSION],
- [GMP_HEADER_GETVAL(__GNU_MP_VERSION,gmp-h.in)[]dnl
- .GMP_HEADER_GETVAL(__GNU_MP_VERSION_MINOR,gmp-h.in)[]dnl
- .GMP_HEADER_GETVAL(__GNU_MP_VERSION_PATCHLEVEL,gmp-h.in)])
-@@ -1506,7 +1506,9 @@ esac
- echo ["define(<CONFIG_TOP_SRCDIR>,<\`$tmp'>)"] >>$gmp_tmpconfigm4
-
- # All CPUs use asm-defs.m4
--echo ["include][(CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4')"] >>$gmp_tmpconfigm4i
-+echo -n ["include("] >>$gmp_tmpconfigm4i
-+echo -n ["CONFIG_TOP_SRCDIR\`/mpn/asm-defs.m4'"] >>$gmp_tmpconfigm4i
-+echo [")"] >>$gmp_tmpconfigm4i
- ])
-
-
-diff -rdup gmp-5.0.1.oorig/configure.in gmp-5.0.1/configure.in
---- gmp-5.0.1.oorig/configure.in 2010-02-06 13:43:13.000000000 +0100
-+++ gmp-5.0.1/configure.in 2010-02-08 17:18:30.000000000 +0100
-@@ -29,12 +29,6 @@ AC_REVISION($Revision$)
- AC_PREREQ(2.59)
- AC_INIT(GNU MP, GMP_VERSION, gmp-bugs@gmplib.org, gmp)
- AC_CONFIG_SRCDIR(gmp-impl.h)
--m4_pattern_forbid([^[ \t]*GMP_])
--m4_pattern_allow(GMP_LDFLAGS)
--m4_pattern_allow(GMP_LIMB_BITS)
--m4_pattern_allow(GMP_MPARAM_H_SUGGEST)
--m4_pattern_allow(GMP_NAIL_BITS)
--m4_pattern_allow(GMP_NUMB_BITS)
-
- # If --target is not used then $target_alias is empty, but if say
- # "./configure athlon-pc-freebsd3.5" is used, then all three of
-@@ -303,7 +297,7 @@ AH_VERBATIM([HAVE_HOST_CPU_1],
- # After GMP specific searches and tests, the standard autoconf AC_PROG_CC is
- # called. User selections of CC etc are respected.
- #
--# Care is taken not to use macros like AC_TRY_COMPILE during the GMP
-+# Care is taken not to use macros like AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) during the GMP
- # pre-testing, since they of course depend on AC_PROG_CC, and also some of
- # them cache their results, which is not wanted.
- #
-@@ -395,7 +389,7 @@ abilist="standard"
- # FIXME: We'd like to prefer an ANSI compiler, perhaps by preferring
- # c89 over cc here. But note that on HP-UX c89 provides a castrated
- # environment, and would want to be excluded somehow. Maybe
--# AC_PROG_CC_STDC already does enough to stick cc into ANSI mode and
-+# already does enough to stick cc into ANSI mode and
- # we don't need to worry.
- #
- cclist="gcc cc"
-@@ -1580,7 +1574,7 @@ esac
- CFLAGS_or_unset=${CFLAGS-'(unset)'}
- CPPFLAGS_or_unset=${CPPFLAGS-'(unset)'}
-
--cat >&AC_FD_CC <<EOF
-+cat >&AS_MESSAGE_LOG_FD() <<EOF
- User:
- ABI=$ABI
- CC=$CC
-@@ -1987,7 +1981,6 @@ AC_SUBST(DEFN_LONG_LONG_LIMB)
-
- # The C compiler and preprocessor, put into ANSI mode if possible.
- AC_PROG_CC
--AC_PROG_CC_STDC
- AC_PROG_CPP
- GMP_H_ANSI
-
-@@ -2010,11 +2003,11 @@ AC_SUBST(CCAS)
-
- # The C++ compiler, if desired.
- want_cxx=no
-+AC_PROG_CXX
- if test $enable_cxx != no; then
- test_CXXFLAGS=${CXXFLAGS+set}
-- AC_PROG_CXX
-
-- echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&AC_FD_CC
-+ echo "CXXFLAGS chosen by autoconf: $CXXFLAGS" >&AS_MESSAGE_LOG_FD()
- cxxflags_ac_prog_cxx=$CXXFLAGS
- cxxflags_list=ac_prog_cxx
-
-@@ -2120,7 +2113,7 @@ case $host in
- esac
-
-
--cat >&AC_FD_CC <<EOF
-+cat >&AS_MESSAGE_LOG_FD() <<EOF
- Decided:
- ABI=$ABI
- CC=$CC
-@@ -3376,7 +3369,7 @@ GMP_FINISH
- # FIXME: Upcoming version of autoconf/automake may not like broken lines.
- # Right now automake isn't accepting the new AC_CONFIG_FILES scheme.
-
--AC_OUTPUT(Makefile \
-+AC_CONFIG_FILES([Makefile \
- mpbsd/Makefile mpf/Makefile mpn/Makefile mpq/Makefile \
- mpz/Makefile printf/Makefile scanf/Makefile cxx/Makefile \
- tests/Makefile tests/devel/Makefile tests/mpbsd/Makefile \
-@@ -3385,4 +3378,5 @@ AC_OUTPUT(Makefile \
- tests/cxx/Makefile \
- doc/Makefile tune/Makefile \
- demos/Makefile demos/calc/Makefile demos/expr/Makefile \
-- gmp.h:gmp-h.in mp.h:mp-h.in)
-+ gmp.h:gmp-h.in mp.h:mp-h.in])
-+AC_OUTPUT
diff --git a/tools/include/byteswap.h b/tools/include/byteswap.h
index fe279ceb2c0..015f09740ad 100644
--- a/tools/include/byteswap.h
+++ b/tools/include/byteswap.h
@@ -1,3 +1,5 @@
#if defined(__linux__) || defined(__CYGWIN__)
#include_next <byteswap.h>
+#else
+#include <endian.h>
#endif
diff --git a/tools/sstrip/include/elf.h b/tools/include/elf.h
index eae96d00037..036a176345e 100644
--- a/tools/sstrip/include/elf.h
+++ b/tools/include/elf.h
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+ Copyright (C) 1995-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -13,15 +13,12 @@
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#ifndef _ELF_H
#define _ELF_H 1
-__BEGIN_DECLS
-
/* Standard ELF types. */
#include <stdint.h>
@@ -139,7 +136,8 @@ typedef struct
#define ELFOSABI_SYSV 0 /* Alias. */
#define ELFOSABI_HPUX 1 /* HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD. */
-#define ELFOSABI_LINUX 3 /* Linux. */
+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
#define ELFOSABI_AIX 7 /* IBM AIX. */
#define ELFOSABI_IRIX 8 /* SGI Irix. */
@@ -147,6 +145,7 @@ typedef struct
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
@@ -246,7 +245,9 @@ typedef struct
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
-#define EM_NUM 95
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_NUM 192
/* If it is necessary to assign new unofficial EM_* values, please
pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
@@ -295,6 +296,10 @@ typedef struct
#define SHN_UNDEF 0 /* Undefined section */
#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
#define SHN_LOPROC 0xff00 /* Start of processor-specific */
+#define SHN_BEFORE 0xff00 /* Order section before all others
+ (Solaris). */
+#define SHN_AFTER 0xff01 /* Order section after all others
+ (Solaris). */
#define SHN_HIPROC 0xff1f /* End of processor-specific */
#define SHN_LOOS 0xff20 /* Start of OS-specific */
#define SHN_HIOS 0xff3f /* End of OS-specific */
@@ -323,7 +328,9 @@ typedef struct
#define SHT_GROUP 17 /* Section group */
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
#define SHT_NUM 19 /* Number of defined types. */
-#define SHT_LOOS 0x60000000 /* Start OS-specific */
+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
@@ -355,6 +362,10 @@ typedef struct
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
+ (Solaris). */
+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+ referenced or allocated (Solaris).*/
/* Section group handling. */
#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
@@ -431,6 +442,7 @@ typedef struct
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types. */
#define STB_LOOS 10 /* Start of OS-specific */
+#define STB_GNU_UNIQUE 10 /* Unique symbol. */
#define STB_HIOS 12 /* End of OS-specific */
#define STB_LOPROC 13 /* Start of processor-specific */
#define STB_HIPROC 15 /* End of processor-specific */
@@ -446,6 +458,7 @@ typedef struct
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_LOOS 10 /* Start of OS-specific */
+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
#define STT_HIOS 12 /* End of OS-specific */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */
@@ -543,6 +556,12 @@ typedef struct
Elf64_Xword p_align; /* Segment alignment */
} Elf64_Phdr;
+/* Special value for e_phnum. This indicates that the real number of
+ program headers is too large to fit into e_phnum. Instead the real
+ value is in the field sh_info of section 0. */
+
+#define PN_XNUM 0xffff
+
/* Legal values for p_type (segment type). */
#define PT_NULL 0 /* Program header table entry unused */
@@ -557,6 +576,7 @@ typedef struct
#define PT_LOOS 0x60000000 /* Start of OS-specific */
#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
@@ -590,7 +610,14 @@ typedef struct
#define NT_UTSNAME 15 /* Contains copy of utsname struct */
#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
-#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct*/
+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
/* Legal values for the note segment descriptor types for object files. */
@@ -688,6 +715,9 @@ typedef struct
If any adjustment is made to the ELF object after it has been
built these entries will need to be adjusted. */
#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
+#define DT_TLSDESC_PLT 0x6ffffef6
+#define DT_TLSDESC_GOT 0x6ffffef7
#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
#define DT_CONFIG 0x6ffffefa /* Configuration information. */
@@ -698,7 +728,7 @@ typedef struct
#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
#define DT_ADDRRNGHI 0x6ffffeff
#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
-#define DT_ADDRNUM 10
+#define DT_ADDRNUM 11
/* The versioning entry types. The next are defined as part of the
GNU extension. */
@@ -888,23 +918,25 @@ typedef struct
typedef struct
{
- int a_type; /* Entry type */
+ uint32_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint32_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf32_auxv_t;
typedef struct
{
- long int a_type; /* Entry type */
+ uint64_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint64_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf64_auxv_t;
@@ -947,11 +979,23 @@ typedef struct
#define AT_SECURE 23 /* Boolean, was exec setuid-like? */
+#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/
+
+#define AT_RANDOM 25 /* Address of 16 random bytes. */
+
+#define AT_EXECFN 31 /* Filename of executable. */
+
/* Pointer to the global system page used for system calls and other
nice things. */
#define AT_SYSINFO 32
#define AT_SYSINFO_EHDR 33
+/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains
+ log2 of line size; mask those to get cache size. */
+#define AT_L1I_CACHESHAPE 34
+#define AT_L1D_CACHESHAPE 35
+#define AT_L2_CACHESHAPE 36
+#define AT_L3_CACHESHAPE 37
/* Note section contents. Each entry in the note section begins with
a header of a fixed form. */
@@ -993,15 +1037,31 @@ typedef struct
word 2: minor version of the ABI
word 3: subminor version of the ABI
*/
-#define ELF_NOTE_ABI 1
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
-/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI
- note section entry. */
+/* Known OSes. These values can appear in word 0 of an
+ NT_GNU_ABI_TAG note section entry. */
#define ELF_NOTE_OS_LINUX 0
#define ELF_NOTE_OS_GNU 1
#define ELF_NOTE_OS_SOLARIS2 2
#define ELF_NOTE_OS_FREEBSD 3
+/* Synthetic hwcap information. The descriptor begins with two words:
+ word 0: number of entries
+ word 1: bitmask of enabled entries
+ Then follow variable-length entries, one byte followed by a
+ '\0'-terminated hwcap name string. The byte gives the bit
+ number to test if enabled, (1U << bit) & bitmask. */
+#define NT_GNU_HWCAP 2
+
+/* Build ID bits as generated by ld --build-id.
+ The descriptor consists of any nonzero number of bytes. */
+#define NT_GNU_BUILD_ID 3
+
+/* Version note generated by GNU gold containing a version string. */
+#define NT_GNU_GOLD_VERSION 4
+
/* Move records. */
typedef struct
@@ -1062,8 +1122,29 @@ typedef struct
#define R_68K_GLOB_DAT 20 /* Create GOT entry */
#define R_68K_JMP_SLOT 21 /* Create PLT entry */
#define R_68K_RELATIVE 22 /* Adjust by program base */
+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
/* Keep this the last entry. */
-#define R_68K_NUM 23
+#define R_68K_NUM 43
/* Intel 80386 specific definitions. */
@@ -1117,14 +1198,24 @@ typedef struct
#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
+/* 38? */
+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
+ descriptor for
+ relaxation. */
+#define R_386_TLS_DESC 41 /* TLS descriptor containing
+ pointer to code and to
+ argument, returning the TLS
+ offset for the symbol. */
+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
/* Keep this the last entry. */
-#define R_386_NUM 38
+#define R_386_NUM 43
/* SUN SPARC specific definitions. */
/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-#define STT_REGISTER 13 /* Global register reserved to app. */
+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
/* Values for Elf64_Ehdr.e_flags. */
@@ -1186,6 +1277,7 @@ typedef struct
#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
#define R_SPARC_7 43 /* Direct 7 bit */
#define R_SPARC_5 44 /* Direct 5 bit */
#define R_SPARC_6 45 /* Direct 6 bit */
@@ -1223,23 +1315,28 @@ typedef struct
#define R_SPARC_TLS_DTPOFF64 77
#define R_SPARC_TLS_TPOFF32 78
#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_WDISP10 88
+#define R_SPARC_JMP_IREL 248
+#define R_SPARC_IRELATIVE 249
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
/* Keep this the last entry. */
-#define R_SPARC_NUM 80
+#define R_SPARC_NUM 253
/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
#define DT_SPARC_REGISTER 0x70000001
#define DT_SPARC_NUM 2
-/* Bits present in AT_HWCAP, primarily for Sparc32. */
-
-#define HWCAP_SPARC_FLUSH 1 /* The cpu supports flush insn. */
-#define HWCAP_SPARC_STBAR 2
-#define HWCAP_SPARC_SWAP 4
-#define HWCAP_SPARC_MULDIV 8
-#define HWCAP_SPARC_V9 16 /* The cpu is v9, so v8plus is ok. */
-#define HWCAP_SPARC_ULTRA3 32
-
/* MIPS R3000 specific definitions. */
/* Legal values for e_flags field of Elf32_Ehdr. */
@@ -1342,6 +1439,7 @@ typedef struct
#define STO_MIPS_INTERNAL 0x1
#define STO_MIPS_HIDDEN 0x2
#define STO_MIPS_PROTECTED 0x3
+#define STO_MIPS_PLT 0x8
#define STO_MIPS_SC_ALIGN_UNUSED 0xff
/* MIPS specific values for `st_info'. */
@@ -1474,8 +1572,24 @@ typedef struct
#define R_MIPS_PJUMP 35
#define R_MIPS_RELGOT 36
#define R_MIPS_JALR 37
+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
/* Keep this the last entry. */
-#define R_MIPS_NUM 38
+#define R_MIPS_NUM 128
/* Legal values for p_type field of Elf32_Phdr. */
@@ -1541,7 +1655,13 @@ typedef struct
#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
-#define DT_MIPS_NUM 0x32
+/* The address of .got.plt in an executable using the new non-PIC ABI. */
+#define DT_MIPS_PLTGOT 0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+ PLT is writable. For a non-writable PLT, this is omitted or has a zero
+ value. */
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_NUM 0x35
/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
@@ -1671,6 +1791,8 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
#define R_PARISC_FPTR64 64 /* 64 bits function address. */
#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
@@ -1731,6 +1853,26 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_GNU_VTENTRY 232
+#define R_PARISC_GNU_VTINHERIT 233
+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
#define R_PARISC_HIRESERVE 255
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
@@ -1834,6 +1976,9 @@ typedef Elf32_Addr Elf32_Conflict;
#define LITUSE_ALPHA_TLS_GD 4
#define LITUSE_ALPHA_TLS_LDM 5
+/* Legal values for d_tag of Elf64_Dyn. */
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
/* PowerPC specific declarations */
@@ -1914,9 +2059,6 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-/* Keep this the last entry. */
-#define R_PPC_NUM 95
-
/* The remaining relocs are from the Embedded ELF ABI, and are not
in the SVR4 ELF ABI. */
#define R_PPC_EMB_NADDR32 101
@@ -1944,10 +2086,22 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+/* GNU extension to support local ifunc. */
+#define R_PPC_IRELATIVE 248
+
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
+
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
@@ -2061,52 +2215,83 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
-/* Keep this the last entry. */
-#define R_PPC64_NUM 107
+/* GNU extension to support local ifunc. */
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
/* PowerPC64 specific values for the Dyn d_tag field. */
#define DT_PPC64_GLINK (DT_LOPROC + 0)
-#define DT_PPC64_NUM 1
+#define DT_PPC64_OPD (DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+#define DT_PPC64_NUM 3
/* ARM specific declarations */
/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x01
-#define EF_ARM_HASENTRY 0x02
-#define EF_ARM_INTERWORK 0x04
-#define EF_ARM_APCS_26 0x08
-#define EF_ARM_APCS_FLOAT 0x10
-#define EF_ARM_PIC 0x20
-#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-#define EF_ARM_NEW_ABI 0x80
-#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
/* Other constants defined in the ARM ELF spec. version B-01. */
/* NB. These conflict with values defined above. */
#define EF_ARM_SYMSARESORTED 0x04
-#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
#define EF_ARM_MAPSYMSFIRST 0x10
#define EF_ARM_EABIMASK 0XFF000000
-#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-#define EF_ARM_EABI_UNKNOWN 0x00000000
-#define EF_ARM_EABI_VER1 0x01000000
-#define EF_ARM_EABI_VER2 0x02000000
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
-/* Additional symbol types for Thumb */
-#define STT_ARM_TFUNC 0xd
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
- in the input to a link step */
+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
+ in the input to a link step. */
/* ARM-specific program header flags */
-#define PF_ARM_SB 0x10000000 /* Segment contains the location
- addressed by the static base */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location
+ addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
+
/* ARM relocs. */
+
#define R_ARM_NONE 0 /* No reloc */
#define R_ARM_PC24 1 /* PC relative 26 bit branch */
#define R_ARM_ABS32 2 /* Direct 32 bit */
@@ -2120,10 +2305,14 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_ARM_THM_PC22 10
#define R_ARM_THM_PC8 11
#define R_ARM_AMP_VCALL9 12
-#define R_ARM_SWI24 13
+#define R_ARM_SWI24 13 /* Obsolete static relocation. */
+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
#define R_ARM_THM_SWI8 14
#define R_ARM_XPC25 15
#define R_ARM_THM_XPC22 16
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
#define R_ARM_COPY 20 /* Copy symbol at runtime */
#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
@@ -2138,10 +2327,26 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_ARM_LDR_SBREL_11_0 35
#define R_ARM_ALU_SBREL_19_12 36
#define R_ARM_ALU_SBREL_27_20 37
+#define R_ARM_TLS_GOTDESC 90
+#define R_ARM_TLS_CALL 91
+#define R_ARM_TLS_DESCSEQ 92
+#define R_ARM_THM_TLS_CALL 93
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
#define R_ARM_THM_PC9 103 /* thumb conditional branch */
+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
+ thread local data */
+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
+ thread local data */
+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
+ block */
+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
+ static TLS block offset */
+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
+ TLS block */
+#define R_ARM_THM_TLS_DESCSEQ 129
+#define R_ARM_IRELATIVE 160
#define R_ARM_RXPC25 249
#define R_ARM_RSBREL32 250
#define R_ARM_THM_RPC22 251
@@ -2162,6 +2367,9 @@ typedef Elf32_Addr Elf32_Conflict;
/* Processor specific values for the Phdr p_type field. */
#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
/* Processor specific flags for the Phdr p_flags field. */
#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
@@ -2263,6 +2471,30 @@ typedef Elf32_Addr Elf32_Conflict;
/* SH specific declarations */
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_SH_MACH_MASK 0x1f
+#define EF_SH_UNKNOWN 0x0
+#define EF_SH1 0x1
+#define EF_SH2 0x2
+#define EF_SH3 0x3
+#define EF_SH_DSP 0x4
+#define EF_SH3_DSP 0x5
+#define EF_SH4AL_DSP 0x6
+#define EF_SH3E 0x8
+#define EF_SH4 0x9
+#define EF_SH2E 0xb
+#define EF_SH4A 0xc
+#define EF_SH2A 0xd
+#define EF_SH4_NOFPU 0x10
+#define EF_SH4A_NOFPU 0x11
+#define EF_SH4_NOMMU_NOFPU 0x12
+#define EF_SH2A_NOFPU 0x13
+#define EF_SH3_NOMMU 0x14
+#define EF_SH2A_SH4_NOFPU 0x15
+#define EF_SH2A_SH3_NOFPU 0x16
+#define EF_SH2A_SH4 0x17
+#define EF_SH2A_SH3E 0x18
+
/* SH relocs. */
#define R_SH_NONE 0
#define R_SH_DIR32 1
@@ -2304,6 +2536,12 @@ typedef Elf32_Addr Elf32_Conflict;
/* Keep this the last entry. */
#define R_SH_NUM 256
+/* S/390 specific definitions. */
+
+/* Valid values for the e_flags field. */
+
+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
+
/* Additional s390 relocs */
#define R_390_NONE 0 /* No reloc. */
@@ -2380,9 +2618,15 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
block. */
-
+#define R_390_20 57 /* Direct 20 bit. */
+#define R_390_GOT20 58 /* 20 bit GOT offset. */
+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
+ block offset. */
+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
/* Keep this the last entry. */
-#define R_390_NUM 57
+#define R_390_NUM 62
+
/* CRIS relocations. */
#define R_CRIS_NONE 0
@@ -2408,6 +2652,7 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_CRIS_NUM 20
+
/* AMD x86-64 relocations. */
#define R_X86_64_NONE 0 /* No reloc */
#define R_X86_64_64 1 /* Direct 64 bit */
@@ -2437,9 +2682,326 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
to GOT entry for IE symbol */
#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
-
-#define R_X86_64_NUM 24
-
-__END_DECLS
+#define R_X86_64_PC64 24 /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
+ offset to GOT */
+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
+ to GOT entry */
+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
+ to PLT entry */
+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
+ descriptor. */
+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
+
+#define R_X86_64_NUM 39
+
+
+/* AM33 relocations. */
+#define R_MN10300_NONE 0 /* No reloc. */
+#define R_MN10300_32 1 /* Direct 32 bit. */
+#define R_MN10300_16 2 /* Direct 16 bit. */
+#define R_MN10300_8 3 /* Direct 8 bit. */
+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
+#define R_MN10300_24 9 /* Direct 24 bit. */
+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
+
+#define R_MN10300_NUM 24
+
+
+/* M32R relocs. */
+#define R_M32R_NONE 0 /* No reloc. */
+#define R_M32R_16 1 /* Direct 16 bit. */
+#define R_M32R_32 2 /* Direct 32 bit. */
+#define R_M32R_24 3 /* Direct 24 bit. */
+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
+#define R_M32R_LO16 9 /* Low 16 bit. */
+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY 12
+/* M32R relocs use SHT_RELA. */
+#define R_M32R_16_RELA 33 /* Direct 16 bit. */
+#define R_M32R_32_RELA 34 /* Direct 32 bit. */
+#define R_M32R_24_RELA 35 /* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
+#define R_M32R_LO16_RELA 41 /* Low 16 bit */
+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY 44
+#define R_M32R_REL32 45 /* PC relative 32 bit. */
+
+#define R_M32R_GOT24 48 /* 24 bit GOT entry */
+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY 50 /* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
+#define R_M32R_RELATIVE 53 /* Adjust by program base */
+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
+ low */
+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
+ low */
+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
+ GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
+ GOT with signed low */
+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
+ GOT */
+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
+ with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
+ with signed low */
+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
+#define R_M32R_NUM 256 /* Keep this the last entry. */
+
+
+/* TILEPro relocations. */
+#define R_TILEPRO_NONE 0 /* No reloc */
+#define R_TILEPRO_32 1 /* Direct 32 bit */
+#define R_TILEPRO_16 2 /* Direct 16 bit */
+#define R_TILEPRO_8 3 /* Direct 8 bit */
+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
+#define R_TILEPRO_LO16 7 /* Low 16 bit */
+#define R_TILEPRO_HI16 8 /* High 16 bit */
+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
+#define R_TILEPRO_COPY 10 /* Copy relocation */
+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined. */
+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM 130
+
+
+/* TILE-Gx relocations. */
+#define R_TILEGX_NONE 0 /* No reloc */
+#define R_TILEGX_64 1 /* Direct 64 bit */
+#define R_TILEGX_32 2 /* Direct 32 bit */
+#define R_TILEGX_16 3 /* Direct 16 bit */
+#define R_TILEGX_8 4 /* Direct 8 bit */
+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
+#define R_TILEGX_HW0 9 /* hword 0 16-bit */
+#define R_TILEGX_HW1 10 /* hword 1 16-bit */
+#define R_TILEGX_HW2 11 /* hword 2 16-bit */
+#define R_TILEGX_HW3 12 /* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
+#define R_TILEGX_COPY 16 /* Copy relocation */
+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
+/* Relocs 66-71 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+/* Relocs 76-77 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
+/* Relocs 94-99 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined. */
+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM 130
#endif /* elf.h */
diff --git a/tools/include/endian.h b/tools/include/endian.h
index 0f17b41da73..bba70abd833 100644
--- a/tools/include/endian.h
+++ b/tools/include/endian.h
@@ -15,6 +15,11 @@
#define bswap_16(x) bswap16(x)
#define bswap_32(x) bswap32(x)
#define bswap_64(x) bswap64(x)
+#elif defined(__OpenBSD__)
+#include <sys/types.h>
+#define bswap_16(x) __swap16(x)
+#define bswap_32(x) __swap32(x)
+#define bswap_64(x) __swap64(x)
#else
#include <machine/endian.h>
#define bswap_16(x) swap16(x)
diff --git a/tools/include/getline.h b/tools/include/getline.h
deleted file mode 100644
index 02df6c2f790..00000000000
--- a/tools/include/getline.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * Copyright (c) 2006 SPARTA, Inc.
- * All rights reserved.
- *
- * This software was developed by SPARTA ISSO under SPAWAR contract
- * N66001-04-C-6019 ("SEFOS").
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if !defined(__linux__) && !(defined(__APPLE__) && __DARWIN_C_LEVEL >= 200809L)
-/*
- * Emulate glibc getline() via BSD fgetln().
- * Note that outsize is not changed unless memory is allocated.
- */
-static inline ssize_t
-getline(char **outbuf, size_t *outsize, FILE *fp)
-{
- size_t len;
-
-#ifndef __CYGWIN__
- char *buf;
- buf = fgetln(fp, &len);
-#else
- char buf[512];
- fgets(buf, sizeof(buf), fp);
- len = strlen(buf);
-#endif
- if (buf == NULL)
- return (-1);
-
- /* Assumes realloc() accepts NULL for ptr (C99) */
- if (*outbuf == NULL || *outsize < len + 1) {
- void *tmp = realloc(*outbuf, len + 1);
- if (tmp == NULL)
- return (-1);
- *outbuf = tmp;
- *outsize = len + 1;
- }
- memcpy(*outbuf, buf, len);
- (*outbuf)[len] = '\0';
- return (len);
-}
-#endif
diff --git a/tools/ipkg-utils/Makefile b/tools/ipkg-utils/Makefile
deleted file mode 100644
index 778260921e1..00000000000
--- a/tools/ipkg-utils/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=ipkg-utils
-PKG_VERSION:=1.7
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://handhelds.org/packages/ipkg-utils/
-PKG_MD5SUM:=da3e3ef772973d7370a6ac95f0fef9b8
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Install
- $(INSTALL_BIN) \
- $(HOST_BUILD_DIR)/ipkg-build \
- $(HOST_BUILD_DIR)/ipkg-buildpackage \
- $(HOST_BUILD_DIR)/ipkg-make-index \
- $(HOST_BUILD_DIR)/ipkg.py \
- $(STAGING_DIR_HOST)/bin/
-endef
-
-define Host/Clean
- rm -f $(STAGING_DIR)/etc/ipkg.conf
- rm -f $(STAGING_DIR_HOST)/bin/ipkg*
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/ipkg-utils/patches/100-build_clean.patch b/tools/ipkg-utils/patches/100-build_clean.patch
deleted file mode 100644
index 7df272f74de..00000000000
--- a/tools/ipkg-utils/patches/100-build_clean.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -47,6 +47,19 @@ pkg_appears_sane() {
-
- PKG_ERROR=0
-
-+ cvs_dirs=`find . -name 'CVS'`
-+ if [ -n "$cvs_dirs" ]; then
-+ if [ "$noclean" = "1" ]; then
-+ echo "*** Warning: The following CVS directories where found.
-+You probably want to remove them: " >&2
-+ ls -ld $cvs_dirs
-+ echo >&2
-+ else
-+ echo "*** Removing the following files: $cvs_dirs"
-+ rm -rf "$cvs_dirs"
-+ fi
-+ fi
-+
- tilde_files=`find . -name '*~'`
- if [ -n "$tilde_files" ]; then
- if [ "$noclean" = "1" ]; then
-@@ -134,8 +147,12 @@ You probably want to chown these to a sy
-
- for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
- if [ -f $script -a ! -x $script ]; then
-+ if [ "$noclean" = "1" ]; then
- echo "*** Error: package script $script is not executable" >&2
- PKG_ERROR=1
-+ else
-+ chmod a+x $script
-+ fi
- fi
- done
-
diff --git a/tools/ipkg-utils/patches/110-buildpackage.patch b/tools/ipkg-utils/patches/110-buildpackage.patch
deleted file mode 100644
index 8e62ee70cf7..00000000000
--- a/tools/ipkg-utils/patches/110-buildpackage.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/ipkg-buildpackage
-+++ b/ipkg-buildpackage
-@@ -30,8 +30,9 @@
-
- set -e
-
--#SCRIPTDIR=/usr/local/bin
--SCRIPTDIR=/other/kurth/ipaq-dev/familiar/dist/ipkg/util/
-+SCRIPTDIR=/usr/local/bin
-+
-+IPKG_BUILD_OPTIONS=$*
-
- SCRIPTNAME=`basename $0`
-
-@@ -212,7 +213,7 @@ done
- # build the ipk package
- owd=`pwd`
- cd ..
--ipkg-build /tmp/${pkg} || exit 1
-+ipkg-build $IPKG_BUILD_OPTIONS /tmp/${pkg} || exit 1
-
- rm -rf /tmp/${pkg}
-
diff --git a/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch b/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch
deleted file mode 100644
index dacdaaefbdb..00000000000
--- a/tools/ipkg-utils/patches/111-buildpackage_conffiles.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/ipkg-buildpackage
-+++ b/ipkg-buildpackage
-@@ -190,7 +190,7 @@ fi
- mkdir /tmp/${pkg}/CONTROL
-
- files_required="control"
--files_optional="preinst postinst prerm postrm"
-+files_optional="preinst postinst prerm postrm conffiles"
-
- for i in ${files_required} ; do
- file=${CONTROL}/$i
diff --git a/tools/ipkg-utils/patches/120-build_tar.patch b/tools/ipkg-utils/patches/120-build_tar.patch
deleted file mode 100644
index acf6b798539..00000000000
--- a/tools/ipkg-utils/patches/120-build_tar.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-This patch from aorlinsk fixes an issue with order in options passed to tar
-
- http://openwrt.org/forum/viewtopic.php?pid=8332#p8332
-
-
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -184,7 +184,7 @@ while getopts "cg:ho:v" opt; do
- g ) group=$OPTARG
- ogargs="$ogargs --group=$group"
- ;;
-- c ) outer=tar
-+ c ) outer=$TAR
- ;;
- C ) noclean=1
- ;;
-@@ -243,8 +243,8 @@ tmp_dir=$dest_dir/IPKG_BUILD.$$
- mkdir $tmp_dir
-
- echo $CONTROL > $tmp_dir/tarX
--( cd $pkg_dir && tar $ogargs -czf $tmp_dir/data.tar.gz . -X $tmp_dir/tarX )
--( cd $pkg_dir/$CONTROL && tar $ogargs -czf $tmp_dir/control.tar.gz . )
-+( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
-+( cd $pkg_dir/$CONTROL && $TAR $ogargs -czf $tmp_dir/control.tar.gz . )
- rm $tmp_dir/tarX
-
- echo "2.0" > $tmp_dir/debian-binary
-@@ -254,7 +254,7 @@ rm -f $pkg_file
- if [ "$outer" = "ar" ] ; then
- ( cd $tmp_dir && ar -crf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
- else
-- ( cd $tmp_dir && tar -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
-+ ( cd $tmp_dir && $TAR -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
- fi
-
- rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
diff --git a/tools/ipkg-utils/patches/130-tar_wildcards.patch b/tools/ipkg-utils/patches/130-tar_wildcards.patch
deleted file mode 100644
index ba949c10031..00000000000
--- a/tools/ipkg-utils/patches/130-tar_wildcards.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/ipkg.py
-+++ b/ipkg.py
-@@ -93,9 +93,9 @@ class Package:
- self.filename = os.path.basename(fn)
- ## sys.stderr.write(" extracting control.tar.gz from %s\n"% (fn,))
- if self.isdeb:
-- control = os.popen("ar p "+fn+" control.tar.gz | tar xfzO - '*control'","r")
-+ control = os.popen("ar p "+fn+" control.tar.gz | tar xzO --wildcards -f - '*control'","r")
- else:
-- control = os.popen("tar xfzO "+fn+" '*control.tar.gz' | tar xfzO - '*control'","r")
-+ control = os.popen("tar xzO --wildcards -f "+fn+" '*control.tar.gz' | tar xzO --wildcards -f - '*control'","r")
- line = control.readline()
- while 1:
- if not line: break
-@@ -122,7 +122,7 @@ class Package:
- if self.isdeb:
- data = os.popen("ar p "+fn+" data.tar.gz | tar tfz -","r")
- else:
-- data = os.popen("tar xfzO "+fn+" '*data.tar.gz' | tar tfz -","r")
-+ data = os.popen("tar xzO --wildcards -f "+fn+" '*data.tar.gz' | tar tfz -","r")
- while 1:
- line = data.readline()
- if not line: break
diff --git a/tools/ipkg-utils/patches/140-portability.patch b/tools/ipkg-utils/patches/140-portability.patch
deleted file mode 100644
index 417c4094d4d..00000000000
--- a/tools/ipkg-utils/patches/140-portability.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -11,6 +11,8 @@ set -e
-
- version=1.0
-
-+TAR="${TAR:-$(which tar)}"
-+
- ipkg_extract_value() {
- sed -e "s/^[^:]*:[[:space:]]*//"
- }
---- a/ipkg-make-index
-+++ b/ipkg-make-index
-@@ -1,4 +1,4 @@
--#!/usr/bin/python
-+#!/usr/bin/env python
- # $Id: ipkg-make-index,v 1.20 2003/10/30 02:32:09 jamey Exp $
-
- import sys, os, posixpath
diff --git a/tools/ipkg-utils/patches/150-uppercase_letters.patch b/tools/ipkg-utils/patches/150-uppercase_letters.patch
deleted file mode 100644
index cef200dcc86..00000000000
--- a/tools/ipkg-utils/patches/150-uppercase_letters.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -133,7 +133,7 @@ You probably want to chown these to a sy
- disallowed_filename=`disallowed_field Filename`
- [ "$?" -ne 0 ] && PKG_ERROR=1
-
-- if echo $pkg | grep '[^a-z0-9.+-]'; then
-+ if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
- echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
- PKG_ERROR=1;
- fi
---- a/ipkg-buildpackage
-+++ b/ipkg-buildpackage
-@@ -69,7 +69,7 @@ pkg_appears_sane_control() {
- required_field Maintainer >/dev/null
- required_field Description >/dev/null
-
-- if echo $pkg | grep '[^a-z0-9.+-]'; then
-+ if echo $pkg | grep '[^a-zA-Z0-9.+-]'; then
- echo "ipkg-build: Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])"
- PKG_ERROR=1;
- fi
diff --git a/tools/ipkg-utils/patches/160-find.patch b/tools/ipkg-utils/patches/160-find.patch
deleted file mode 100644
index 45ef3c65170..00000000000
--- a/tools/ipkg-utils/patches/160-find.patch
+++ /dev/null
@@ -1,39 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -10,7 +10,8 @@
- set -e
-
- version=1.0
--
-+FIND="$(which find)"
-+FIND="${FIND:-$(which gfind)}"
- TAR="${TAR:-$(which tar)}"
-
- ipkg_extract_value() {
-@@ -49,7 +50,7 @@ pkg_appears_sane() {
-
- PKG_ERROR=0
-
-- cvs_dirs=`find . -name 'CVS'`
-+ cvs_dirs=`$FIND . -name 'CVS'`
- if [ -n "$cvs_dirs" ]; then
- if [ "$noclean" = "1" ]; then
- echo "*** Warning: The following CVS directories where found.
-@@ -62,7 +63,7 @@ You probably want to remove them: " >&2
- fi
- fi
-
-- tilde_files=`find . -name '*~'`
-+ tilde_files=`$FIND . -name '*~'`
- if [ -n "$tilde_files" ]; then
- if [ "$noclean" = "1" ]; then
- echo "*** Warning: The following files have names ending in '~'.
-@@ -75,7 +76,7 @@ You probably want to remove them: " >&2
- fi
- fi
-
-- large_uid_files=`find . -uid +99 || true`
-+ large_uid_files=`$FIND . -uid +99 || true`
-
- if [ "$ogargs" = "" ] && [ -n "$large_uid_files" ]; then
- echo "*** Warning: The following files have a UID greater than 99.
diff --git a/tools/ipkg-utils/patches/170-resolve_conffiles.patch b/tools/ipkg-utils/patches/170-resolve_conffiles.patch
deleted file mode 100644
index 31faf30a039..00000000000
--- a/tools/ipkg-utils/patches/170-resolve_conffiles.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -160,12 +160,15 @@ You probably want to chown these to a sy
- done
-
- if [ -f $CONTROL/conffiles ]; then
-- for cf in `cat $CONTROL/conffiles`; do
-- if [ ! -f ./$cf ]; then
-- echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
-- PKG_ERROR=1
-- fi
-+ rm -f $CONTROL/conffiles.resolved
-+
-+ for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
-+ echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
- done
-+
-+ rm $CONTROL/conffiles
-+ mv $CONTROL/conffiles.resolved $CONTROL/conffiles
-+ chmod 0644 $CONTROL/conffiles
- fi
-
- cd $owd
diff --git a/tools/ipkg-utils/patches/180-add_installed_size.patch b/tools/ipkg-utils/patches/180-add_installed_size.patch
deleted file mode 100644
index fb91a319097..00000000000
--- a/tools/ipkg-utils/patches/180-add_installed_size.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -250,6 +250,11 @@ mkdir $tmp_dir
-
- echo $CONTROL > $tmp_dir/tarX
- ( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
-+
-+installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
-+sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
-+ $pkg_dir/$CONTROL/control
-+
- ( cd $pkg_dir/$CONTROL && $TAR $ogargs -czf $tmp_dir/control.tar.gz . )
- rm $tmp_dir/tarX
-
diff --git a/tools/ipkg-utils/patches/190-preserve_permissions.patch b/tools/ipkg-utils/patches/190-preserve_permissions.patch
deleted file mode 100644
index 27ba5217b06..00000000000
--- a/tools/ipkg-utils/patches/190-preserve_permissions.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/ipkg-build
-+++ b/ipkg-build
-@@ -249,7 +249,8 @@ tmp_dir=$dest_dir/IPKG_BUILD.$$
- mkdir $tmp_dir
-
- echo $CONTROL > $tmp_dir/tarX
--( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
-+# Preserve permissions (-p) when creating data.tar.gz as non-root user
-+( cd $pkg_dir && $TAR $ogargs -X $tmp_dir/tarX -czpf $tmp_dir/data.tar.gz . )
-
- installed_size=`du -b $tmp_dir/data.tar.gz | cut -f1`
- sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
diff --git a/tools/isl/Makefile b/tools/isl/Makefile
new file mode 100644
index 00000000000..da37437119d
--- /dev/null
+++ b/tools/isl/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2009-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=isl
+PKG_VERSION:=0.18
+
+PKG_SOURCE_URL:=http://isl.gforge.inria.fr
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_HASH:=0f35051cc030b87c673ac1f187de40e386a1482a0cfdf2c552dd6031b307ddc4
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+unexport CFLAGS
+
+HOST_CONFIGURE_ARGS += \
+ --enable-static \
+ --disable-shared \
+ --with-gmp-prefix=$(STAGING_DIR_HOST)
+
+$(eval $(call HostBuild))
diff --git a/tools/kernel2minor/Makefile b/tools/kernel2minor/Makefile
new file mode 100644
index 00000000000..be730b4df6a
--- /dev/null
+++ b/tools/kernel2minor/Makefile
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2016 adron@yapic.net
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=kernel2minor
+PKG_VERSION:=0.25
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://github.com/adron-s/kernel2minor.git
+PKG_MIRROR_HASH:=6083c46c2fe0da37bacd04d5d5439c0e2a9d00e58ff47a63acfd5057d2aa2145
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=1e5a52c7941945f6d64807ebca4a5923ba5466bd
+PKG_HASH:=33ca413403a3341af0c9a8e6d9bb58f4ad080a5339e8a8729b83637d35bfaf1b
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/kernel2minor $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/kernel2minor
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/libelf/Makefile b/tools/libelf/Makefile
index f38d70d09b1..ab7360ffee1 100644
--- a/tools/libelf/Makefile
+++ b/tools/libelf/Makefile
@@ -9,12 +9,14 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=libelf
PKG_VERSION:=0.8.13
-PKG_MD5SUM:=4136d7b4c04df68b686570afa26988ac
+PKG_HASH:=591a9b4ec81c1f2042a97aa60564e0cb79d041c52faa7416acb38bc95bd2c76d
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.mr511.de/software/
+HOST_BUILD_PARALLEL:=1
+
include $(INCLUDE_DIR)/host-build.mk
HOST_CONFIGURE_ARGS += \
@@ -30,7 +32,7 @@ endef
define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR)/lib/ libelf.a
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR)/lib/ libelf.a
endef
define Host/Install
diff --git a/tools/libressl/Makefile b/tools/libressl/Makefile
new file mode 100644
index 00000000000..4c7e8a7b6ec
--- /dev/null
+++ b/tools/libressl/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2016-2017 LEDE project
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libressl
+PKG_VERSION:=2.7.2
+PKG_HASH:=917a8779c342177ff3751a2bf955d0262d1d8916a4b408930c45cef326700995
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://mirror.ox.ac.uk/pub/OpenBSD/LibreSSL \
+ http://ftp.jaist.ac.jp/pub/OpenBSD/LibreSSL \
+ http://ftp.openbsd.org/pub/OpenBSD/LibreSSL
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOST_CONFIGURE_ARGS += --disable-shared
+HOST_CFLAGS += $(FPIC)
+
+$(eval $(call HostBuild))
diff --git a/tools/libtool/Makefile b/tools/libtool/Makefile
index 080689b8ac2..dd4a7f63809 100644
--- a/tools/libtool/Makefile
+++ b/tools/libtool/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008 OpenWrt.org
+# Copyright (C) 2008-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,17 +7,26 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libtool
+PKG_CPE_ID:=cpe:/a:gnu:libtool
PKG_VERSION:=2.4
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_MD5SUM:=b32b04148ecdd7344abc6fe8bd1bb021
+PKG_HASH:=afcce660d3dc54c63a0a5ba3cf05272239dc3c54bbeba20f6bad250f9dc007ae
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
HOST_CONFIGURE_VARS += \
lt_cv_sys_dlsearch_path=""
+define Host/Prepare
+ $(call Host/Prepare/Default)
+ (cd $(STAGING_DIR_HOST)/share/aclocal/ && rm -f libtool.m4 ltdl.m4 lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4)
+ (cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) ./bootstrap)
+endef
+
define Host/Install
$(MAKE) -C $(HOST_BUILD_DIR) install
$(SED) 's,\(hardcode_into_libs\)=yes,\1=no,g' $(STAGING_DIR_HOST)/bin/libtool
diff --git a/tools/libtool/patches/000-relocatable.patch b/tools/libtool/patches/000-relocatable.patch
index c36b806584a..55265fe5332 100644
--- a/tools/libtool/patches/000-relocatable.patch
+++ b/tools/libtool/patches/000-relocatable.patch
@@ -1,30 +1,62 @@
--- a/libltdl/config/general.m4sh
+++ b/libltdl/config/general.m4sh
-@@ -53,7 +53,7 @@ test "${ECHO+set}" = set || ECHO=${as_ec
+@@ -45,15 +45,22 @@ progpath="$0"
+ M4SH_VERBATIM([[
+ : ${CP="cp -f"}
+ test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+-: ${EGREP="@EGREP@"}
+-: ${FGREP="@FGREP@"}
+-: ${GREP="@GREP@"}
+ : ${LN_S="@LN_S@"}
+ : ${MAKE="make"}
: ${MKDIR="mkdir"}
: ${MV="mv -f"}
: ${RM="rm -f"}
-: ${SED="@SED@"}
-+test "${STAGING_DIR+set}" = set && ${SED="$STAGING_DIR/../host/bin/sed"} || ${SED="@SED@"}
++if test -n "$STAGING_DIR"; then
++ : ${EGREP="$STAGING_DIR/../host/bin/grep -E"}
++ : ${FGREP="$STAGING_DIR/../host/bin/grep -F"}
++ : ${GREP="$STAGING_DIR/../host/bin/grep"}
++ : ${SED="$STAGING_DIR/../host/bin/sed"}
++else
++ : ${EGREP="@EGREP@"}
++ : ${FGREP="@FGREP@"}
++ : ${GREP="@GREP@"}
++ : ${SED="@SED@"}
++fi
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
: ${Xsed="$SED -e 1s/^X//"}
--- a/libtoolize.in
+++ b/libtoolize.in
-@@ -334,7 +334,11 @@ test "${ECHO+set}" = set || ECHO=${as_ec
+@@ -326,15 +326,22 @@ as_unset=as_fn_unset
+
+ : ${CP="cp -f"}
+ test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+-: ${EGREP="@EGREP@"}
+-: ${FGREP="@FGREP@"}
+-: ${GREP="@GREP@"}
+ : ${LN_S="@LN_S@"}
+ : ${MAKE="make"}
: ${MKDIR="mkdir"}
: ${MV="mv -f"}
: ${RM="rm -f"}
-: ${SED="@SED@"}
+if test -n "$STAGING_DIR"; then
++ : ${EGREP="$STAGING_DIR/../host/bin/grep -E"}
++ : ${FGREP="$STAGING_DIR/../host/bin/grep -F"}
++ : ${GREP="$STAGING_DIR/../host/bin/grep"}
+ : ${SED="$STAGING_DIR/../host/bin/sed"}
+else
++ : ${EGREP="@EGREP@"}
++ : ${FGREP="@FGREP@"}
++ : ${GREP="@GREP@"}
+ : ${SED="@SED@"}
+fi
: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
: ${Xsed="$SED -e 1s/^X//"}
-@@ -2476,10 +2480,17 @@ func_check_macros ()
+@@ -2476,10 +2483,17 @@ func_check_macros ()
# Locations for important files:
prefix=@prefix@
@@ -83,6 +115,19 @@
_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+@@ -7509,9 +7508,9 @@ m4_defun([_LT_DECL_EGREP],
+ [AC_REQUIRE([AC_PROG_EGREP])dnl
+ AC_REQUIRE([AC_PROG_FGREP])dnl
+ test -z "$GREP" && GREP=grep
+-_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+-_LT_DECL([], [EGREP], [1], [An ERE matcher])
+-_LT_DECL([], [FGREP], [1], [A literal string matcher])
++_LT_DECL([], [GREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep"], [A grep program that handles long lines])
++_LT_DECL([], [EGREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep -E"], [An ERE matcher])
++_LT_DECL([], [FGREP], ["\${STAGING_DIR:-$STAGING_DIR}/../host/bin/grep -F"], [A literal string matcher])
+ dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+ AC_SUBST([GREP])
+ ])
@@ -7544,9 +7543,8 @@ AC_SUBST([DLLTOOL])
# as few characters as possible. Prefer GNU sed if found.
m4_defun([_LT_DECL_SED],
diff --git a/tools/libtool/patches/160-passthrough-ssp.patch b/tools/libtool/patches/160-passthrough-ssp.patch
new file mode 100644
index 00000000000..9fad9aa9df7
--- /dev/null
+++ b/tools/libtool/patches/160-passthrough-ssp.patch
@@ -0,0 +1,12 @@
+diff -ur libtool-2.4.orig/libltdl/config/ltmain.m4sh libtool-2.4/libltdl/config/ltmain.m4sh
+--- libtool-2.4.orig/libltdl/config/ltmain.m4sh 2015-06-18 10:46:15.499996979 +0200
++++ libtool-2.4/libltdl/config/ltmain.m4sh 2015-06-18 10:48:24.686882213 +0200
+@@ -5061,7 +5061,7 @@
+ # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+- -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
++ -O*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
diff --git a/tools/libtool/patches/200-openwrt-branding.patch b/tools/libtool/patches/200-openwrt-branding.patch
index 56ea8bf2135..dd3e3d6b784 100644
--- a/tools/libtool/patches/200-openwrt-branding.patch
+++ b/tools/libtool/patches/200-openwrt-branding.patch
@@ -1,6 +1,6 @@
--- a/libltdl/config/general.m4sh
+++ b/libltdl/config/general.m4sh
-@@ -352,7 +352,7 @@ opt_warning=:
+@@ -359,7 +359,7 @@ opt_warning=:
# name if it has been set yet.
func_echo ()
{
@@ -9,7 +9,7 @@
}
# func_verbose arg...
-@@ -378,14 +378,14 @@ func_echo_all ()
+@@ -385,14 +385,14 @@ func_echo_all ()
# Echo program name prefixed message to standard error.
func_error ()
{
@@ -56,7 +56,7 @@
:
--- a/libtoolize.in
+++ b/libtoolize.in
-@@ -637,7 +637,7 @@ opt_warning=:
+@@ -640,7 +640,7 @@ opt_warning=:
# name if it has been set yet.
func_echo ()
{
@@ -65,7 +65,7 @@
}
# func_verbose arg...
-@@ -663,14 +663,14 @@ func_echo_all ()
+@@ -666,14 +666,14 @@ func_echo_all ()
# Echo program name prefixed message to standard error.
func_error ()
{
diff --git a/tools/lzma-old/Makefile b/tools/lzma-old/Makefile
index 08511b0ec95..5204127a809 100644
--- a/tools/lzma-old/Makefile
+++ b/tools/lzma-old/Makefile
@@ -11,7 +11,7 @@ PKG_VERSION:=4.32
PKG_SOURCE:=lzma-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/
-PKG_MD5SUM:=5587d6ac230ad1903d504fc3253f0e42
+PKG_HASH:=49053e4bb5e0646a841d250d9cb81f7714f5fff04a133216c4748163567acc3d
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/lzma-$(PKG_VERSION)
@@ -21,7 +21,9 @@ LIB_DIR=$(HOST_BUILD_DIR)/C/7zip/Compress/LZMA_Lib
ALONE_DIR=$(HOST_BUILD_DIR)/C/7zip/Compress/LZMA_Alone
define Host/Compile
+ +$(HOST_MAKE_VARS) \
$(MAKE) -C $(LIB_DIR)
+ +$(HOST_MAKE_VARS) \
$(MAKE) -f makefile.gcc -C $(ALONE_DIR)
endef
diff --git a/tools/lzma-old/patches/120-add-cflags.patch b/tools/lzma-old/patches/120-add-cflags.patch
new file mode 100644
index 00000000000..9022e7cd279
--- /dev/null
+++ b/tools/lzma-old/patches/120-add-cflags.patch
@@ -0,0 +1,11 @@
+--- a/C/7zip/Compress/LZMA_Lib/makefile
++++ b/C/7zip/Compress/LZMA_Lib/makefile
+@@ -2,7 +2,7 @@ PROG = liblzma.a
+ CXX = g++ -O3 -Wall
+ AR = ar
+ RM = rm -f
+-CFLAGS = -c -I ../../../
++CFLAGS += -c -I ../../../
+
+ OBJS = \
+ ZLib.o \
diff --git a/tools/lzma/Makefile b/tools/lzma/Makefile
index 4922f8087f6..7d2669e95f3 100644
--- a/tools/lzma/Makefile
+++ b/tools/lzma/Makefile
@@ -11,7 +11,7 @@ PKG_VERSION:=4.65
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://downloads.openwrt.org/sources/
-PKG_MD5SUM:=434e51a018b4c8ef377bf81520a53af0
+PKG_HASH:=dcbdb5f4843eff638e4a5e8be0e2486a3c5483df73c70823618db8e66f609ec2
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
diff --git a/tools/lzma/patches/101-move-copyright-to-usage-info.patch b/tools/lzma/patches/101-move-copyright-to-usage-info.patch
new file mode 100644
index 00000000000..ec69285d8e6
--- /dev/null
+++ b/tools/lzma/patches/101-move-copyright-to-usage-info.patch
@@ -0,0 +1,20 @@
+--- a/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
++++ b/CPP/7zip/Compress/LZMA_Alone/LzmaAlone.cpp
+@@ -101,6 +101,8 @@ static const int kNumSwitches = sizeof(k
+
+ static void PrintHelp()
+ {
++ fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
++
+ fprintf(stderr, "\nUsage: LZMA <e|d> inputFile outputFile [<switches>...]\n"
+ " e: encode file\n"
+ " d: decode file\n"
+@@ -168,8 +170,6 @@ int main2(int n, const char *args[])
+ g_IsNT = IsItWindowsNT();
+ #endif
+
+- fprintf(stderr, "\nLZMA " MY_VERSION_COPYRIGHT_DATE "\n");
+-
+ if (n == 1)
+ {
+ PrintHelp();
diff --git a/tools/m4/Makefile b/tools/m4/Makefile
index b838799ab0f..a6d931b0fd5 100644
--- a/tools/m4/Makefile
+++ b/tools/m4/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2008 OpenWrt.org
+# Copyright (C) 2008-2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,15 +7,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=m4
-PKG_VERSION:=1.4.16
+PKG_CPE_ID:=cpe:/a:gnu:m4
+PKG_VERSION:=1.4.18
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_MD5SUM:=a5dfb4f2b7370e9d34293d23fd09b280
-PKG_CAT:=zcat
+PKG_HASH:=f2c1e86ca0a404ff281631bdc8377638992744b175afb806e25871a24a934e07
+PKG_CAT:=xzcat
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
+HOST_CONFIGURE_VARS += gl_cv_func_strstr_linear=no
+
define Host/Clean
-$(MAKE) -C $(HOST_BUILD_DIR) uninstall
$(call Host/Clean/Default)
diff --git a/tools/m4/patches/001-fix-macos-vasnprintf.patch b/tools/m4/patches/001-fix-macos-vasnprintf.patch
new file mode 100644
index 00000000000..e41315d34ec
--- /dev/null
+++ b/tools/m4/patches/001-fix-macos-vasnprintf.patch
@@ -0,0 +1,25 @@
+--- a/lib/vasnprintf.c
++++ b/lib/vasnprintf.c
+@@ -4858,7 +4858,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *
+ #endif
+ *fbp = dp->conversion;
+ #if USE_SNPRINTF
+-# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
++# if ! (((__GLIBC__ > 2 \
++ || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
++ && !defined __UCLIBC__) \
++ || (defined __APPLE__ && defined __MACH__) \
++ || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+ fbp[1] = '%';
+ fbp[2] = 'n';
+ fbp[3] = '\0';
+@@ -4872,6 +4876,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *
+ in format strings in writable memory may crash the program
+ (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
+ in this situation. */
++ /* macOS 10.13 High Sierra behaves like glibc with
++ _FORTIFY_SOURCE=2, and older macOS releases
++ presumably do not need %n. */
+ /* On native Windows systems (such as mingw), we can avoid using
+ %n because:
+ - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
diff --git a/tools/m4/patches/010-glibc-change-work-around.patch b/tools/m4/patches/010-glibc-change-work-around.patch
new file mode 100644
index 00000000000..0ef6216965c
--- /dev/null
+++ b/tools/m4/patches/010-glibc-change-work-around.patch
@@ -0,0 +1,118 @@
+Subject: Workaround change in glibc
+
+Temporary workaround to compile with glibc 2.28, which
+deprecated some constants
+
+Taken from the rpms/m4 Fedora repository, commit 814d5921
+(Work around change in glibc)
+
+Original filename: m4-1.4.18-glibc-change-work-around.patch
+
+--- a/lib/stdio-impl.h
++++ b/lib/stdio-impl.h
+@@ -18,6 +18,12 @@
+ the same implementation of stdio extension API, except that some fields
+ have different naming conventions, or their access requires some casts. */
+
++/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
++ problem by defining it ourselves. FIXME: Do not rely on glibc
++ internals. */
++#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
++# define _IO_IN_BACKUP 0x100
++#endif
+
+ /* BSD stdio derived implementations. */
+
+--- a/lib/fflush.c
++++ b/lib/fflush.c
+@@ -33,7 +33,7 @@
+ #undef fflush
+
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ /* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
+ static void
+@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
+
+ #endif
+
+-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
++#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
+
+ # if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
+ if (stream == NULL || ! freading (stream))
+ return fflush (stream);
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+
+ clear_ungetc_buffer_preserving_position (stream);
+
+--- a/lib/fpending.c
++++ b/lib/fpending.c
+@@ -32,7 +32,7 @@ __fpending (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return fp->_IO_write_ptr - fp->_IO_write_base;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+--- a/lib/fpurge.c
++++ b/lib/fpurge.c
+@@ -62,7 +62,7 @@ fpurge (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_IO_read_end = fp->_IO_read_ptr;
+ fp->_IO_write_ptr = fp->_IO_write_base;
+ /* Avoid memory leak when there is an active ungetc buffer. */
+--- a/lib/freadahead.c
++++ b/lib/freadahead.c
+@@ -25,7 +25,7 @@
+ size_t
+ freadahead (FILE *fp)
+ {
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_write_ptr > fp->_IO_write_base)
+ return 0;
+ return (fp->_IO_read_end - fp->_IO_read_ptr)
+--- a/lib/freading.c
++++ b/lib/freading.c
+@@ -31,7 +31,7 @@ freading (FILE *fp)
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return ((fp->_flags & _IO_NO_WRITES) != 0
+ || ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
+ && fp->_IO_read_base != NULL));
+--- a/lib/fseeko.c
++++ b/lib/fseeko.c
+@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int when
+ #endif
+
+ /* These tests are based on fpurge.c. */
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ if (fp->_IO_read_end == fp->_IO_read_ptr
+ && fp->_IO_write_ptr == fp->_IO_write_base
+ && fp->_IO_save_base == NULL)
+@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int when
+ return -1;
+ }
+
+-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
++#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ fp->_flags &= ~_IO_EOF_SEEN;
+ fp->_offset = pos;
+ #elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
diff --git a/tools/make-ext4fs/Makefile b/tools/make-ext4fs/Makefile
new file mode 100644
index 00000000000..f67ab6e5b58
--- /dev/null
+++ b/tools/make-ext4fs/Makefile
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+# Copyright (C) 2016 LEDE project
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=make-ext4fs
+
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/make_ext4fs.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_DATE:=2016-08-14
+PKG_SOURCE_VERSION:=484903e4332be6c317f531b008cb2a841a18c506
+PKG_MIRROR_HASH:=d7ccd5e426b1d15331ff000a37dc15161f6eef594453e970fd584fcde5a25075
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/make_ext4fs $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/make_ext4fs
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/make-ext4fs/patches/100-add-ldflags.patch b/tools/make-ext4fs/patches/100-add-ldflags.patch
new file mode 100644
index 00000000000..d9ce47bb809
--- /dev/null
+++ b/tools/make-ext4fs/patches/100-add-ldflags.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -27,7 +27,7 @@ OBJ := \
+ $(CC) $(CFLAGS) -c -o $@ $^
+
+ make_ext4fs: $(OBJ) libsparse/libsparse.a
+- $(CC) -o $@ $^ $(ZLIB)
++ $(CC) $(LDFLAGS)-o $@ $^ $(ZLIB)
+
+ libsparse/libsparse.a:
+ $(MAKE) -C libsparse/ libsparse.a
diff --git a/tools/missing-macros/Makefile b/tools/missing-macros/Makefile
index ab50a674682..e4b69b3875c 100644
--- a/tools/missing-macros/Makefile
+++ b/tools/missing-macros/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2010-2011 OpenWrt.org
+# Copyright (C) 2010-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -21,6 +21,8 @@ endef
define Host/Install
$(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal
$(INSTALL_DATA) ./src/m4/*.m4 $(STAGING_DIR_HOST)/share/aclocal/
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+ $(INSTALL_BIN) ./src/bin/* $(STAGING_DIR_HOST)/bin/
endef
$(eval $(call HostBuild))
diff --git a/tools/missing-macros/src/bin/help2man b/tools/missing-macros/src/bin/help2man
new file mode 100755
index 00000000000..6cbec57c50f
--- /dev/null
+++ b/tools/missing-macros/src/bin/help2man
@@ -0,0 +1,29 @@
+#!/usr/bin/env perl
+
+use strict;
+use Getopt::Long;
+
+my $output;
+my $version;
+
+Getopt::Long::Configure('pass_through');
+Getopt::Long::GetOptions(
+ 'output=s' => \$output,
+ 'version' => \$version
+);
+
+if ($version)
+{
+ printf "OpenWrt help2man 1.40.10\n";
+ exit 0;
+}
+elsif ($output)
+{
+ open O, "> $output" || die "Unable to open $output: $!\n";
+ print O "Dummy man page.\n";
+ close O;
+}
+else
+{
+ print O "Dummy man page.\n";
+}
diff --git a/tools/missing-macros/src/bin/makeinfo b/tools/missing-macros/src/bin/makeinfo
new file mode 100755
index 00000000000..e163cba0843
--- /dev/null
+++ b/tools/missing-macros/src/bin/makeinfo
@@ -0,0 +1,112 @@
+#!/usr/bin/env perl
+
+use strict;
+use Getopt::Long;
+
+my $output;
+my $version;
+my $docbook;
+my $html;
+my $xml;
+my $plaintext;
+my $no_split;
+my $no_headers;
+
+Getopt::Long::Configure('pass_through');
+Getopt::Long::GetOptions(
+ 'output=s' => \$output,
+ 'version' => \$version,
+ 'no-split' => \$no_split,
+ 'no-headers' => \$no_headers,
+ 'docbook' => \$docbook,
+ 'html' => \$html,
+ 'xml' => \$xml,
+ 'plaintext' => \$plaintext
+);
+
+if ($version)
+{
+ print "makeinfo (OpenWrt stub) 4.13\n";
+ exit 0;
+}
+
+
+sub output_filename
+{
+ my $path = shift || return;
+ my $name = $path;
+ my $setfile;
+
+ if (open F, "< $path")
+ {
+ while (defined(my $line = readline F))
+ {
+ if ($line =~ /\@setfilename\s+(\S+)/)
+ {
+ $setfile = $1;
+ $setfile =~ s!^.+/!!;
+ last;
+ }
+ }
+
+ close F;
+ }
+
+ $name =~ s!^.+/!!;
+ $name =~ s!\.[^.]+$!!;
+
+ if ($html)
+ {
+ $setfile =~ s!\.[^.]+$!! if $setfile;
+
+ if ($no_split)
+ {
+ return $setfile ? "$setfile.html" : "$name.html" unless $output;
+ return $output;
+ }
+
+ return $setfile ? "$setfile/index.html" : "$name/index.html" unless $output;
+ return "$output/index.html";
+ }
+ elsif ($xml || $docbook)
+ {
+ $setfile =~ s!\.[^.]+$!! if $setfile;
+
+ return $setfile ? "$setfile.xml" : "$name.info" unless $output;
+ return $output;
+ }
+ elsif ($plaintext)
+ {
+ return ($output || "-");
+ }
+
+ return ($output || $setfile || "$name.info");
+}
+
+foreach my $arg (@ARGV)
+{
+ next unless -f $arg;
+
+ my $out = output_filename($arg);
+ if ($out =~ m!^(.+/)[^/]+$!)
+ {
+ system("mkdir", "-p", $1);
+ }
+
+ my $fd = \*STDOUT;
+ if ($out ne "-" && !$no_headers)
+ {
+ open $fd, "> $out" || die "Can't open $out: $!\n";
+ }
+
+ if ($html || $xml || $docbook)
+ {
+ print $fd "<!-- Dummy output for $arg -->\n";
+ }
+ else
+ {
+ print $fd "Dummy output for $arg\n";
+ }
+
+ close $fd;
+}
diff --git a/tools/missing-macros/src/m4/esd.m4 b/tools/missing-macros/src/m4/esd.m4
deleted file mode 100644
index bb07d0f1755..00000000000
--- a/tools/missing-macros/src/m4/esd.m4
+++ /dev/null
@@ -1,196 +0,0 @@
-# esd.m4 serial 1 (libmikmod-3.1.12)
-# Configure paths for ESD
-# Manish Singh 98-9-30
-# stolen back from Frank Belew
-# stolen from Manish Singh
-# Shamelessly stolen from Owen Taylor
-
-dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS
-dnl
-AC_DEFUN([AM_PATH_ESD],
-[dnl
-dnl Get the cflags and libraries from the esd-config script
-dnl
-AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)],
- esd_prefix="$withval", esd_prefix="")
-AC_ARG_WITH(esd-exec-prefix,[ --with-esd-exec-prefix=PFX Exec prefix where ESD is installed (optional)],
- esd_exec_prefix="$withval", esd_exec_prefix="")
-AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run a test ESD program],
- , enable_esdtest=yes)
-
- if test x$esd_exec_prefix != x ; then
- esd_args="$esd_args --exec-prefix=$esd_exec_prefix"
- if test x${ESD_CONFIG+set} != xset ; then
- ESD_CONFIG=$esd_exec_prefix/bin/esd-config
- fi
- fi
- if test x$esd_prefix != x ; then
- esd_args="$esd_args --prefix=$esd_prefix"
- if test x${ESD_CONFIG+set} != xset ; then
- ESD_CONFIG=$esd_prefix/bin/esd-config
- fi
- fi
-
- AC_PATH_PROG(ESD_CONFIG, esd-config, no)
- min_esd_version=ifelse([$1], ,0.2.7,$1)
- AC_MSG_CHECKING(for ESD - version >= $min_esd_version)
- no_esd=""
- if test "$ESD_CONFIG" = "no" ; then
- no_esd=yes
- else
- AC_LANG_SAVE
- AC_LANG_C
- ESD_CFLAGS=`$ESD_CONFIG $esdconf_args --cflags`
- ESD_LIBS=`$ESD_CONFIG $esdconf_args --libs`
-
- esd_major_version=`$ESD_CONFIG $esd_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
- esd_minor_version=`$ESD_CONFIG $esd_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
- esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
- if test "x$enable_esdtest" = "xyes" ; then
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $ESD_CFLAGS"
- LIBS="$LIBS $ESD_LIBS"
-dnl
-dnl Now check if the installed ESD is sufficiently new. (Also sanity
-dnl checks the results of esd-config to some extent
-dnl
- rm -f conf.esdtest
- AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <esd.h>
-
-char*
-my_strdup (char *str)
-{
- char *new_str;
-
- if (str)
- {
- new_str = malloc ((strlen (str) + 1) * sizeof(char));
- strcpy (new_str, str);
- }
- else
- new_str = NULL;
-
- return new_str;
-}
-
-int main ()
-{
- int major, minor, micro;
- char *tmp_version;
-
- system ("touch conf.esdtest");
-
- /* HP/UX 9 (%@#!) writes to sscanf strings */
- tmp_version = my_strdup("$min_esd_version");
- if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
- printf("%s, bad version string\n", "$min_esd_version");
- exit(1);
- }
-
- if (($esd_major_version > major) ||
- (($esd_major_version == major) && ($esd_minor_version > minor)) ||
- (($esd_major_version == major) && ($esd_minor_version == minor) && ($esd_micro_version >= micro)))
- {
- return 0;
- }
- else
- {
- printf("\n*** 'esd-config --version' returned %d.%d.%d, but the minimum version\n", $esd_major_version, $esd_minor_version, $esd_micro_version);
- printf("*** of ESD required is %d.%d.%d. If esd-config is correct, then it is\n", major, minor, micro);
- printf("*** best to upgrade to the required version.\n");
- printf("*** If esd-config was wrong, set the environment variable ESD_CONFIG\n");
- printf("*** to point to the correct copy of esd-config, and remove the file\n");
- printf("*** config.cache before re-running configure\n");
- return 1;
- }
-}
-
-],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- AC_LANG_RESTORE
- fi
- fi
- if test "x$no_esd" = x ; then
- AC_MSG_RESULT(yes)
- ifelse([$2], , :, [$2])
- else
- AC_MSG_RESULT(no)
- if test "$ESD_CONFIG" = "no" ; then
- echo "*** The esd-config script installed by ESD could not be found"
- echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in"
- echo "*** your path, or set the ESD_CONFIG environment variable to the"
- echo "*** full path to esd-config."
- else
- if test -f conf.esdtest ; then
- :
- else
- echo "*** Could not run ESD test program, checking why..."
- CFLAGS="$CFLAGS $ESD_CFLAGS"
- LIBS="$LIBS $ESD_LIBS"
- AC_LANG_SAVE
- AC_LANG_C
- AC_TRY_LINK([
-#include <stdio.h>
-#include <esd.h>
-], [ return 0; ],
- [ echo "*** The test program compiled, but did not run. This usually means"
- echo "*** that the run-time linker is not finding ESD or finding the wrong"
- echo "*** version of ESD. If it is not finding ESD, you'll need to set your"
- echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
- echo "*** to the installed location Also, make sure you have run ldconfig if that"
- echo "*** is required on your system"
- echo "***"
- echo "*** If you have an old version installed, it is best to remove it, although"
- echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
- [ echo "*** The test program failed to compile or link. See the file config.log for the"
- echo "*** exact error that occured. This usually means ESD was incorrectly installed"
- echo "*** or that you have moved ESD since it was installed. In the latter case, you"
- echo "*** may want to edit the esd-config script: $ESD_CONFIG" ])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- AC_LANG_RESTORE
- fi
- fi
- ESD_CFLAGS=""
- ESD_LIBS=""
- ifelse([$3], , :, [$3])
- fi
- AC_SUBST(ESD_CFLAGS)
- AC_SUBST(ESD_LIBS)
- rm -f conf.esdtest
-])
-
-dnl AM_ESD_SUPPORTS_MULTIPLE_RECORD([ACTION-IF-SUPPORTS [, ACTION-IF-NOT-SUPPORTS]])
-dnl Test, whether esd supports multiple recording clients (version >=0.2.21)
-dnl
-AC_DEFUN([AM_ESD_SUPPORTS_MULTIPLE_RECORD],
-[dnl
- AC_MSG_NOTICE([whether installed esd version supports multiple recording clients])
- ac_save_ESD_CFLAGS="$ESD_CFLAGS"
- ac_save_ESD_LIBS="$ESD_LIBS"
- AM_PATH_ESD(0.2.21,
- ifelse([$1], , [
- AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, true)
- AC_DEFINE(ESD_SUPPORTS_MULTIPLE_RECORD, 1,
- [Define if you have esound with support of multiple recording clients.])],
- [$1]),
- ifelse([$2], , [AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, false)], [$2])
- if test "x$ac_save_ESD_CFLAGS" != x ; then
- ESD_CFLAGS="$ac_save_ESD_CFLAGS"
- fi
- if test "x$ac_save_ESD_LIBS" != x ; then
- ESD_LIBS="$ac_save_ESD_LIBS"
- fi
- )
-])
-
diff --git a/tools/missing-macros/src/m4/xaw.m4 b/tools/missing-macros/src/m4/xaw.m4
deleted file mode 100644
index 60404ae8c28..00000000000
--- a/tools/missing-macros/src/m4/xaw.m4
+++ /dev/null
@@ -1,65 +0,0 @@
-dnl Copyright 2005 Red Hat, Inc
-dnl
-dnl Permission to use, copy, modify, distribute, and sell this software and its
-dnl documentation for any purpose is hereby granted without fee, provided that
-dnl the above copyright notice appear in all copies and that both that
-dnl copyright notice and this permission notice appear in supporting
-dnl documentation.
-dnl
-dnl The above copyright notice and this permission notice shall be included
-dnl in all copies or substantial portions of the Software.
-dnl
-dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-dnl OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-dnl MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-dnl IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
-dnl OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-dnl ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-dnl OTHER DEALINGS IN THE SOFTWARE.
-dnl
-dnl Except as contained in this notice, the name of the copyright holders shall
-dnl not be used in advertising or otherwise to promote the sale, use or
-dnl other dealings in this Software without prior written authorization
-dnl from the copyright holders.
-dnl
-
-# XAW_CHECK_XPRINT_SUPPORT()
-# --------------------------
-# Adds --enable/disable-xprint and selects the appropriate version of the Xaw
-# library. If neither --enable-xprint nor --disable-xprint are given,
-# the presence of an Xaw with Xprint support will be auto detected
-
-AC_DEFUN([XAW_CHECK_XPRINT_SUPPORT],[
- AC_ARG_ENABLE(xprint, AC_HELP_STRING([--enable-xprint], [Enable XPrint support]),
- [use_xprint=$enableval],[use_xprint=auto])
- if test "x$use_xprint" = "xyes"; then
- TMP_CHECK1=xaw8
- TMP_CHECK2=
- xaw_use_xprint=yes
- elif test "x$use_xprint" = "xno"; then
- TMP_CHECK1=xaw7
- TMP_CHECK2=
- xaw_use_xprint=no
- else
- TMP_CHECK1=xaw8
- TMP_CHECK2=xaw7
- xaw_use_xprint=yes
- fi
-
- PKG_CHECK_MODULES(TMP_XAW, $TMP_CHECK1, success=yes, success=no)
- if [[ ! -z $TMP_CHECK2 ]] ; then
- if test $success = no ; then
- PKG_CHECK_MODULES(TMP_XAW, $TMP_CHECK2, success=yes, success=no)
- xaw_use_xprint=no
- fi
- fi
-
- if test "x$success" = "xyes"; then
- $1_CFLAGS=$TMP_XAW_CFLAGS
- $1_LIBS=$TMP_XAW_LIBS
-
- AM_CONDITIONAL([XAW_USE_XPRINT], [test "x$xaw_use_xprint" = "xyes"])
- else
- AC_MSG_ERROR([No suitable version of Xaw found])
- fi
-])
diff --git a/tools/missing-macros/src/m4/xmms.m4 b/tools/missing-macros/src/m4/xmms.m4
deleted file mode 100644
index 8aeaad817d3..00000000000
--- a/tools/missing-macros/src/m4/xmms.m4
+++ /dev/null
@@ -1,149 +0,0 @@
-# CFLAGS and library paths for XMMS
-# written 15 December 1999 by Ben Gertzfield <che@debian.org>
-
-dnl Usage:
-dnl AM_PATH_XMMS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
-dnl
-dnl Example:
-dnl AM_PATH_XMMS(0.9.5.1, , AC_MSG_ERROR([*** XMMS >= 0.9.5.1 not installed - please install first ***]))
-dnl
-dnl Defines XMMS_CFLAGS, XMMS_LIBS, XMMS_DATA_DIR, XMMS_PLUGIN_DIR,
-dnl XMMS_VISUALIZATION_PLUGIN_DIR, XMMS_INPUT_PLUGIN_DIR,
-dnl XMMS_OUTPUT_PLUGIN_DIR, XMMS_GENERAL_PLUGIN_DIR, XMMS_EFFECT_PLUGIN_DIR,
-dnl and XMMS_VERSION for your plugin pleasure.
-dnl
-
-dnl XMMS_TEST_VERSION(AVAILABLE-VERSION, NEEDED-VERSION [, ACTION-IF-OKAY [, ACTION-IF-NOT-OKAY]])
-AC_DEFUN([XMMS_TEST_VERSION], [
-
-# Determine which version number is greater. Prints 2 to stdout if
-# the second number is greater, 1 if the first number is greater,
-# 0 if the numbers are equal.
-
-# Written 15 December 1999 by Ben Gertzfield <che@debian.org>
-# Revised 15 December 1999 by Jim Monty <monty@primenet.com>
-
- AC_PROG_AWK
- xmms_got_version=[` $AWK ' \
-BEGIN { \
- print vercmp(ARGV[1], ARGV[2]); \
-} \
- \
-function vercmp(ver1, ver2, ver1arr, ver2arr, \
- ver1len, ver2len, \
- ver1int, ver2int, len, i, p) { \
- \
- ver1len = split(ver1, ver1arr, /\./); \
- ver2len = split(ver2, ver2arr, /\./); \
- \
- len = ver1len > ver2len ? ver1len : ver2len; \
- \
- for (i = 1; i <= len; i++) { \
- p = 1000 ^ (len - i); \
- ver1int += ver1arr[i] * p; \
- ver2int += ver2arr[i] * p; \
- } \
- \
- if (ver1int < ver2int) \
- return 2; \
- else if (ver1int > ver2int) \
- return 1; \
- else \
- return 0; \
-}' $1 $2`]
-
- if test $xmms_got_version -eq 2; then # failure
- ifelse([$4], , :, $4)
- else # success!
- ifelse([$3], , :, $3)
- fi
-])
-
-AC_DEFUN([AM_PATH_XMMS],
-[
-AC_ARG_WITH(xmms-prefix,[ --with-xmms-prefix=PFX Prefix where XMMS is installed (optional)],
- xmms_config_prefix="$withval", xmms_config_prefix="")
-AC_ARG_WITH(xmms-exec-prefix,[ --with-xmms-exec-prefix=PFX Exec prefix where XMMS is installed (optional)],
- xmms_config_exec_prefix="$withval", xmms_config_exec_prefix="")
-
-if test x$xmms_config_exec_prefix != x; then
- xmms_config_args="$xmms_config_args --exec-prefix=$xmms_config_exec_prefix"
- if test x${XMMS_CONFIG+set} != xset; then
- XMMS_CONFIG=$xmms_config_exec_prefix/bin/xmms-config
- fi
-fi
-
-if test x$xmms_config_prefix != x; then
- xmms_config_args="$xmms_config_args --prefix=$xmms_config_prefix"
- if test x${XMMS_CONFIG+set} != xset; then
- XMMS_CONFIG=$xmms_config_prefix/bin/xmms-config
- fi
-fi
-
-AC_PATH_PROG(XMMS_CONFIG, xmms-config, no)
-min_xmms_version=ifelse([$1], ,0.9.5.1, $1)
-
-if test "$XMMS_CONFIG" = "no"; then
- no_xmms=yes
-else
- XMMS_CFLAGS=`$XMMS_CONFIG $xmms_config_args --cflags`
- XMMS_LIBS=`$XMMS_CONFIG $xmms_config_args --libs`
- XMMS_VERSION=`$XMMS_CONFIG $xmms_config_args --version`
- XMMS_DATA_DIR=`$XMMS_CONFIG $xmms_config_args --data-dir`
- XMMS_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --plugin-dir`
- XMMS_VISUALIZATION_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args \
- --visualization-plugin-dir`
- XMMS_INPUT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --input-plugin-dir`
- XMMS_OUTPUT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --output-plugin-dir`
- XMMS_EFFECT_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --effect-plugin-dir`
- XMMS_GENERAL_PLUGIN_DIR=`$XMMS_CONFIG $xmms_config_args --general-plugin-dir`
-
- XMMS_TEST_VERSION($XMMS_VERSION, $min_xmms_version, ,no_xmms=version)
-fi
-
-AC_MSG_CHECKING(for XMMS - version >= $min_xmms_version)
-
-if test "x$no_xmms" = x; then
- AC_MSG_RESULT(yes)
- ifelse([$2], , :, [$2])
-else
- AC_MSG_RESULT(no)
-
- if test "$XMMS_CONFIG" = "no" ; then
- echo "*** The xmms-config script installed by XMMS could not be found."
- echo "*** If XMMS was installed in PREFIX, make sure PREFIX/bin is in"
- echo "*** your path, or set the XMMS_CONFIG environment variable to the"
- echo "*** full path to xmms-config."
- else
- if test "$no_xmms" = "version"; then
- echo "*** An old version of XMMS, $XMMS_VERSION, was found."
- echo "*** You need a version of XMMS newer than $min_xmms_version."
- echo "*** The latest version of XMMS is always available from"
- echo "*** http://www.xmms.org/"
- echo "***"
-
- echo "*** If you have already installed a sufficiently new version, this error"
- echo "*** probably means that the wrong copy of the xmms-config shell script is"
- echo "*** being found. The easiest way to fix this is to remove the old version"
- echo "*** of XMMS, but you can also set the XMMS_CONFIG environment to point to the"
- echo "*** correct copy of xmms-config. (In this case, you will have to"
- echo "*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf"
- echo "*** so that the correct libraries are found at run-time)"
- fi
- fi
- XMMS_CFLAGS=""
- XMMS_LIBS=""
- ifelse([$3], , :, [$3])
-fi
-AC_SUBST(XMMS_CFLAGS)
-AC_SUBST(XMMS_LIBS)
-AC_SUBST(XMMS_VERSION)
-AC_SUBST(XMMS_DATA_DIR)
-AC_SUBST(XMMS_PLUGIN_DIR)
-AC_SUBST(XMMS_VISUALIZATION_PLUGIN_DIR)
-AC_SUBST(XMMS_INPUT_PLUGIN_DIR)
-AC_SUBST(XMMS_OUTPUT_PLUGIN_DIR)
-AC_SUBST(XMMS_GENERAL_PLUGIN_DIR)
-AC_SUBST(XMMS_EFFECT_PLUGIN_DIR)
-])
-
diff --git a/tools/mkimage/Makefile b/tools/mkimage/Makefile
index 2ea1123c265..d0ff5f7e370 100644
--- a/tools/mkimage/Makefile
+++ b/tools/mkimage/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2006-2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,29 +7,42 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mkimage
-PKG_VERSION:=2011.06
+PKG_VERSION:=2018.03
PKG_SOURCE:=u-boot-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
-PKG_MD5SUM:=0cc5026aad02f218a9b9ac56b301c97a
-PKG_CAT:=bzcat
+PKG_SOURCE_URL:=\
+ http://mirror2.openwrt.org/sources \
+ ftp://ftp.denx.de/pub/u-boot
+PKG_HASH:=7e7477534409d5368eb1371ffde6820f0f79780a1a1f676161c48442cb303dfd
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/u-boot-$(PKG_VERSION)
include $(INCLUDE_DIR)/host-build.mk
+define Host/Prepare
+ $(Host/Prepare/Default)
+ mkdir -p $(HOST_BUILD_DIR)/include/config
+ touch $(HOST_BUILD_DIR)/include/config/auto.conf
+endef
+
define Host/Compile
- rm -f $(HOST_BUILD_DIR)/tools/.depend
- touch $(HOST_BUILD_DIR)/include/config.h
- $(MAKE) -C $(HOST_BUILD_DIR) BUILD_DIR= BIN_FILES-y="mkimage" tools
+ $(MAKE) -C $(HOST_BUILD_DIR) \
+ HOSTCFLAGS="$(HOST_CFLAGS)" \
+ HOSTLDFLAGS="$(HOST_LDFLAGS)" \
+ no-dot-config-targets=tools-only \
+ CONFIG_MKIMAGE_DTC_PATH=dtc \
+ CONFIG_FIT_SIGNATURE=y \
+ tools-only
endef
define Host/Install
$(CP) $(HOST_BUILD_DIR)/tools/mkimage $(STAGING_DIR_HOST)/bin/
+ $(CP) $(HOST_BUILD_DIR)/tools/mkenvimage $(STAGING_DIR_HOST)/bin/
endef
define Host/Clean
rm -f $(STAGING_DIR_HOST)/bin/mkimage
+ rm -f $(STAGING_DIR_HOST)/bin/mkenvimage
endef
$(eval $(call HostBuild))
diff --git a/tools/mkimage/patches/010-freebsd-ulong-fix.patch b/tools/mkimage/patches/010-freebsd-ulong-fix.patch
index 32fa0745339..7d891657f8a 100644
--- a/tools/mkimage/patches/010-freebsd-ulong-fix.patch
+++ b/tools/mkimage/patches/010-freebsd-ulong-fix.patch
@@ -1,6 +1,6 @@
--- a/include/image.h
+++ b/include/image.h
-@@ -50,6 +50,10 @@
+@@ -51,6 +51,10 @@ struct lmb;
#endif /* USE_HOSTCC */
@@ -8,6 +8,6 @@
+#define ulong unsigned long
+#endif
+
- #if defined(CONFIG_FIT)
- #include <fdt.h>
- #include <libfdt.h>
+ #if IMAGE_ENABLE_FIT
+ #include <hash.h>
+ #include <linux/libfdt.h>
diff --git a/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch b/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch
deleted file mode 100644
index ff1ae807da0..00000000000
--- a/tools/mkimage/patches/020-darwin-10_7-getline-fix.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/tools/os_support.h
-+++ b/tools/os_support.h
-@@ -28,7 +28,7 @@
- #include "mingw_support.h"
- #endif
-
--#ifdef __APPLE__
-+#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
- #include "getline.h"
- #endif
-
---- a/tools/os_support.c
-+++ b/tools/os_support.c
-@@ -23,6 +23,7 @@
- #ifdef __MINGW32__
- #include "mingw_support.c"
- #endif
--#ifdef __APPLE__
-+
-+#if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L
- #include "getline.c"
- #endif
diff --git a/tools/mkimage/patches/020-include_compile_fix.patch b/tools/mkimage/patches/020-include_compile_fix.patch
new file mode 100644
index 00000000000..276cae0cb16
--- /dev/null
+++ b/tools/mkimage/patches/020-include_compile_fix.patch
@@ -0,0 +1,10 @@
+--- a/include/u-boot/rsa-checksum.h
++++ b/include/u-boot/rsa-checksum.h
+@@ -7,7 +7,6 @@
+ #ifndef _RSA_CHECKSUM_H
+ #define _RSA_CHECKSUM_H
+
+-#include <errno.h>
+ #include <image.h>
+ #include <u-boot/sha1.h>
+ #include <u-boot/sha256.h>
diff --git a/tools/mkimage/patches/030-allow-to-use-different-magic.patch b/tools/mkimage/patches/030-allow-to-use-different-magic.patch
index 31a9065f3f0..c6de9a0aaf6 100644
--- a/tools/mkimage/patches/030-allow-to-use-different-magic.patch
+++ b/tools/mkimage/patches/030-allow-to-use-different-magic.patch
@@ -1,48 +1,65 @@
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
-@@ -37,6 +37,7 @@ struct mkimage_params params = {
+@@ -21,6 +21,7 @@ static struct image_tool_params params =
.arch = IH_ARCH_PPC,
.type = IH_TYPE_KERNEL,
.comp = IH_COMP_GZIP,
+ .magic = IH_MAGIC,
.dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,
.imagename = "",
- };
-@@ -180,6 +181,16 @@ main (int argc, char **argv)
- genimg_get_comp_id (*++argv)) < 0)
- usage ();
- goto NXTARG;
-+ case 'M':
-+ if (--argc <=0)
-+ usage ();
-+ params.magic = strtoul (*++argv, &ptr, 16);
-+ if (*ptr) {
-+ fprintf (stderr,
-+ "%s: invalid magic %s\n",
-+ params.cmdname, *argv);
-+ }
-+ goto NXTARG;
- case 'D':
- if (--argc <= 0)
- usage ();
-@@ -580,12 +591,13 @@ usage ()
- fprintf (stderr, "Usage: %s -l image\n"
+ .imagename2 = "",
+@@ -77,11 +78,12 @@ static void usage(const char *msg)
" -l ==> list image header information\n",
params.cmdname);
-- fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp "
-+ fprintf (stderr, " %s [-x] -A arch -O os -T type -C comp -M magic "
- "-a addr -e ep -n name -d data_file[:data_file...] image\n"
- " -A ==> set architecture to 'arch'\n"
- " -O ==> set operating system to 'os'\n"
- " -T ==> set image type to 'type'\n"
- " -C ==> set compression type 'comp'\n"
-+ " -M ==> set image magic to 'magic'\n"
- " -a ==> set load address to 'addr' (hex)\n"
- " -e ==> set entry point to 'ep' (hex)\n"
- " -n ==> set image name to 'name'\n"
---- a/tools/mkimage.h
-+++ b/tools/mkimage.h
-@@ -64,6 +64,7 @@ struct mkimage_params {
+ fprintf(stderr,
+- " %s [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image\n"
++ " %s [-x] -A arch -O os -T type -C comp -M magic -a addr -e ep -n name -d data_file[:data_file...] image\n"
+ " -A ==> set architecture to 'arch'\n"
+ " -O ==> set operating system to 'os'\n"
+ " -T ==> set image type to 'type'\n"
+ " -C ==> set compression type 'comp'\n"
++ " -M ==> set image magic to 'magic'\n"
+ " -a ==> set load address to 'addr' (hex)\n"
+ " -e ==> set entry point to 'ep' (hex)\n"
+ " -n ==> set image name to 'name'\n"
+@@ -144,7 +146,7 @@ static void process_args(int argc, char
+ int opt;
+
+ while ((opt = getopt(argc, argv,
+- "a:A:b:c:C:d:D:e:Ef:Fk:i:K:ln:N:p:O:rR:qsT:vVx")) != -1) {
++ "a:A:b:c:C:d:D:e:Ef:Fk:i:K:lM:n:N:p:O:rR:qsT:vVx")) != -1) {
+ switch (opt) {
+ case 'a':
+ params.addr = strtoull(optarg, &ptr, 16);
+@@ -222,6 +224,14 @@ static void process_args(int argc, char
+ case 'l':
+ params.lflag = 1;
+ break;
++ case 'M':
++ params.magic = strtoull(optarg, &ptr, 16);
++ if (*ptr) {
++ fprintf(stderr, "%s: invalid magic %s\n",
++ params.cmdname, optarg);
++ exit(EXIT_FAILURE);
++ }
++ break;
+ case 'n':
+ params.imagename = optarg;
+ break;
+--- a/tools/default_image.c
++++ b/tools/default_image.c
+@@ -106,7 +106,7 @@ static void image_set_header(void *ptr,
+ imagesize = sbuf->st_size - sizeof(image_header_t);
+
+ /* Build new header */
+- image_set_magic(hdr, IH_MAGIC);
++ image_set_magic(hdr, params->magic);
+ image_set_time(hdr, time);
+ image_set_size(hdr, imagesize);
+ image_set_load(hdr, params->addr);
+--- a/tools/imagetool.h
++++ b/tools/imagetool.h
+@@ -54,6 +54,7 @@ struct image_tool_params {
int arch;
int type;
int comp;
@@ -50,14 +67,3 @@
char *dtc;
unsigned int addr;
unsigned int ep;
---- a/tools/default_image.c
-+++ b/tools/default_image.c
-@@ -110,7 +110,7 @@ static void image_set_header (void *ptr,
- sbuf->st_size - sizeof(image_header_t));
-
- /* Build new header */
-- image_set_magic (hdr, IH_MAGIC);
-+ image_set_magic (hdr, params->magic);
- image_set_time (hdr, sbuf->st_mtime);
- image_set_size (hdr, sbuf->st_size - sizeof(image_header_t));
- image_set_load (hdr, params->addr);
diff --git a/tools/mkimage/patches/050-image_h_portability.patch b/tools/mkimage/patches/050-image_h_portability.patch
new file mode 100644
index 00000000000..dabab399080
--- /dev/null
+++ b/tools/mkimage/patches/050-image_h_portability.patch
@@ -0,0 +1,31 @@
+--- a/include/image.h
++++ b/include/image.h
+@@ -17,7 +17,6 @@
+ #define __IMAGE_H__
+
+ #include "compiler.h"
+-#include <asm/byteorder.h>
+
+ /* Define this to avoid #ifdefs later on */
+ struct lmb;
+@@ -308,13 +307,13 @@ enum {
+ * all data in network byte order (aka natural aka bigendian).
+ */
+ typedef struct image_header {
+- __be32 ih_magic; /* Image Header Magic Number */
+- __be32 ih_hcrc; /* Image Header CRC Checksum */
+- __be32 ih_time; /* Image Creation Timestamp */
+- __be32 ih_size; /* Image Data Size */
+- __be32 ih_load; /* Data Load Address */
+- __be32 ih_ep; /* Entry Point Address */
+- __be32 ih_dcrc; /* Image Data CRC Checksum */
++ uint32_t ih_magic; /* Image Header Magic Number */
++ uint32_t ih_hcrc; /* Image Header CRC Checksum */
++ uint32_t ih_time; /* Image Creation Timestamp */
++ uint32_t ih_size; /* Image Data Size */
++ uint32_t ih_load; /* Data Load Address */
++ uint32_t ih_ep; /* Entry Point Address */
++ uint32_t ih_dcrc; /* Image Data CRC Checksum */
+ uint8_t ih_os; /* Operating System */
+ uint8_t ih_arch; /* CPU architecture */
+ uint8_t ih_type; /* Image Type */
diff --git a/tools/mkimage/patches/060-remove_kernel_includes.patch b/tools/mkimage/patches/060-remove_kernel_includes.patch
new file mode 100644
index 00000000000..e61d8cc4961
--- /dev/null
+++ b/tools/mkimage/patches/060-remove_kernel_includes.patch
@@ -0,0 +1,35 @@
+--- a/include/compiler.h
++++ b/include/compiler.h
+@@ -66,6 +66,11 @@ typedef uint8_t __u8;
+ typedef uint16_t __u16;
+ typedef uint32_t __u32;
+ typedef unsigned int uint;
++typedef uint64_t __u64;
++#ifndef linux
++typedef int __kernel_daddr_t;
++typedef unsigned int __kernel_ino_t;
++#endif
+
+ #define uswap_16(x) \
+ ((((x) & 0xff00) >> 8) | \
+--- a/include/linux/posix_types.h
++++ b/include/linux/posix_types.h
+@@ -43,6 +43,8 @@ typedef void (*__kernel_sighandler_t)(in
+ /* Type of a SYSV IPC key. */
+ typedef int __kernel_key_t;
+
++#ifdef linux
+ #include <asm/posix_types.h>
++#endif
+
+ #endif /* _LINUX_POSIX_TYPES_H */
+--- a/include/linux/types.h
++++ b/include/linux/types.h
+@@ -2,7 +2,6 @@
+ #define _LINUX_TYPES_H
+
+ #include <linux/posix_types.h>
+-#include <asm/types.h>
+ #include <stdbool.h>
+
+ #ifndef __KERNEL_STRICT_NAMES
diff --git a/tools/mkimage/patches/080-remove_compiler_check.patch b/tools/mkimage/patches/080-remove_compiler_check.patch
new file mode 100644
index 00000000000..5e0792f25f3
--- /dev/null
+++ b/tools/mkimage/patches/080-remove_compiler_check.patch
@@ -0,0 +1,16 @@
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -146,13 +146,6 @@
+
+ #if GCC_VERSION >= 40000
+
+-/* GCC 4.1.[01] miscompiles __weak */
+-#ifdef __KERNEL__
+-# if GCC_VERSION >= 40100 && GCC_VERSION <= 40101
+-# error Your version of gcc miscompiles the __weak directive
+-# endif
+-#endif
+-
+ #define __used __attribute__((__used__))
+ #define __compiler_offsetof(a, b) \
+ __builtin_offsetof(a, b)
diff --git a/tools/mkimage/patches/100-freebsd-compat.patch b/tools/mkimage/patches/100-freebsd-compat.patch
new file mode 100644
index 00000000000..1567285714d
--- /dev/null
+++ b/tools/mkimage/patches/100-freebsd-compat.patch
@@ -0,0 +1,14 @@
+--- a/Makefile
++++ b/Makefile
+@@ -634,7 +634,10 @@ UBOOTINCLUDE := \
+ -I$(srctree)/arch/$(ARCH)/include \
+ -include $(srctree)/include/linux/kconfig.h
+
+-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
++ifneq ($(shell uname),FreeBSD)
++ NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
++endif
++
+ CHECKFLAGS += $(NOSTDINC_FLAGS)
+
+ # FIX ME
diff --git a/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch b/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch
new file mode 100644
index 00000000000..29058e22b71
--- /dev/null
+++ b/tools/mkimage/patches/200-rsa-sign-add-support-for-libressl.patch
@@ -0,0 +1,68 @@
+From 69176c8602e29f4bd30457240374800d88dc39ed Mon Sep 17 00:00:00 2001
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Sat, 14 Apr 2018 22:39:34 +0200
+Subject: [PATCH] rsa-sign: add support for libressl
+
+---
+ lib/rsa/rsa-sign.c | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+--- a/lib/rsa/rsa-sign.c
++++ b/lib/rsa/rsa-sign.c
+@@ -21,7 +21,8 @@
+ #define HAVE_ERR_REMOVE_THREAD_STATE
+ #endif
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
+ static void RSA_get0_key(const RSA *r,
+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+ {
+@@ -300,7 +301,8 @@ static int rsa_init(void)
+ {
+ int ret;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
+ ret = SSL_library_init();
+ #else
+ ret = OPENSSL_init_ssl(0, NULL);
+@@ -309,7 +311,7 @@ static int rsa_init(void)
+ fprintf(stderr, "Failure to init SSL library\n");
+ return -1;
+ }
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ SSL_load_error_strings();
+
+ OpenSSL_add_all_algorithms();
+@@ -355,7 +357,7 @@ err_set_rsa:
+ err_engine_init:
+ ENGINE_free(e);
+ err_engine_by_id:
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ENGINE_cleanup();
+ #endif
+ return ret;
+@@ -363,7 +365,7 @@ err_engine_by_id:
+
+ static void rsa_remove(void)
+ {
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ CRYPTO_cleanup_all_ex_data();
+ ERR_free_strings();
+ #ifdef HAVE_ERR_REMOVE_THREAD_STATE
+@@ -433,7 +435,8 @@ static int rsa_sign_with_key(RSA *rsa, s
+ ret = rsa_err("Could not obtain signature");
+ goto err_sign;
+ }
+- #if OPENSSL_VERSION_NUMBER < 0x10100000L
++ #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ defined(LIBRESSL_VERSION_NUMBER)
+ EVP_MD_CTX_cleanup(context);
+ #else
+ EVP_MD_CTX_reset(context);
diff --git a/tools/mkimage/patches/210-link-libcrypto-static.patch b/tools/mkimage/patches/210-link-libcrypto-static.patch
new file mode 100644
index 00000000000..66412ce43b5
--- /dev/null
+++ b/tools/mkimage/patches/210-link-libcrypto-static.patch
@@ -0,0 +1,14 @@
+OpenWrt links the libressl statically against mkimage, make sure all the
+needed dependencies are added too.
+
+--- a/tools/Makefile
++++ b/tools/Makefile
+@@ -145,7 +145,7 @@ endif
+ # MXSImage needs LibSSL
+ ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_ARMADA_39X)$(CONFIG_FIT_SIGNATURE),)
+ HOSTLOADLIBES_mkimage += \
+- $(shell pkg-config --libs libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto")
++ $(shell pkg-config --libs --static libssl libcrypto 2> /dev/null || echo "-lssl -lcrypto")
+
+ # OS X deprecate openssl in favour of CommonCrypto, supress deprecation
+ # warnings on those systems
diff --git a/tools/mklibs/Makefile b/tools/mklibs/Makefile
index bd967217ead..507c2fd3949 100644
--- a/tools/mklibs/Makefile
+++ b/tools/mklibs/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mklibs
-PKG_VERSION:=0.1.29
+PKG_VERSION:=0.1.35
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://ftp.de.debian.org/debian/pool/main/m/mklibs/
-PKG_MD5SUM:=7f35dfdbde249a090199829c1a1222d8
+PKG_HASH:=ccb1023dc1729c5a37ca6c3eca8e4bac3491116763c8820dfce8eea4845c8567
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/mklibs
+HOST_FIXUP:=autoreconf
include $(INCLUDE_DIR)/host-build.mk
@@ -21,8 +21,8 @@ HOST_CFLAGS += -I$(CURDIR)/include
define Host/Install
$(INSTALL_BIN) \
- $(HOST_BUILD_DIR)/src/mklibs.py \
- $(HOST_BUILD_DIR)/src/mklibs-copy.py \
+ $(HOST_BUILD_DIR)/src/mklibs \
+ $(HOST_BUILD_DIR)/src/mklibs-copy \
$(HOST_BUILD_DIR)/src/mklibs-readelf/mklibs-readelf \
$(STAGING_DIR_HOST)/bin/
endef
diff --git a/tools/mklibs/patches/001-compile.patch b/tools/mklibs/patches/001-compile.patch
new file mode 100644
index 00000000000..09b831ada2c
--- /dev/null
+++ b/tools/mklibs/patches/001-compile.patch
@@ -0,0 +1,8 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,4 +1,4 @@
+-AC_INIT([mklibs],m4_esyscmd(dpkg-parsechangelog | perl -ne 'print $1 if m/^Version: (.*)$/;'))
++AC_INIT([mklibs],m4_esyscmd([head -n1 debian/changelog | awk -F'[\\\\(\\\\)]' '{ print $2 }' | xargs -I{} echo -n {}]))
+ AM_INIT_AUTOMAKE([foreign no-define])
+ AC_CONFIG_HEADERS([config.h])
+ AM_MAINTAINER_MODE
diff --git a/tools/mklibs/patches/001-missing_stdio.patch b/tools/mklibs/patches/001-missing_stdio.patch
deleted file mode 100644
index fe05ee29a8e..00000000000
--- a/tools/mklibs/patches/001-missing_stdio.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/src/mklibs-readelf/main.cpp
-+++ b/src/mklibs-readelf/main.cpp
-@@ -7,6 +7,7 @@
-
- #include <elf.h>
- #include <getopt.h>
-+#include <stdio.h>
-
- #include "elf.hpp"
-
diff --git a/tools/mklibs/patches/002-disable_symbol_checks.patch b/tools/mklibs/patches/002-disable_symbol_checks.patch
index 7ec63937c43..44be637609d 100644
--- a/tools/mklibs/patches/002-disable_symbol_checks.patch
+++ b/tools/mklibs/patches/002-disable_symbol_checks.patch
@@ -1,23 +1,20 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -500,7 +500,7 @@ while 1:
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -524,7 +524,7 @@ while 1:
# No progress in last pass. Verify all remaining symbols are weak.
for name in unresolved:
if not needed_symbols[name].weak:
-- raise "Unresolvable symbol %s" % name
+- raise Exception("Unresolvable symbol %s" % name)
+ print "WARNING: Unresolvable symbol %s" % name
break
previous_pass_unresolved = unresolved
-@@ -533,10 +533,7 @@ while 1:
-
- # which symbols are actually used from each lib
+@@ -559,7 +559,7 @@ while 1:
for name in needed_symbols:
-- if not name in symbol_provider:
-- if not needed_symbols[name].weak:
-- raise "No library provides non-weak %s" % name
-- else:
-+ if name in symbol_provider:
+ if not name in symbol_provider:
+ if not needed_symbols[name].weak:
+- raise Exception("No library provides non-weak %s" % name)
++ print "WARNING: Unresolvable symbol %s" % name
+ else:
lib = symbol_provider[name]
library_symbols_used[lib].add(library_symbols[lib][name])
-
diff --git a/tools/mklibs/patches/003-no_copy.patch b/tools/mklibs/patches/003-no_copy.patch
index bd6505aff99..e0ab2ac88d1 100644
--- a/tools/mklibs/patches/003-no_copy.patch
+++ b/tools/mklibs/patches/003-no_copy.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -440,7 +440,7 @@ while 1:
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -463,7 +463,7 @@ while 1:
passnr = passnr + 1
# Gather all already reduced libraries and treat them as objects as well
small_libs = []
@@ -9,7 +9,7 @@
obj = dest_path + "/" + lib
small_libs.append(obj)
inode = os.stat(obj)[ST_INO]
-@@ -552,12 +552,7 @@ while 1:
+@@ -579,12 +579,7 @@ while 1:
if not so_file:
sys.exit("File not found:" + library)
pic_file = find_pic(library)
@@ -23,7 +23,7 @@
# we have a pic file, recompile
debug(DEBUG_SPAM, "extracting from:", pic_file, "so_file:", so_file)
soname = extract_soname(so_file)
-@@ -600,22 +595,14 @@ while 1:
+@@ -627,22 +622,14 @@ while 1:
cmd.append(library_depends_gcc_libnames(so_file))
command(target + "gcc", *cmd)
diff --git a/tools/mklibs/patches/004-libpthread_link.patch b/tools/mklibs/patches/004-libpthread_link.patch
index b4a6e4f5132..657e232b0cb 100644
--- a/tools/mklibs/patches/004-libpthread_link.patch
+++ b/tools/mklibs/patches/004-libpthread_link.patch
@@ -1,13 +1,13 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -105,14 +105,14 @@ def library_depends(obj):
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -106,14 +106,14 @@ def library_depends(obj):
# Return a list of libraries the passed objects depend on. The
# libraries are in "-lfoo" format suitable for passing to gcc.
-def library_depends_gcc_libnames(obj):
+def library_depends_gcc_libnames(obj, soname):
if not os.access(obj, os.F_OK):
- raise "Cannot find lib: " + obj
+ raise Exception("Cannot find lib: " + obj)
libs = library_depends(obj)
ret = []
for i in libs:
@@ -17,7 +17,7 @@
if match.group('ld'):
ret.append(find_lib(match.group(0)))
elif match.group('lib'):
-@@ -592,7 +592,7 @@ while 1:
+@@ -619,7 +619,7 @@ while 1:
cmd.extend(extra_flags)
cmd.append("-lgcc")
cmd.extend(["-L%s" % a for a in [dest_path] + [sysroot + b for b in lib_path if sysroot == "" or b not in ("/" + libdir + "/", "/usr/" + libdir + "/")]])
diff --git a/tools/mklibs/patches/006-duplicate_syms.patch b/tools/mklibs/patches/005-duplicate_syms.patch
index 3f39ee5bb48..8428abfc9a0 100644
--- a/tools/mklibs/patches/006-duplicate_syms.patch
+++ b/tools/mklibs/patches/005-duplicate_syms.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -507,7 +507,6 @@ while 1:
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -531,7 +531,6 @@ while 1:
library_symbols = {}
library_symbols_used = {}
@@ -8,7 +8,7 @@
# WORKAROUND: Always add libgcc on old-abi arm
header = elf_header(find_lib(libraries.copy().pop()))
-@@ -525,17 +524,13 @@ while 1:
+@@ -549,20 +548,13 @@ while 1:
library_symbols_used[library] = set()
for symbol in symbols:
for name in symbol.base_names():
@@ -21,7 +21,10 @@
# which symbols are actually used from each lib
for name in needed_symbols:
-- if name in symbol_provider:
+- if not name in symbol_provider:
+- if not needed_symbols[name].weak:
+- print "WARNING: Unresolvable symbol %s" % name
+- else:
- lib = symbol_provider[name]
- library_symbols_used[lib].add(library_symbols[lib][name])
+ for lib in libraries:
diff --git a/tools/mklibs/patches/005-readelf_fixes.patch b/tools/mklibs/patches/005-readelf_fixes.patch
deleted file mode 100644
index f755942cd8a..00000000000
--- a/tools/mklibs/patches/005-readelf_fixes.patch
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/src/mklibs-readelf/main.cpp
-+++ b/src/mklibs-readelf/main.cpp
-@@ -57,6 +57,10 @@ static void process_elf_header (Elf::fil
- static void process_dynamics (Elf::file *file, int64_t tag)
- {
- const Elf::section_type<Elf::section_type_DYNAMIC> *section = file->get_section_DYNAMIC ();
-+
-+ if (!section)
-+ return;
-+
- for (std::vector<Elf::dynamic *>::const_iterator it = section->get_dynamics ().begin (); it != section->get_dynamics ().end (); ++it)
- {
- Elf::dynamic *dynamic = *it;
-@@ -67,6 +71,9 @@ static void process_dynamics (Elf::file
-
- static void process_symbols_provided (const Elf::section_type<Elf::section_type_DYNSYM> *section)
- {
-+ if (!section)
-+ return;
-+
- for (std::vector<Elf::symbol *>::const_iterator it = section->get_symbols ().begin (); it != section->get_symbols ().end (); ++it)
- {
- const Elf::symbol *symbol = *it;
-@@ -95,6 +102,9 @@ static void process_symbols_provided (co
-
- static void process_symbols_undefined (const Elf::section_type<Elf::section_type_DYNSYM> *section)
- {
-+ if (!section)
-+ return;
-+
- for (std::vector<Elf::symbol *>::const_iterator it = section->get_symbols ().begin (); it != section->get_symbols ().end (); ++it)
- {
- const Elf::symbol *symbol = *it;
diff --git a/tools/mklibs/patches/007-uclibc_init.patch b/tools/mklibs/patches/006-uclibc_init.patch
index e76515085c4..2df7fe43556 100644
--- a/tools/mklibs/patches/007-uclibc_init.patch
+++ b/tools/mklibs/patches/006-uclibc_init.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -571,6 +571,11 @@ while 1:
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -595,6 +595,11 @@ while 1:
extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o")
symbols.add(ProvidedSymbol('__dso_handle', None, None, True))
diff --git a/tools/mklibs/patches/008-gc_sections.patch b/tools/mklibs/patches/007-gc_sections.patch
index 2775493b092..068d88a532a 100644
--- a/tools/mklibs/patches/008-gc_sections.patch
+++ b/tools/mklibs/patches/007-gc_sections.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -583,7 +583,7 @@ while 1:
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -607,7 +607,7 @@ while 1:
# compile in only used symbols
cmd = []
cmd.extend(gcc_options)
diff --git a/tools/mklibs/patches/009-uclibc_libgcc_link.patch b/tools/mklibs/patches/008-uclibc_libgcc_link.patch
index 36f20671931..432a313b6c3 100644
--- a/tools/mklibs/patches/009-uclibc_libgcc_link.patch
+++ b/tools/mklibs/patches/008-uclibc_libgcc_link.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -112,11 +112,8 @@ def library_depends_gcc_libnames(obj, so
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -113,11 +113,8 @@ def library_depends_gcc_libnames(obj, so
ret = []
for i in libs:
match = re.match("^(((?P<ld>ld\S*)|(lib(?P<lib>\S+))))\.so.*$", i)
@@ -14,7 +14,7 @@
return ' '.join(ret)
class Symbol(object):
-@@ -560,6 +557,7 @@ while 1:
+@@ -584,6 +581,7 @@ while 1:
extra_flags = []
extra_pre_obj = []
extra_post_obj = []
@@ -22,7 +22,7 @@
symbols.update(library_symbols_used[library])
-@@ -590,9 +588,10 @@ while 1:
+@@ -614,9 +612,10 @@ while 1:
cmd.append(pic_file)
cmd.extend(extra_post_obj)
cmd.extend(extra_flags)
diff --git a/tools/mklibs/patches/010-uclibc_libpthread_symbols.patch b/tools/mklibs/patches/009-uclibc_libpthread_symbols.patch
index 0c97216d1aa..34866f72905 100644
--- a/tools/mklibs/patches/010-uclibc_libpthread_symbols.patch
+++ b/tools/mklibs/patches/009-uclibc_libpthread_symbols.patch
@@ -1,6 +1,6 @@
---- a/src/mklibs.py
-+++ b/src/mklibs.py
-@@ -161,9 +161,10 @@ def undefined_symbols(obj):
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -162,9 +162,10 @@ def undefined_symbols(obj):
return result
class ProvidedSymbol(Symbol):
@@ -12,7 +12,7 @@
def base_names(self):
ret = []
-@@ -204,11 +205,15 @@ def provided_symbols(obj):
+@@ -205,11 +206,15 @@ def provided_symbols(obj):
if version_string.lower() not in ('base', 'none'):
version = version_string
@@ -29,7 +29,7 @@
return result
-@@ -476,6 +481,9 @@ while 1:
+@@ -500,6 +505,9 @@ while 1:
debug(DEBUG_SPAM, "present_symbols adding %s" % symbol)
names = symbol.base_names()
for name in names:
@@ -39,7 +39,7 @@
present_symbols[name] = symbol
# are we finished?
-@@ -567,12 +575,16 @@ while 1:
+@@ -591,12 +599,16 @@ while 1:
# may segfault in ptmalloc_init due to undefined weak reference
extra_pre_obj.append(sysroot + libc_extras_dir + "/soinit.o")
extra_post_obj.append(sysroot + libc_extras_dir + "/sofini.o")
diff --git a/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch b/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch
new file mode 100644
index 00000000000..6bae8c7ce53
--- /dev/null
+++ b/tools/mklibs/patches/010-remove_STT_GNU_IFUNC.patch
@@ -0,0 +1,20 @@
+--- a/src/mklibs-readelf/main.cpp
++++ b/src/mklibs-readelf/main.cpp
+@@ -84,7 +84,7 @@ static void process_symbols_provided (co
+ continue;
+ if (shndx == SHN_UNDEF || shndx == SHN_ABS)
+ continue;
+- if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_GNU_IFUNC && type != STT_COMMON && type != STT_TLS)
++ if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_COMMON && type != STT_TLS)
+ continue;
+ if (!name.size())
+ continue;
+@@ -115,7 +115,7 @@ static void process_symbols_undefined (c
+ continue;
+ if (shndx != SHN_UNDEF)
+ continue;
+- if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_GNU_IFUNC && type != STT_COMMON && type != STT_TLS)
++ if (type != STT_NOTYPE && type != STT_OBJECT && type != STT_FUNC && type != STT_COMMON && type != STT_TLS)
+ continue;
+ if (!name.size())
+ continue;
diff --git a/tools/mklibs/patches/011-remove_multiarch.patch b/tools/mklibs/patches/011-remove_multiarch.patch
new file mode 100644
index 00000000000..a32d8ee17a8
--- /dev/null
+++ b/tools/mklibs/patches/011-remove_multiarch.patch
@@ -0,0 +1,10 @@
+--- a/src/mklibs
++++ b/src/mklibs
+@@ -263,6 +263,7 @@ def extract_soname(so_file):
+ return ""
+
+ def multiarch(paths):
++ return paths
+ devnull = open('/dev/null', 'w')
+ dpkg_architecture = subprocess.Popen(
+ ['dpkg-architecture', '-qDEB_HOST_MULTIARCH'],
diff --git a/tools/mm-macros/Makefile b/tools/mm-macros/Makefile
index f2a0cccbf33..2d7991455f1 100644
--- a/tools/mm-macros/Makefile
+++ b/tools/mm-macros/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2010 OpenWrt.org
+# Copyright (C) 2010-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -8,11 +8,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mm-macros
-PKG_VERSION:=0.9.2
+PKG_VERSION:=0.9.12
-PKG_SOURCE_URL:=http://ftp.gnome.org/pub/GNOME/sources/mm-common/0.9
-PKG_SOURCE:=mm-common-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=8cdc5620bd864d1a17e353398e8ec1ab
+PKG_SOURCE_URL:=@GNOME/mm-common/0.9
+PKG_SOURCE:=mm-common-$(PKG_VERSION).tar.xz
+PKG_HASH:=ceffdcce1e5b52742884c233ec604bf6fded12eea9da077ce7a62c02c87e7c0b
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/mm-common-$(PKG_VERSION)
diff --git a/tools/mpc/Makefile b/tools/mpc/Makefile
index ab799b269e5..70dca2637d6 100644
--- a/tools/mpc/Makefile
+++ b/tools/mpc/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,11 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mpc
-PKG_VERSION:=0.8.2
+PKG_VERSION:=1.1.0
-PKG_SOURCE_URL:=http://www.multiprecision.org/mpc/download/
+PKG_SOURCE_URL:=@GNU/mpc/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=e98267ebd5648a39f881d66797122fb6
+PKG_HASH:=6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
@@ -23,13 +25,4 @@ HOST_CONFIGURE_ARGS += \
--with-mpfr=$(TOPDIR)/staging_dir/host \
--with-gmp=$(TOPDIR)/staging_dir/host
-define Host/Configure
- (cd $(HOST_BUILD_DIR)/$(3); \
- $(HOST_CONFIGURE_CMD) \
- $(HOST_CONFIGURE_VARS) \
- $(HOST_CONFIGURE_ARGS); \
- )
-endef
-
-
$(eval $(call HostBuild))
diff --git a/tools/mpfr/Makefile b/tools/mpfr/Makefile
index 72712f219dc..dfff7964ce4 100644
--- a/tools/mpfr/Makefile
+++ b/tools/mpfr/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,12 +7,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mpfr
-PKG_VERSION:=3.0.0
+PKG_VERSION:=4.0.1
+PKG_CPE_ID:=cpe:/a:mpfr:gnu_mpfr
-PKG_SOURCE_URL:=http://www.mpfr.org/mpfr-$(PKG_VERSION)
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=f45bac3584922c8004a10060ab1a8f9f
+PKG_SOURCE_URL:=http://www.mpfr.org/mpfr-$(PKG_VERSION) \
+ @GNU/mpfr
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_HASH:=67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e
+HOST_BUILD_PARALLEL:=1
HOST_FIXUP:=autoreconf
include $(INCLUDE_DIR)/host-build.mk
@@ -22,9 +25,4 @@ HOST_CONFIGURE_ARGS += \
--disable-shared \
--with-gmp=$(STAGING_DIR_HOST)
-define Host/Configure
- echo "PATH=$(shell echo $$PATH)"
- $(call Host/Configure/Default)
-endef
-
$(eval $(call HostBuild))
diff --git a/tools/mpfr/patches/000-upstream_cumulative.patch b/tools/mpfr/patches/000-upstream_cumulative.patch
deleted file mode 100644
index e21571b52a1..00000000000
--- a/tools/mpfr/patches/000-upstream_cumulative.patch
+++ /dev/null
@@ -1,1945 +0,0 @@
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-06-23 11:02:49.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-06-23 11:03:36.000000000 +0000
-@@ -0,0 +1 @@
-+mpfr_out_str
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-06-23 11:03:20.000000000 +0000
-@@ -1 +1 @@
--3.0.0
-+3.0.0-p1
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-06-23 11:03:20.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0"
-+#define MPFR_VERSION_STRING "3.0.0-p1"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/mpfr.texi mpfr-3.0.0-b/mpfr.texi
---- mpfr-3.0.0-a/mpfr.texi 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.texi 2010-06-23 11:03:12.000000000 +0000
-@@ -2050,7 +2050,7 @@
- are printed. If @var{base} is greater than 10, @samp{@@} will be used
- instead of @samp{e} as exponent delimiter.
-
--Return the number of bytes written, or if an error occurred, return 0.
-+Return the number of characters written, or if an error occurred, return 0.
- @end deftypefun
-
- @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd})
-diff -Naurd mpfr-3.0.0-a/out_str.c mpfr-3.0.0-b/out_str.c
---- mpfr-3.0.0-a/out_str.c 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/out_str.c 2010-06-23 11:03:12.000000000 +0000
-@@ -22,6 +22,16 @@
-
- #include "mpfr-impl.h"
-
-+/* Warning! S should not contain "%". */
-+#define OUT_STR_RET(S) \
-+ do \
-+ { \
-+ int r; \
-+ r = fprintf (stream, (S)); \
-+ return r < 0 ? 0 : r; \
-+ } \
-+ while (0)
-+
- size_t
- mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
- mpfr_rnd_t rnd_mode)
-@@ -29,6 +39,7 @@
- char *s, *s0;
- size_t l;
- mpfr_exp_t e;
-+ int err;
-
- MPFR_ASSERTN (base >= 2 && base <= 62);
-
-@@ -36,37 +47,16 @@
- if (stream == NULL)
- stream = stdout;
-
-- if (MPFR_IS_NAN(op))
-- {
-- fprintf (stream, "@NaN@");
-- return 3;
-- }
--
-- if (MPFR_IS_INF(op))
-- {
-- if (MPFR_SIGN(op) > 0)
-- {
-- fprintf (stream, "@Inf@");
-- return 3;
-- }
-- else
-- {
-- fprintf (stream, "-@Inf@");
-- return 4;
-- }
-- }
--
-- if (MPFR_IS_ZERO(op))
-+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
- {
-- if (MPFR_SIGN(op) > 0)
-- {
-- fprintf(stream, "0");
-- return 1;
-- }
-+ if (MPFR_IS_NAN (op))
-+ OUT_STR_RET ("@NaN@");
-+ else if (MPFR_IS_INF (op))
-+ OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@");
- else
- {
-- fprintf(stream, "-0");
-- return 2;
-+ MPFR_ASSERTD (MPFR_IS_ZERO (op));
-+ OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0");
- }
- }
-
-@@ -77,21 +67,31 @@
-
- l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str
- - may be incorrect, as only an upper bound? */
-- if (*s == '-')
-- fputc (*s++, stream);
-
-- /* outputs mantissa */
-- fputc (*s++, stream); e--; /* leading digit */
-- fputc ((unsigned char) MPFR_DECIMAL_POINT, stream);
-- fputs (s, stream); /* rest of mantissa */
-+ /* outputs possible sign and significand */
-+ err = (*s == '-' && fputc (*s++, stream) == EOF)
-+ || fputc (*s++, stream) == EOF /* leading digit */
-+ || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
-+ || fputs (s, stream) == EOF; /* trailing significand */
- (*__gmp_free_func) (s0, l);
-+ if (MPFR_UNLIKELY (err))
-+ return 0;
-+
-+ e--; /* due to the leading digit */
-
- /* outputs exponent */
- if (e)
- {
-+ int r;
-+
- MPFR_ASSERTN(e >= LONG_MIN);
- MPFR_ASSERTN(e <= LONG_MAX);
-- l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
-+
-+ r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
-+ if (MPFR_UNLIKELY (r < 0))
-+ return 0;
-+
-+ l += r;
- }
-
- return l;
-diff -Naurd mpfr-3.0.0-a/tests/tout_str.c mpfr-3.0.0-b/tests/tout_str.c
---- mpfr-3.0.0-a/tests/tout_str.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tout_str.c 2010-06-23 11:03:12.000000000 +0000
-@@ -46,22 +46,54 @@
- special (void)
- {
- mpfr_t x;
-+ unsigned int n;
-
- mpfr_init (x);
-
- mpfr_set_nan (x);
-- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ if (n != 5)
-+ {
-+ printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u "
-+ "characters instead of 5.\n", n);
-+ exit (1);
-+ }
-
- mpfr_set_inf (x, 1);
-- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ if (n != 5)
-+ {
-+ printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u "
-+ "characters instead of 5.\n", n);
-+ exit (1);
-+ }
-
- mpfr_set_inf (x, -1);
-- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ if (n != 6)
-+ {
-+ printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u "
-+ "characters instead of 6.\n", n);
-+ exit (1);
-+ }
-
- mpfr_set_ui (x, 0, MPFR_RNDN);
-- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ if (n != 1)
-+ {
-+ printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u "
-+ "characters instead of 1.\n", n);
-+ exit (1);
-+ }
-+
- mpfr_neg (x, x, MPFR_RNDN);
-- mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+ if (n != 2)
-+ {
-+ printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u "
-+ "characters instead of 2.\n", n);
-+ exit (1);
-+ }
-
- mpfr_clear (x);
- }
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-06-23 11:03:20.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0";
-+ return "3.0.0-p1";
- }
-diff -Naurd mpfr-3.0.0-a/Makefile.in mpfr-3.0.0-b/Makefile.in
---- mpfr-3.0.0-a/Makefile.in 2010-06-10 11:00:52.000000000 +0000
-+++ mpfr-3.0.0-b/Makefile.in 2010-06-10 11:00:52.000000000 +0000
-@@ -239,6 +239,7 @@
- distuninstallcheck_listfiles = find . -type f -print
- distcleancheck_listfiles = find . -type f -print
- ACLOCAL = @ACLOCAL@
-+ALLOCA = @ALLOCA@
- AMTAR = @AMTAR@
- AR = @AR@
- AS = @AS@
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-06-23 11:03:36.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-06-25 13:23:13.000000000 +0000
-@@ -0,0 +1 @@
-+alloca
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-06-23 11:03:20.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-06-25 13:23:13.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p1
-+3.0.0-p2
-diff -Naurd mpfr-3.0.0-a/acinclude.m4 mpfr-3.0.0-b/acinclude.m4
---- mpfr-3.0.0-a/acinclude.m4 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/acinclude.m4 2010-06-10 11:00:14.000000000 +0000
-@@ -59,6 +59,9 @@
- dnl sys/fpu.h - MIPS specific
- AC_CHECK_HEADERS([sys/time.h sys/fpu.h])
-
-+dnl Check how to get `alloca'
-+AC_FUNC_ALLOCA
-+
- dnl SIZE_MAX macro
- gl_SIZE_MAX
-
-diff -Naurd mpfr-3.0.0-a/configure mpfr-3.0.0-b/configure
---- mpfr-3.0.0-a/configure 2010-06-10 11:00:51.000000000 +0000
-+++ mpfr-3.0.0-b/configure 2010-06-25 13:23:05.000000000 +0000
-@@ -783,6 +783,7 @@
- OBJDUMP
- DLLTOOL
- AS
-+ALLOCA
- MPFR_LIBM
- ANSI2KNR
- U
-@@ -5622,6 +5623,197 @@
- done
-
-
-+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-+# for constant arguments. Useless!
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
-+$as_echo_n "checking for working alloca.h... " >&6; }
-+if test "${ac_cv_working_alloca_h+set}" = set; then :
-+ $as_echo_n "(cached) " >&6
-+else
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+#include <alloca.h>
-+int
-+main ()
-+{
-+char *p = (char *) alloca (2 * sizeof (int));
-+ if (p) return 0;
-+ ;
-+ return 0;
-+}
-+_ACEOF
-+if ac_fn_c_try_link "$LINENO"; then :
-+ ac_cv_working_alloca_h=yes
-+else
-+ ac_cv_working_alloca_h=no
-+fi
-+rm -f core conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
-+$as_echo "$ac_cv_working_alloca_h" >&6; }
-+if test $ac_cv_working_alloca_h = yes; then
-+
-+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
-+
-+fi
-+
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
-+$as_echo_n "checking for alloca... " >&6; }
-+if test "${ac_cv_func_alloca_works+set}" = set; then :
-+ $as_echo_n "(cached) " >&6
-+else
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+#ifdef __GNUC__
-+# define alloca __builtin_alloca
-+#else
-+# ifdef _MSC_VER
-+# include <malloc.h>
-+# define alloca _alloca
-+# else
-+# ifdef HAVE_ALLOCA_H
-+# include <alloca.h>
-+# else
-+# ifdef _AIX
-+ #pragma alloca
-+# else
-+# ifndef alloca /* predefined by HP cc +Olibcalls */
-+char *alloca ();
-+# endif
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+int
-+main ()
-+{
-+char *p = (char *) alloca (1);
-+ if (p) return 0;
-+ ;
-+ return 0;
-+}
-+_ACEOF
-+if ac_fn_c_try_link "$LINENO"; then :
-+ ac_cv_func_alloca_works=yes
-+else
-+ ac_cv_func_alloca_works=no
-+fi
-+rm -f core conftest.err conftest.$ac_objext \
-+ conftest$ac_exeext conftest.$ac_ext
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
-+$as_echo "$ac_cv_func_alloca_works" >&6; }
-+
-+if test $ac_cv_func_alloca_works = yes; then
-+
-+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
-+
-+else
-+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
-+# that cause trouble. Some versions do not even contain alloca or
-+# contain a buggy version. If you still want to use their alloca,
-+# use ar to extract alloca.o from them instead of compiling alloca.c.
-+
-+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
-+
-+$as_echo "#define C_ALLOCA 1" >>confdefs.h
-+
-+
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
-+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
-+if test "${ac_cv_os_cray+set}" = set; then :
-+ $as_echo_n "(cached) " >&6
-+else
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+#if defined CRAY && ! defined CRAY2
-+webecray
-+#else
-+wenotbecray
-+#endif
-+
-+_ACEOF
-+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-+ $EGREP "webecray" >/dev/null 2>&1; then :
-+ ac_cv_os_cray=yes
-+else
-+ ac_cv_os_cray=no
-+fi
-+rm -f conftest*
-+
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
-+$as_echo "$ac_cv_os_cray" >&6; }
-+if test $ac_cv_os_cray = yes; then
-+ for ac_func in _getb67 GETB67 getb67; do
-+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-+eval as_val=\$$as_ac_var
-+ if test "x$as_val" = x""yes; then :
-+
-+cat >>confdefs.h <<_ACEOF
-+#define CRAY_STACKSEG_END $ac_func
-+_ACEOF
-+
-+ break
-+fi
-+
-+ done
-+fi
-+
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
-+$as_echo_n "checking stack direction for C alloca... " >&6; }
-+if test "${ac_cv_c_stack_direction+set}" = set; then :
-+ $as_echo_n "(cached) " >&6
-+else
-+ if test "$cross_compiling" = yes; then :
-+ ac_cv_c_stack_direction=0
-+else
-+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-+/* end confdefs.h. */
-+$ac_includes_default
-+int
-+find_stack_direction ()
-+{
-+ static char *addr = 0;
-+ auto char dummy;
-+ if (addr == 0)
-+ {
-+ addr = &dummy;
-+ return find_stack_direction ();
-+ }
-+ else
-+ return (&dummy > addr) ? 1 : -1;
-+}
-+
-+int
-+main ()
-+{
-+ return find_stack_direction () < 0;
-+}
-+_ACEOF
-+if ac_fn_c_try_run "$LINENO"; then :
-+ ac_cv_c_stack_direction=1
-+else
-+ ac_cv_c_stack_direction=-1
-+fi
-+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-+ conftest.$ac_objext conftest.beam conftest.$ac_ext
-+fi
-+
-+fi
-+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
-+$as_echo "$ac_cv_c_stack_direction" >&6; }
-+cat >>confdefs.h <<_ACEOF
-+#define STACK_DIRECTION $ac_cv_c_stack_direction
-+_ACEOF
-+
-+
-+fi
-+
-+
-
- for ac_header in stdint.h
- do :
-@@ -7564,13 +7756,13 @@
- else
- lt_cv_nm_interface="BSD nm"
- echo "int some_variable = 0;" > conftest.$ac_ext
-- (eval echo "\"\$as_me:7567: $ac_compile\"" >&5)
-+ (eval echo "\"\$as_me:7759: $ac_compile\"" >&5)
- (eval "$ac_compile" 2>conftest.err)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:7570: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
-+ (eval echo "\"\$as_me:7762: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
- (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
- cat conftest.err >&5
-- (eval echo "\"\$as_me:7573: output\"" >&5)
-+ (eval echo "\"\$as_me:7765: output\"" >&5)
- cat conftest.out >&5
- if $GREP 'External.*some_variable' conftest.out > /dev/null; then
- lt_cv_nm_interface="MS dumpbin"
-@@ -8772,7 +8964,7 @@
- ;;
- *-*-irix6*)
- # Find out which ABI we are using.
-- echo '#line 8775 "configure"' > conftest.$ac_ext
-+ echo '#line 8967 "configure"' > conftest.$ac_ext
- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
-@@ -10032,11 +10224,11 @@
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:10035: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:10227: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:10039: \$? = $ac_status" >&5
-+ echo "$as_me:10231: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -10371,11 +10563,11 @@
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:10374: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:10566: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>conftest.err)
- ac_status=$?
- cat conftest.err >&5
-- echo "$as_me:10378: \$? = $ac_status" >&5
-+ echo "$as_me:10570: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s "$ac_outfile"; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings other than the usual output.
-@@ -10476,11 +10668,11 @@
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:10479: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:10671: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:10483: \$? = $ac_status" >&5
-+ echo "$as_me:10675: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -10531,11 +10723,11 @@
- -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
- -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
- -e 's:$: $lt_compiler_flag:'`
-- (eval echo "\"\$as_me:10534: $lt_compile\"" >&5)
-+ (eval echo "\"\$as_me:10726: $lt_compile\"" >&5)
- (eval "$lt_compile" 2>out/conftest.err)
- ac_status=$?
- cat out/conftest.err >&5
-- echo "$as_me:10538: \$? = $ac_status" >&5
-+ echo "$as_me:10730: \$? = $ac_status" >&5
- if (exit $ac_status) && test -s out/conftest2.$ac_objext
- then
- # The compiler can only warn and ignore the option if not recognized
-@@ -12915,7 +13107,7 @@
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 12918 "configure"
-+#line 13110 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-@@ -13011,7 +13203,7 @@
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<_LT_EOF
--#line 13014 "configure"
-+#line 13206 "configure"
- #include "confdefs.h"
-
- #if HAVE_DLFCN_H
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-06-23 11:03:20.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-06-25 13:23:13.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p1"
-+#define MPFR_VERSION_STRING "3.0.0-p2"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/tests/Makefile.in mpfr-3.0.0-b/tests/Makefile.in
---- mpfr-3.0.0-a/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000
-+++ mpfr-3.0.0-b/tests/Makefile.in 2010-06-10 11:00:52.000000000 +0000
-@@ -960,6 +960,7 @@
- red=; grn=; lgn=; blu=; std=
- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
- ACLOCAL = @ACLOCAL@
-+ALLOCA = @ALLOCA@
- AMTAR = @AMTAR@
- AR = @AR@
- AS = @AS@
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-06-23 11:03:20.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-06-25 13:23:13.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p1";
-+ return "3.0.0-p2";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-07-10 00:11:19.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-07-10 00:12:50.000000000 +0000
-@@ -0,0 +1 @@
-+gamma_underflow
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-06-25 13:23:13.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-07-10 00:11:53.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p2
-+3.0.0-p3
-diff -Naurd mpfr-3.0.0-a/gamma.c mpfr-3.0.0-b/gamma.c
---- mpfr-3.0.0-a/gamma.c 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/gamma.c 2010-07-10 00:11:46.000000000 +0000
-@@ -274,7 +274,7 @@
- /* we want an upper bound for x * [log(2-x)-1].
- since x < 0, we need a lower bound on log(2-x) */
- mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
-- mpfr_log (xp, xp, MPFR_RNDD);
-+ mpfr_log2 (xp, xp, MPFR_RNDD);
- mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
- mpfr_mul (xp, xp, x, MPFR_RNDU);
-
-@@ -303,8 +303,8 @@
- {
- mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */
- mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */
-- mpfr_log (tmp, tmp, MPFR_RNDU);
-- mpfr_add (tmp, tmp, xp, MPFR_RNDU);
-+ mpfr_log2 (tmp, tmp, MPFR_RNDU);
-+ mpfr_add (xp, tmp, xp, MPFR_RNDU);
- underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0;
- }
-
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-06-25 13:23:13.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-07-10 00:11:53.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p2"
-+#define MPFR_VERSION_STRING "3.0.0-p3"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/tests/tgamma.c mpfr-3.0.0-b/tests/tgamma.c
---- mpfr-3.0.0-a/tests/tgamma.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tgamma.c 2010-07-10 00:11:46.000000000 +0000
-@@ -461,6 +461,20 @@
- mpfr_clear (x);
- }
-
-+/* bug found by Stathis, only occurs on 32-bit machines */
-+static void
-+test20100709 (void)
-+{
-+ mpfr_t x;
-+ int inex;
-+
-+ mpfr_init2 (x, 100);
-+ mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
-+ inex = mpfr_gamma (x, x, MPFR_RNDN);
-+ MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
-+ mpfr_clear (x);
-+}
-+
- int
- main (int argc, char *argv[])
- {
-@@ -471,6 +485,7 @@
- test_generic (2, 100, 2);
- gamma_integer ();
- test20071231 ();
-+ test20100709 ();
-
- data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
-
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-06-25 13:23:13.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-07-10 00:11:53.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p2";
-+ return "3.0.0-p3";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-09-07 08:44:01.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-09-07 08:48:46.000000000 +0000
-@@ -0,0 +1 @@
-+mpfr_cmp/set_ui/si
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-07-10 00:11:53.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-09-07 08:46:06.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p3
-+3.0.0-p4
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-07-10 00:11:53.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-09-07 08:46:06.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p3"
-+#define MPFR_VERSION_STRING "3.0.0-p4"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-@@ -798,35 +798,45 @@
- anyway. Checking with other ICC versions is needed. Possibly detect
- whether warnings are produced or not with a configure test.
- + Remove C++ too, since it complains too much. */
-+/* Added casts to improve robustness in case of undefined behavior and
-+ compiler extensions based on UB (in particular -fwrapv). MPFR doesn't
-+ use such extensions, but these macros will be used by 3rd-party code,
-+ where such extensions may be required.
-+ Moreover casts to unsigned long have been added to avoid warnings in
-+ programs that use MPFR and are compiled with -Wconversion; such casts
-+ are OK since if X is a constant expression, then (unsigned long) X is
-+ also a constant expression, so that the optimizations still work. */
- #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
- #if (__GNUC__ >= 2)
- #undef mpfr_cmp_ui
--/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0. */
--#define mpfr_cmp_ui(_f,_u) \
-- (__builtin_constant_p (_u) && (_u) == 0 ? \
-- mpfr_sgn (_f) : \
-- mpfr_cmp_ui_2exp ((_f),(_u),0))
-+/* We use the fact that mpfr_sgn on NaN sets the erange flag and returns 0.
-+ But warning! mpfr_sgn is specified as a macro in the API, thus the macro
-+ mustn't be used if side effects are possible, like here. */
-+#define mpfr_cmp_ui(_f,_u) \
-+ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
-+ (mpfr_sgn) (_f) : \
-+ mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
- #undef mpfr_cmp_si
--#define mpfr_cmp_si(_f,_s) \
-- (__builtin_constant_p (_s) && (_s) >= 0 ? \
-- mpfr_cmp_ui ((_f), (_s)) : \
-- mpfr_cmp_si_2exp ((_f), (_s), 0))
-+#define mpfr_cmp_si(_f,_s) \
-+ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
-+ mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \
-+ mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
- #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
- #undef mpfr_set_ui
--#define mpfr_set_ui(_f,_u,_r) \
-- (__builtin_constant_p (_u) && (_u) == 0 ? \
-- __extension__ ({ \
-- mpfr_ptr _p = (_f); \
-- _p->_mpfr_sign = 1; \
-- _p->_mpfr_exp = __MPFR_EXP_ZERO; \
-- (void) (_r); 0; }) : \
-- mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
-+#define mpfr_set_ui(_f,_u,_r) \
-+ (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
-+ __extension__ ({ \
-+ mpfr_ptr _p = (_f); \
-+ _p->_mpfr_sign = 1; \
-+ _p->_mpfr_exp = __MPFR_EXP_ZERO; \
-+ (void) (_r); 0; }) : \
-+ mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
- #endif
- #undef mpfr_set_si
--#define mpfr_set_si(_f,_s,_r) \
-- (__builtin_constant_p (_s) && (_s) >= 0 ? \
-- mpfr_set_ui ((_f), (_s), (_r)) : \
-- mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
-+#define mpfr_set_si(_f,_s,_r) \
-+ (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
-+ mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \
-+ mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
- #endif
- #endif
-
-diff -Naurd mpfr-3.0.0-a/tests/tcmp_ui.c mpfr-3.0.0-b/tests/tcmp_ui.c
---- mpfr-3.0.0-a/tests/tcmp_ui.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tcmp_ui.c 2010-09-07 08:45:12.000000000 +0000
-@@ -88,6 +88,126 @@
- mpfr_clear (x);
- }
-
-+/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro
-+ with __builtin_constant_p for GCC, check that side effects are
-+ handled correctly. */
-+static void
-+check_macros (void)
-+{
-+ mpfr_t x;
-+ int c;
-+
-+ mpfr_init2 (x, 32);
-+
-+ c = 0;
-+ mpfr_set_ui (x, 17, MPFR_RNDN);
-+ if (mpfr_cmp_ui (x, 17) != 0)
-+ {
-+ printf ("Error 1 on mpfr_cmp_ui(x,17) in check_macros\n");
-+ exit (1);
-+ }
-+ if (mpfr_cmp_ui (x, (c++, 17)) != 0)
-+ {
-+ printf ("Error 2 on mpfr_cmp_ui(x,17) in check_macros\n");
-+ exit (1);
-+ }
-+ if (c != 1)
-+ {
-+ printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n"
-+ "(c = %d instead of 1)\n", c);
-+ exit (1);
-+ }
-+ if (mpfr_cmp_si (x, 17) != 0)
-+ {
-+ printf ("Error 1 on mpfr_cmp_si(x,17) in check_macros\n");
-+ exit (1);
-+ }
-+ if (mpfr_cmp_si (x, (c++, 17)) != 0)
-+ {
-+ printf ("Error 2 on mpfr_cmp_si(x,17) in check_macros\n");
-+ exit (1);
-+ }
-+ if (c != 2)
-+ {
-+ printf ("Error 3 on mpfr_cmp_si(x,17) in check_macros\n"
-+ "(c = %d instead of 2)\n", c);
-+ exit (1);
-+ }
-+
-+ c = 0;
-+ mpfr_set_ui (x, 0, MPFR_RNDN);
-+ if (mpfr_cmp_ui (x, 0) != 0)
-+ {
-+ printf ("Error 1 on mpfr_cmp_ui(x,0) in check_macros\n");
-+ exit (1);
-+ }
-+ if (mpfr_cmp_ui (x, (c++, 0)) != 0)
-+ {
-+ printf ("Error 2 on mpfr_cmp_ui(x,0) in check_macros\n");
-+ exit (1);
-+ }
-+ if (c != 1)
-+ {
-+ printf ("Error 3 on mpfr_cmp_ui(x,0) in check_macros\n"
-+ "(c = %d instead of 1)\n", c);
-+ exit (1);
-+ }
-+ if (mpfr_cmp_si (x, 0) != 0)
-+ {
-+ printf ("Error 1 on mpfr_cmp_si(x,0) in check_macros\n");
-+ exit (1);
-+ }
-+ if (mpfr_cmp_si (x, (c++, 0)) != 0)
-+ {
-+ printf ("Error 2 on mpfr_cmp_si(x,0) in check_macros\n");
-+ exit (1);
-+ }
-+ if (c != 2)
-+ {
-+ printf ("Error 3 on mpfr_cmp_si(x,0) in check_macros\n"
-+ "(c = %d instead of 2)\n", c);
-+ exit (1);
-+ }
-+
-+ mpfr_clear (x);
-+}
-+
-+/* Bug in r7114 */
-+static void
-+test_macros (void)
-+{
-+ mpfr_t x[3];
-+ mpfr_ptr p;
-+
-+ mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
-+ mpfr_set_ui (x[0], 0, MPFR_RNDN);
-+ p = x[0];
-+ if (mpfr_cmp_ui (p++, 0) != 0)
-+ {
-+ printf ("Error in mpfr_cmp_ui macro: result should be 0.\n");
-+ exit (1);
-+ }
-+ if (p != x[1])
-+ {
-+ printf ("Error in mpfr_cmp_ui macro: p - x[0] = %d (expecting 1)\n",
-+ (int) (p - x[0]));
-+ exit (1);
-+ }
-+ p = x[0];
-+ if (mpfr_cmp_si (p++, 0) != 0)
-+ {
-+ printf ("Error in mpfr_cmp_si macro: result should be 0.\n");
-+ exit (1);
-+ }
-+ if (p != x[1])
-+ {
-+ printf ("Error in mpfr_cmp_si macro: p - x[0] = %d (expecting 1)\n",
-+ (int) (p - x[0]));
-+ exit (1);
-+ }
-+ mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
-+}
-+
- int
- main (void)
- {
-@@ -216,6 +336,8 @@
- mpfr_clear (x);
-
- check_nan ();
-+ check_macros ();
-+ test_macros ();
-
- tests_end_mpfr ();
- return 0;
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-07-10 00:11:53.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-09-07 08:46:06.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p3";
-+ return "3.0.0-p4";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-10-21 20:28:38.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:28:38.000000000 +0000
-@@ -0,0 +1 @@
-+tcan_round
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-09-07 08:46:06.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-10-21 20:28:38.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p4
-+3.0.0-p5
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-09-07 08:46:06.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:28:38.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p4"
-+#define MPFR_VERSION_STRING "3.0.0-p5"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/tests/tcan_round.c mpfr-3.0.0-b/tests/tcan_round.c
---- mpfr-3.0.0-a/tests/tcan_round.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tcan_round.c 2010-10-21 20:28:38.000000000 +0000
-@@ -41,7 +41,7 @@
- /* avoid mpn_random which leaks memory */
- for (i = 0; i < n; i++)
- buf[i] = randlimb ();
-- p = (mpfr_prec_t) randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
-+ p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
- err = p + randlimb () % GMP_NUMB_BITS;
- r1 = mpfr_round_p (buf, n, err, p);
- r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-09-07 08:46:06.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-10-21 20:28:38.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p4";
-+ return "3.0.0-p5";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-10-21 20:59:32.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-10-21 20:59:32.000000000 +0000
-@@ -0,0 +1 @@
-+mpfr_sub1
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-10-21 20:28:38.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-10-21 20:59:32.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p5
-+3.0.0-p6
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:28:38.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 20:59:32.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p5"
-+#define MPFR_VERSION_STRING "3.0.0-p6"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/sub1.c mpfr-3.0.0-b/sub1.c
---- mpfr-3.0.0-a/sub1.c 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/sub1.c 2010-10-21 20:59:32.000000000 +0000
-@@ -37,7 +37,9 @@
- mp_size_t cancel2, an, bn, cn, cn0;
- mp_limb_t *ap, *bp, *cp;
- mp_limb_t carry, bb, cc, borrow = 0;
-- int inexact, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0;
-+ int inexact, shift_b, shift_c, add_exp = 0;
-+ int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
-+ negative if low(b) < low(c), positive if low(b)>low(c) */
- int sh, k;
- MPFR_TMP_DECL(marker);
-
-@@ -196,7 +198,8 @@
- }
-
- #ifdef DEBUG
-- printf ("shift_b=%d shift_c=%d diffexp=%lu\n", shift_b, shift_c,
-+ printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
-+ mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
- (unsigned long) diff_exp);
- #endif
-
-@@ -307,17 +310,18 @@
- {
- if (MPFR_LIKELY(sh))
- {
-- is_exact = (carry == 0);
- /* can decide except when carry = 2^(sh-1) [middle]
- or carry = 0 [truncate, but cannot decide inexact flag] */
-- down = (carry < (MPFR_LIMB_ONE << (sh - 1)));
- if (carry > (MPFR_LIMB_ONE << (sh - 1)))
- goto add_one_ulp;
-- else if ((0 < carry) && down)
-+ else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1))))
- {
- inexact = -1; /* result if smaller than exact value */
- goto truncate;
- }
-+ /* now carry = 2^(sh-1), in which case cmp_low=2,
-+ or carry = 0, in which case cmp_low=0 */
-+ cmp_low = (carry == 0) ? 0 : 2;
- }
- }
- else /* directed rounding: set rnd_mode to RNDZ iff toward zero */
-@@ -344,12 +348,32 @@
- cn -= (long int) an + cancel2;
-
- #ifdef DEBUG
-- printf ("last %d bits from a are %lu, bn=%ld, cn=%ld\n",
-+ printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
- sh, (unsigned long) carry, (long) bn, (long) cn);
- #endif
-
-+ /* for rounding to nearest, we couldn't conclude up to here in the following
-+ cases:
-+ 1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp
-+ or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp
-+ 2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1):
-+ -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp
-+ we can't decide the rounding, in that case cmp_low=2:
-+ either we truncate and flag=-1, or we add one ulp and flag=1
-+ 3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to
-+ truncate but we can't decide the ternary value, here cmp_low=0:
-+ -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp
-+ we always truncate and inexact can be any of -1,0,1
-+ */
-+
-+ /* note: here cn might exceed cn0, in which case we consider a zero limb */
- for (k = 0; (bn > 0) || (cn > 0); k = 1)
- {
-+ /* if cmp_low < 0, we know low(b) - low(c) < 0
-+ if cmp_low > 0, we know low(b) - low(c) > 0
-+ (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far)
-+ if cmp_low = 0, so far low(b) - low(c) = 0 */
-+
- /* get next limbs */
- bb = (bn > 0) ? bp[--bn] : 0;
- if ((cn > 0) && (cn-- <= cn0))
-@@ -357,76 +381,115 @@
- else
- cc = 0;
-
-- /* down is set when low(b) < low(c) */
-- if (down == 0)
-- down = (bb < cc);
-+ /* cmp_low compares low(b) and low(c) */
-+ if (cmp_low == 0) /* case 1 or 3 */
-+ cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0;
-+
-+ /* Case 1 for k=0 splits into 7 subcases:
-+ 1a: bb > cc + half
-+ 1b: bb = cc + half
-+ 1c: 0 < bb - cc < half
-+ 1d: bb = cc
-+ 1e: -half < bb - cc < 0
-+ 1f: bb - cc = -half
-+ 1g: bb - cc < -half
-+
-+ Case 2 splits into 3 subcases:
-+ 2a: bb > cc
-+ 2b: bb = cc
-+ 2c: bb < cc
-+
-+ Case 3 splits into 3 subcases:
-+ 3a: bb > cc
-+ 3b: bb = cc
-+ 3c: bb < cc
-+ */
-
- /* the case rounding to nearest with sh=0 is special since one couldn't
- subtract above 1/2 ulp in the trailing limb of the result */
-- if ((rnd_mode == MPFR_RNDN) && sh == 0 && k == 0)
-+ if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */
- {
- mp_limb_t half = MPFR_LIMB_HIGHBIT;
-
-- is_exact = (bb == cc);
--
- /* add one ulp if bb > cc + half
- truncate if cc - half < bb < cc + half
- sub one ulp if bb < cc - half
- */
-
-- if (down)
-+ if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0,
-+ cases 1e, 1f and 1g */
- {
- if (cc >= half)
- cc -= half;
-- else
-+ else /* since bb < cc < half, bb+half < 2*half */
- bb += half;
-+ /* now we have bb < cc + half:
-+ we have to subtract one ulp if bb < cc,
-+ and truncate if bb > cc */
- }
-- else /* bb >= cc */
-+ else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */
- {
- if (cc < half)
- cc += half;
-- else
-+ else /* since bb >= cc >= half, bb - half >= 0 */
- bb -= half;
-+ /* now we have bb > cc - half: we have to add one ulp if bb > cc,
-+ and truncate if bb < cc */
-+ if (cmp_low > 0)
-+ cmp_low = 2;
- }
- }
-
- #ifdef DEBUG
-- printf (" bb=%lu cc=%lu down=%d is_exact=%d\n",
-- (unsigned long) bb, (unsigned long) cc, down, is_exact);
-+ printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
-+ (unsigned long) bb, (unsigned long) cc, cmp_low);
- #endif
-- if (bb < cc)
-+ if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
-+ one ulp */
- {
- if (rnd_mode == MPFR_RNDZ)
-- goto sub_one_ulp;
-+ goto sub_one_ulp; /* set inexact=-1 */
- else if (rnd_mode != MPFR_RNDN) /* round away */
- {
- inexact = 1;
- goto truncate;
- }
-- else /* round to nearest: special case here since for sh=k=0
-- bb = bb0 - MPFR_LIMB_HIGHBIT */
-+ else /* round to nearest */
- {
-- if (is_exact && sh == 0)
-- {
-- /* For k=0 we can't decide exactness since it may depend
-- from low order bits.
-- For k=1, the first low limbs matched: low(b)-low(c)<0. */
-- if (k)
-- {
-- inexact = 1;
-- goto truncate;
-- }
-- }
-- else if (down && sh == 0)
-- goto sub_one_ulp;
-- else
-- {
-- inexact = (is_exact) ? 1 : -1;
-+ /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0,
-+ whatever the value of sh.
-+ If sh>0, then cmp_low < 0 implies that the initial neglected
-+ sh bits were 0 (otherwise cmp_low=2 initially), thus the
-+ weight of the new bits is less than 0.5 ulp too.
-+ If k > 0 (and sh=0) this means that either the first neglected
-+ limbs bb and cc were equal (thus cmp_low was 0 for k=0),
-+ or we had bb - cc = -0.5 ulp or 0.5 ulp.
-+ The last case is not possible here since we would have
-+ cmp_low > 0 which is sticky.
-+ In the first case (where we have cmp_low = -1), we truncate,
-+ whereas in the 2nd case we have cmp_low = -2 and we subtract
-+ one ulp.
-+ */
-+ if (bb > cc || sh > 0 || cmp_low == -1)
-+ { /* -0.5 ulp < low(b)-low(c) < 0,
-+ bb > cc corresponds to cases 1e and 1f1
-+ sh > 0 corresponds to cases 3c and 3b3
-+ cmp_low = -1 corresponds to case 1d3 (also 3b3) */
-+ inexact = 1;
- goto truncate;
- }
-+ else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp,
-+ this corresponds to cases 1g and 1f3 */
-+ goto sub_one_ulp;
-+ /* the only case where we can't conclude is sh=0 and bb=cc,
-+ i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus
-+ we don't know if we must truncate or subtract one ulp.
-+ Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to
-+ now, since low(b) - low(c) > 1/2^sh */
- }
- }
-- else if (bb > cc)
-+ else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or
-+ add one ulp */
- {
- if (rnd_mode == MPFR_RNDZ)
- {
-@@ -437,34 +500,70 @@
- goto add_one_ulp;
- else /* round to nearest */
- {
-- if (is_exact)
-+ if (bb > cc)
- {
-- inexact = -1;
-- goto truncate;
-+ /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp,
-+ and similarly when cmp_low=2 */
-+ if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */
-+ goto add_one_ulp;
-+ /* sh > 0 and cmp_low > 0: this implies that the sh initial
-+ neglected bits were 0, and the remaining low(b)-low(c)>0,
-+ but its weight is less than 0.5 ulp */
-+ else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to
-+ cases 3a, 1d1 and 3b1 */
-+ {
-+ inexact = -1;
-+ goto truncate;
-+ }
- }
-- else if (down)
-+ else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c,
-+ 1b3, 2b3 and 2c */
- {
-- inexact = 1;
-+ inexact = -1;
- goto truncate;
- }
-- else
-- goto add_one_ulp;
-+ /* the only case where we can't conclude is bb=cc, i.e.,
-+ low(b) - low(c) = 0.5 ulp (up to now), thus we don't know
-+ if we must truncate or add one ulp. */
- }
- }
-+ /* after k=0, we cannot conclude in the following cases, we split them
-+ according to the values of bb and cc for k=1:
-+ 1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp]
-+ 1b1. bb > cc: add one ulp, inex = 1
-+ 1b2: bb = cc: cannot conclude
-+ 1b3: bb < cc: truncate, inex = -1
-+ 1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0]
-+ 1d1: bb > cc: truncate, inex = -1
-+ 1d2: bb = cc: cannot conclude
-+ 1d3: bb < cc: truncate, inex = +1
-+ 1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp]
-+ 1f1: bb > cc: truncate, inex = +1
-+ 1f2: bb = cc: cannot conclude
-+ 1f3: bb < cc: sub one ulp, inex = -1
-+ 2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp]
-+ 2b1. bb > cc: add one ulp, inex = 1
-+ 2b2: bb = cc: cannot conclude
-+ 2b3: bb < cc: truncate, inex = -1
-+ 3b. sh > 0 and cmp_low = 0 [around 0]
-+ 3b1. bb > cc: truncate, inex = -1
-+ 3b2: bb = cc: cannot conclude
-+ 3b3: bb < cc: truncate, inex = +1
-+ */
- }
-
-- if ((rnd_mode == MPFR_RNDN) && !is_exact)
-+ if ((rnd_mode == MPFR_RNDN) && cmp_low != 0)
- {
- /* even rounding rule */
- if ((ap[0] >> sh) & 1)
- {
-- if (down)
-+ if (cmp_low < 0)
- goto sub_one_ulp;
- else
- goto add_one_ulp;
- }
- else
-- inexact = (down) ? 1 : -1;
-+ inexact = (cmp_low > 0) ? -1 : 1;
- }
- else
- inexact = 0;
-diff -Naurd mpfr-3.0.0-a/tests/tfma.c mpfr-3.0.0-b/tests/tfma.c
---- mpfr-3.0.0-a/tests/tfma.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tfma.c 2010-10-21 20:59:32.000000000 +0000
-@@ -337,6 +337,94 @@
- mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
- }
-
-+static void
-+bug20101018 (void)
-+{
-+ mpfr_t x, y, z, t, u;
-+ int i;
-+
-+ mpfr_init2 (x, 64);
-+ mpfr_init2 (y, 64);
-+ mpfr_init2 (z, 64);
-+ mpfr_init2 (t, 64);
-+ mpfr_init2 (u, 64);
-+
-+ mpfr_set_str (x, "0xf.fffffffffffffffp-14766", 16, MPFR_RNDN);
-+ mpfr_set_str (y, "-0xf.fffffffffffffffp+317", 16, MPFR_RNDN);
-+ mpfr_set_str (z, "0x8.3ffffffffffe3ffp-14443", 16, MPFR_RNDN);
-+ mpfr_set_str (t, "0x8.7ffffffffffc7ffp-14444", 16, MPFR_RNDN);
-+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
-+ if (mpfr_cmp (u, t) != 0)
-+ {
-+ printf ("Wrong result in bug20101018 (a)\n");
-+ printf ("Expected ");
-+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
-+ printf ("\nGot ");
-+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
-+ printf ("\n");
-+ exit (1);
-+ }
-+ if (i <= 0)
-+ {
-+ printf ("Wrong ternary value in bug20101018 (a)\n");
-+ printf ("Expected > 0\n");
-+ printf ("Got %d\n", i);
-+ exit (1);
-+ }
-+
-+ mpfr_set_str (x, "-0xf.fffffffffffffffp-11420", 16, MPFR_RNDN);
-+ mpfr_set_str (y, "0xf.fffffffffffffffp+9863", 16, MPFR_RNDN);
-+ mpfr_set_str (z, "0x8.fffff80ffffffffp-1551", 16, MPFR_RNDN);
-+ mpfr_set_str (t, "0x9.fffff01ffffffffp-1552", 16, MPFR_RNDN);
-+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
-+ if (mpfr_cmp (u, t) != 0)
-+ {
-+ printf ("Wrong result in bug20101018 (b)\n");
-+ printf ("Expected ");
-+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
-+ printf ("\nGot ");
-+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
-+ printf ("\n");
-+ exit (1);
-+ }
-+ if (i <= 0)
-+ {
-+ printf ("Wrong ternary value in bug20101018 (b)\n");
-+ printf ("Expected > 0\n");
-+ printf ("Got %d\n", i);
-+ exit (1);
-+ }
-+
-+ mpfr_set_str (x, "0xf.fffffffffffffffp-2125", 16, MPFR_RNDN);
-+ mpfr_set_str (y, "-0xf.fffffffffffffffp-6000", 16, MPFR_RNDN);
-+ mpfr_set_str (z, "0x8p-8119", 16, MPFR_RNDN);
-+ mpfr_set_str (t, "0x8.000000000000001p-8120", 16, MPFR_RNDN);
-+ i = mpfr_fma (u, x, y, z, MPFR_RNDN);
-+ if (mpfr_cmp (u, t) != 0)
-+ {
-+ printf ("Wrong result in bug20101018 (c)\n");
-+ printf ("Expected ");
-+ mpfr_out_str (stdout, 16, 0, t, MPFR_RNDN);
-+ printf ("\nGot ");
-+ mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
-+ printf ("\n");
-+ exit (1);
-+ }
-+ if (i <= 0)
-+ {
-+ printf ("Wrong ternary value in bug20101018 (c)\n");
-+ printf ("Expected > 0\n");
-+ printf ("Got %d\n", i);
-+ exit (1);
-+ }
-+
-+ mpfr_clear (x);
-+ mpfr_clear (y);
-+ mpfr_clear (z);
-+ mpfr_clear (t);
-+ mpfr_clear (u);
-+}
-+
- int
- main (int argc, char *argv[])
- {
-@@ -345,6 +433,8 @@
-
- tests_start_mpfr ();
-
-+ bug20101018 ();
-+
- mpfr_init (x);
- mpfr_init (s);
- mpfr_init (y);
-diff -Naurd mpfr-3.0.0-a/tests/tsub.c mpfr-3.0.0-b/tests/tsub.c
---- mpfr-3.0.0-a/tests/tsub.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tsub.c 2010-10-21 20:59:32.000000000 +0000
-@@ -201,6 +201,8 @@
- if (mpfr_cmp (z, x))
- {
- printf ("Error in mpfr_sub (2)\n");
-+ printf ("Expected "); mpfr_print_binary (x); puts ("");
-+ printf ("Got "); mpfr_print_binary (z); puts ("");
- exit (1);
- }
- mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
-@@ -478,6 +480,156 @@
- mpfr_clear (u);
- }
-
-+/* Bug found by Jakub Jelinek
-+ * http://bugzilla.redhat.com/643657
-+ * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301
-+ * The consequence can be either an assertion failure (i = 2 in the
-+ * testcase below, in debug mode) or an incorrectly rounded value.
-+ */
-+static void
-+bug20101017 (void)
-+{
-+ mpfr_t a, b, c;
-+ int inex;
-+ int i;
-+
-+ mpfr_init2 (a, GMP_NUMB_BITS * 2);
-+ mpfr_init2 (b, GMP_NUMB_BITS);
-+ mpfr_init2 (c, GMP_NUMB_BITS);
-+
-+ /* a = 2^(2N) + k.2^(2N-1) + 2^N and b = 1
-+ with N = GMP_NUMB_BITS and k = 0 or 1.
-+ c = a - b should round to the same value as a. */
-+
-+ for (i = 2; i <= 3; i++)
-+ {
-+ mpfr_set_ui_2exp (a, i, GMP_NUMB_BITS - 1, MPFR_RNDN);
-+ mpfr_add_ui (a, a, 1, MPFR_RNDN);
-+ mpfr_mul_2ui (a, a, GMP_NUMB_BITS, MPFR_RNDN);
-+ mpfr_set_ui (b, 1, MPFR_RNDN);
-+ inex = mpfr_sub (c, a, b, MPFR_RNDN);
-+ mpfr_set (b, a, MPFR_RNDN);
-+ if (! mpfr_equal_p (c, b))
-+ {
-+ printf ("Error in bug20101017 for i = %d.\n", i);
-+ printf ("Expected ");
-+ mpfr_out_str (stdout, 16, 0, b, MPFR_RNDN);
-+ putchar ('\n');
-+ printf ("Got ");
-+ mpfr_out_str (stdout, 16, 0, c, MPFR_RNDN);
-+ putchar ('\n');
-+ exit (1);
-+ }
-+ if (inex >= 0)
-+ {
-+ printf ("Error in bug20101017 for i = %d: bad inex value.\n", i);
-+ printf ("Expected negative, got %d.\n", inex);
-+ exit (1);
-+ }
-+ }
-+
-+ mpfr_set_prec (a, 64);
-+ mpfr_set_prec (b, 129);
-+ mpfr_set_prec (c, 2);
-+ mpfr_set_str_binary (b, "0.100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001E65");
-+ mpfr_set_str_binary (c, "0.10E1");
-+ inex = mpfr_sub (a, b, c, MPFR_RNDN);
-+ if (mpfr_cmp_ui_2exp (a, 1, 64) != 0 || inex >= 0)
-+ {
-+ printf ("Error in mpfr_sub for b-c for b=2^64+1+2^(-64), c=1\n");
-+ printf ("Expected result 2^64 with inex < 0\n");
-+ printf ("Got "); mpfr_print_binary (a);
-+ printf (" with inex=%d\n", inex);
-+ exit (1);
-+ }
-+
-+ mpfr_clears (a, b, c, (mpfr_ptr) 0);
-+}
-+
-+/* hard test of rounding */
-+static void
-+check_rounding (void)
-+{
-+ mpfr_t a, b, c, res;
-+ mpfr_prec_t p;
-+ long k, l;
-+ int i;
-+
-+#define MAXKL (2 * GMP_NUMB_BITS)
-+ for (p = MPFR_PREC_MIN; p <= GMP_NUMB_BITS; p++)
-+ {
-+ mpfr_init2 (a, p);
-+ mpfr_init2 (res, p);
-+ mpfr_init2 (b, p + 1 + MAXKL);
-+ mpfr_init2 (c, MPFR_PREC_MIN);
-+
-+ /* b = 2^p + 1 + 2^(-k), c = 2^(-l) */
-+ for (k = 0; k <= MAXKL; k++)
-+ for (l = 0; l <= MAXKL; l++)
-+ {
-+ mpfr_set_ui_2exp (b, 1, p, MPFR_RNDN);
-+ mpfr_add_ui (b, b, 1, MPFR_RNDN);
-+ mpfr_mul_2ui (b, b, k, MPFR_RNDN);
-+ mpfr_add_ui (b, b, 1, MPFR_RNDN);
-+ mpfr_div_2ui (b, b, k, MPFR_RNDN);
-+ mpfr_set_ui_2exp (c, 1, -l, MPFR_RNDN);
-+ i = mpfr_sub (a, b, c, MPFR_RNDN);
-+ /* b - c = 2^p + 1 + 2^(-k) - 2^(-l), should be rounded to
-+ 2^p for l <= k, and 2^p+2 for l < k */
-+ if (l <= k)
-+ {
-+ if (mpfr_cmp_ui_2exp (a, 1, p) != 0)
-+ {
-+ printf ("Wrong result in check_rounding\n");
-+ printf ("p=%lu k=%ld l=%ld\n", p, k, l);
-+ printf ("b="); mpfr_print_binary (b); puts ("");
-+ printf ("c="); mpfr_print_binary (c); puts ("");
-+ printf ("Expected 2^%lu\n", p);
-+ printf ("Got "); mpfr_print_binary (a); puts ("");
-+ exit (1);
-+ }
-+ if (i >= 0)
-+ {
-+ printf ("Wrong ternary value in check_rounding\n");
-+ printf ("p=%lu k=%ld l=%ld\n", p, k, l);
-+ printf ("b="); mpfr_print_binary (b); puts ("");
-+ printf ("c="); mpfr_print_binary (c); puts ("");
-+ printf ("a="); mpfr_print_binary (a); puts ("");
-+ printf ("Expected < 0, got %d\n", i);
-+ exit (1);
-+ }
-+ }
-+ else /* l < k */
-+ {
-+ mpfr_set_ui_2exp (res, 1, p, MPFR_RNDN);
-+ mpfr_add_ui (res, res, 2, MPFR_RNDN);
-+ if (mpfr_cmp (a, res) != 0)
-+ {
-+ printf ("Wrong result in check_rounding\n");
-+ printf ("b="); mpfr_print_binary (b); puts ("");
-+ printf ("c="); mpfr_print_binary (c); puts ("");
-+ printf ("Expected "); mpfr_print_binary (res); puts ("");
-+ printf ("Got "); mpfr_print_binary (a); puts ("");
-+ exit (1);
-+ }
-+ if (i <= 0)
-+ {
-+ printf ("Wrong ternary value in check_rounding\n");
-+ printf ("b="); mpfr_print_binary (b); puts ("");
-+ printf ("c="); mpfr_print_binary (c); puts ("");
-+ printf ("Expected > 0, got %d\n", i);
-+ exit (1);
-+ }
-+ }
-+ }
-+
-+ mpfr_clear (a);
-+ mpfr_clear (res);
-+ mpfr_clear (b);
-+ mpfr_clear (c);
-+ }
-+}
-+
- #define TEST_FUNCTION test_sub
- #define TWO_ARGS
- #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
-@@ -491,6 +643,8 @@
-
- tests_start_mpfr ();
-
-+ bug20101017 ();
-+ check_rounding ();
- check_diverse ();
- check_inexact ();
- bug_ddefour ();
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-10-21 20:28:38.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-10-21 20:59:32.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p5";
-+ return "3.0.0-p6";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-10-21 21:18:26.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-10-21 21:18:26.000000000 +0000
-@@ -0,0 +1 @@
-+mpfr_set_ld
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-10-21 20:59:32.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-10-21 21:18:26.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p6
-+3.0.0-p7
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-10-21 20:59:32.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-10-21 21:18:26.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p6"
-+#define MPFR_VERSION_STRING "3.0.0-p7"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-diff -Naurd mpfr-3.0.0-a/set_ld.c mpfr-3.0.0-b/set_ld.c
---- mpfr-3.0.0-a/set_ld.c 2010-06-10 11:00:14.000000000 +0000
-+++ mpfr-3.0.0-b/set_ld.c 2010-10-21 21:18:26.000000000 +0000
-@@ -102,21 +102,25 @@
- {
- x /= div13; /* exact */
- shift_exp += 8192;
-+ mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
- }
- if (ABS (x) >= div12)
- {
- x /= div12; /* exact */
- shift_exp += 4096;
-+ mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
- }
- if (ABS (x) >= div11)
- {
- x /= div11; /* exact */
- shift_exp += 2048;
-+ mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
- }
- if (ABS (x) >= div10)
- {
- x /= div10; /* exact */
- shift_exp += 1024;
-+ mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
- }
- /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
- therefore we have one extra exponent reduction step */
-@@ -124,9 +128,10 @@
- {
- x /= div9; /* exact */
- shift_exp += 512;
-+ mpfr_div_2si (t, t, 512, MPFR_RNDZ);
- }
- } /* Check overflow of double */
-- else
-+ else /* no overflow on double */
- {
- long double div9, div10, div11;
-
-@@ -149,29 +154,34 @@
- {
- x /= div13; /* exact */
- shift_exp -= 8192;
-+ mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
- }
- if (ABS (x) <= div12)
- {
- x /= div12; /* exact */
- shift_exp -= 4096;
-+ mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
- }
- if (ABS (x) <= div11)
- {
- x /= div11; /* exact */
- shift_exp -= 2048;
-+ mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
- }
- if (ABS (x) <= div10)
- {
- x /= div10; /* exact */
- shift_exp -= 1024;
-+ mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
- }
- if (ABS(x) <= div9)
- {
- x /= div9; /* exact */
- shift_exp -= 512;
-+ mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
- }
- }
-- else
-+ else /* no underflow */
- {
- inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
- MPFR_ASSERTD (inexact == 0);
-diff -Naurd mpfr-3.0.0-a/tests/tset_ld.c mpfr-3.0.0-b/tests/tset_ld.c
---- mpfr-3.0.0-a/tests/tset_ld.c 2010-06-10 11:00:13.000000000 +0000
-+++ mpfr-3.0.0-b/tests/tset_ld.c 2010-10-21 21:18:26.000000000 +0000
-@@ -147,12 +147,39 @@
- test_fixed_bugs (void)
- {
- mpfr_t x;
-- long double d;
-+ long double l, m;
-
- /* bug found by Steve Kargl (2009-03-14) */
- mpfr_init2 (x, 64);
- mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
-- d = mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
-+ mpfr_get_ld (x, MPFR_RNDN); /* an assertion failed in init2.c:50 */
-+
-+ /* bug reported by Jakub Jelinek (2010-10-17)
-+ https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
-+ mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
-+ /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
-+ l = 8.215640181713713164092636634579e-276;
-+ mpfr_set_ld (x, l, MPFR_RNDN);
-+ m = mpfr_get_ld (x, MPFR_RNDN);
-+ if (m != l)
-+ {
-+ printf ("Error in get_ld o set_ld for l=%Le\n", l);
-+ printf ("Got m=%Le instead of l\n", m);
-+ exit (1);
-+ }
-+
-+ /* another similar test which failed with extended double precision and the
-+ generic code for mpfr_set_ld */
-+ /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
-+ l = 4.560596445887084662336528403703e-292;
-+ mpfr_set_ld (x, l, MPFR_RNDN);
-+ m = mpfr_get_ld (x, MPFR_RNDN);
-+ if (m != l)
-+ {
-+ printf ("Error in get_ld o set_ld for l=%Le\n", l);
-+ printf ("Got m=%Le instead of l\n", m);
-+ exit (1);
-+ }
-
- mpfr_clear (x);
- }
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-10-21 20:59:32.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-10-21 21:18:26.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p6";
-+ return "3.0.0-p7";
- }
-diff -Naurd mpfr-3.0.0-a/PATCHES mpfr-3.0.0-b/PATCHES
---- mpfr-3.0.0-a/PATCHES 2010-11-09 15:15:07.000000000 +0000
-+++ mpfr-3.0.0-b/PATCHES 2010-11-09 15:15:07.000000000 +0000
-@@ -0,0 +1 @@
-+macros
-diff -Naurd mpfr-3.0.0-a/VERSION mpfr-3.0.0-b/VERSION
---- mpfr-3.0.0-a/VERSION 2010-10-21 21:18:26.000000000 +0000
-+++ mpfr-3.0.0-b/VERSION 2010-11-09 15:15:07.000000000 +0000
-@@ -1 +1 @@
--3.0.0-p7
-+3.0.0-p8
-diff -Naurd mpfr-3.0.0-a/mpfr.h mpfr-3.0.0-b/mpfr.h
---- mpfr-3.0.0-a/mpfr.h 2010-10-21 21:18:26.000000000 +0000
-+++ mpfr-3.0.0-b/mpfr.h 2010-11-09 15:15:07.000000000 +0000
-@@ -27,7 +27,7 @@
- #define MPFR_VERSION_MAJOR 3
- #define MPFR_VERSION_MINOR 0
- #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0-p7"
-+#define MPFR_VERSION_STRING "3.0.0-p8"
-
- /* Macros dealing with MPFR VERSION */
- #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-@@ -67,6 +67,16 @@
- # define _MPFR_H_HAVE_INTMAX_T 1
- #endif
-
-+/* Avoid some problems with macro expansion if the user defines macros
-+ with the same name as keywords. By convention, identifiers and macro
-+ names starting with mpfr_ are reserved by MPFR. */
-+typedef void mpfr_void;
-+typedef int mpfr_int;
-+typedef unsigned int mpfr_uint;
-+typedef long mpfr_long;
-+typedef unsigned long mpfr_ulong;
-+typedef size_t mpfr_size_t;
-+
- /* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
- Warning! Changing the contents of this enum should be seen as an
- interface change since the old and the new types are not compatible
-@@ -136,7 +146,7 @@
- typedef mp_exp_t mpfr_exp_t;
-
- /* Definition of the standard exponent limits */
--#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((unsigned long) 1 << 30) - 1))
-+#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1))
- #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
-
- /* Definition of the main structure */
-@@ -725,13 +735,13 @@
- unexpected results with future compilers and aggressive optimisations.
- Why not working only with signed types, using INT_MIN and LONG_MIN? */
- #if __GMP_MP_SIZE_T_INT
--#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+2))
--#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+1))
--#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+3))
-+#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+2))
-+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+1))
-+#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+3))
- #else
--#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+2))
--#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+1))
--#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+3))
-+#define __MPFR_EXP_NAN ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+2))
-+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+1))
-+#define __MPFR_EXP_INF ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+3))
- #endif
-
- /* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */
-@@ -760,9 +770,9 @@
- #define mpfr_inf_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_INF)
- #define mpfr_zero_p(_x) ((_x)->_mpfr_exp == __MPFR_EXP_ZERO)
- #define mpfr_regular_p(_x) ((_x)->_mpfr_exp > __MPFR_EXP_INF)
--#define mpfr_sgn(_x) \
-- ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \
-- (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (void) 0), 0 : \
-+#define mpfr_sgn(_x) \
-+ ((_x)->_mpfr_exp < __MPFR_EXP_INF ? \
-+ (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \
- MPFR_SIGN (_x))
-
- /* Prevent them from using as lvalues */
-@@ -805,7 +815,19 @@
- Moreover casts to unsigned long have been added to avoid warnings in
- programs that use MPFR and are compiled with -Wconversion; such casts
- are OK since if X is a constant expression, then (unsigned long) X is
-- also a constant expression, so that the optimizations still work. */
-+ also a constant expression, so that the optimizations still work. The
-+ warnings are probably related to the following two bugs:
-+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
-+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
-+ and the casts could be removed once these bugs are fixed.
-+ Casts shouldn't be used on the generic calls (to the ..._2exp functions),
-+ where implicit conversions are performed. Indeed, having at least one
-+ implicit conversion in the macro allows the compiler to emit diagnostics
-+ when normally expected, for instance in the following call:
-+ mpfr_set_ui (x, "foo", MPFR_RNDN);
-+ If this is not possible (for future macros), one of the tricks described
-+ on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could
-+ be used. */
- #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
- #if (__GNUC__ >= 2)
- #undef mpfr_cmp_ui
-@@ -813,45 +835,45 @@
- But warning! mpfr_sgn is specified as a macro in the API, thus the macro
- mustn't be used if side effects are possible, like here. */
- #define mpfr_cmp_ui(_f,_u) \
-- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
-+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
- (mpfr_sgn) (_f) : \
-- mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
-+ mpfr_cmp_ui_2exp ((_f), (_u), 0))
- #undef mpfr_cmp_si
--#define mpfr_cmp_si(_f,_s) \
-- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
-- mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) : \
-- mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
-+#define mpfr_cmp_si(_f,_s) \
-+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
-+ mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) : \
-+ mpfr_cmp_si_2exp ((_f), (_s), 0))
- #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
- #undef mpfr_set_ui
- #define mpfr_set_ui(_f,_u,_r) \
-- (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ? \
-+ (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ? \
- __extension__ ({ \
- mpfr_ptr _p = (_f); \
- _p->_mpfr_sign = 1; \
- _p->_mpfr_exp = __MPFR_EXP_ZERO; \
-- (void) (_r); 0; }) : \
-- mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
-+ (mpfr_void) (_r); 0; }) : \
-+ mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
- #endif
- #undef mpfr_set_si
- #define mpfr_set_si(_f,_s,_r) \
-- (__builtin_constant_p (_s) && (long) (_s) >= 0 ? \
-- mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) : \
-- mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
-+ (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ? \
-+ mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) : \
-+ mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
- #endif
- #endif
-
- /* Macro version of mpfr_stack interface for fast access */
--#define mpfr_custom_get_size(p) ((size_t) \
-+#define mpfr_custom_get_size(p) ((mpfr_size_t) \
- (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t)))
- #define mpfr_custom_init(m,p) do {} while (0)
--#define mpfr_custom_get_significand(x) ((void*)((x)->_mpfr_d))
-+#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d))
- #define mpfr_custom_get_exp(x) ((x)->_mpfr_exp)
- #define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0)
- #define mpfr_custom_init_set(x,k,e,p,m) do { \
- mpfr_ptr _x = (x); \
- mpfr_exp_t _e; \
- mpfr_kind_t _t; \
-- int _s, _k; \
-+ mpfr_int _s, _k; \
- _k = (k); \
- if (_k >= 0) { \
- _t = (mpfr_kind_t) _k; \
-@@ -868,11 +890,13 @@
- _x->_mpfr_exp = _e; \
- _x->_mpfr_d = (mp_limb_t*) (m); \
- } while (0)
--#define mpfr_custom_get_kind(x) \
-- ( (x)->_mpfr_exp > __MPFR_EXP_INF ? (int)MPFR_REGULAR_KIND*MPFR_SIGN (x) \
-- : (x)->_mpfr_exp == __MPFR_EXP_INF ? (int)MPFR_INF_KIND*MPFR_SIGN (x) \
-- : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (int)MPFR_NAN_KIND \
-- : (int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
-+#define mpfr_custom_get_kind(x) \
-+ ( (x)->_mpfr_exp > __MPFR_EXP_INF ? \
-+ (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x) \
-+ : (x)->_mpfr_exp == __MPFR_EXP_INF ? \
-+ (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x) \
-+ : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND \
-+ : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
-
-
- #endif /* MPFR_USE_NO_MACRO */
-diff -Naurd mpfr-3.0.0-a/version.c mpfr-3.0.0-b/version.c
---- mpfr-3.0.0-a/version.c 2010-10-21 21:18:26.000000000 +0000
-+++ mpfr-3.0.0-b/version.c 2010-11-09 15:15:07.000000000 +0000
-@@ -25,5 +25,5 @@
- const char *
- mpfr_get_version (void)
- {
-- return "3.0.0-p7";
-+ return "3.0.0-p8";
- }
diff --git a/tools/mpfr/patches/001-no_tests.patch b/tools/mpfr/patches/001-no_tests.patch
deleted file mode 100644
index 08c1a4ff469..00000000000
--- a/tools/mpfr/patches/001-no_tests.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Index: mpfr-3.0.0/Makefile.am
-===================================================================
---- mpfr-3.0.0.orig/Makefile.am
-+++ mpfr-3.0.0/Makefile.am
-@@ -12,7 +12,7 @@
- AUTOMAKE_OPTIONS = gnu ansi2knr
- ACLOCAL_AMFLAGS = -I m4
-
--SUBDIRS = tests
-+SUBDIRS =
-
- nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER FAQ.html NEWS TODO \
- examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \
-Index: mpfr-3.0.0/Makefile.in
-===================================================================
---- mpfr-3.0.0.orig/Makefile.in
-+++ mpfr-3.0.0/Makefile.in
-@@ -357,7 +357,7 @@ top_builddir = @top_builddir@
- top_srcdir = @top_srcdir@
- AUTOMAKE_OPTIONS = gnu ansi2knr
- ACLOCAL_AMFLAGS = -I m4
--SUBDIRS = tests
-+SUBDIRS =
- nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER FAQ.html NEWS TODO \
- examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c \
- examples/version.c
diff --git a/tools/mpfr/patches/001-only_src.patch b/tools/mpfr/patches/001-only_src.patch
new file mode 100644
index 00000000000..019928741af
--- /dev/null
+++ b/tools/mpfr/patches/001-only_src.patch
@@ -0,0 +1,22 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -18,7 +18,7 @@ AUTOMAKE_OPTIONS = gnu
+ # old Automake version.
+ ACLOCAL_AMFLAGS = -I m4
+
+-SUBDIRS = doc src tests tune tools/bench
++SUBDIRS = src
+
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = mpfr.pc
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -383,7 +383,7 @@ AUTOMAKE_OPTIONS = gnu
+ # libtoolize and in case some developer needs to switch back to an
+ # old Automake version.
+ ACLOCAL_AMFLAGS = -I m4
+-SUBDIRS = doc src tests tune tools/bench
++SUBDIRS = src
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = mpfr.pc
+ nobase_dist_doc_DATA = AUTHORS BUGS COPYING COPYING.LESSER NEWS TODO \
diff --git a/tools/mpfr/patches/100-freebsd-compat.patch b/tools/mpfr/patches/100-freebsd-compat.patch
new file mode 100644
index 00000000000..c357b68736f
--- /dev/null
+++ b/tools/mpfr/patches/100-freebsd-compat.patch
@@ -0,0 +1,10 @@
+--- a/src/vasprintf.c
++++ b/src/vasprintf.c
+@@ -61,6 +61,7 @@ http://www.gnu.org/licenses/ or write to
+ #endif /* HAVE_VA_COPY */
+
+ #ifdef HAVE_WCHAR_H
++#include <stddef.h>
+ #include <wchar.h>
+ #endif
+
diff --git a/tools/mtd-utils/Makefile b/tools/mtd-utils/Makefile
index 4763aad1918..ff000b99e3a 100644
--- a/tools/mtd-utils/Makefile
+++ b/tools/mtd-utils/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2010 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,52 +7,41 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mtd-utils
-PKG_VERSION:=1.4.5
+PKG_VERSION:=2.0.2
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=git://git.infradead.org/mtd-utils.git
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_VERSION:=5319b84974fcb71504aed2d1b8285e9c0a4a4bb8
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
-PKG_CAT:=zcat
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=ftp://ftp.infradead.org/pub/mtd-utils/
+PKG_HASH:=fb3de61be8e932abb424e8ea3c30298f553d5f970ad158a737bb303bbf9660b8
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
+PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/host-build.mk
-HOST_CFLAGS += -I$(STAGING_DIR_HOST)/include/e2fsprogs
-CFLAGS := $(HOST_CFLAGS) -I$(HOST_BUILD_DIR)/include -L$(HOST_BUILD_DIR) -L$(STAGING_DIR_HOST)/lib -DNO_NATIVE_SUPPORT
ifneq ($(HOST_OS),Linux)
-CFLAGS += -Dloff_t=off_t -D__BYTE_ORDER=BYTE_ORDER -include getline.h -include endian.h -I$(CURDIR)/include -include fls.h
+ HOST_CFLAGS += \
+ -I$(CURDIR)/include \
+ -Dloff_t=off_t \
+ -D__BYTE_ORDER=BYTE_ORDER \
+ -include endian.h \
+ -DNO_NATIVE_SUPPORT \
+ -include fls.h
endif
-MTD_MAKEOPTS = \
- CFLAGS="$(CFLAGS)" \
- WITHOUT_LZO=1 WITHOUT_XATTR=1 \
- LZMA_STATIC_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \
- SUBDIRS="" \
- BUILDDIR="$(HOST_BUILD_DIR)"
+HOST_CONFIGURE_VARS+= \
+ UUID_CFLAGS="-I$(STAGING_DIR_HOST)/include/e2fsprogs/uuid"
-define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR)/lib \
- $(MTD_MAKEOPTS) \
- TARGETS="libmtd.a libcrc32.a" \
- LIBS="libmtd libcrc32"
- $(MAKE) -C $(HOST_BUILD_DIR) \
- $(MTD_MAKEOPTS) \
- TARGETS=mkfs.jffs2
- $(MAKE) -C $(HOST_BUILD_DIR)/ubi-utils \
- $(MTD_MAKEOPTS) \
- TARGETS=ubinize
- $(MAKE) -C $(HOST_BUILD_DIR)/mkfs.ubifs \
- $(MTD_MAKEOPTS) \
- BUILDDIR="$(HOST_BUILD_DIR)/mkfs.ubifs"
-endef
+HOST_CONFIGURE_ARGS+= \
+ --disable-tests \
+ --without-xattr \
+ --without-lzo
+
+HOST_MAKE_FLAGS += \
+ PROGRAMS="mkfs.jffs2 ubinize mkfs.ubifs"
define Host/Install
$(CP) \
$(HOST_BUILD_DIR)/mkfs.jffs2 \
- $(HOST_BUILD_DIR)/mkfs.ubifs/mkfs.ubifs \
+ $(HOST_BUILD_DIR)/mkfs.ubifs \
$(HOST_BUILD_DIR)/ubinize \
$(STAGING_DIR_HOST)/bin/
endef
diff --git a/tools/mtd-utils/patches/100-optional_lzo.patch b/tools/mtd-utils/patches/100-optional_lzo.patch
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/tools/mtd-utils/patches/100-optional_lzo.patch
+++ /dev/null
diff --git a/tools/mtd-utils/patches/100-sscanf_fix.patch b/tools/mtd-utils/patches/100-sscanf_fix.patch
new file mode 100644
index 00000000000..ae6f86722b9
--- /dev/null
+++ b/tools/mtd-utils/patches/100-sscanf_fix.patch
@@ -0,0 +1,11 @@
+--- a/jffsX-utils/mkfs.jffs2.c
++++ b/jffsX-utils/mkfs.jffs2.c
+@@ -427,7 +427,7 @@ static int interpret_table_entry(struct
+
+ if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu",
+ SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor,
+- &start, &increment, &count) < 0)
++ &start, &increment, &count) < 10)
+ {
+ return 1;
+ }
diff --git a/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch b/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/tools/mtd-utils/patches/101-ubifs-optional_lzo.patch
+++ /dev/null
diff --git a/tools/mtd-utils/patches/110-portability.patch b/tools/mtd-utils/patches/110-portability.patch
index 5bf1b95bc21..a2942270d72 100644
--- a/tools/mtd-utils/patches/110-portability.patch
+++ b/tools/mtd-utils/patches/110-portability.patch
@@ -1,5 +1,5 @@
---- a/compr_lzo.c
-+++ b/compr_lzo.c
+--- a/jffsX-utils/compr_lzo.c
++++ b/jffsX-utils/compr_lzo.c
@@ -26,7 +26,6 @@
#include <string.h>
@@ -8,8 +8,8 @@
#include <linux/jffs2.h>
#include <lzo/lzo1x.h>
#include "compr.h"
---- a/compr_zlib.c
-+++ b/compr_zlib.c
+--- a/jffsX-utils/compr_zlib.c
++++ b/jffsX-utils/compr_zlib.c
@@ -39,7 +39,6 @@
#include <zlib.h>
#undef crc32
@@ -18,8 +18,8 @@
#include <linux/jffs2.h>
#include "common.h"
#include "compr.h"
---- a/rbtree.h
-+++ b/rbtree.h
+--- a/jffsX-utils/rbtree.h
++++ b/jffsX-utils/rbtree.h
@@ -94,8 +94,7 @@ static inline struct page * rb_insert_pa
#ifndef _LINUX_RBTREE_H
#define _LINUX_RBTREE_H
@@ -48,14 +48,17 @@
/* The version of UBI images supported by this implementation */
#define UBI_VERSION 1
---- a/mkfs.ubifs/mkfs.ubifs.h
-+++ b/mkfs.ubifs/mkfs.ubifs.h
-@@ -34,7 +34,14 @@
+--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
++++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.h
+@@ -32,7 +32,17 @@
#include <endian.h>
#include <byteswap.h>
#include <linux/types.h>
+#ifdef __linux__
#include <linux/fs.h>
++# if defined(__x86_64__) && defined(__ILP32__)
++# define llseek lseek64
++# endif
+#else
+# ifndef O_LARGEFILE
+# define O_LARGEFILE 0
@@ -65,20 +68,9 @@
#include <getopt.h>
#include <sys/types.h>
---- a/mkfs.ubifs/mkfs.ubifs.c
-+++ b/mkfs.ubifs/mkfs.ubifs.c
-@@ -821,8 +821,8 @@ int write_leb(int lnum, int len, void *b
- if (ubi_leb_change_start(ubi, out_fd, lnum, c->leb_size, dtype))
- return sys_err_msg("ubi_leb_change_start failed");
-
-- if (lseek64(out_fd, pos, SEEK_SET) != pos)
-- return sys_err_msg("lseek64 failed seeking %lld",
-+ if (llseek(out_fd, pos, SEEK_SET) != pos)
-+ return sys_err_msg("llseek failed seeking %lld",
- (long long)pos);
-
- if (write(out_fd, buf, c->leb_size) != c->leb_size)
-@@ -1079,6 +1079,7 @@ static int add_inode_with_data(struct st
+--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
++++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+@@ -1219,6 +1219,7 @@ static int add_inode(struct stat *st, in
if (c->default_compr != UBIFS_COMPR_NONE)
use_flags |= UBIFS_COMPR_FL;
@@ -86,7 +78,7 @@
if (flags & FS_COMPR_FL)
use_flags |= UBIFS_COMPR_FL;
if (flags & FS_SYNC_FL)
-@@ -1089,6 +1090,7 @@ static int add_inode_with_data(struct st
+@@ -1229,6 +1230,7 @@ static int add_inode(struct stat *st, in
use_flags |= UBIFS_APPEND_FL;
if (flags & FS_DIRSYNC_FL && S_ISDIR(st->st_mode))
use_flags |= UBIFS_DIRSYNC_FL;
@@ -94,7 +86,7 @@
memset(ino, 0, UBIFS_INO_NODE_SZ);
-@@ -1158,7 +1160,9 @@ static int add_dir_inode(DIR *dir, ino_t
+@@ -1293,7 +1295,9 @@ static int add_dir_inode(const char *pat
fd = dirfd(dir);
if (fd == -1)
return sys_err_msg("dirfd failed");
@@ -104,20 +96,23 @@
flags = 0;
}
-@@ -1343,10 +1347,12 @@ static int add_file(const char *path_nam
+@@ -1476,6 +1480,7 @@ static int add_file(const char *path_nam
key_write(&key, &dn->key);
dn->size = cpu_to_le32(bytes_read);
out_len = NODE_BUFFER_SIZE - UBIFS_DATA_NODE_SZ;
+#ifndef NO_NATIVE_SUPPORT
if (c->default_compr == UBIFS_COMPR_NONE &&
(flags & FS_COMPR_FL))
+ #ifdef WITHOUT_LZO
+@@ -1484,6 +1489,7 @@ static int add_file(const char *path_nam
use_compr = UBIFS_COMPR_LZO;
+ #endif
else
+#endif
use_compr = c->default_compr;
compr_type = compress_data(buf, bytes_read, &dn->data,
&out_len, use_compr);
-@@ -1388,7 +1394,9 @@ static int add_non_dir(const char *path_
+@@ -1527,7 +1533,9 @@ static int add_non_dir(const char *path_
if (fd == -1)
return sys_err_msg("failed to open file '%s'",
path_name);
@@ -127,9 +122,9 @@
flags = 0;
if (close(fd) == -1)
return sys_err_msg("failed to close file '%s'",
---- a/mkfs.ubifs/devtable.c
-+++ b/mkfs.ubifs/devtable.c
-@@ -134,6 +134,7 @@ static int interpret_table_entry(const c
+--- a/ubifs-utils/mkfs.ubifs/devtable.c
++++ b/ubifs-utils/mkfs.ubifs/devtable.c
+@@ -135,6 +135,7 @@ static int interpret_table_entry(const c
unsigned int mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
unsigned int start = 0, increment = 0, count = 0;
@@ -137,14 +132,44 @@
if (sscanf(line, "%1023s %c %o %u %u %u %u %u %u %u",
buf, &type, &mode, &uid, &gid, &major, &minor,
&start, &increment, &count) < 0)
-@@ -144,8 +145,8 @@ static int interpret_table_entry(const c
+@@ -145,10 +146,10 @@ static int interpret_table_entry(const c
buf, type, mode, uid, gid, major, minor, start,
increment, count);
- len = strnlen(buf, 1024);
-- if (len == 1024)
+ len = strlen(buf);
+ if (len == 0)
+ return err_msg("empty path");
+- if (len == 1024)
+ if (len == 1023)
return err_msg("too long path");
- if (!strcmp(buf, "/"))
+ if (buf[0] != '/')
+--- a/include/common.h
++++ b/include/common.h
+@@ -26,7 +26,6 @@
+ #include <string.h>
+ #include <fcntl.h>
+ #include <errno.h>
+-#include <features.h>
+ #include <inttypes.h>
+ #include <unistd.h>
+ #include <sys/sysmacros.h>
+--- a/include/mtd/ubifs-media.h
++++ b/include/mtd/ubifs-media.h
+@@ -33,7 +33,15 @@
+ #ifndef __UBIFS_MEDIA_H__
+ #define __UBIFS_MEDIA_H__
+
++#ifdef __linux__
+ #include <asm/byteorder.h>
++#else
++#include <stdint.h>
++typedef uint8_t __u8;
++typedef uint16_t __be16;
++typedef uint32_t __be32;
++typedef uint64_t __be64;
++#endif
+
+ /* UBIFS node magic number (must not have the padding byte first or last) */
+ #define UBIFS_NODE_MAGIC 0x06101831
diff --git a/tools/mtd-utils/patches/120-cygwin_fixes.patch b/tools/mtd-utils/patches/120-cygwin_fixes.patch
deleted file mode 100644
index 3dc21614b1f..00000000000
--- a/tools/mtd-utils/patches/120-cygwin_fixes.patch
+++ /dev/null
@@ -1,457 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -12,6 +12,11 @@ else
- LZOLDLIBS = -llzo2
- endif
-
-+ifeq ($(shell uname -o),Cygwin)
-+CPPFLAGS += -I./include/cygwin
-+endif
-+
-+ifneq ($(shell uname -o),Cygwin)
- SUBDIRS = lib ubi-utils mkfs.ubifs
- TESTS = tests
-
-@@ -23,6 +28,10 @@ TARGETS = ftl_format flash_erase nanddum
- rfddump rfdformat \
- serve_image recv_image \
- sumtool #jffs2reader
-+else
-+SUBDIRS =
-+TARGETS = mkfs.jffs2
-+endif
- SCRIPTS = flash_eraseall
-
- SYMLINKS =
---- /dev/null
-+++ b/include/cygwin/bits-byteswap.h
-@@ -0,0 +1,132 @@
-+/* Macros to swap the order of bytes in integer values.
-+ Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
-+# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
-+#endif
-+
-+#ifndef _BITS_BYTESWAP_H
-+#define _BITS_BYTESWAP_H 1
-+
-+/* Swap bytes in 16 bit value. */
-+#define __bswap_constant_16(x) \
-+ ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
-+
-+#ifdef __GNUC__
-+# if __GNUC__ >= 2
-+# define __bswap_16(x) \
-+ (__extension__ \
-+ ({ register unsigned short int __v, __x = (x); \
-+ if (__builtin_constant_p (__x)) \
-+ __v = __bswap_constant_16 (__x); \
-+ else \
-+ __asm__ ("rorw $8, %w0" \
-+ : "=r" (__v) \
-+ : "0" (__x) \
-+ : "cc"); \
-+ __v; }))
-+# else
-+/* This is better than nothing. */
-+# define __bswap_16(x) \
-+ (__extension__ \
-+ ({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
-+# endif
-+#else
-+static __inline unsigned short int
-+__bswap_16 (unsigned short int __bsx)
-+{
-+ return __bswap_constant_16 (__bsx);
-+}
-+#endif
-+
-+/* Swap bytes in 32 bit value. */
-+#define __bswap_constant_32(x) \
-+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
-+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
-+
-+#ifdef __GNUC__
-+# if __GNUC__ >= 2
-+/* To swap the bytes in a word the i486 processors and up provide the
-+ `bswap' opcode. On i386 we have to use three instructions. */
-+# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__
-+# define __bswap_32(x) \
-+ (__extension__ \
-+ ({ register unsigned int __v, __x = (x); \
-+ if (__builtin_constant_p (__x)) \
-+ __v = __bswap_constant_32 (__x); \
-+ else \
-+ __asm__ ("rorw $8, %w0;" \
-+ "rorl $16, %0;" \
-+ "rorw $8, %w0" \
-+ : "=r" (__v) \
-+ : "0" (__x) \
-+ : "cc"); \
-+ __v; }))
-+# else
-+# define __bswap_32(x) \
-+ (__extension__ \
-+ ({ register unsigned int __v, __x = (x); \
-+ if (__builtin_constant_p (__x)) \
-+ __v = __bswap_constant_32 (__x); \
-+ else \
-+ __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
-+ __v; }))
-+# endif
-+# else
-+# define __bswap_32(x) \
-+ (__extension__ \
-+ ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
-+# endif
-+#else
-+static __inline unsigned int
-+__bswap_32 (unsigned int __bsx)
-+{
-+ return __bswap_constant_32 (__bsx);
-+}
-+#endif
-+
-+
-+#if defined __GNUC__ && __GNUC__ >= 2
-+/* Swap bytes in 64 bit value. */
-+#define __bswap_constant_64(x) \
-+ ((((x) & 0xff00000000000000ull) >> 56) \
-+ | (((x) & 0x00ff000000000000ull) >> 40) \
-+ | (((x) & 0x0000ff0000000000ull) >> 24) \
-+ | (((x) & 0x000000ff00000000ull) >> 8) \
-+ | (((x) & 0x00000000ff000000ull) << 8) \
-+ | (((x) & 0x0000000000ff0000ull) << 24) \
-+ | (((x) & 0x000000000000ff00ull) << 40) \
-+ | (((x) & 0x00000000000000ffull) << 56))
-+
-+# define __bswap_64(x) \
-+ (__extension__ \
-+ ({ union { __extension__ unsigned long long int __ll; \
-+ unsigned long int __l[2]; } __w, __r; \
-+ if (__builtin_constant_p (x)) \
-+ __r.__ll = __bswap_constant_64 (x); \
-+ else \
-+ { \
-+ __w.__ll = (x); \
-+ __r.__l[0] = __bswap_32 (__w.__l[1]); \
-+ __r.__l[1] = __bswap_32 (__w.__l[0]); \
-+ } \
-+ __r.__ll; }))
-+#endif
-+
-+#endif /* _BITS_BYTESWAP_H */
---- /dev/null
-+++ b/include/cygwin/byteswap.h
-@@ -0,0 +1,40 @@
-+/* Copyright (C) 1997 Free Software Foundation, Inc.
-+ This file is part of the GNU C Library.
-+
-+ The GNU C Library is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU Lesser General Public
-+ License as published by the Free Software Foundation; either
-+ version 2.1 of the License, or (at your option) any later version.
-+
-+ The GNU C Library is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ Lesser General Public License for more details.
-+
-+ You should have received a copy of the GNU Lesser General Public
-+ License along with the GNU C Library; if not, write to the Free
-+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ 02111-1307 USA. */
-+
-+#ifndef _BYTESWAP_H
-+#define _BYTESWAP_H 1
-+
-+/* Get the machine specific, optimized definitions. */
-+#include "bits-byteswap.h"
-+
-+
-+/* The following definitions must all be macros since otherwise some
-+ of the possible optimizations are not possible. */
-+
-+/* Return a value with all bytes in the 16 bit argument swapped. */
-+#define bswap_16(x) __bswap_16 (x)
-+
-+/* Return a value with all bytes in the 32 bit argument swapped. */
-+#define bswap_32(x) __bswap_32 (x)
-+
-+#if defined __GNUC__ && __GNUC__ >= 2
-+/* Return a value with all bytes in the 64 bit argument swapped. */
-+# define bswap_64(x) __bswap_64 (x)
-+#endif
-+
-+#endif /* byteswap.h */
---- /dev/null
-+++ b/include/cygwin/endian.h
-@@ -0,0 +1,26 @@
-+#ifndef _CYGENDIAN_H_
-+#define _CYGENDIAN_H_
-+
-+#ifdef __CYGWIN__
-+
-+#include <sys/param.h>
-+
-+#ifndef __BIG_ENDIAN
-+#define __BIG_ENDIAN 4321
-+#endif
-+
-+#ifndef __LITTLE_ENDIAN
-+#define __LITTLE_ENDIAN 1234
-+#endif
-+
-+#ifndef __BYTE_ORDER
-+#define __BYTE_ORDER __LITTLE_ENDIAN
-+#endif
-+
-+#ifndef BYTE_ORDER
-+#define BYTE_ORDER __LITTLE_ENDIAN
-+#endif
-+
-+#endif /* __CYGWIN__ */
-+
-+#endif /* _CYGENDIAN_H_ */
---- /dev/null
-+++ b/include/cygwin/ioctl.h
-@@ -0,0 +1,38 @@
-+#ifndef _CYGIOCTL_H_
-+#define _CYGIOCTL_H_
-+
-+#ifdef __CYGWIN__
-+
-+#define _IOC_NRBITS 8
-+#define _IOC_TYPEBITS 8
-+#define _IOC_SIZEBITS 14
-+#define _IOC_DIRBITS 2
-+
-+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-+
-+#define _IOC_NRSHIFT 0
-+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-+
-+#define _IOC_NONE 0U
-+#define _IOC_WRITE 1U
-+#define _IOC_READ 2U
-+
-+#define _IOC(dir,type,nr,size) \
-+ (((dir) << _IOC_DIRSHIFT) | \
-+ ((type) << _IOC_TYPESHIFT) | \
-+ ((nr) << _IOC_NRSHIFT) | \
-+ ((size) << _IOC_SIZESHIFT))
-+
-+#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-+#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-+
-+#endif /* __CYGWIN__ */
-+
-+#endif /* _CYGIOCTL_H_ */
---- /dev/null
-+++ b/include/cygwin/pread.c
-@@ -0,0 +1,41 @@
-+#ifdef __CYGWIN__
-+
-+#include <errno.h>
-+
-+ssize_t
-+pread(int fd, void *p, size_t n, off_t off)
-+{
-+ off_t ooff;
-+ int oerrno;
-+
-+ if ((ooff = lseek(fd, off, SEEK_SET)) == -1)
-+ return -1;
-+
-+ n = read(fd, p, n);
-+
-+ oerrno = errno;
-+ lseek(fd, ooff, SEEK_SET);
-+ errno = oerrno;
-+
-+ return n;
-+}
-+
-+ssize_t
-+pwrite(int fd, const void *p, size_t n, off_t off)
-+{
-+ off_t ooff;
-+ int oerrno;
-+
-+ if ((ooff = lseek(fd, off, SEEK_SET)) == -1)
-+ return -1;
-+
-+ n = write(fd, p, n);
-+
-+ oerrno = errno;
-+ lseek(fd, ooff, SEEK_SET);
-+ errno = oerrno;
-+
-+ return n;
-+}
-+
-+#endif /* __CYGWIN__ */
---- /dev/null
-+++ b/lnconf.sh
-@@ -0,0 +1,53 @@
-+#!/bin/sh
-+#
-+# Generic configure replacement.
-+#
-+# $Id: lnconf.sh,v 1.1 2004/04/05 21:55:59 igor Exp $
-+#
-+# Copies all files from the script directory to the current one.
-+# Intended to replace 'configure' for packages that don't have one, to
-+# allow building outside of the source tree.
-+#
-+# Note: this does not do any fancy things with detecting shells and
-+# supporting other platforms. But it should work on Cygwin.
-+
-+# find out where the script is located
-+tdir=`echo "$0" | sed 's%[\\/][^\\/][^\\/]*$%%'`
-+test "x$tdir" = "x$0" && tdir=.
-+
-+a_srcdir=`cd $tdir; pwd`
-+a_destdir=`pwd`
-+
-+# sanity checks:
-+# are we in the script directory?
-+test "x$a_srcdir" = "x$a_destdir" && exit 0
-+# is there any chance that this is the script directory?
-+test "x`cd "$a_srcdir" && /bin/ls -id`" = "x`/bin/ls -id`" && exit 0
-+
-+# try to find lndir and use it if it's available
-+LNDIR="`which lndir 2>/dev/null`"
-+if [ "x$LNDIR" = "x" ]; then
-+ lndir() {
-+ test "x$1" = "x" && return 1
-+ # be careful of the current directory
-+ DINODE=`find . -maxdepth 0 -ls | sed 's/ .*$//'`
-+ case "`pwd`" in
-+ "`cd "$1" && pwd`"/*) CUR="-type d -inum $DINODE -prune -o";;
-+ esac
-+ # duplicate the directory structure
-+ (cd "$1" && find . $CUR -type d -mindepth 1 -print) | xargs -tr mkdir -p
-+ # copy all symbolic links
-+ (cd "$1" && find . $CUR -type l -mindepth 1 -print) | xargs -ri sh -c "ln -s \"\`readlink "$1/{}"\`\" \"{}\""
-+ # or simply
-+ #(cd "$1" && find . $CUR -type l -mindepth 1 -print) | xargs -ri ln -s "$1"/{} {}
-+ # link all files
-+ (cd "$1" && find . $CUR -type f -mindepth 1 -print) | xargs -ri ln -s "$1"/{} {}
-+ }
-+else
-+ lndir() {
-+ "$LNDIR" "$@"
-+ }
-+fi
-+
-+lndir "$tdir"
-+
---- a/mkfs.jffs2.c
-+++ b/mkfs.jffs2.c
-@@ -77,6 +77,14 @@
- #include "rbtree.h"
- #include "common.h"
-
-+#ifdef __CYGWIN__
-+#include <cygwin/ioctl.h>
-+#include <cygwin/endian.h>
-+#include <cygwin/pread.c>
-+# define IFTODT(mode) (((mode) & 0170000) >> 12)
-+# define DTTOIF(dirtype) ((dirtype) << 12)
-+#endif /* __CYGWIN__ */
-+
- /* Do not use the weird XPG version of basename */
- #undef basename
-
-@@ -376,7 +384,7 @@ static struct filesystem_entry *recursiv
- the following macros use it if available or use a hacky workaround...
- */
-
--#ifdef __GNUC__
-+#if defined __GNUC__ && !defined __CYGWIN__
- #define SCANF_PREFIX "a"
- #define SCANF_STRING(s) (&s)
- #define GETCWD_SIZE 0
-@@ -459,6 +467,14 @@ static int interpret_table_entry(struct
- }
- entry = find_filesystem_entry(root, name, mode);
- if (entry && !(count > 0 && (type == 'c' || type == 'b'))) {
-+ /* Check the type */
-+ if ((mode & S_IFMT) != (entry->sb.st_mode & S_IFMT)) {
-+ error_msg ("skipping device_table entry '%s': type mismatch!", name);
-+ free(name);
-+ free(hostpath);
-+ return 1;
-+ }
-+
- /* Ok, we just need to fixup the existing entry
- * and we will be all done... */
- entry->sb.st_uid = uid;
-@@ -468,11 +484,21 @@ static int interpret_table_entry(struct
- entry->sb.st_rdev = makedev(major, minor);
- }
- } else {
-+ if (type == 'f' || type == 'l') {
-+ error_msg ("skipping device_table entry '%s': file does not exist!", name);
-+ free(name);
-+ free(hostpath);
-+ return 1;
-+ }
- /* If parent is NULL (happens with device table entries),
- * try and find our parent now) */
- tmp = strdup(name);
- dir = dirname(tmp);
-- parent = find_filesystem_entry(root, dir, S_IFDIR);
-+ if (!strcmp(dir, "/")) {
-+ parent = root;
-+ } else {
-+ parent = find_filesystem_entry(root, dir, S_IFDIR);
-+ }
- free(tmp);
- if (parent == NULL) {
- errmsg ("skipping device_table entry '%s': no parent directory!", name);
-@@ -486,6 +512,7 @@ static int interpret_table_entry(struct
- add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent);
- break;
- case 'f':
-+ case 'l':
- add_host_filesystem_entry(name, hostpath, uid, gid, mode, 0, parent);
- break;
- case 'p':
---- a/ubi-utils/src/libubi.c
-+++ b/ubi-utils/src/libubi.c
-@@ -32,6 +32,9 @@
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/types.h>
-+#ifdef __CYGWIN__
-+#include <cygwin/ioctl.h>
-+#endif
- #include <libubi.h>
- #include "libubi_int.h"
- #include "common.h"
diff --git a/tools/mtd-utils/patches/130-lzma_jffs2.patch b/tools/mtd-utils/patches/130-lzma_jffs2.patch
index be1c361fe1d..d9cbfeebec1 100644
--- a/tools/mtd-utils/patches/130-lzma_jffs2.patch
+++ b/tools/mtd-utils/patches/130-lzma_jffs2.patch
@@ -1,33 +1,35 @@
---- a/Makefile
-+++ b/Makefile
-@@ -1,7 +1,7 @@
+--- a/jffsX-utils/Makemodule.am
++++ b/jffsX-utils/Makemodule.am
+@@ -4,11 +4,19 @@ mkfs_jffs2_SOURCES = \
+ jffsX-utils/compr_zlib.c \
+ jffsX-utils/compr.h \
+ jffsX-utils/rbtree.c \
+- jffsX-utils/compr_lzo.c \
++ jffsX-utils/compr_lzma.c \
++ jffsX-utils/lzma/LzFind.c \
++ jffsX-utils/lzma/LzmaEnc.c \
++ jffsX-utils/lzma/LzmaDec.c \
+ jffsX-utils/compr.c \
+ jffsX-utils/compr_rtime.c
++
++if !WITHOUT_LZO
++mkfs_jffs2_SOURCES += jffsX-utils/compr_lzo.c
++endif
++
+ mkfs_jffs2_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS)
+-mkfs_jffs2_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS)
++mkfs_jffs2_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CFLAGS) $(LZO_CFLAGS) -I./include/linux/lzma
- # -*- sh -*-
-
--CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)
-+CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma
-
- ifeq ($(WITHOUT_XATTR), 1)
- CPPFLAGS += -DWITHOUT_XATTR
-@@ -59,7 +59,9 @@ $(SYMLINKS):
- ln -sf ../fs/jffs2/$@ $@
-
- $(BUILDDIR)/mkfs.jffs2: $(addprefix $(BUILDDIR)/,\
-- compr_rtime.o mkfs.jffs2.o compr_zlib.o compr_lzo.o \
-+ compr_rtime.o mkfs.jffs2.o compr_zlib.o \
-+ $(if $(WITHOUT_LZO),,compr_lzo.o) \
-+ compr_lzma.o lzma/LzFind.o lzma/LzmaEnc.o lzma/LzmaDec.o \
- compr.o rbtree.o)
- LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS)
- LDLIBS_mkfs.jffs2 = -lz $(LZOLDLIBS)
---- a/compr.c
-+++ b/compr.c
+ jffs2reader_SOURCES = jffsX-utils/jffs2reader.c
+ jffs2reader_LDADD = libmtd.a $(ZLIB_LIBS) $(LZO_LIBS)
+--- a/jffsX-utils/compr.c
++++ b/jffsX-utils/compr.c
@@ -520,6 +520,9 @@ int jffs2_compressors_init(void)
#ifdef CONFIG_JFFS2_LZO
jffs2_lzo_init();
#endif
+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_init();
++ jffs2_lzma_init();
+#endif
return 0;
}
@@ -37,12 +39,12 @@
jffs2_lzo_exit();
#endif
+#ifdef CONFIG_JFFS2_LZMA
-+ jffs2_lzma_exit();
++ jffs2_lzma_exit();
+#endif
return 0;
}
---- a/compr.h
-+++ b/compr.h
+--- a/jffsX-utils/compr.h
++++ b/jffsX-utils/compr.h
@@ -18,13 +18,14 @@
#define CONFIG_JFFS2_ZLIB
@@ -73,7 +75,7 @@
#endif /* __JFFS2_COMPR_H__ */
--- /dev/null
-+++ b/compr_lzma.c
++++ b/jffsX-utils/compr_lzma.c
@@ -0,0 +1,128 @@
+/*
+ * JFFS2 -- Journalling Flash File System, Version 2.
@@ -120,11 +122,11 @@
+ return -1;
+ }
+
-+ return 0;
++ return 0;
+}
+
+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen, void *model)
++ uint32_t *sourcelen, uint32_t *dstlen)
+{
+ SizeT compress_size = (SizeT)(*dstlen);
+ int ret;
@@ -149,7 +151,7 @@
+}
+
+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen, void *model)
++ uint32_t srclen, uint32_t destlen)
+{
+ int ret;
+ SizeT dl = (SizeT)destlen;
@@ -176,26 +178,26 @@
+
+int INIT jffs2_lzma_init(void)
+{
-+ int ret;
++ int ret;
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+
-+ props.dictSize = LZMA_BEST_DICT(0x2000);
-+ props.level = LZMA_BEST_LEVEL;
-+ props.lc = LZMA_BEST_LC;
-+ props.lp = LZMA_BEST_LP;
-+ props.pb = LZMA_BEST_PB;
-+ props.fb = LZMA_BEST_FB;
++ props.dictSize = LZMA_BEST_DICT(0x2000);
++ props.level = LZMA_BEST_LEVEL;
++ props.lc = LZMA_BEST_LC;
++ props.lp = LZMA_BEST_LP;
++ props.pb = LZMA_BEST_PB;
++ props.fb = LZMA_BEST_FB;
+
+ ret = lzma_alloc_workspace(&props);
-+ if (ret < 0)
-+ return ret;
++ if (ret < 0)
++ return ret;
+
+ ret = jffs2_register_compressor(&jffs2_lzma_comp);
+ if (ret)
+ lzma_free_workspace();
+
-+ return ret;
++ return ret;
+}
+
+void jffs2_lzma_exit(void)
@@ -246,7 +248,7 @@
+ #define LZMA_FREE free
+ #define PRINT_ERROR(msg) fprintf(stderr, msg)
+ #define INIT
-+ #define STATIC
++ #define STATIC static
+#endif
+
+#include "lzma/LzmaDec.h"
@@ -262,16 +264,16 @@
+
+static void *p_lzma_malloc(void *p, size_t size)
+{
-+ if (size == 0)
-+ return NULL;
++ if (size == 0)
++ return NULL;
+
-+ return LZMA_MALLOC(size);
++ return LZMA_MALLOC(size);
+}
+
+static void p_lzma_free(void *p, void *address)
+{
-+ if (address != NULL)
-+ LZMA_FREE(address);
++ if (address != NULL)
++ LZMA_FREE(address);
+}
+
+static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free};
@@ -901,7 +903,7 @@
+
+#endif
--- /dev/null
-+++ b/lzma/LzFind.c
++++ b/jffsX-utils/lzma/LzFind.c
@@ -0,0 +1,753 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2008-04-04
@@ -950,9 +952,9 @@
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
++static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
+
-+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
++static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
@@ -1657,7 +1659,7 @@
+ }
+}
--- /dev/null
-+++ b/lzma/LzmaDec.c
++++ b/jffsX-utils/lzma/LzmaDec.c
@@ -0,0 +1,1014 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-04-29
@@ -2358,7 +2360,7 @@
+ p->needFlush = 0;
+}
+
-+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
++static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+ p->needFlush = 1;
+ p->remainLen = 0;
@@ -2674,7 +2676,7 @@
+ return res;
+}
--- /dev/null
-+++ b/lzma/LzmaEnc.c
++++ b/jffsX-utils/lzma/LzmaEnc.c
@@ -0,0 +1,2335 @@
+/* LzmaEnc.c -- LZMA Encoder
+2008-04-28
@@ -2778,7 +2780,7 @@
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
-+void LzmaEnc_FastPosInit(Byte *g_FastPos)
++static void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+ int c = 2, slotFast;
+ g_FastPos[0] = 0;
@@ -3032,7 +3034,7 @@
+ CSaveState saveState;
+} CLzmaEnc;
+
-+void LzmaEnc_SaveState(CLzmaEncHandle pp)
++static void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CSaveState *dest = &p->saveState;
@@ -3058,7 +3060,7 @@
+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
-+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
++static void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *dest = (CLzmaEnc *)pp;
+ const CSaveState *p = &dest->saveState;
@@ -3301,7 +3303,7 @@
+ while (symbol < 0x10000);
+}
+
-+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
++static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+ UInt32 i;
+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -4427,7 +4429,7 @@
+ p->matchPriceCount = 0;
+}
+
-+void LzmaEnc_Construct(CLzmaEnc *p)
++static void LzmaEnc_Construct(CLzmaEnc *p)
+{
+ RangeEnc_Construct(&p->rc);
+ MatchFinder_Construct(&p->matchFinderBase);
@@ -4460,7 +4462,7 @@
+ return p;
+}
+
-+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
++static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->litProbs);
+ alloc->Free(alloc, p->saveState.litProbs);
@@ -4468,7 +4470,7 @@
+ p->saveState.litProbs = 0;
+}
+
-+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
++static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
@@ -4699,7 +4701,7 @@
+ return SZ_OK;
+}
+
-+void LzmaEnc_Init(CLzmaEnc *p)
++static void LzmaEnc_Init(CLzmaEnc *p)
+{
+ UInt32 i;
+ p->state = 0;
@@ -4758,7 +4760,7 @@
+ p->lpMask = (1 << p->lp) - 1;
+}
+
-+void LzmaEnc_InitPrices(CLzmaEnc *p)
++static void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+ if (!p->fastMode)
+ {
@@ -4799,7 +4801,7 @@
+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
-+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
++static SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+ ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
@@ -4815,7 +4817,7 @@
+ p->seqBufInStream.rem = srcLen;
+}
+
-+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
++static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -4824,7 +4826,7 @@
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+
-+void LzmaEnc_Finish(CLzmaEncHandle pp)
++static void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+ #ifdef COMPRESS_MF_MT
+ CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -4856,19 +4858,19 @@
+}
+
+
-+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
++static UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
-+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
++static const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
-+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
++static SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -5011,9 +5013,9 @@
+ LzmaEnc_Destroy(p, alloc, allocBig);
+ return res;
+}
---- a/mkfs.jffs2.c
-+++ b/mkfs.jffs2.c
-@@ -1685,11 +1685,11 @@ int main(int argc, char **argv)
+--- a/jffsX-utils/mkfs.jffs2.c
++++ b/jffsX-utils/mkfs.jffs2.c
+@@ -1666,11 +1666,11 @@ int main(int argc, char **argv)
}
erase_block_size *= units;
diff --git a/tools/mtd-utils/patches/131-fix_lib_compile.patch b/tools/mtd-utils/patches/131-fix_lib_compile.patch
deleted file mode 100644
index 8c977c1774d..00000000000
--- a/tools/mtd-utils/patches/131-fix_lib_compile.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -7,7 +7,7 @@ SUBDIRS =
- # CFLAGS += -Werror
- CPPFLAGS += -I../include
- LIBS = libmtd
--TARGETS = libmtd.a
-+override TARGETS = libmtd.a
-
- include ../common.mk
-
diff --git a/tools/mtd-utils/patches/133-error-fix.patch b/tools/mtd-utils/patches/133-error-fix.patch
deleted file mode 100644
index 4854138d023..00000000000
--- a/tools/mtd-utils/patches/133-error-fix.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/mkfs.jffs2.c
-+++ b/mkfs.jffs2.c
-@@ -469,7 +469,7 @@ static int interpret_table_entry(struct
- if (entry && !(count > 0 && (type == 'c' || type == 'b'))) {
- /* Check the type */
- if ((mode & S_IFMT) != (entry->sb.st_mode & S_IFMT)) {
-- error_msg ("skipping device_table entry '%s': type mismatch!", name);
-+ sys_errmsg ("skipping device_table entry '%s': type mismatch!", name);
- free(name);
- free(hostpath);
- return 1;
-@@ -485,7 +485,7 @@ static int interpret_table_entry(struct
- }
- } else {
- if (type == 'f' || type == 'l') {
-- error_msg ("skipping device_table entry '%s': file does not exist!", name);
-+ sys_errmsg ("skipping device_table entry '%s': file does not exist!", name);
- free(name);
- free(hostpath);
- return 1;
diff --git a/tools/mtd-utils/patches/134-freebsd_loff_t.patch b/tools/mtd-utils/patches/134-freebsd_loff_t.patch
index 68a835292ca..2d141bd7a3a 100644
--- a/tools/mtd-utils/patches/134-freebsd_loff_t.patch
+++ b/tools/mtd-utils/patches/134-freebsd_loff_t.patch
@@ -1,13 +1,14 @@
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
-@@ -114,8 +114,8 @@ struct otp_info {
- #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
- #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
+@@ -171,9 +171,9 @@ struct otp_info {
+ /* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */
#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo)
+ /* Check if an eraseblock is bad */
-#define MEMGETBADBLOCK _IOW('M', 11, __kernel_loff_t)
--#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t)
+#define MEMGETBADBLOCK _IOW('M', 11, loff_t)
+ /* Mark an eraseblock as bad */
+-#define MEMSETBADBLOCK _IOW('M', 12, __kernel_loff_t)
+#define MEMSETBADBLOCK _IOW('M', 12, loff_t)
+ /* Set OTP (One-Time Programmable) mode (factory vs. user) */
#define OTPSELECT _IOR('M', 13, int)
- #define OTPGETREGIONCOUNT _IOW('M', 14, int)
- #define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
+ /* Get number of OTP (One-Time Programmable) regions */
diff --git a/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch b/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch
deleted file mode 100644
index 82b6c2fe94e..00000000000
--- a/tools/mtd-utils/patches/135-mkubifs_optional_lzo.patch
+++ /dev/null
@@ -1,119 +0,0 @@
---- a/mkfs.ubifs/compr.c
-+++ b/mkfs.ubifs/compr.c
-@@ -24,7 +24,6 @@
- #include <stdio.h>
- #include <stdint.h>
- #include <string.h>
--#include <lzo/lzo1x.h>
- #include <linux/types.h>
-
- #define crc32 __zlib_crc32
-@@ -35,7 +34,6 @@
- #include "ubifs-media.h"
- #include "mkfs.ubifs.h"
-
--static void *lzo_mem;
- static unsigned long long errcnt = 0;
- static struct ubifs_info *c = &info_;
-
-@@ -86,6 +84,25 @@ static int zlib_deflate(void *in_buf, si
- return 0;
- }
-
-+#ifndef WITHOUT_LZO
-+#include <lzo/lzo1x.h>
-+
-+static void *lzo_mem;
-+
-+static int lzo_init(void)
-+{
-+ lzo_mem = malloc(LZO1X_999_MEM_COMPRESS);
-+ if (!lzo_mem)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+static void lzo_fini(void)
-+{
-+ free(lzo_mem);
-+}
-+
- static int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
- size_t *out_len)
- {
-@@ -103,6 +120,12 @@ static int lzo_compress(void *in_buf, si
-
- return 0;
- }
-+#else
-+static inline int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
-+ size_t *out_len) { return -1; }
-+static inline int lzo_init(void) { return 0; }
-+static inline void lzo_fini(void) { }
-+#endif
-
- static int no_compress(void *in_buf, size_t in_len, void *out_buf,
- size_t *out_len)
-@@ -123,7 +146,6 @@ static int favor_lzo_compress(void *in_b
- lzo_len = zlib_len = *out_len;
- lzo_ret = lzo_compress(in_buf, in_len, out_buf, &lzo_len);
- zlib_ret = zlib_deflate(in_buf, in_len, zlib_buf, &zlib_len);
--
- if (lzo_ret && zlib_ret)
- /* Both compressors failed */
- return -1;
-@@ -198,23 +220,28 @@ int compress_data(void *in_buf, size_t i
-
- int init_compression(void)
- {
-- lzo_mem = malloc(LZO1X_999_MEM_COMPRESS);
-- if (!lzo_mem)
-- return -1;
-+ int ret;
-+
-+ ret = lzo_init();
-+ if (ret)
-+ goto err;
-
- zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
-- if (!zlib_buf) {
-- free(lzo_mem);
-- return -1;
-- }
-+ if (!zlib_buf)
-+ goto err_lzo;
-
- return 0;
-+
-+err_lzo:
-+ lzo_fini();
-+err:
-+ return ret;
- }
-
- void destroy_compression(void)
- {
- free(zlib_buf);
-- free(lzo_mem);
-+ lzo_fini();
- if (errcnt)
- fprintf(stderr, "%llu compression errors occurred\n", errcnt);
- }
---- a/mkfs.ubifs/Makefile
-+++ b/mkfs.ubifs/Makefile
-@@ -6,7 +6,13 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch]
-
- TARGETS = mkfs.ubifs
-
--LDLIBS_mkfs.ubifs = -lz -llzo2 -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
-+ifeq ($(WITHOUT_LZO), 1)
-+ CPPFLAGS += -DWITHOUT_LZO
-+else
-+ LZOLDLIBS = -llzo2
-+endif
-+
-+LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
- LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd
- LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
-
diff --git a/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch b/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch
deleted file mode 100644
index 1e44ba4c274..00000000000
--- a/tools/mtd-utils/patches/136-mkfs.ubifs-xz-support.patch
+++ /dev/null
@@ -1,404 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -1,7 +1,7 @@
-
- # -*- sh -*-
-
--CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) -I./include/linux/lzma
-+CPPFLAGS += -I./include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(XZCPPFLAGS) -I./include/linux/lzma
-
- ifeq ($(WITHOUT_XATTR), 1)
- CPPFLAGS += -DWITHOUT_XATTR
---- a/mkfs.ubifs/compr.c
-+++ b/mkfs.ubifs/compr.c
-@@ -127,6 +127,114 @@ static inline int lzo_init(void) { retur
- static inline void lzo_fini(void) { }
- #endif
-
-+#ifndef WITHOUT_XZ
-+
-+#include <lzma.h>
-+
-+struct xz_ctx {
-+ lzma_filter filters[3];
-+ lzma_options_lzma opts;
-+};
-+
-+static struct xz_ctx *xz_ctx;
-+
-+#define LZMA_COMPRESSION_LEVEL 9
-+
-+static struct xz_ctx *xz_ctx_init(void)
-+{
-+ struct xz_ctx *ctx;
-+ lzma_options_lzma *opts_lzma;
-+ uint32_t preset;
-+ int ret;
-+
-+ ctx = malloc(sizeof(struct xz_ctx));
-+ if (ctx == NULL)
-+ goto err;
-+
-+ memset(ctx, 0, sizeof(struct xz_ctx));
-+
-+ opts_lzma = &ctx->opts;
-+
-+ preset = LZMA_COMPRESSION_LEVEL | LZMA_PRESET_EXTREME;
-+ ret = lzma_lzma_preset(opts_lzma, preset);
-+ if (ret)
-+ goto err_free_ctx;
-+
-+ /* TODO: allow to specify LZMA options via command line */
-+#if 0
-+ opts_lzma->lc = 3;
-+ opts_lzma->lp = 0;
-+ opts_lzma->pb = 2;
-+ opts_lzma->nice_len = 64;
-+#else
-+ opts_lzma->lc = 0;
-+ opts_lzma->lp = 2;
-+ opts_lzma->pb = 2;
-+ opts_lzma->nice_len = 64;
-+#endif
-+
-+ ctx->filters[0].id = LZMA_FILTER_LZMA2;
-+ ctx->filters[0].options = opts_lzma;
-+ ctx->filters[1].id = LZMA_VLI_UNKNOWN;
-+
-+ return ctx;
-+
-+err_free_ctx:
-+ free(ctx);
-+err:
-+ return NULL;
-+}
-+
-+static void xz_ctx_free(struct xz_ctx *ctx)
-+{
-+ free(ctx);
-+}
-+
-+static int xz_init(void)
-+{
-+ xz_ctx = xz_ctx_init();
-+ if (xz_ctx == NULL)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+static void xz_fini(void)
-+{
-+ xz_ctx_free(xz_ctx);
-+}
-+
-+static int xz_compress(void *in_buf, size_t in_len, void *out_buf,
-+ size_t *out_len)
-+{
-+ size_t ret_len;
-+ lzma_ret ret_xz;
-+ int ret;
-+
-+ ret = -1;
-+
-+ ret_len = 0;
-+ ret_xz = lzma_stream_buffer_encode(xz_ctx->filters, LZMA_CHECK_CRC32,
-+ NULL, in_buf, in_len, out_buf,
-+ &ret_len, *out_len);
-+ if (ret_xz != LZMA_OK) {
-+ fprintf(stderr, "XZ error: %d\n", (int) ret_xz);
-+ goto out;
-+ }
-+
-+ *out_len = ret_len;
-+
-+ ret = 0;
-+out:
-+ return ret;
-+}
-+#else
-+static inline int xz_init(void) { return 0; }
-+static inline void xz_fini(void) { }
-+static inline int xz_compress(void *in_buf, size_t in_len, void *out_buf,
-+ size_t *out_len) { return -1; }
-+#endif
-+
- static int no_compress(void *in_buf, size_t in_len, void *out_buf,
- size_t *out_len)
- {
-@@ -199,6 +307,9 @@ int compress_data(void *in_buf, size_t i
- case MKFS_UBIFS_COMPR_LZO:
- ret = lzo_compress(in_buf, in_len, out_buf, out_len);
- break;
-+ case MKFS_UBIFS_COMPR_XZ:
-+ ret = xz_compress(in_buf, in_len, out_buf, out_len);
-+ break;
- case MKFS_UBIFS_COMPR_ZLIB:
- ret = zlib_deflate(in_buf, in_len, out_buf, out_len);
- break;
-@@ -226,12 +337,18 @@ int init_compression(void)
- if (ret)
- goto err;
-
-+ ret = xz_init();
-+ if (ret)
-+ goto err_lzo;
-+
- zlib_buf = malloc(UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR);
- if (!zlib_buf)
-- goto err_lzo;
-+ goto err_xz;
-
- return 0;
-
-+err_xz:
-+ xz_fini();
- err_lzo:
- lzo_fini();
- err:
-@@ -241,6 +358,7 @@ err:
- void destroy_compression(void)
- {
- free(zlib_buf);
-+ xz_fini();
- lzo_fini();
- if (errcnt)
- fprintf(stderr, "%llu compression errors occurred\n", errcnt);
---- a/mkfs.ubifs/compr.h
-+++ b/mkfs.ubifs/compr.h
-@@ -36,6 +36,7 @@ enum compression_type
- MKFS_UBIFS_COMPR_NONE,
- MKFS_UBIFS_COMPR_LZO,
- MKFS_UBIFS_COMPR_ZLIB,
-+ MKFS_UBIFS_COMPR_XZ,
- };
-
- int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
---- a/mkfs.ubifs/Makefile
-+++ b/mkfs.ubifs/Makefile
-@@ -6,21 +6,33 @@ ALL_SOURCES=*.[ch] hashtable/*.[ch]
-
- TARGETS = mkfs.ubifs
-
-+MKFS_UBIFS_OBJS = $(addprefix $(BUILDDIR)/,\
-+ crc16.o lpt.o compr.o devtable.o \
-+ hashtable/hashtable.o hashtable/hashtable_itr.o)
-+
- ifeq ($(WITHOUT_LZO), 1)
- CPPFLAGS += -DWITHOUT_LZO
- else
- LZOLDLIBS = -llzo2
- endif
-
--LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
-+ifeq ($(WITHOUT_XZ), 1)
-+ CPPFLAGS += -DWITHOUT_XZ
-+else
-+ifneq ($(LZMA_STATIC_LIB),)
-+ MKFS_UBIFS_OBJS += $(LZMA_STATIC_LIB)
-+else
-+ XZLDLIBS = -llzma
-+endif
-+endif
-+
-+LDLIBS_mkfs.ubifs = -lz $(LZOLDLIBS) $(XZLDLIBS) -lm -luuid -L$(BUILDDIR)/../ubi-utils/ -lubi
- LDLIBS_mkfs.ubifs += -L$(BUILDDIR)/../lib -lmtd
--LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS)
-+LDLIBS_mkfs.ubifs += $(ZLIBLDFLAGS) $(LZOLDFLAGS) $(XZLDFLAGS)
-
- include ../common.mk
-
--$(BUILDDIR)/mkfs.ubifs: $(addprefix $(BUILDDIR)/,\
-- crc16.o lpt.o compr.o devtable.o \
-- hashtable/hashtable.o hashtable/hashtable_itr.o)
-+$(BUILDDIR)/mkfs.ubifs: $(MKFS_UBIFS_OBJS)
-
- clean::
- rm -f $(BUILDDIR)/hashtable/*.o cscope.*
---- a/mkfs.ubifs/mkfs.ubifs.c
-+++ b/mkfs.ubifs/mkfs.ubifs.c
-@@ -98,6 +98,9 @@ struct ubifs_info info_;
- static struct ubifs_info *c = &info_;
- static libubi_t ubi;
-
-+static int force_compr_set;
-+static int force_compr;
-+
- /* Debug levels are: 0 (none), 1 (statistics), 2 (files) ,3 (more details) */
- int debug_level;
- int verbose;
-@@ -132,7 +135,7 @@ static struct inum_mapping **hash_table;
- /* Inode creation sequence number */
- static unsigned long long creat_sqnum;
-
--static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQq";
-+static const char *optstring = "d:r:m:o:D:h?vVe:c:g:f:Fp:k:x:X:y:j:R:l:j:UQq";
-
- static const struct option longopts[] = {
- {"root", 1, NULL, 'r'},
-@@ -149,6 +152,7 @@ static const struct option longopts[] =
- {"reserved", 1, NULL, 'R'},
- {"compr", 1, NULL, 'x'},
- {"favor-percent", 1, NULL, 'X'},
-+ {"force-compr", 1, NULL, 'y'},
- {"fanout", 1, NULL, 'f'},
- {"space-fixup", 0, NULL, 'F'},
- {"keyhash", 1, NULL, 'k'},
-@@ -178,11 +182,13 @@ static const char *helptext =
- "-o, --output=FILE output to FILE\n"
- "-j, --jrn-size=SIZE journal size\n"
- "-R, --reserved=SIZE how much space should be reserved for the super-user\n"
--"-x, --compr=TYPE compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n"
--" \"none\" (default: \"lzo\")\n"
-+"-x, --compr=TYPE default compression type - \"lzo\", \"favor_lzo\",\n"
-+" \"zlib\" or \"none\" (default: \"lzo\")\n"
- "-X, --favor-percent may only be used with favor LZO compression and defines\n"
- " how many percent better zlib should compress to make\n"
- " mkfs.ubifs use zlib instead of LZO (default 20%)\n"
-+"-y, --force-compr=TYPE force to build the fs with different compression -\n"
-+" \"lzo\", \"zlib\" or \"none\"\n"
- "-f, --fanout=NUM fanout NUM (default: 8)\n"
- "-F, --space-fixup file-system free space has to be fixed up on first mount\n"
- " (requires kernel version 3.0 or greater)\n"
-@@ -530,6 +536,43 @@ static int open_ubi(const char *node)
- return 0;
- }
-
-+static const char *get_compr_str(int compr)
-+{
-+ switch (compr) {
-+ case UBIFS_COMPR_LZO:
-+ return "lzo";
-+ case UBIFS_COMPR_ZLIB:
-+ return "zlib";
-+ case UBIFS_COMPR_XZ:
-+ return "xz";
-+ case UBIFS_COMPR_NONE:
-+ return "none";
-+ }
-+
-+ return "unknown";
-+}
-+
-+static int get_compr_option(char *opt, int *compr_type, int *favor_lzo)
-+{
-+ *compr_type = UBIFS_COMPR_LZO;
-+
-+ if (favor_lzo)
-+ *favor_lzo = 0;
-+
-+ if (favor_lzo && strcmp(optarg, "favor_lzo") == 0)
-+ *favor_lzo = 1;
-+ else if (strcmp(optarg, "zlib") == 0)
-+ *compr_type = UBIFS_COMPR_ZLIB;
-+ else if (strcmp(optarg, "xz") == 0)
-+ *compr_type = UBIFS_COMPR_XZ;
-+ else if (strcmp(optarg, "none") == 0)
-+ *compr_type = UBIFS_COMPR_NONE;
-+ else if (strcmp(optarg, "lzo") != 0)
-+ return -1;
-+
-+ return 0;
-+}
-+
- static int get_options(int argc, char**argv)
- {
- int opt, i;
-@@ -649,14 +692,13 @@ static int get_options(int argc, char**a
- return err_msg("bad key hash");
- break;
- case 'x':
-- if (strcmp(optarg, "favor_lzo") == 0)
-- c->favor_lzo = 1;
-- else if (strcmp(optarg, "zlib") == 0)
-- c->default_compr = UBIFS_COMPR_ZLIB;
-- else if (strcmp(optarg, "none") == 0)
-- c->default_compr = UBIFS_COMPR_NONE;
-- else if (strcmp(optarg, "lzo") != 0)
-- return err_msg("bad compressor name");
-+ if (get_compr_option(optarg, &c->default_compr,
-+ &c->favor_lzo))
-+ return err_msg("bad compressor name '%s'",
-+ optarg);
-+ if (c->default_compr == UBIFS_COMPR_XZ)
-+ return err_msg("'%s' can't be used as default compressor",
-+ optarg);
- break;
- case 'X':
- c->favor_percent = strtol(optarg, &endp, 0);
-@@ -665,6 +707,12 @@ static int get_options(int argc, char**a
- return err_msg("bad favor LZO percent '%s'",
- optarg);
- break;
-+ case 'y':
-+ if (get_compr_option(optarg, &force_compr, NULL))
-+ return err_msg("bad forced compressor name '%s'",
-+ optarg);
-+ force_compr_set = 1;
-+ break;
- case 'j':
- c->max_bud_bytes = get_bytes(optarg);
- if (c->max_bud_bytes <= 0)
-@@ -749,6 +797,9 @@ static int get_options(int argc, char**a
- c->min_io_size = 8;
- c->rp_size = add_space_overhead(c->rp_size);
-
-+ if (force_compr_set == 0)
-+ force_compr = c->default_compr;
-+
- if (verbose) {
- printf("mkfs.ubifs\n");
- printf("\troot: %s\n", root);
-@@ -758,17 +809,10 @@ static int get_options(int argc, char**a
- printf("\toutput: %s\n", output);
- printf("\tjrn_size: %llu\n", c->max_bud_bytes);
- printf("\treserved: %llu\n", c->rp_size);
-- switch (c->default_compr) {
-- case UBIFS_COMPR_LZO:
-- printf("\tcompr: lzo\n");
-- break;
-- case UBIFS_COMPR_ZLIB:
-- printf("\tcompr: zlib\n");
-- break;
-- case UBIFS_COMPR_NONE:
-- printf("\tcompr: none\n");
-- break;
-- }
-+ printf("\tcompr: %s\n", get_compr_str(c->default_compr));
-+ if (force_compr_set)
-+ printf("\tforced compr: %s\n",
-+ get_compr_str(force_compr));
- printf("\tkeyhash: %s\n", (c->key_hash == key_r5_hash) ?
- "r5" : "test");
- printf("\tfanout: %d\n", c->fanout);
-@@ -1353,7 +1397,7 @@ static int add_file(const char *path_nam
- use_compr = UBIFS_COMPR_LZO;
- else
- #endif
-- use_compr = c->default_compr;
-+ use_compr = force_compr;
- compr_type = compress_data(buf, bytes_read, &dn->data,
- &out_len, use_compr);
- dn->compr_type = cpu_to_le16(compr_type);
---- a/mkfs.ubifs/mkfs.ubifs.h
-+++ b/mkfs.ubifs/mkfs.ubifs.h
-@@ -77,6 +77,9 @@
- #if MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
- #error MKFS_UBIFS_COMPR_ZLIB != UBIFS_COMPR_ZLIB
- #endif
-+#if MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
-+#error MKFS_UBIFS_COMPR_XZ != UBIFS_COMPR_XZ
-+#endif
-
- extern int verbose;
- extern int debug_level;
---- a/mkfs.ubifs/ubifs-media.h
-+++ b/mkfs.ubifs/ubifs-media.h
-@@ -303,6 +303,7 @@ enum {
- UBIFS_COMPR_NONE,
- UBIFS_COMPR_LZO,
- UBIFS_COMPR_ZLIB,
-+ UBIFS_COMPR_XZ,
- UBIFS_COMPR_TYPES_CNT,
- };
-
diff --git a/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch b/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch
new file mode 100644
index 00000000000..d95ece184c7
--- /dev/null
+++ b/tools/mtd-utils/patches/200-libubigen-add-ubigen_write_terminator-function.patch
@@ -0,0 +1,89 @@
+--- a/lib/libubigen.c
++++ b/lib/libubigen.c
+@@ -122,8 +122,9 @@ int ubigen_add_volume(const struct ubige
+ return 0;
+ }
+
+-void ubigen_init_ec_hdr(const struct ubigen_info *ui,
+- struct ubi_ec_hdr *hdr, long long ec)
++static void __ubigen_init_ec_hdr(const struct ubigen_info *ui,
++ struct ubi_ec_hdr *hdr, long long ec,
++ int eof)
+ {
+ uint32_t crc;
+
+@@ -136,10 +137,22 @@ void ubigen_init_ec_hdr(const struct ubi
+ hdr->data_offset = cpu_to_be32(ui->data_offs);
+ hdr->image_seq = cpu_to_be32(ui->image_seq);
+
++ if (eof) {
++ hdr->padding1[0] = 'E';
++ hdr->padding1[1] = 'O';
++ hdr->padding1[2] = 'F';
++ }
++
+ crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC);
+ hdr->hdr_crc = cpu_to_be32(crc);
+ }
+
++void ubigen_init_ec_hdr(const struct ubigen_info *ui,
++ struct ubi_ec_hdr *hdr, long long ec)
++{
++ __ubigen_init_ec_hdr(ui, hdr, ec, 0);
++}
++
+ void ubigen_init_vid_hdr(const struct ubigen_info *ui,
+ const struct ubigen_vol_info *vi,
+ struct ubi_vid_hdr *hdr, int lnum,
+@@ -307,6 +320,39 @@ int ubigen_write_layout_vol(const struct
+ }
+
+ free(outbuf);
++ return 0;
++
++out_free:
++ free(outbuf);
++ return -1;
++}
++
++int ubigen_write_eof_markers(const struct ubigen_info *ui, long long ec,
++ int count, int out_fd)
++{
++ char *outbuf;
++ int peb_size = ui->peb_size;
++
++ outbuf = malloc(peb_size);
++ if (!outbuf) {
++ sys_errmsg("cannot allocate %d bytes of memory", peb_size);
++ return -1;
++ }
++
++ memset(outbuf, 0xFF, peb_size);
++ __ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec, 1);
++
++ while (count) {
++ if (write(out_fd, outbuf, peb_size) != peb_size) {
++ sys_errmsg("cannot write %d bytes to the output file",
++ peb_size);
++ goto out_free;
++ }
++
++ count--;
++ }
++
++ free(outbuf);
+ return 0;
+
+ out_free:
+--- a/include/libubigen.h
++++ b/include/libubigen.h
+@@ -188,6 +188,9 @@ int ubigen_write_layout_vol(const struct
+ long long ec1, long long ec2,
+ struct ubi_vtbl_record *vtbl, int fd);
+
++int ubigen_write_eof_markers(const struct ubigen_info *ui, long long ec,
++ int count, int out_fd);
++
+ #ifdef __cplusplus
+ }
+ #endif
diff --git a/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch b/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch
new file mode 100644
index 00000000000..0da28b71f2e
--- /dev/null
+++ b/tools/mtd-utils/patches/201-ubinize-add-terminator-support.patch
@@ -0,0 +1,68 @@
+--- a/ubi-utils/ubinize.c
++++ b/ubi-utils/ubinize.c
+@@ -60,6 +60,8 @@ static const char optionsstr[] =
+ " (default is 1)\n"
+ "-Q, --image-seq=<num> 32-bit UBI image sequence number to use\n"
+ " (by default a random number is picked)\n"
++"-E, --eof-markers=<num> number of eof-markers to put at the end of the\n"
++" output image\n"
+ "-v, --verbose be verbose\n"
+ "-h, --help print help message\n"
+ "-V, --version print program version\n\n";
+@@ -79,6 +81,7 @@ static const struct option long_options[
+ { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' },
+ { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' },
+ { .name = "image-seq", .has_arg = 1, .flag = NULL, .val = 'Q' },
++ { .name = "eof-markers", .has_arg = 1, .flag = NULL, .val = 'E' },
+ { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' },
+ { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' },
+ { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' },
+@@ -98,6 +101,7 @@ struct args {
+ uint32_t image_seq;
+ int verbose;
+ dictionary *dict;
++ int eof_markers;
+ };
+
+ static struct args args = {
+@@ -116,7 +120,7 @@ static int parse_opt(int argc, char * co
+ int key, error = 0;
+ unsigned long int image_seq;
+
+- key = getopt_long(argc, argv, "o:p:m:s:O:e:x:Q:vhV", long_options, NULL);
++ key = getopt_long(argc, argv, "o:p:m:s:O:e:x:Q:E:vhV", long_options, NULL);
+ if (key == -1)
+ break;
+
+@@ -176,6 +180,12 @@ static int parse_opt(int argc, char * co
+ args.image_seq = image_seq;
+ break;
+
++ case 'E':
++ args.eof_markers = simple_strtoul(optarg, &error);
++ if (error)
++ return errmsg("bad number of eof-markers: \"%s\"", optarg);
++ break;
++
+ case 'v':
+ args.verbose = 1;
+ break;
+@@ -559,6 +569,18 @@ int main(int argc, char * const argv[])
+ printf("\n");
+ }
+
++ if (args.eof_markers) {
++ verbose(args.verbose, "writing %d eof-marker blocks",
++ args.eof_markers);
++
++ err = ubigen_write_eof_markers(&ui, args.ec, args.eof_markers,
++ args.out_fd);
++ if (err) {
++ errmsg("cannot write eof-marker blocks");
++ goto out_free;
++ }
++ }
++
+ verbose(args.verbose, "writing layout volume");
+
+ err = ubigen_write_layout_vol(&ui, 0, 1, args.ec, args.ec, vtbl, args.out_fd);
diff --git a/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch b/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch
new file mode 100644
index 00000000000..8e580595769
--- /dev/null
+++ b/tools/mtd-utils/patches/320-mkfs.jffs2-SOURCE_DATE_EPOCH.patch
@@ -0,0 +1,60 @@
+--- a/jffsX-utils/mkfs.jffs2.c
++++ b/jffsX-utils/mkfs.jffs2.c
+@@ -109,7 +109,7 @@ static char *rootdir = default_rootdir;
+ static int verbose = 0;
+ static int squash_uids = 0;
+ static int squash_perms = 0;
+-static int fake_times = 0;
++static time_t fixed_timestamp = -1;
+ int target_endian = __BYTE_ORDER;
+
+ static uint32_t find_hardlink(struct filesystem_entry *e)
+@@ -250,8 +250,8 @@ static struct filesystem_entry *add_host
+ mode &= ~(S_ISUID | S_ISGID);
+ }
+ }
+- if (fake_times) {
+- timestamp = 0;
++ if (fixed_timestamp != -1) {
++ timestamp = fixed_timestamp;
+ }
+
+ entry = xcalloc(1, sizeof(struct filesystem_entry));
+@@ -1557,6 +1557,20 @@ static void parse_image(void){
+ close(in_fd);
+ }
+
++static void set_source_date_epoch() {
++ char *env = getenv("SOURCE_DATE_EPOCH");
++ char *endptr = env;
++ errno = 0;
++ if (env && *env) {
++ fixed_timestamp = strtoull(env, &endptr, 10);
++ if (errno || (endptr && *endptr != '\0')) {
++ fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
++ exit(1);
++ }
++ }
++}
++
++
+ int main(int argc, char **argv)
+ {
+ int c, opt;
+@@ -1575,6 +1589,7 @@ int main(int argc, char **argv)
+ warn_page_size = 1; /* warn user if page size not 4096 */
+
+ jffs2_compressors_init();
++ set_source_date_epoch();
+
+ while ((opt = getopt_long(argc, argv,
+ "D:d:r:s:o:qUPfh?vVe:lbp::nc:m:x:X:Lty:i:", long_options, &c)) >= 0)
+@@ -1625,7 +1640,7 @@ int main(int argc, char **argv)
+ break;
+
+ case 'f':
+- fake_times = 1;
++ fixed_timestamp = 0;
+ break;
+
+ case 'h':
diff --git a/tools/mtools/Makefile b/tools/mtools/Makefile
new file mode 100644
index 00000000000..64be6ae01bb
--- /dev/null
+++ b/tools/mtools/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2012-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mtools
+PKG_VERSION:=4.0.18
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
+PKG_HASH:=30d408d039b4cedcd04fbf824c89b0ff85dcbb6f71f13d2d8d65abb3f58cacc3
+PKG_CAT:=zcat
+
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOST_CONFIGURE_VARS += \
+ ac_cv_header_iconv_h=no
+
+define Host/Compile
+ $(MAKE) -C $(HOST_BUILD_DIR) mcopy mmd
+endef
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/mcopy $(STAGING_DIR_HOST)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/mmd $(STAGING_DIR_HOST)/bin/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/mcopy
+ rm -f $(STAGING_DIR_HOST)/bin/mmd
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/mtools/patches/100-compile_fix.patch b/tools/mtools/patches/100-compile_fix.patch
new file mode 100644
index 00000000000..698e1560298
--- /dev/null
+++ b/tools/mtools/patches/100-compile_fix.patch
@@ -0,0 +1,19 @@
+--- a/sysincludes.h
++++ b/sysincludes.h
+@@ -101,14 +101,8 @@ typedef void *caddr_t;
+ #if defined __GNUC__ && defined __STDC__
+ /* gcc -traditional doesn't have PACKED, UNUSED and NORETURN */
+ # define PACKED __attribute__ ((packed))
+-# if __GNUC__ == 2 && __GNUC_MINOR__ > 6 || __GNUC__ >= 3
+-/* gcc 2.6.3 doesn't have "unused" */ /* mool */
+-# define UNUSED(x) x __attribute__ ((unused));x
+-# define UNUSEDP __attribute__ ((unused))
+-# else
+-# define UNUSED(x) x
+-# define UNUSEDP /* */
+-# endif
++# define UNUSED(x) x
++# define UNUSEDP /* */
+ # define NORETURN __attribute__ ((noreturn))
+ #else
+ # define UNUSED(x) x
diff --git a/tools/padjffs2/Makefile b/tools/padjffs2/Makefile
index a949ac06282..0a583b8e1a8 100644
--- a/tools/padjffs2/Makefile
+++ b/tools/padjffs2/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2011 OpenWrt.org
+# Copyright (C) 2011-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -18,6 +18,10 @@ define Host/Prepare
find $(HOST_BUILD_DIR) -name .svn | $(XARGS) rm -rf
endef
+define Host/Compile
+ $(MAKE) -C $(HOST_BUILD_DIR)
+endef
+
define Host/Configure
endef
diff --git a/tools/padjffs2/src/Makefile b/tools/padjffs2/src/Makefile
index fe1a7aa628d..45da8e5dbc3 100644
--- a/tools/padjffs2/src/Makefile
+++ b/tools/padjffs2/src/Makefile
@@ -9,7 +9,7 @@ all: padjffs2
$(CC) $(CFLAGS) $(WFLAGS) -c -o $@ $<
padjffs2: $(padjffs2-objs)
- $(CC) -o $@ $(padjffs2-objs)
+ $(CC) $(LDFLAGS) -o $@ $(padjffs2-objs)
clean:
rm -f padjffs2 *.o
diff --git a/tools/padjffs2/src/padjffs2.c b/tools/padjffs2/src/padjffs2.c
index 58d99140d92..6308292431e 100644
--- a/tools/padjffs2/src/padjffs2.c
+++ b/tools/padjffs2/src/padjffs2.c
@@ -15,11 +15,18 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
static char *progname;
+static unsigned int xtra_offset;
static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
+static unsigned char jffs2_pad_be[] = "\x19\x85\x20\x04\x04\x00\x00\x00\xc4\x94\xdb\xf4";
+static unsigned char jffs2_pad_le[] = "\x85\x19\x04\x20\x00\x00\x00\x04\xa8\xfb\xa0\xb4";
+static unsigned char *pad = eof_mark;
+static int pad_len = sizeof(eof_mark);
+static bool pad_to_stdout = false;
#define ERR(fmt, ...) do { \
fflush(0); \
@@ -41,6 +48,7 @@ static int pad_image(char *name, uint32_t pad_mask)
{
char *buf;
int fd;
+ int outfd;
ssize_t in_len;
ssize_t out_len;
int ret = -1;
@@ -61,8 +69,15 @@ static int pad_image(char *name, uint32_t pad_mask)
if (in_len < 0)
goto close;
+ if (!pad_to_stdout)
+ outfd = fd;
+ else
+ outfd = STDOUT_FILENO;
+
memset(buf, '\xff', BUF_SIZE);
+ in_len += xtra_offset;
+
out_len = in_len;
while (pad_mask) {
uint32_t mask;
@@ -83,7 +98,7 @@ static int pad_image(char *name, uint32_t pad_mask)
pad_mask &= ~mask;
}
- printf("padding image to %08x\n", (unsigned int) in_len);
+ fprintf(stderr, "padding image to %08x\n", (unsigned int) in_len - xtra_offset);
while (out_len < in_len) {
ssize_t len;
@@ -92,7 +107,7 @@ static int pad_image(char *name, uint32_t pad_mask)
if (len > BUF_SIZE)
len = BUF_SIZE;
- t = write(fd, buf, len);
+ t = write(outfd, buf, len);
if (t != len) {
ERRS("Unable to write to %s", name);
goto close;
@@ -102,12 +117,12 @@ static int pad_image(char *name, uint32_t pad_mask)
}
/* write out the JFFS end-of-filesystem marker */
- t = write(fd, eof_mark, 4);
- if (t != 4) {
+ t = write(outfd, pad, pad_len);
+ if (t != pad_len) {
ERRS("Unable to write to %s", name);
goto close;
}
- out_len += 4;
+ out_len += pad_len;
}
ret = 0;
@@ -120,31 +135,71 @@ out:
return ret;
}
+static int usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s file [<options>] [pad0] [pad1] [padN]\n"
+ "Options:\n"
+ " -x <offset>: Add an extra offset for padding data\n"
+ " -J: Use a fake big-endian jffs2 padding element instead of EOF\n"
+ " This is used to work around broken boot loaders that\n"
+ " try to parse the entire firmware area as one big jffs2\n"
+ " -j: (like -J, but little-endian instead of big-endian)\n"
+ " -c: write padding to stdout\n"
+ "\n",
+ progname);
+ return EXIT_FAILURE;
+}
+
int main(int argc, char* argv[])
{
+ char *image;
uint32_t pad_mask;
int ret = EXIT_FAILURE;
int err;
- int i;
+ int ch, i;
progname = basename(argv[0]);
- if (argc < 2) {
- fprintf(stderr,
- "Usage: %s file [pad0] [pad1] [padN]\n",
- progname);
- goto out;
- }
+ if (argc < 2)
+ return usage();
+
+ image = argv[1];
+ argv++;
+ argc--;
pad_mask = 0;
- for (i = 2; i < argc; i++)
+ while ((ch = getopt(argc, argv, "x:Jjc")) != -1) {
+ switch (ch) {
+ case 'x':
+ xtra_offset = strtoul(optarg, NULL, 0);
+ fprintf(stderr, "assuming %u bytes offset\n",
+ xtra_offset);
+ break;
+ case 'J':
+ pad = jffs2_pad_be;
+ pad_len = sizeof(jffs2_pad_be) - 1;
+ break;
+ case 'j':
+ pad = jffs2_pad_le;
+ pad_len = sizeof(jffs2_pad_le) - 1;
+ break;
+ case 'c':
+ pad_to_stdout = true;
+ break;
+ default:
+ return usage();
+ }
+ }
+
+ for (i = optind; i < argc; i++)
pad_mask |= strtoul(argv[i], NULL, 0) * 1024;
if (pad_mask == 0)
pad_mask = (4 * 1024) | (8 * 1024) | (64 * 1024) |
(128 * 1024);
- err = pad_image(argv[1], pad_mask);
+ err = pad_image(image, pad_mask);
if (err)
goto out;
diff --git a/tools/patch-cmdline/Makefile b/tools/patch-image/Makefile
index 9a3f971ef7e..6f2900b96ce 100644
--- a/tools/patch-cmdline/Makefile
+++ b/tools/patch-image/Makefile
@@ -1,25 +1,28 @@
#
-# Copyright (C) 2007 OpenWrt.org
+# Copyright (C) 2007-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
-PKG_NAME:=patch-cmdline
+PKG_NAME:=patch-image
include $(INCLUDE_DIR)/host-build.mk
define Host/Compile
- $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/$(PKG_NAME) src/$(PKG_NAME).c
+ $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/patch-cmdline src/patch-cmdline.c
+ $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/patch-dtb src/patch-dtb.c
endef
define Host/Install
$(CP) $(HOST_BUILD_DIR)/patch-cmdline $(STAGING_DIR_HOST)/bin/
+ $(CP) $(HOST_BUILD_DIR)/patch-dtb $(STAGING_DIR_HOST)/bin/
endef
define Host/Clean
rm -f $(STAGING_DIR_HOST)/bin/patch-cmdline
+ rm -f $(STAGING_DIR_HOST)/bin/patch-dtb
endef
$(eval $(call HostBuild))
diff --git a/tools/patch-cmdline/src/patch-cmdline.c b/tools/patch-image/src/patch-cmdline.c
index 571f848d81c..8d1fce9172c 100644
--- a/tools/patch-cmdline/src/patch-cmdline.c
+++ b/tools/patch-image/src/patch-cmdline.c
@@ -1,7 +1,7 @@
/*
* patch-cmdline.c - patch the kernel command line on rb532
*
- * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,10 +35,16 @@ int main(int argc, char **argv)
{
int fd, found = 0, len, ret = -1;
char *ptr, *p;
+ unsigned int search_space;
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <file> <cmdline>\n", argv[0]);
+ if (argc <= 2 || argc > 4) {
+ fprintf(stderr, "Usage: %s <file> <cmdline> [size]\n", argv[0]);
goto err1;
+ } else if (argc == 3) {
+ fprintf(stdout, "search space used is default of 16KB\n");
+ search_space = SEARCH_SPACE;
+ } else {
+ search_space = atoi(argv[3]);
}
len = strlen(argv[2]);
if (len + 9 > CMDLINE_MAX) {
@@ -47,12 +53,12 @@ int main(int argc, char **argv)
}
if (((fd = open(argv[1], O_RDWR)) < 0) ||
- (ptr = (char *) mmap(0, SEARCH_SPACE + CMDLINE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) {
+ (ptr = (char *) mmap(0, search_space + CMDLINE_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) {
fprintf(stderr, "Could not open kernel image");
goto err2;
}
- for (p = ptr; p < (ptr + SEARCH_SPACE); p += 4) {
+ for (p = ptr; p < (ptr + search_space); p += 4) {
if (memcmp(p, "CMDLINE:", 8) == 0) {
found = 1;
p += 8;
diff --git a/tools/patch-image/src/patch-dtb.c b/tools/patch-image/src/patch-dtb.c
new file mode 100644
index 00000000000..a94da3fa415
--- /dev/null
+++ b/tools/patch-image/src/patch-dtb.c
@@ -0,0 +1,103 @@
+/*
+ * patch-dtb.c - patch a dtb into an image
+ *
+ * Copyright (C) 2006 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * based on patch-cmdline.c
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define DTB_MAX (16 * 1024)
+
+int main(int argc, char **argv)
+{
+ int fd, fddtb, found = 0, len, ret = -1;
+ char *ptr, *ptrdtb, *p;
+ struct stat s;
+ unsigned int search_space , dtb_max_size;
+
+ if (argc <= 2 || argc > 4) {
+ fprintf(stderr, "Usage: %s <file> <dtb> [size]\n", argv[0]);
+ goto err1;
+ } else if (argc == 3) {
+ fprintf(stdout, "DT size used is default of 16KB\n");
+ search_space = dtb_max_size = DTB_MAX;
+ } else {
+ search_space = dtb_max_size = atoi(argv[3]);
+ }
+
+ if (stat(argv[2], &s)) {
+ fprintf(stderr, "DTB not found\n");
+ goto err1;
+ }
+
+ len = s.st_size;
+ if (len + 8 > dtb_max_size) {
+ fprintf(stderr, "DTB too big\n");
+ goto err1;
+ }
+
+ if (((fddtb = open(argv[2], O_RDONLY)) < 0) ||
+ (ptrdtb = (char *) mmap(0, dtb_max_size, PROT_READ, MAP_SHARED, fddtb, 0)) == (void *) (-1)) {
+ fprintf(stderr, "Could not open DTB");
+ goto err2;
+ }
+
+ if (((fd = open(argv[1], O_RDWR)) < 0) ||
+ (ptr = (char *) mmap(0, search_space + dtb_max_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1)) {
+ fprintf(stderr, "Could not open kernel image");
+ goto err3;
+ }
+
+ for (p = ptr; p < (ptr + search_space); p += 4) {
+ if (memcmp(p, "OWRTDTB:", 8) == 0) {
+ found = 1;
+ p += 8;
+ break;
+ }
+ }
+ if (!found) {
+ fprintf(stderr, "DTB marker not found!\n");
+ goto err4;
+ }
+
+ memset(p, 0, dtb_max_size - 8);
+ memcpy(p, ptrdtb, len);
+ msync(p, len, MS_SYNC|MS_INVALIDATE);
+ ret = 0;
+
+err4:
+ munmap((void *) ptr, len);
+err3:
+ if (fd > 0)
+ close(fd);
+ munmap((void *) ptrdtb, len);
+err2:
+ if (fddtb > 0)
+ close(fddtb);
+err1:
+ return ret;
+}
diff --git a/tools/patch/Makefile b/tools/patch/Makefile
new file mode 100644
index 00000000000..4c4c09bc088
--- /dev/null
+++ b/tools/patch/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=patch
+PKG_VERSION:=2.7.6
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNU/patch
+PKG_HASH:=ac610bda97abe0d9f6b7c963255a11dcb196c25e337c61f94e4778d632f1d8fd
+
+HOST_BUILD_PARALLEL := 1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
+
+$(eval $(call HostBuild))
diff --git a/tools/patchelf/Makefile b/tools/patchelf/Makefile
new file mode 100644
index 00000000000..1728fba2770
--- /dev/null
+++ b/tools/patchelf/Makefile
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=patchelf
+PKG_VERSION:=0.9
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://nixos.org/releases/patchelf/patchelf-$(PKG_VERSION)
+PKG_HASH:=a0f65c1ba148890e9f2f7823f4bedf7ecad5417772f64f994004f59a39014f83
+
+HOST_BUILD_PARALLEL:=1
+HOST_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/patchelf $(STAGING_DIR_HOST)/bin/patchelf
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/pkg-config/Makefile b/tools/pkg-config/Makefile
index e7d2982f7f4..17a8737be16 100644
--- a/tools/pkg-config/Makefile
+++ b/tools/pkg-config/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,17 +7,26 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=pkg-config
-PKG_VERSION:=0.25
+PKG_VERSION:=0.29.2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://pkgconfig.freedesktop.org/releases/
-PKG_MD5SUM:=a3270bab3f4b69b7dc6dbdacbcae9745
+PKG_SOURCE_URL:=https://pkgconfig.freedesktop.org/releases/
+PKG_HASH:=6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
+unexport PKG_CONFIG
+
+HOST_CONFIGURE_ARGS += --with-internal-glib
+
+ifeq ($(HOST_OS),Darwin)
+HOST_LDFLAGS += -framework CoreFoundation -framework Carbon
+endif
+
define Host/Install
- $(MAKE) -C $(HOST_BUILD_DIR) \
- install
+ $(MAKE) -C $(HOST_BUILD_DIR) install
mv $(STAGING_DIR_HOST)/bin/pkg-config $(STAGING_DIR_HOST)/bin/pkg-config.real
$(INSTALL_BIN) ./files/pkg-config $(STAGING_DIR_HOST)/bin/pkg-config
endef
diff --git a/tools/pkg-config/patches/100-disable_compat_cmd.patch b/tools/pkg-config/patches/100-disable_compat_cmd.patch
deleted file mode 100644
index 990784045ec..00000000000
--- a/tools/pkg-config/patches/100-disable_compat_cmd.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/parse.c
-+++ b/parse.c
-@@ -1187,15 +1187,12 @@ try_command (const char *command)
- Package *
- get_compat_package (const char *name)
- {
--#ifdef G_OS_WIN32
-- /* There has never been any of these legacy *-config scripts on
-- * Windows as far as I know. No use trying to execute them, will
-- * only confuse users to see the "blabla is not recognized as an
-- * internal or external command, operable program or batch file"
-- * messages.
-+ /*
-+ * We don't need this compatibility stuff on a system
-+ * that is free of legacy stuff
- */
- return NULL;
--#else
-+#if 0
-
- Package *pkg;
-
diff --git a/tools/ppl/Makefile b/tools/ppl/Makefile
deleted file mode 100644
index 46c966d827c..00000000000
--- a/tools/ppl/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2009 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=ppl
-PKG_VERSION:=0.10.2
-
-PKG_SOURCE_URL:=ftp://gcc.gnu.org/pub/gcc/infrastructure
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=e7dd265afdeaea81f7e87a72b182d875
-
-HOST_FIXUP:=autoreconf
-
-include $(INCLUDE_DIR)/host-build.mk
-
-unexport CFLAGS
-
-HOST_CONFIGURE_ARGS += \
- --enable-static \
- --disable-shared
-
-define Host/Configure
- (cd $(HOST_BUILD_DIR)/$(3); \
- $(HOST_CONFIGURE_CMD) \
- $(HOST_CONFIGURE_VARS) \
- $(HOST_CONFIGURE_ARGS); \
- )
-endef
-
-
-$(eval $(call HostBuild))
diff --git a/tools/ppl/patches/001-gmp_5_fix.patch b/tools/ppl/patches/001-gmp_5_fix.patch
deleted file mode 100644
index bd7fad3f411..00000000000
--- a/tools/ppl/patches/001-gmp_5_fix.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Roberto Bagnara <bagnara@cs.unipr.it>
-Date: Sat, 9 Jan 2010 15:32:08 +0000 (+0100)
-Subject: Added support for GMP 5.0.
-X-Git-Url: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl%2Fppl.git;a=commitdiff_plain;h=9c19bc2b318a35016e0189f9552c98910be37f53
-
-Added support for GMP 5.0.
----
-
-diff --git a/m4/ac_check_gmp.m4 b/m4/ac_check_gmp.m4
-index 60cecdc..15acb18 100644
---- a/m4/ac_check_gmp.m4
-+++ b/m4/ac_check_gmp.m4
-@@ -71,6 +71,10 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
- #GMP version 4.1.3 or higher is required
- #endif
-
-+#ifndef BITS_PER_MP_LIMB
-+#define BITS_PER_MP_LIMB GMP_LIMB_BITS
-+#endif
-+
- int
- main() {
- std::string header_version;
-@@ -97,11 +101,11 @@ main() {
- return 1;
- }
-
-- if (sizeof(mp_limb_t)*CHAR_BIT != GMP_LIMB_BITS
-- || GMP_LIMB_BITS != mp_bits_per_limb) {
-+ if (sizeof(mp_limb_t)*CHAR_BIT != BITS_PER_MP_LIMB
-+ || BITS_PER_MP_LIMB != mp_bits_per_limb) {
- std::cerr
- << "GMP header (gmp.h) and library (ligmp.*) bits-per-limb mismatch:\n"
-- << "header gives " << __GMP_BITS_PER_MP_LIMB << ";\n"
-+ << "header gives " << BITS_PER_MP_LIMB << ";\n"
- << "library gives " << mp_bits_per_limb << ".\n"
- << "This probably means you are on a bi-arch system and\n"
- << "you are compiling with the wrong header or linking with\n"
diff --git a/tools/qemu/Makefile b/tools/qemu/Makefile
index c0d587b243f..d63ab3482eb 100644
--- a/tools/qemu/Makefile
+++ b/tools/qemu/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2010 OpenWrt.org
+# Copyright (C) 2010-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,26 +7,31 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=qemu
-PKG_VERSION:=0.13.0
+PKG_CPE_ID:=cpe:/a:qemu:qemu
+PKG_VERSION:=0.14.1
PKG_RELEASE:=1
-PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/qemu/
+PKG_SOURCE_URL:=@SAVANNAH/qemu
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_MD5SUM:=397a0d665da8ba9d3b9583629f3d6421
+PKG_HASH:=33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3
include $(INCLUDE_DIR)/host-build.mk
-HOST_CFLAGS += -I$(STAGING_DIR_HOST)/include/e2fsprogs
-
-define Host/Configure
- (cd $(HOST_BUILD_DIR); \
- CFLAGS="$(HOST_CFLAGS)" \
- LDFLAGS="$(HOST_LDFLAGS)" \
- $(HOST_CONFIGURE_CMD) \
- --extra-cflags="$(HOST_CFLAGS)" \
- --enable-uuid \
- )
-endef
+HOST_CFLAGS += \
+ -I$(STAGING_DIR_HOST)/include/e2fsprogs \
+ -DAES_cbc_encrypt=QEMU_AES_cbc_encrypt \
+ -DAES_decrypt=QEMU_AES_decrypt \
+ -DAES_encrypt=QEMU_AES_encrypt \
+ -DAES_set_decrypt_key=QEMU_AES_set_decrypt_key \
+ -DAES_set_encrypt_key=QEMU_AES_set_encrypt_key
+
+HOST_CONFIGURE_VARS := \
+ CFLAGS="$(HOST_CFLAGS)" \
+ LDFLAGS="$(HOST_LDFLAGS)"
+
+HOST_CONFIGURE_ARGS := \
+ --extra-cflags="$(HOST_CFLAGS)" \
+ --enable-uuid
define Host/Compile
$(MAKE) -C $(HOST_BUILD_DIR) qemu-img
diff --git a/tools/qemu/patches/010-freebsd-fix.patch b/tools/qemu/patches/010-freebsd-fix.patch
deleted file mode 100644
index 1fc09120964..00000000000
--- a/tools/qemu/patches/010-freebsd-fix.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/block/sheepdog.c
-+++ b/block/sheepdog.c
-@@ -12,7 +12,7 @@
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
--#else
-+#elifndef __FreeBSD__
- #include <netdb.h>
- #include <netinet/tcp.h>
-
diff --git a/tools/quilt/Makefile b/tools/quilt/Makefile
index 510d8f6fd5a..d0532b5984e 100644
--- a/tools/quilt/Makefile
+++ b/tools/quilt/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 -2010 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,21 +7,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=quilt
-PKG_VERSION:=0.48
+PKG_VERSION:=0.65
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/$(PKG_NAME)
-PKG_MD5SUM:=f77adda60039ffa753f3c584a286f12b
+PKG_SOURCE_URL:=@SAVANNAH/quilt
+PKG_HASH:=f6cbc788e5cbbb381a3c6eab5b9efce67c776a8662a7795c7432fd27aa096819
include $(INCLUDE_DIR)/host-build.mk
-GETOPT:=$(shell which getopt)
-
-HOST_CONFIGURE_ARGS += \
- --with-patch=$(PATCH) \
- --with-find=$(FIND) \
- --with-getopt=$(GETOPT)
-
define Host/Configure
cd $(HOST_BUILD_DIR) && autoconf
$(call Host/Configure/Default)
@@ -29,7 +22,7 @@ define Host/Configure
endef
define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" all lib/backup-files
+ $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)" all
endef
define Host/Install
diff --git a/tools/quilt/patches/000-relocatable.patch b/tools/quilt/patches/000-relocatable.patch
index f8110236a6d..0e0eb7380ce 100644
--- a/tools/quilt/patches/000-relocatable.patch
+++ b/tools/quilt/patches/000-relocatable.patch
@@ -1,69 +1,59 @@
--- a/bin/quilt.in
+++ b/bin/quilt.in
-@@ -7,9 +7,15 @@
- # See the COPYING and AUTHORS files for more details.
+@@ -15,14 +15,22 @@ unset POSIXLY_CORRECT
+ unset GREP_OPTIONS
export TEXTDOMAIN=quilt
-export TEXTDOMAINDIR=@LOCALEDIR@
--: ${QUILT_DIR=@QUILT_DIR@} ${QUILT_LIB=@QUILT_LIB@}
-+if test -n "$STAGING_DIR"; then
-+ export TEXTDOMAINDIR="$STAGING_DIR/../host/share/locale"
-+ : ${QUILT_DIR=$STAGING_DIR/../host/share/quilt} ${QUILT_LIB=$STAGING_DIR/../host/lib/quilt}
+-: ${QUILT_DIR=@QUILT_DIR@}
++if test -n "$STAGING_DIR_HOST"; then
++ export TEXTDOMAINDIR="$STAGING_DIR_HOST/share/locale"
++ : ${QUILT_DIR=$STAGING_DIR_HOST/share/quilt} ${QUILT_LIB=$STAGING_DIR_HOST/lib/quilt}
++ : ${QUILT_ETC=$STAGING_DIR_HOST/etc}
+else
+ export TEXTDOMAINDIR=@LOCALEDIR@
-+ : ${QUILT_DIR=@QUILT_DIR@} ${QUILT_LIB=@QUILT_LIB@}
++ : ${QUILT_DIR=@QUILT_DIR@}
++ : ${QUILT_ETC=@ETCDIR@}
+fi
+
- export QUILT_DIR QUILT_LIB
+ export QUILT_DIR
if [ -z "$QUILTRC" ]
+ then
+- for QUILTRC in $HOME/.quiltrc @ETCDIR@/quilt.quiltrc; do
++ for QUILTRC in $HOME/.quiltrc $QUILT_ETC/quilt.quiltrc; do
+ [ -e $QUILTRC ] && break
+ done
+ export QUILTRC
--- a/quilt/scripts/edmail.in
+++ b/quilt/scripts/edmail.in
-@@ -29,7 +29,7 @@ BEGIN {
- }
-
- setlocale(LC_MESSAGES, "");
--bindtextdomain("quilt", "@LOCALEDIR@");
-+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@");
- textdomain("quilt");
+@@ -1,4 +1,6 @@
+-#! @PERL@ -w
++#! @PERL@
++
++use warnings;
- sub _($) {
---- a/quilt/scripts/inspect.in
-+++ b/quilt/scripts/inspect.in
-@@ -6,7 +6,11 @@
+ # RFCs important for this script:
#
- # See the COPYING and AUTHORS files for more details.
-
--: ${QUILT_DIR=@QUILT_DIR@}
-+if test -n "$STAGING_DIR"; then
-+ : ${QUILT_DIR="$STAGING_DIR/../host/share/quilt"}
-+else
-+ : ${QUILT_DIR=@QUILT_DIR@}
-+fi
-
- if ! [ -r $QUILT_DIR/scripts/patchfns ]
- then
---- a/quilt/scripts/parse-patch.in
-+++ b/quilt/scripts/parse-patch.in
-@@ -34,7 +34,7 @@ BEGIN {
+@@ -29,7 +31,7 @@ BEGIN {
}
setlocale(LC_MESSAGES, "");
-bindtextdomain("quilt", "@LOCALEDIR@");
-+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@");
++bindtextdomain("quilt", $ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/locale' : "@LOCALEDIR@");
textdomain("quilt");
sub _($) {
--- a/quilt/scripts/patchfns.in
+++ b/quilt/scripts/patchfns.in
-@@ -10,7 +10,11 @@
+@@ -8,7 +8,11 @@
# See the COPYING and AUTHORS files for more details.
export TEXTDOMAIN=quilt
-export TEXTDOMAINDIR=@LOCALEDIR@
-+if [ -n "$STAGING_DIR" ]; then
-+ export TEXTDOMAINDIR="$STAGING_DIR/../host/share/locale"
++if [ -n "$STAGING_DIR_HOST" ]; then
++ export TEXTDOMAINDIR="$STAGING_DIR_HOST/share/locale"
+else
+ export TEXTDOMAINDIR=@LOCALEDIR@
+fi
@@ -72,12 +62,109 @@
: ${LC_MESSAGES:=$LANG}
--- a/quilt/scripts/remove-trailing-ws.in
+++ b/quilt/scripts/remove-trailing-ws.in
-@@ -31,7 +31,7 @@ BEGIN {
+@@ -1,4 +1,6 @@
+-#! @PERL@ -w
++#! @PERL@
++
++use warnings;
+
+ # Remove trailing whitespace from modified lines in working files.
+ #
+@@ -31,7 +33,7 @@ BEGIN {
}
setlocale(LC_MESSAGES, "");
-bindtextdomain("quilt", "@LOCALEDIR@");
-+bindtextdomain("quilt", $ENV{'STAGING_DIR'} ? $ENV{'STAGING_DIR'} . '/../host/share/locale' : "@LOCALEDIR@");
++bindtextdomain("quilt", $ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/locale' : "@LOCALEDIR@");
textdomain("quilt");
sub _($) {
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -21,8 +21,8 @@ COLUMN := @COLUMN@
+ GETOPT := @GETOPT@
+ CP := @CP@
+ DATE := @DATE@
+-PERL := @PERL@
+-BASH := @BASH@
++PERL := /usr/bin/env perl
++BASH := /usr/bin/env bash
+ SHELL:= @BASH@ # It does not work if dash is used as a shell, for example
+ GREP := @GREP@
+ TAIL := @TAIL@
+@@ -32,7 +32,7 @@ AWK := @AWK@
+ FIND := @FIND@
+ XARGS := @XARGS@
+ DIFF := @DIFF@
+-PATCH := @PATCH@
++PATCH := /usr/bin/env patch
+ MKTEMP := @MKTEMP@
+ MSGMERGE := @MSGMERGE@
+ MSGFMT := @MSGFMT@
+@@ -48,8 +48,8 @@ USE_NLS := @USE_NLS@
+ STAT_HARDLINK := @STAT_HARDLINK@
+ PATCH_WRAPPER := @PATCH_WRAPPER@
+
+-COMPAT_SYMLINKS := @COMPAT_SYMLINKS@
+-COMPAT_PROGRAMS := @COMPAT_PROGRAMS@
++COMPAT_SYMLINKS :=
++COMPAT_PROGRAMS :=
+
+ default: all
+
+--- a/quilt/scripts/backup-files.in
++++ b/quilt/scripts/backup-files.in
+@@ -53,7 +53,12 @@ usage ()
+ "
+ }
+
+-: ${QUILT_DIR=@QUILT_DIR@}
++if test -n "$STAGING_DIR_HOST"; then
++ : ${QUILT_DIR="$STAGING_DIR_HOST/share/quilt"}
++else
++ : ${QUILT_DIR=@QUILT_DIR@}
++fi
++
+ . $QUILT_DIR/scripts/utilfns
+
+ ensure_nolinks()
+--- a/bin/guards.in
++++ b/bin/guards.in
+@@ -1,4 +1,6 @@
+-#!@PERL@ -w
++#!@PERL@
++
++use warnings;
+
+ # This script is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License version 2 as
+--- a/compat/date.in
++++ b/compat/date.in
+@@ -1,4 +1,6 @@
+-#! @PERL@ -w
++#! @PERL@
++
++use warnings;
+
+ # This script is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License version 2 as
+--- a/compat/getopt.in
++++ b/compat/getopt.in
+@@ -1,4 +1,6 @@
+-#! @PERL@ -w
++#! @PERL@
++
++use warnings;
+
+ # This script is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License version 2 as
+--- a/quilt/scripts/dependency-graph.in
++++ b/quilt/scripts/dependency-graph.in
+@@ -1,4 +1,6 @@
+-#!@PERL@ -w
++#!@PERL@
++
++use warnings;
+
+ # This script is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License version 2 as
diff --git a/tools/quilt/patches/001-fix_compile.patch b/tools/quilt/patches/001-fix_compile.patch
index 51a4f5e206b..c829515f83d 100644
--- a/tools/quilt/patches/001-fix_compile.patch
+++ b/tools/quilt/patches/001-fix_compile.patch
@@ -1,7 +1,7 @@
--- a/Makefile.in
+++ b/Makefile.in
-@@ -273,13 +273,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu
- lib/backup-files.o :: Makefile
+@@ -272,13 +272,10 @@ $(patsubst %.in,%,$(wildcard bin/*.in qu
+ @$(if $(filter $@,$(NON_EXEC_IN)),,chmod +x $@)
configure : configure.ac aclocal.m4
- autoconf
@@ -14,5 +14,5 @@
- @false
+ @touch $@
- compat_leftover := $(filter-out $(COMPAT),$(shell $(FIND) compat -maxdepth 1 -type f -perm +111))
+ compat_leftover := $(filter-out $(COMPAT),$(shell $(FIND) compat -type f -perm -0100))
diff --git a/tools/quilt/patches/100-patch_2.6.1_version.patch b/tools/quilt/patches/100-patch_2.6.1_version.patch
deleted file mode 100644
index 1e9ed75df1c..00000000000
--- a/tools/quilt/patches/100-patch_2.6.1_version.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -274,7 +274,11 @@ fi
- AC_MSG_CHECKING([the version of $PATCH])
- if $PATCH --version 2> /dev/null | grep GNU >/dev/null; then
- set -- `$PATCH --version 2> /dev/null`
-- patch_version=$2
-+ if test x$1 = xGNU ; then
-+ patch_version=$3
-+ else
-+ patch_version=$2
-+ fi
- AC_MSG_RESULT($patch_version)
- saved_IFS=$IFS; IFS='.'
- set -- $patch_version
diff --git a/tools/scons/Makefile b/tools/scons/Makefile
new file mode 100644
index 00000000000..fc325bff02a
--- /dev/null
+++ b/tools/scons/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2011-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=scons
+PKG_VERSION:=3.0.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/scons \
+ http://fossies.org/linux/misc/
+PKG_HASH:=24475e38d39c19683bc88054524df018fe6949d70fbd4c69e298d39a0269f173
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Configure
+endef
+
+define Host/Compile
+endef
+
+define Host/Install
+ ./files/pywrap.sh $(HOST_BUILD_DIR)/setup.py install --prefix=$(STAGING_DIR_HOST)
+ rm -f $(STAGING_DIR_HOST)/bin/scons*.py
+ for bin in $(STAGING_DIR_HOST)/bin/scons*; do \
+ mv "$$$$bin" "$$$$bin.py"; \
+ cp ./files/pywrap.sh "$$$$bin"; \
+ done
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/scons/files/pywrap.sh b/tools/scons/files/pywrap.sh
new file mode 100755
index 00000000000..f62f590e0bc
--- /dev/null
+++ b/tools/scons/files/pywrap.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+case "${0##*/}" in
+ pywrap.sh) arg1="";;
+ *) arg1="$0.py" ;;
+esac
+
+for bin in python python2 python2.7 python2.6 python2.5 python2.4; do
+ case "$($bin -V 2>&1)" in
+ "Python 2"*) exec $bin $arg1 "$@" ;;
+ esac
+done
+
+echo "Unable to find a Python 2.x interpreter for executing ${arg1:+$arg1 }$@ !" >&2
+exit 1
diff --git a/tools/scons/patches/001-platform_env.patch b/tools/scons/patches/001-platform_env.patch
new file mode 100644
index 00000000000..2be31470c27
--- /dev/null
+++ b/tools/scons/patches/001-platform_env.patch
@@ -0,0 +1,11 @@
+--- a/engine/SCons/Platform/__init__.py
++++ b/engine/SCons/Platform/__init__.py
+@@ -65,6 +65,8 @@ def platform_default():
+ care about the machine architecture.
+ """
+ osname = os.name
++ if 'PLATFORM' in os.environ:
++ return os.environ['PLATFORM']
+ if osname == 'java':
+ osname = os._osType
+ if osname == 'posix':
diff --git a/tools/sdimage/Makefile b/tools/sdimage/Makefile
new file mode 100644
index 00000000000..44d671414fb
--- /dev/null
+++ b/tools/sdimage/Makefile
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=imx-uuc
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/mhei/fsl-imx-uuc.git
+PKG_SOURCE_DATE:=2016-01-10
+PKG_SOURCE_VERSION:=d395b310b6c0f41ab1302242a639e7d0d7767207
+PKG_MIRROR_HASH:=d67ec9d509201511bc7cba9f7551baa729361817f97390f7c5cbb99b5a7b89b1
+
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Configure
+endef
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/sdimage $(STAGING_DIR_HOST)/bin/sdimage
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/bin/sdimage
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/sed/Makefile b/tools/sed/Makefile
index 9ccfc7b9d3b..834519b7375 100644
--- a/tools/sed/Makefile
+++ b/tools/sed/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2010 OpenWrt.org
+# Copyright (C) 2006-2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,18 +7,31 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sed
-PKG_VERSION:=4.2.1
+PKG_VERSION:=4.5
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_MD5SUM:=7d310fbd76e01a01115075c1fd3f455a
-PKG_CAT:=bzcat
+PKG_HASH:=7aad73c8839c2bdadca9476f884d2953cdace9567ecd0d90f9959f229d146b40
export SED:=
+HOST_BUILD_PARALLEL:=1
+
+HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
+
include $(INCLUDE_DIR)/host-build.mk
+HOST_CONFIGURE_ARGS += \
+ --disable-acl \
+ --disable-nls \
+
+HOST_CONFIGURE_VARS += \
+ ac_cv_search_setfilecon=no \
+ ac_cv_header_selinux_context_h=no \
+ ac_cv_header_selinux_selinux_h=no \
+
define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR) SHELL="$(BASH)"
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) SHELL="$(BASH)"
endef
define Host/Install
diff --git a/tools/sparse/Makefile b/tools/sparse/Makefile
new file mode 100644
index 00000000000..959016b1323
--- /dev/null
+++ b/tools/sparse/Makefile
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2014 Qualcomm-Atheros Inc.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sparse
+
+PKG_VERSION:=0.5.2
+PKG_HASH:=4632b7b74af72214247f982f976ba44206933bab3a2717e09df166fb5b8abe7a
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/software/devel/sparse/dist/
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/sparse $(STAGING_DIR_HOST)/bin
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/squashfs/Makefile b/tools/squashfs/Makefile
index 473c5265108..385cf69d9d7 100644
--- a/tools/squashfs/Makefile
+++ b/tools/squashfs/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,11 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=squashfs
+PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs
PKG_VERSION:=3.0
PKG_SOURCE:=$(PKG_NAME)$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/squashfs
-PKG_MD5SUM:=9fd05d0bfbb712f5fb95edafea5bc733
+PKG_HASH:=39dbda43cf118536deb746c7730b468702d514a19f4cfab73b710e32908ddf20
PKG_CAT:=zcat
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)$(PKG_VERSION)
@@ -20,6 +21,9 @@ include $(INCLUDE_DIR)/host-build.mk
define Host/Compile
$(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \
+ CC="$(HOSTCC)" \
+ CFLAGS="$(HOST_CFLAGS) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I." \
+ CXX="$(CXX)" \
LZMAPATH=$(STAGING_DIR_HOST)/lib \
mksquashfs-lzma unsquashfs-lzma
endef
diff --git a/tools/squashfs/patches/100-lzma.patch b/tools/squashfs/patches/100-lzma.patch
index e3b2a3a89c1..73f6a4e0552 100644
--- a/tools/squashfs/patches/100-lzma.patch
+++ b/tools/squashfs/patches/100-lzma.patch
@@ -1,6 +1,6 @@
--- a/squashfs-tools/Makefile
+++ b/squashfs-tools/Makefile
-@@ -7,6 +8,9 @@ all: mksquashfs unsquashfs
+@@ -7,6 +7,9 @@ all: mksquashfs unsquashfs
mksquashfs: mksquashfs.o read_fs.o sort.o
$(CC) mksquashfs.o read_fs.o sort.o -lz -o $@
@@ -10,7 +10,7 @@
mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h
read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h
-@@ -16,4 +20,9 @@ sort.o: sort.c squashfs_fs.h global.h so
+@@ -16,4 +19,9 @@ sort.o: sort.c squashfs_fs.h global.h so
unsquashfs: unsquashfs.o
$(CC) unsquashfs.o -lz -o $@
diff --git a/tools/squashfs/patches/110-no_nonstatic_inline.patch b/tools/squashfs/patches/110-no_nonstatic_inline.patch
new file mode 100644
index 00000000000..8e288f336e0
--- /dev/null
+++ b/tools/squashfs/patches/110-no_nonstatic_inline.patch
@@ -0,0 +1,11 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -1347,7 +1347,7 @@ struct inode_info *lookup_inode(struct s
+ }
+
+
+-inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, struct inode_info *inode_info, void *data, struct dir_info *dir)
++static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir, struct inode_info *inode_info, void *data, struct dir_info *dir)
+ {
+ if((dir->count % DIR_ENTRIES) == 0)
+ if((dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) * sizeof(struct dir_ent *))) == NULL)
diff --git a/tools/squashfs/patches/120-add-fixed-timestamp-support.patch b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch
new file mode 100644
index 00000000000..e2f4bb2e049
--- /dev/null
+++ b/tools/squashfs/patches/120-add-fixed-timestamp-support.patch
@@ -0,0 +1,79 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -117,6 +117,9 @@ unsigned int inode_bytes = 0, inode_size
+ char *data_cache = NULL;
+ unsigned int cache_bytes = 0, cache_size = 0, inode_count = 0;
+
++/* override all timestamps */
++time_t fixed_time = -1;
++
+ /* in memory directory data */
+ #define I_COUNT_SIZE 128
+ #define DIR_ENTRIES 32
+@@ -1554,6 +1557,11 @@ void dir_scan(squashfs_inode *inode, cha
+ perror(buffer);
+ return;
+ }
++
++ /* override timestamp of lstat if fixed_time is given */
++ if(fixed_time != -1)
++ inode_info->buf.st_mtime = fixed_time;
++
+ if(sorted)
+ sort_files_and_write(dir_info);
+ dir_scan2(inode, dir_info);
+@@ -1582,6 +1590,10 @@ struct dir_info *dir_scan1(char *pathnam
+ perror(buffer);
+ continue;
+ }
++
++ if(fixed_time != -1)
++ buf.st_mtime = fixed_time;
++
+ if(excluded(filename, &buf))
+ continue;
+
+@@ -1621,6 +1633,9 @@ int dir_scan2(squashfs_inode *inode, str
+ char *dir_name = dir_ent->name;
+ unsigned int inode_number = ((buf->st_mode & S_IFMT) == S_IFDIR) ? dir_ent->inode->inode_number : dir_ent->inode->inode_number + dir_inode_no;
+
++ if(fixed_time != -1)
++ buf->st_mtime = fixed_time;
++
+ if(dir_ent->inode->inode == SQUASHFS_INVALID_BLK) {
+ switch(buf->st_mode & S_IFMT) {
+ case S_IFREG:
+@@ -1898,6 +1913,16 @@ int main(int argc, char *argv[])
+ exit(1);
+ }
+ }
++ } else if(strcmp(argv[i], "-fixed-time") == 0) {
++ if(++i == argc) {
++ ERROR("%s: -fixed-time missing a timestamp\n", argv[0]);
++ exit(1);
++ }
++ fixed_time = strtoll(argv[i], &b, 10);
++ if(*b != '\0') {
++ ERROR("%s: -fixed-time has an invalid number\n", argv[0]);
++ exit(1);
++ }
+ } else if(strcmp(argv[i], "-noI") == 0 ||
+ strcmp(argv[i], "-noInodeCompression") == 0)
+ noI = TRUE;
+@@ -1967,6 +1992,7 @@ printOptions:
+ ERROR("-all-root\t\tmake all files owned by root\n");
+ ERROR("-force-uid uid\t\tset all file uids to uid\n");
+ ERROR("-force-gid gid\t\tset all file gids to gid\n");
++ ERROR("-fixed-time timestamp\tset all timestamps to timestamp\n");
+ ERROR("-le\t\t\tcreate a little endian filesystem\n");
+ ERROR("-be\t\t\tcreate a big endian filesystem\n");
+ ERROR("-nopad\t\t\tdo not pad filesystem to a multiple of 4K\n");
+@@ -2190,7 +2216,7 @@ printOptions:
+ sBlk.block_size = block_size;
+ sBlk.block_log = block_log;
+ sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, check_data, noF, no_fragments, always_use_fragments, duplicate_checking);
+- sBlk.mkfs_time = time(NULL);
++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL);
+
+ restore_filesystem:
+ write_fragment();
diff --git a/tools/squashfs/patches/130-include_sysmacros.patch b/tools/squashfs/patches/130-include_sysmacros.patch
new file mode 100644
index 00000000000..f0149d6f65f
--- /dev/null
+++ b/tools/squashfs/patches/130-include_sysmacros.patch
@@ -0,0 +1,20 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -30,6 +30,7 @@
+ #include <unistd.h>
+ #include <stdio.h>
+ #include <sys/types.h>
++#include <sys/sysmacros.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
+--- a/squashfs-tools/unsquashfs.c
++++ b/squashfs-tools/unsquashfs.c
+@@ -25,6 +25,7 @@
+ #define FALSE 0
+ #include <stdio.h>
+ #include <sys/types.h>
++#include <sys/sysmacros.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile
index 04a5456f6c2..409b1b5a238 100644
--- a/tools/squashfs4/Makefile
+++ b/tools/squashfs4/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,11 +7,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=squashfs4
+PKG_CPE_ID:=cpe:/a:phillip_lougher:squashfs
PKG_VERSION:=4.2
PKG_SOURCE:=squashfs$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/squashfs
-PKG_MD5SUM:=1b7a781fb4cf8938842279bd3e8ee852
+PKG_HASH:=d9e0195aa922dbb665ed322b9aaa96e04a476ee650f39bbeadb0d00b24022e96
PKG_CAT:=zcat
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION)
@@ -19,6 +20,7 @@ HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION)
include $(INCLUDE_DIR)/host-build.mk
define Host/Compile
+ +$(HOST_MAKE_VARS) \
$(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \
XZ_SUPPORT=1 \
LZMA_XZ_SUPPORT=1 \
diff --git a/tools/squashfs4/patches/130-include_sysmacros.patch b/tools/squashfs4/patches/130-include_sysmacros.patch
new file mode 100644
index 00000000000..e8845130ef7
--- /dev/null
+++ b/tools/squashfs4/patches/130-include_sysmacros.patch
@@ -0,0 +1,20 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -33,6 +33,7 @@
+ #include <stddef.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
++#include <sys/sysmacros.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
+--- a/squashfs-tools/unsquashfs.c
++++ b/squashfs-tools/unsquashfs.c
+@@ -30,6 +30,7 @@
+ #include "xattr.h"
+
+ #include <sys/types.h>
++#include <sys/sysmacros.h>
+
+ struct cache *fragment_cache, *data_cache;
+ struct queue *to_reader, *to_deflate, *to_writer, *from_writer;
diff --git a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch
index d6063969d27..9e1c1fbb1ea 100644
--- a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch
+++ b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch
@@ -40,6 +40,7 @@
+
+
+struct lzma_opts {
++ uint32_t dict_size;
+ uint32_t flags;
+#define LZMA_OPT_FLT_MASK 0xffff
+#define LZMA_OPT_PRE_OFF 16
@@ -53,7 +54,6 @@
+#define LZMA_OPT_PB_OFF 6
+#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF)
+ uint16_t fb;
-+ uint32_t dict_size;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
@@ -637,7 +637,7 @@
}
name = argv[1];
-@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int
+@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int
}
if(bcj[i].name == NULL) {
fprintf(stderr, "xz: -Xbcj unrecognised "
@@ -864,7 +864,7 @@
SQUASHFS_METADATA_SIZE;
filter[0].filter[0].id = LZMA_FILTER_LZMA2;
-@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void
+@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void
lzma_ret res = 0;
struct xz_stream *stream = strm;
struct filter *selected = NULL;
diff --git a/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch
index ad69b190ea9..bc7d6c7a4a0 100644
--- a/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch
+++ b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch
@@ -16,7 +16,7 @@
#define SQUASHFS_METADATA_LOG 13
--- a/squashfs-tools/unsquashfs.c
+++ b/squashfs-tools/unsquashfs.c
-@@ -1463,10 +1463,12 @@ int read_super(char *source)
+@@ -1464,10 +1464,12 @@ int read_super(char *source)
*/
read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block),
&sBlk_4);
@@ -31,7 +31,7 @@
sBlk_4.s_minor == 0) {
s_ops.squashfs_opendir = squashfs_opendir_4;
s_ops.read_fragment = read_fragment_4;
-@@ -1479,7 +1481,11 @@ int read_super(char *source)
+@@ -1480,7 +1482,11 @@ int read_super(char *source)
/*
* Check the compression type
*/
@@ -44,7 +44,7 @@
return TRUE;
}
-@@ -1494,8 +1500,10 @@ int read_super(char *source)
+@@ -1495,8 +1501,10 @@ int read_super(char *source)
* Check it is a SQUASHFS superblock
*/
swap = 0;
@@ -57,7 +57,7 @@
squashfs_super_block_3 sblk;
ERROR("Reading a different endian SQUASHFS filesystem "
"on %s\n", source);
-@@ -1573,7 +1581,11 @@ int read_super(char *source)
+@@ -1574,7 +1582,11 @@ int read_super(char *source)
/*
* 1.x, 2.x and 3.x filesystems use gzip compression.
*/
diff --git a/tools/squashfs4/patches/180-openbsd_compat.patch b/tools/squashfs4/patches/180-openbsd_compat.patch
new file mode 100644
index 00000000000..4f7afd89cc9
--- /dev/null
+++ b/tools/squashfs4/patches/180-openbsd_compat.patch
@@ -0,0 +1,24 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -32,6 +32,9 @@
+ #include <stdio.h>
+ #include <stddef.h>
+ #include <sys/time.h>
++#if defined(__OpenBSD__)
++#include <sys/param.h>
++#endif
+ #include <sys/types.h>
+ #include <sys/sysmacros.h>
+ #include <sys/stat.h>
+--- a/squashfs-tools/unsquashfs.h
++++ b/squashfs-tools/unsquashfs.h
+@@ -25,6 +25,9 @@
+ #define TRUE 1
+ #define FALSE 0
+ #include <stdio.h>
++#if defined(__OpenBSD__)
++#include <sys/param.h>
++#endif
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stdlib.h>
diff --git a/tools/squashfs4/patches/190-no_nonstatic_inline.patch b/tools/squashfs4/patches/190-no_nonstatic_inline.patch
new file mode 100644
index 00000000000..8cab1208325
--- /dev/null
+++ b/tools/squashfs4/patches/190-no_nonstatic_inline.patch
@@ -0,0 +1,36 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -736,13 +736,13 @@ void cache_block_put(struct file_buffer
+ + (((char *)A) - data_cache)))
+
+
+-inline void inc_progress_bar()
++static inline void inc_progress_bar()
+ {
+ cur_uncompressed ++;
+ }
+
+
+-inline void update_progress_bar()
++static inline void update_progress_bar()
+ {
+ pthread_mutex_lock(&progress_mutex);
+ pthread_cond_signal(&progress_wait);
+@@ -750,7 +750,7 @@ inline void update_progress_bar()
+ }
+
+
+-inline void waitforthread(int i)
++static inline void waitforthread(int i)
+ {
+ TRACE("Waiting for thread %d\n", i);
+ while(thread[i] != 0)
+@@ -3359,7 +3359,7 @@ struct inode_info *lookup_inode(struct s
+ }
+
+
+-inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir,
++static inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir,
+ struct inode_info *inode_info, struct dir_info *dir)
+ {
+ if((dir->count % DIR_ENTRIES) == 0) {
diff --git a/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch
new file mode 100644
index 00000000000..7411b978449
--- /dev/null
+++ b/tools/squashfs4/patches/200-add-fixed-timestamp-option.patch
@@ -0,0 +1,82 @@
+--- a/squashfs-tools/mksquashfs.c
++++ b/squashfs-tools/mksquashfs.c
+@@ -176,6 +176,9 @@ unsigned int cache_bytes = 0, cache_size
+ /* inode lookup table */
+ squashfs_inode *inode_lookup_table = NULL;
+
++/* override all timestamps */
++time_t fixed_time = -1;
++
+ /* in memory directory data */
+ #define I_COUNT_SIZE 128
+ #define DIR_ENTRIES 32
+@@ -2453,6 +2456,8 @@ again:
+ restat:
+ fstat(file, &buf2);
+ close(file);
++ if (fixed_time != -1)
++ buf2.st_mtime = fixed_time;
+ if(read_size != buf2.st_size) {
+ memcpy(buf, &buf2, sizeof(struct stat));
+ file_buffer->error = 2;
+@@ -3613,7 +3618,7 @@ void dir_scan(squashfs_inode *inode, cha
+ buf.st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR;
+ buf.st_uid = getuid();
+ buf.st_gid = getgid();
+- buf.st_mtime = time(NULL);
++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL);
+ buf.st_dev = 0;
+ buf.st_ino = 0;
+ dir_ent->inode = lookup_inode(&buf);
+@@ -3624,6 +3629,8 @@ void dir_scan(squashfs_inode *inode, cha
+ pathname, strerror(errno));
+ return;
+ }
++ if(fixed_time != -1)
++ buf.st_mtime = fixed_time;
+ dir_ent->inode = lookup_inode(&buf);
+ }
+
+@@ -3678,6 +3685,8 @@ struct dir_info *dir_scan1(char *pathnam
+ filename, strerror(errno));
+ continue;
+ }
++ if(fixed_time != -1)
++ buf.st_mtime = fixed_time;
+
+ if((buf.st_mode & S_IFMT) != S_IFREG &&
+ (buf.st_mode & S_IFMT) != S_IFDIR &&
+@@ -3796,7 +3805,7 @@ struct dir_info *dir_scan2(struct dir_in
+ buf.st_gid = pseudo_ent->dev->gid;
+ buf.st_rdev = makedev(pseudo_ent->dev->major,
+ pseudo_ent->dev->minor);
+- buf.st_mtime = time(NULL);
++ buf.st_mtime = fixed_time != -1 ? fixed_time : time(NULL);
+ buf.st_ino = pseudo_ino ++;
+
+ if(pseudo_ent->dev->type == 'f') {
+@@ -4675,6 +4684,15 @@ int main(int argc, char *argv[])
+ progress = FALSE;
+ else if(strcmp(argv[i], "-no-exports") == 0)
+ exportable = FALSE;
++ else if(strcmp(argv[i], "-fixed-time") == 0) {
++ if((++i == argc) || (fixed_time =
++ strtoll(argv[i], &b, 10), *b != '\0')) {
++ ERROR("%s: -fixed-time missing or invalid "
++ "timestamp\n", argv[0]);
++
++ exit(1);
++ }
++ }
+ else if(strcmp(argv[i], "-processors") == 0) {
+ if((++i == argc) || (processors =
+ strtol(argv[i], &b, 10), *b != '\0')) {
+@@ -5315,7 +5333,7 @@ printOptions:
+ sBlk.flags = SQUASHFS_MKFLAGS(noI, noD, noF, noX, no_fragments,
+ always_use_fragments, duplicate_checking, exportable,
+ no_xattrs, comp_opts);
+- sBlk.mkfs_time = time(NULL);
++ sBlk.mkfs_time = fixed_time != -1 ? fixed_time : time(NULL);
+
+ restore_filesystem:
+ if(progress && estimated_uncompressed) {
diff --git a/tools/sstrip/Makefile b/tools/sstrip/Makefile
index 681e533be43..180bd1743e5 100644
--- a/tools/sstrip/Makefile
+++ b/tools/sstrip/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -11,7 +11,7 @@ PKG_NAME:=sstrip
include $(INCLUDE_DIR)/host-build.mk
define Host/Compile
- $(HOSTCC) $(HOST_CFLAGS) -I./include -include endian.h -o $(HOST_BUILD_DIR)/sstrip src/sstrip.c
+ $(HOSTCC) $(HOST_CFLAGS) -include endian.h -o $(HOST_BUILD_DIR)/sstrip src/sstrip.c
endef
define Host/Install
diff --git a/tools/sstrip/src/sstrip.c b/tools/sstrip/src/sstrip.c
index 0508aaac81e..12cf12e0958 100644
--- a/tools/sstrip/src/sstrip.c
+++ b/tools/sstrip/src/sstrip.c
@@ -59,6 +59,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
+#include <byteswap.h>
#ifndef TRUE
#define TRUE 1
@@ -103,7 +104,7 @@ static int do_reverse_endian;
} else if (sizeof(X) == 8) { \
__res = bswap_64((X)); \
} else { \
- fprintf(stderr, "%s: %s: EGET failed for size %d\n", \
+ fprintf(stderr, "%s: %s: EGET failed for size %zu\n", \
progname, filename, sizeof(X)); \
exit(EXIT_FAILURE); \
} \
@@ -124,7 +125,7 @@ static int do_reverse_endian;
} else if (sizeof(Y) == 8) { \
Y = bswap_64((uint64_t)(X)); \
} else { \
- fprintf(stderr, "%s: %s: ESET failed for size %d\n", \
+ fprintf(stderr, "%s: %s: ESET failed for size %zu\n", \
progname, filename, sizeof(Y)); \
exit(EXIT_FAILURE); \
} while (0)
@@ -197,7 +198,7 @@ static int getmemorysize ## CLASS (Elf ## CLASS ## _Ehdr const *ehdr, \
{ \
Elf ## CLASS ## _Phdr const *phdr; \
unsigned long size, n; \
- int i; \
+ size_t i; \
\
/* Start by setting the size to include the ELF header and the \
* complete program segment header table. \
@@ -230,7 +231,7 @@ static int modifyheaders ## CLASS (Elf ## CLASS ## _Ehdr *ehdr, \
unsigned long newsize) \
{ \
Elf ## CLASS ## _Phdr *phdr; \
- int i; \
+ size_t i; \
\
/* If the section header table is gone, then remove all references \
* to it in the ELF header. \
diff --git a/tools/tar/Makefile b/tools/tar/Makefile
new file mode 100644
index 00000000000..baa431e2db6
--- /dev/null
+++ b/tools/tar/Makefile
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=tar
+PKG_CPE_ID:=cpe:/a:gnu:tar
+PKG_VERSION:=1.30
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@GNU/tar
+PKG_HASH:=87592b86cb037c554375f5868bdd3cc57748aef38d6cb741c81065f0beac63b7
+
+HOST_BUILD_PARALLEL := 1
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
+
+HOST_CONFIGURE_ARGS += \
+ --without-posix-acls \
+ --without-selinux \
+ --without-xattrs \
+ --disable-acl \
+ --disable-nls
+
+$(eval $(call HostBuild))
diff --git a/tools/tar/patches/100-symlink-force-root-name.patch b/tools/tar/patches/100-symlink-force-root-name.patch
new file mode 100644
index 00000000000..93f889761b7
--- /dev/null
+++ b/tools/tar/patches/100-symlink-force-root-name.patch
@@ -0,0 +1,27 @@
+Force root/root as names for uid0/gid0 instead of using the system
+names. This helps make packed download tarballs more reproducible
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+--- a/src/create.c
++++ b/src/create.c
+@@ -544,17 +544,8 @@ write_gnu_long_link (struct tar_stat_inf
+ union block *header;
+
+ header = start_private_header ("././@LongLink", size, 0);
+- if (! numeric_owner_option)
+- {
+- static char *uname, *gname;
+- if (!uname)
+- {
+- uid_to_uname (0, &uname);
+- gid_to_gname (0, &gname);
+- }
+- UNAME_TO_CHARS (uname, header->header.uname);
+- GNAME_TO_CHARS (gname, header->header.gname);
+- }
++ UNAME_TO_CHARS ("root", header->header.uname);
++ GNAME_TO_CHARS ("root", header->header.gname);
+
+ strcpy (header->buffer + offsetof (struct posix_header, magic),
+ OLDGNU_MAGIC);
diff --git a/tools/tar/patches/110-symlink-force-permissions.patch b/tools/tar/patches/110-symlink-force-permissions.patch
new file mode 100644
index 00000000000..6fb799bc0a3
--- /dev/null
+++ b/tools/tar/patches/110-symlink-force-permissions.patch
@@ -0,0 +1,10 @@
+--- a/src/create.c
++++ b/src/create.c
+@@ -1853,6 +1853,7 @@ dump_file0 (struct tar_stat_info *st, ch
+ #ifdef HAVE_READLINK
+ else if (S_ISLNK (st->stat.st_mode))
+ {
++ st->stat.st_mode |= 0777; /* make permissions portable */
+ st->link_name = areadlinkat_with_size (parentfd, name, st->stat.st_size);
+ if (!st->link_name)
+ {
diff --git a/tools/upslug2/Makefile b/tools/upslug2/Makefile
index 6a73853f3c2..42448b0185b 100644
--- a/tools/upslug2/Makefile
+++ b/tools/upslug2/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2009 OpenWrt.org
+# Copyright (C) 2009-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -13,7 +13,8 @@ PKG_SOURCE_URL:=http://svn.nslu2-linux.org/svnroot/upslug2/trunk
PKG_SOURCE_PROTO:=svn
PKG_SOURCE_SUBDIR:=upslug2-$(PKG_VERSION)
PKG_SOURCE_VERSION:=41
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_MIRROR_HASH:=5c69eae3a2affef8f4f7194cfedfdb9175b04ca433f9ae046c85309b42bdb21e
include $(INCLUDE_DIR)/host-build.mk
diff --git a/tools/upx/Makefile b/tools/upx/Makefile
deleted file mode 100644
index 2f3313ca389..00000000000
--- a/tools/upx/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Copyright (C) 2011 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=upx
-PKG_VERSION:=3.07
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-src.tar.bz2
-PKG_SOURCE_URL:=@SF/upx
-PKG_MD5SUM:=8186ab103288242f7e8ecad1acd4af03
-PKG_CAT:=bzcat
-
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)-src
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Compile
- rm -f $(HOST_BUILD_DIR)/src/.depend
- $(MAKE) UPX_LZMADIR="$(BUILD_DIR_HOST)/lzma-4.65" -C $(HOST_BUILD_DIR)/src \
- CXXFLAGS_WERROR=
-endef
-
-define Host/Install
- $(CP) $(HOST_BUILD_DIR)/src/upx.out $(STAGING_DIR_HOST)/bin/upx
-endef
-
-define Host/Clean
- rm -f $(STAGING_DIR_HOST)/bin/upx
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/upx/patches/100-lzmaonly.patch b/tools/upx/patches/100-lzmaonly.patch
deleted file mode 100644
index a3098b47613..00000000000
--- a/tools/upx/patches/100-lzmaonly.patch
+++ /dev/null
@@ -1,156 +0,0 @@
---- a/src/compress.cpp
-+++ b/src/compress.cpp
-@@ -41,7 +41,7 @@
- if (len == 0)
- return adler;
- assert(buf != NULL);
--#if 0
-+#if !(WITH_UCL)
- return adler32(adler, (const Bytef *) buf, len); // zlib
- #elif (WITH_UCL)
- return ucl_adler32(adler, (const ucl_bytep) buf, len);
---- a/src/conf.h
-+++ b/src/conf.h
-@@ -179,7 +179,7 @@
- # undef __unix
- #endif
-
--#if !defined(WITH_UCL)
-+#if defined(WITH_UCL)
- # define WITH_UCL 1
- #endif
- #if 0 && !defined(WITH_LZMA)
-@@ -645,7 +645,11 @@
- };
-
-
-+#if (WITH_UCL)
- struct ucl_compress_config_t : public REAL_ucl_compress_config_t
-+#else
-+struct ucl_compress_config_t
-+#endif
- {
- void reset() { memset(this, 0xff, sizeof(*this)); }
- };
-@@ -697,7 +701,9 @@
-
- struct ucl_compress_result_t
- {
-+#if (WITH_UCL)
- ucl_uint result[16];
-+#endif
-
- void reset() { memset(this, 0, sizeof(*this)); }
- };
---- a/src/main.cpp
-+++ b/src/main.cpp
-@@ -618,7 +618,9 @@
- opt->method = -1;
- opt->all_filters = true;
- opt->filter = -1;
-+#if (WITH_UCL)
- opt->crp.crp_ucl.m_size = 999999;
-+#endif
- /* fallthrough */
- case 900: // --best
- if (!set_method(-1, 10))
-@@ -709,6 +711,7 @@
- opt->exact = true;
- break;
- // compression runtime parameters
-+#if (WITH_UCL)
- case 801:
- getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg);
- break;
-@@ -730,6 +733,7 @@
- case 807:
- getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg);
- break;
-+#endif
- case 811:
- getoptvar(&opt->crp.crp_lzma.pos_bits, arg);
- break;
---- a/src/Makefile
-+++ b/src/Makefile
-@@ -57,7 +57,10 @@
- INCLUDES += -I$(UPX_UCLDIR)/include
- LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
- endif
--LIBS += -lucl -lz
-+ifeq ($(WITH_UCL),1)
-+LIBS += -lucl
-+endif
-+LIBS += -lz
- # you should set envvar UPX_LZMADIR to point to your unpacked LZMA SDK
- include $(top_srcdir)/src/stub/src/c/Makevars.lzma
- ifneq ($(UPX_LZMA_VERSION),)
---- a/src/packer.cpp
-+++ b/src/packer.cpp
-@@ -199,6 +199,7 @@
- if (cconf_parm)
- cconf = *cconf_parm;
- // cconf options
-+#if (WITH_UCL)
- if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
- {
- if (opt->crp.crp_ucl.c_flags != -1)
-@@ -216,6 +217,7 @@
- step = 0;
- #endif
- }
-+#endif
- if (M_IS_LZMA(ph.method))
- {
- oassign(cconf.conf_lzma.pos_bits, opt->crp.crp_lzma.pos_bits);
-@@ -250,6 +252,7 @@
- if (r != UPX_E_OK)
- throwInternalError("compression failed");
-
-+#if (WITH_UCL)
- if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
- {
- const ucl_uint *res = ph.compress_result.result_ucl.result;
-@@ -267,6 +270,7 @@
- assert(cconf.conf_ucl.max_match == 0 || cconf.conf_ucl.max_match >= ph.max_match_found);
- }
- }
-+#endif
-
- //printf("\nPacker::compress: %d/%d: %7d -> %7d\n", ph.method, ph.level, ph.u_len, ph.c_len);
- if (!checkCompressionRatio(ph.u_len, ph.c_len))
---- a/src/p_exe.cpp
-+++ b/src/p_exe.cpp
-@@ -506,7 +506,9 @@
- Filter ft(ph.level);
- // compress (max_match = 8192)
- upx_compress_config_t cconf; cconf.reset();
-+#if (WITH_UCL)
- cconf.conf_ucl.max_match = MAXMATCH;
-+#endif
- cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
- compressWithFilters(&ft, 32, &cconf);
-
---- a/src/p_ps1.cpp
-+++ b/src/p_ps1.cpp
-@@ -499,7 +499,9 @@
-
- // compress (max_match = 65535)
- upx_compress_config_t cconf; cconf.reset();
-+#if (WITH_UCL)
- cconf.conf_ucl.max_match = 65535;
-+#endif
- cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
- compressWithFilters(&ft, sa_cnt, &cconf);
-
---- a/src/p_tos.cpp
-+++ b/src/p_tos.cpp
-@@ -506,7 +506,9 @@
- Filter ft(ph.level);
- // compress (max_match = 65535)
- upx_compress_config_t cconf; cconf.reset();
-+#if (WITH_UCL)
- cconf.conf_ucl.max_match = 65535;
-+#endif
- cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
- compressWithFilters(&ft, 512, &cconf);
-
diff --git a/tools/wrt350nv2-builder/Makefile b/tools/wrt350nv2-builder/Makefile
index 689fd32a538..a705b6dc8d8 100644
--- a/tools/wrt350nv2-builder/Makefile
+++ b/tools/wrt350nv2-builder/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006-2010 OpenWrt.org
+# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -8,7 +8,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wrt350nv2-builder
-PKG_VERSION:=2.3
+PKG_VERSION:=2.4
+PKG_REVISION:=2
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME}-$(PKG_VERSION)
@@ -18,7 +19,8 @@ define Host/Compile
$(HOSTCC) $(HOST_CFLAGS) -c src/md5.c -o $(HOST_BUILD_DIR)/md5.o
$(HOSTCC) $(HOST_CFLAGS) -c src/ioapi.c -o $(HOST_BUILD_DIR)/ioapi.o
$(HOSTCC) $(HOST_CFLAGS) -c src/wrt350nv2-builder.c -o $(HOST_BUILD_DIR)/wrt350nv2-builder.o
- $(HOSTCC) $(HOST_CFLAGS) -o $(HOST_BUILD_DIR)/wrt350nv2-builder $(HOST_BUILD_DIR)/wrt350nv2-builder.o $(HOST_BUILD_DIR)/md5.o $(HOST_BUILD_DIR)/ioapi.o
+ $(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $(HOST_BUILD_DIR)/wrt350nv2-builder \
+ $(HOST_BUILD_DIR)/wrt350nv2-builder.o $(HOST_BUILD_DIR)/md5.o $(HOST_BUILD_DIR)/ioapi.o
endef
define Host/Install
diff --git a/tools/wrt350nv2-builder/src/ioapi.h b/tools/wrt350nv2-builder/src/ioapi.h
index 7d457baab34..5fa9786148a 100644
--- a/tools/wrt350nv2-builder/src/ioapi.h
+++ b/tools/wrt350nv2-builder/src/ioapi.h
@@ -35,13 +35,13 @@
extern "C" {
#endif
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode);
+typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size);
+typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size);
+typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream);
+typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin);
+typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream);
+typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream);
typedef struct zlib_filefunc_def_s
{
@@ -57,7 +57,7 @@ typedef struct zlib_filefunc_def_s
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_fopen_filefunc (zlib_filefunc_def* pzlib_filefunc_def);
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
diff --git a/tools/wrt350nv2-builder/src/wrt350nv2-builder.c b/tools/wrt350nv2-builder/src/wrt350nv2-builder.c
index 2ce57234c5f..3ebb40ed511 100644
--- a/tools/wrt350nv2-builder/src/wrt350nv2-builder.c
+++ b/tools/wrt350nv2-builder/src/wrt350nv2-builder.c
@@ -1,8 +1,8 @@
/*
- WRT350Nv2-Builder 2.3 (previously called buildimg)
+ WRT350Nv2-Builder 2.4 (previously called buildimg)
Copyright (C) 2008-2009 Dirk Teurlings <info@upexia.nl>
- Copyright (C) 2009-2010 Matthias Buecher (http://www.maddes.net/)
+ Copyright (C) 2009-2011 Matthias Buecher (http://www.maddes.net/)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -33,6 +33,9 @@
:u-boot 0 /path/to/u-boot.bin
#version 0x2020
+ Additionally since v2.4 an already complete image can be used:
+ :image 0 /path/to/openwrt-wrt350nv2-[squashfs|jffs2-64k].img
+
args:
1 wrt350nv2.par parameter file describing the image layout
2 wrt350nv2.img output file for linksys style image
@@ -62,6 +65,8 @@
https://forum.openwrt.org/viewtopic.php?pid=92928#p92928
Changelog:
+ v2.4 - added ":image" definition for parameter file, this allows
+ to use a complete sysupgrade image without any kernel size check
v2.3 - allow jffs by adding its magic number (0x8519)
added parameter option -i to ignore unknown magic numbers
v2.2 - fixed checksum byte calculation for other versions than 0x2019
@@ -92,7 +97,7 @@
// version info
-#define VERSION "2.3"
+#define VERSION "2.4"
char program_info[] = "WRT350Nv2-Builder v%s by Dirk Teurlings <info@upexia.nl> and Matthias Buecher (http://www.maddes.net/)\n";
// verbosity
@@ -112,6 +117,7 @@ typedef struct {
mtd_info mtd_kernel = { "kernel", 0, 0, NULL, 0L, { 0, 0 } };
mtd_info mtd_rootfs = { "rootfs", 0, 0, NULL, 0L, { 0, 0 } };
+mtd_info mtd_image = { "image", 0, 0, NULL, 0L, { 0, 0 } };
mtd_info mtd_uboot = { "u-boot", 0, 0, NULL, 0L, { 0, 0 } };
#define ROOTFS_END_OFFSET 0x00760000
@@ -281,6 +287,8 @@ int parse_par_file(FILE *f_par) {
mtd = &mtd_rootfs;
} else if (!strcmp(string1, mtd_uboot.name)) {
mtd = &mtd_uboot;
+ } else if (!strcmp(string1, mtd_image.name)) {
+ mtd = &mtd_image;
}
if (!mtd) {
@@ -404,20 +412,24 @@ int create_bin_file(char *bin_filename) {
// add files
if (!exitcode) {
- for (i = 1; i <= 3; i++) {
+ for (i = 1; i <= 4; i++) {
addsize = 0;
padsize = 0;
switch (i) {
case 1:
- mtd = &mtd_kernel;
+ mtd = &mtd_image;
+ padsize = ROOTFS_MIN_OFFSET - mtd->filesize;
break;
case 2:
+ mtd = &mtd_kernel;
+ break;
+ case 3:
mtd = &mtd_rootfs;
addsize = mtd->filesize;
padsize = ROOTFS_MIN_OFFSET - mtd_kernel.size - mtd->filesize;
break;
- case 3:
+ case 4:
mtd = &mtd_uboot;
addsize = mtd->filesize;
break;
@@ -723,7 +735,6 @@ int main(int argc, char *argv[]) {
int i;
mtd_info *mtd;
- int mandatory;
int noupdate;
int sizecheck;
int magiccheck;
@@ -934,28 +945,30 @@ int main(int argc, char *argv[]) {
if ((!exitcode) && (par_filename)) {
lprintf(DEBUG, "checking mtd data...\n");
- for (i = 1; i <= 3; i++) {
- mandatory = 0;
+ for (i = 1; i <= 4; i++) {
noupdate = 0;
sizecheck = 0;
magiccheck = 0;
switch (i) {
case 1:
+ mtd = &mtd_image;
+ sizecheck = ROOTFS_END_OFFSET;
+ magiccheck = 1;
+ break;
+ case 2:
mtd = &mtd_kernel;
- mandatory = 1;
sizecheck = mtd_kernel.size - 16;
magiccheck = 1;
break;
- case 2:
+ case 3:
mtd = &mtd_rootfs;
mtd->offset = mtd_kernel.size;
mtd->size = ROOTFS_END_OFFSET - mtd_kernel.size;
- mandatory = 1;
sizecheck = PRODUCT_ID_OFFSET - mtd_kernel.size;
magiccheck = 1;
break;
- case 3:
+ case 4:
mtd = &mtd_uboot;
mtd->offset = BOOT_ADDR_BASE_OFF;
noupdate = 1;
@@ -974,10 +987,6 @@ int main(int argc, char *argv[]) {
lprintf(DEBUG_LVL2, " checking mtd %s\n", mtd->name);
// general checks
- if ((mandatory) && (!mtd->filename)) {
- exitcode = 1;
- printf("mtd %s not specified correctly or at all in parameter file\n", mtd->name);
- }
// no further checks if no file data present
if (!mtd->filename) {
@@ -993,14 +1002,15 @@ int main(int argc, char *argv[]) {
magicerror = 0;
if (magiccheck) {
switch (i) {
- case 1: // kernel
+ case 1: // image
+ case 2: // kernel
if (!(
((mtd->magic[0] == 0x27) && (mtd->magic[1] == 0x05)) // uImage
)) {
magicerror = 1;
}
break;
- case 2: // rootfs
+ case 3: // rootfs
if (!(
((mtd->magic[0] == 0x68) && (mtd->magic[1] == 0x73)) // squashfs
|| ((mtd->magic[0] == 0x85) && (mtd->magic[1] == 0x19)) // jffs
@@ -1024,8 +1034,15 @@ int main(int argc, char *argv[]) {
}
// mtd specific size check
+ if (mtd == &mtd_image) {
+ if (mtd->filesize < 0x00200000) {
+ exitcode = 1;
+ printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
+ }
+ }
+
if (mtd == &mtd_kernel) {
- if (mtd->filesize < 0x00050000) {
+ if (mtd->filesize < 0x00080000) {
exitcode = 1;
printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
}
@@ -1044,6 +1061,25 @@ int main(int argc, char *argv[]) {
}
}
}
+
+ // Check for mandatory parts
+ if ((!mtd_image.filename) && (!mtd_kernel.filename || !mtd_rootfs.filename)) {
+ exitcode = 1;
+ if (mtd_kernel.filename && !mtd_rootfs.filename) {
+ printf("Kernel without rootfs, either incorrectly specified or not at all in parameter file\n");
+ } else if (!mtd_kernel.filename && mtd_rootfs.filename) {
+ printf("Rootfs without kernel, either incorrectly specified or not at all in parameter file\n");
+ } else {
+ printf("Neither an image nor kernel with rootfs was/were correctly specified or at all in parameter file\n");
+ }
+ }
+
+ // Check for duplicate parts
+ if ((mtd_image.filename) && (mtd_kernel.filename || mtd_rootfs.filename)) {
+ exitcode = 1;
+ printf("Image and kernel/rootfs specified in parameter file\n");
+ }
+
lprintf(DEBUG, "...done checking mtd data\n");
}
diff --git a/tools/xfce-macros/Makefile b/tools/xfce-macros/Makefile
deleted file mode 100644
index 974404714dd..00000000000
--- a/tools/xfce-macros/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Copyright (C) 2011 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=xfce-macros
-PKG_VERSION:=4.8.0
-
-PKG_SOURCE_URL:=http://archive.xfce.org/xfce/4.8/src
-PKG_SOURCE:=xfce4-dev-tools-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=9591299c49d92d00ba47974c42a735fa
-
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/xfce4-dev-tools-$(PKG_VERSION)
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Configure
-endef
-
-define Host/Compile
-endef
-
-define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal
- $(INSTALL_DATA) $(HOST_BUILD_DIR)/m4macros/*.m4 $(STAGING_DIR_HOST)/share/aclocal/
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/xorg-macros/Makefile b/tools/xorg-macros/Makefile
deleted file mode 100644
index 54df4028e93..00000000000
--- a/tools/xorg-macros/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Copyright (C) 2010 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=xorg-macros
-PKG_VERSION:=1.11.0
-
-PKG_SOURCE_URL:=http://xorg.freedesktop.org/releases/individual/util/
-PKG_SOURCE:=util-macros-$(PKG_VERSION).tar.bz2
-PKG_MD5SUM:=22d5cdff672450cb6902e0d68c200dcb
-
-HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/util-macros-$(PKG_VERSION)
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/share/aclocal
- $(INSTALL_DATA) $(HOST_BUILD_DIR)/xorg-macros.m4 $(STAGING_DIR_HOST)/share/aclocal/
-endef
-
-define Host/Clean
- -$(MAKE) -C $(HOST_BUILD_DIR) uninstall
- $(call Host/Clean/Default)
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/xz/Makefile b/tools/xz/Makefile
index cabc4fdfbb7..d6b619db41f 100644
--- a/tools/xz/Makefile
+++ b/tools/xz/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (C) 2006 OpenWrt.org
+# Copyright (C) 2006-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
@@ -7,16 +7,27 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=xz
-PKG_VERSION:=5.0.2
+PKG_VERSION:=5.2.4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=http://tukaani.org/xz
-PKG_MD5SUM:=ee05b17a4062bb55cba099ef46eca007
+PKG_SOURCE_URL:=@SF/lzmautils \
+ http://tukaani.org/xz
+PKG_HASH:=3313fd2a95f43d88e44264e6b015e7d03053e681860b0d5d3f9baca79c57b7bf
+
+HOST_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
+HOSTCC := $(HOSTCC_NOCACHE)
+HOSTCXX := $(HOSTCXX_NOCACHE)
+
+HOST_CONFIGURE_ARGS += \
+ --enable-static=yes \
+ --enable-shared=no \
+ --disable-doc
+
define Host/Install
- $(MAKE) -C $(HOST_BUILD_DIR) install xzlinks="unxz xzcat"
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) install xzlinks="unxz xzcat"
endef
$(eval $(call HostBuild))
diff --git a/tools/yaffs2/Makefile b/tools/yaffs2/Makefile
deleted file mode 100644
index 344b61a2c86..00000000000
--- a/tools/yaffs2/Makefile
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Copyright (C) 2008 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=yaffs2_android
-PKG_VERSION:=2008-12-18
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
-PKG_SOURCE_URL:=git://android.git.kernel.org/platform/external/yaffs2.git
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_SUBDIR:=$(PKG_NAME)
-PKG_SOURCE_VERSION:=d333fc232d7e5ae3370080d5d6f7d88ea9c6b3a1
-HOST_BUILD_DIR=$(BUILD_DIR_HOST)/$(PKG_NAME)
-
-include $(INCLUDE_DIR)/host-build.mk
-
-define Host/Compile
- $(MAKE) -C $(HOST_BUILD_DIR)/yaffs2/utils \
- CFLAGS="$(HOST_CFLAGS) -include endian.h" \
- mkyaffs2image
-endef
-
-define Host/Install
- $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
- $(INSTALL_BIN) $(HOST_BUILD_DIR)/yaffs2/utils/mkyaffs2image $(STAGING_DIR_HOST)/bin/
-endef
-
-define Host/Clean
- rm -f $(STAGING_DIR_HOST)/bin/mkyaffs2image
-endef
-
-$(eval $(call HostBuild))
diff --git a/tools/yaffs2/patches/100-compile.patch b/tools/yaffs2/patches/100-compile.patch
deleted file mode 100644
index 2f83e1fff2d..00000000000
--- a/tools/yaffs2/patches/100-compile.patch
+++ /dev/null
@@ -1,125 +0,0 @@
---- a/yaffs2/utils/Makefile
-+++ b/yaffs2/utils/Makefile
-@@ -16,12 +16,11 @@
-
- #KERNELDIR = /usr/src/kernel-headers-2.4.18
-
--CFLAGS = -I/usr/include -I.. -O2 -Wall -DCONFIG_YAFFS_UTIL
--CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
--CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
-+CPPFLAGS = -I.. -DCONFIG_YAFFS_UTIL
-+CFLAGS = -O2
-
- ## Change if you are using a cross-compiler
--MAKETOOLS =
-+MAKETOOLS =
-
- CC=$(MAKETOOLS)gcc
-
-@@ -41,7 +40,7 @@ $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS
- ln -s ../$@ $@
-
- $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) : %.o: %.c
-- $(CC) -c $(CFLAGS) $< -o $@
-+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
-
- mkyaffsimage: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS)
- $(CC) -o $@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS)
---- a/yaffs2/utils/mkyaffs2image.c
-+++ b/yaffs2/utils/mkyaffs2image.c
-@@ -32,8 +32,6 @@
- #include <string.h>
- #include <unistd.h>
-
--#include <private/android_filesystem_config.h>
--
- #include "yaffs_ecc.h"
- #include "yaffs_guts.h"
-
-@@ -69,10 +67,12 @@ static int outFile;
-
- static int error;
-
--#ifdef HAVE_BIG_ENDIAN
-+#if BYTE_ORDER == BIG_ENDIAN
- static int convert_endian = 1;
--#elif defined(HAVE_LITTLE_ENDIAN)
-+#elif BYTE_ORDER == LITTLE_ENDIAN
- static int convert_endian = 0;
-+#else
-+#error Unknown endian type
- #endif
-
- static int obj_compare(const void *a, const void * b)
-@@ -298,8 +298,8 @@ static int write_object_header(int objId
-
- static void fix_stat(const char *path, struct stat *s)
- {
-- path += source_path_len;
-- fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode);
-+ s->st_uid = 0;
-+ s->st_gid = 0;
- }
-
- static int process_directory(int parent, const char *path, int fixstats)
-@@ -342,9 +342,8 @@ static int process_directory(int parent,
- newObj = obj_id++;
- nObjects++;
-
-- if (fixstats) {
-+ if (fixstats)
- fix_stat(full_name, &stats);
-- }
-
- //printf("Object %d, %s is a ",newObj,full_name);
-
-@@ -473,13 +472,13 @@ int main(int argc, char *argv[])
- fprintf(stderr," -f fix file stat (mods, user, group) for device\n");
- fprintf(stderr," dir the directory tree to be converted\n");
- fprintf(stderr," image_file the output file to hold the image\n");
-- fprintf(stderr," 'convert' produce a big-endian image from a little-endian machine\n");
-+ fprintf(stderr," 'convert' produce a big-endian image\n");
- exit(1);
- }
-
- if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert"))))
- {
-- convert_endian = 1;
-+ convert_endian = !convert_endian;
- }
-
- if(stat(argv[1],&stats) < 0)
-@@ -503,20 +502,9 @@ int main(int argc, char *argv[])
- exit(1);
- }
-
-- if (fixstats) {
-- int len = strlen(argv[1]);
--
-- if((len >= 4) && (!strcmp(argv[1] + len - 4, "data"))) {
-- source_path_len = len - 4;
-- } else if((len >= 7) && (!strcmp(argv[1] + len - 6, "system"))) {
-- source_path_len = len - 6;
-- } else {
-- fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n");
-- exit(1);
-- }
-+ if (fixstats)
- fix_stat(argv[1], &stats);
-- }
--
-+
- //printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
- error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
- if(error)
---- a/yaffs2/devextras.h
-+++ b/yaffs2/devextras.h
-@@ -37,7 +37,7 @@ typedef unsigned char __u8;
- typedef unsigned short __u16;
- typedef unsigned __u32;
-
--#if defined(__APPLE__)
-+#if defined(__APPLE__) || defined(__FreeBSD__)
- typedef long long loff_t;
- #endif
-
diff --git a/tools/zlib/Makefile b/tools/zlib/Makefile
new file mode 100644
index 00000000000..279851f758d
--- /dev/null
+++ b/tools/zlib/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zlib
+PKG_VERSION:=1.2.11
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/libpng http://www.zlib.net
+PKG_HASH:=4ff941449631ace0d4d203e3483be9dbc9da454084111f97ea0a2114e19bf066
+
+PKG_LICENSE:=Zlib
+PKG_LICENSE_FILES:=README
+PKG_CPE_ID:=cpe:/a:gnu:zlib
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+HOST_CFLAGS +=-fPIC
+
+define Host/Install
+ $(CP) $(HOST_BUILD_DIR)/libz.a $(STAGING_DIR_HOST)/lib/
+ $(CP) $(HOST_BUILD_DIR)/zconf.h $(STAGING_DIR_HOST)/include/
+ $(CP) $(HOST_BUILD_DIR)/zlib.h $(STAGING_DIR_HOST)/include/
+ $(CP) $(HOST_BUILD_DIR)/zlib.pc $(STAGING_DIR_HOST)/lib/pkgconfig/
+endef
+
+define Host/Clean
+ rm -f $(STAGING_DIR_HOST)/lib/libz.a
+ rm -f $(STAGING_DIR_HOST)/include/zconf.h
+ rm -f $(STAGING_DIR_HOST)/include/zlib.h
+ rm -f $(STAGING_DIR_HOST)/lib/pkgconfig//zlib.pc
+endef
+
+$(eval $(call HostBuild))
diff --git a/tools/zlib/patches/900-overridable-pc-exec-prefix.patch b/tools/zlib/patches/900-overridable-pc-exec-prefix.patch
new file mode 100644
index 00000000000..4f1e376c909
--- /dev/null
+++ b/tools/zlib/patches/900-overridable-pc-exec-prefix.patch
@@ -0,0 +1,14 @@
+--- a/zlib.pc.cmakein
++++ b/zlib.pc.cmakein
+@@ -1,8 +1,8 @@
+ prefix=@CMAKE_INSTALL_PREFIX@
+ exec_prefix=@CMAKE_INSTALL_PREFIX@
+-libdir=@INSTALL_LIB_DIR@
+-sharedlibdir=@INSTALL_LIB_DIR@
+-includedir=@INSTALL_INC_DIR@
++libdir=${prefix}/lib
++sharedlibdir=${prefix}/lib
++includedir=${prefix}/include
+
+ Name: zlib
+ Description: zlib compression library