Browse Source

first commit

Votre Nom 2 years ago
commit
2f76d8f3a7
100 changed files with 11026 additions and 0 deletions
  1. 7 0
      BSDmakefile
  2. 34 0
      Config.in
  3. 340 0
      LICENSE
  4. 92 0
      Makefile
  5. 35 0
      README
  6. 296 0
      config/Config-build.in
  7. 112 0
      config/Config-devel.in
  8. 315 0
      config/Config-images.in
  9. 632 0
      config/Config-kernel.in
  10. 15 0
      docs/.gitignore
  11. 48 0
      docs/Makefile
  12. 590 0
      docs/adding.tex
  13. 52 0
      docs/bugs.tex
  14. 594 0
      docs/build.tex
  15. 101 0
      docs/config.tex
  16. 61 0
      docs/debugging.tex
  17. 60 0
      docs/init-scripts.tex
  18. 55 0
      docs/network-scripts.tex
  19. 231 0
      docs/network.tex
  20. 10 0
      docs/openwrt.sty
  21. 41 0
      docs/openwrt.tex
  22. 53 0
      docs/submitting-patches.tex
  23. 492 0
      docs/wireless.tex
  24. 112 0
      docs/working.tex
  25. 8 0
      feeds.conf.default
  26. 170 0
      include/autotools.mk
  27. 105 0
      include/cmake.mk
  28. 51 0
      include/debug.mk
  29. 48 0
      include/depends.mk
  30. 5 0
      include/device_table.txt
  31. 209 0
      include/download.mk
  32. 39 0
      include/feeds.mk
  33. 50 0
      include/hardening.mk
  34. 200 0
      include/host-build.mk
  35. 51 0
      include/host.mk
  36. 615 0
      include/image.mk
  37. 147 0
      include/kernel-build.mk
  38. 179 0
      include/kernel-defaults.mk
  39. 25 0
      include/kernel-version.mk
  40. 243 0
      include/kernel.mk
  41. 382 0
      include/netfilter.mk
  42. 40 0
      include/nls.mk
  43. 33 0
      include/package-bin.mk
  44. 162 0
      include/package-defaults.mk
  45. 91 0
      include/package-dumpinfo.mk
  46. 236 0
      include/package-ipkg.mk
  47. 15 0
      include/package-seccomp.mk
  48. 309 0
      include/package.mk
  49. 170 0
      include/prereq-build.mk
  50. 108 0
      include/prereq.mk
  51. 171 0
      include/quilt.mk
  52. 19 0
      include/scan.awk
  53. 102 0
      include/scan.mk
  54. 23 0
      include/scons.mk
  55. 37 0
      include/shell.sh
  56. 30 0
      include/site/aarch64
  57. 30 0
      include/site/aarch64_be
  58. 30 0
      include/site/arc
  59. 30 0
      include/site/arm
  60. 30 0
      include/site/armeb
  61. 3 0
      include/site/i386
  62. 30 0
      include/site/i486
  63. 3 0
      include/site/i686
  64. 78 0
      include/site/linux
  65. 28 0
      include/site/m68k
  66. 30 0
      include/site/mips
  67. 30 0
      include/site/mips64
  68. 30 0
      include/site/mips64el
  69. 30 0
      include/site/mipsel
  70. 30 0
      include/site/powerpc
  71. 30 0
      include/site/sparc
  72. 30 0
      include/site/x86_64
  73. 92 0
      include/subdir.mk
  74. 307 0
      include/target.mk
  75. 25 0
      include/toolchain-build.mk
  76. 239 0
      include/toplevel.mk
  77. 16 0
      include/uclibc++.mk
  78. 81 0
      include/unpack.mk
  79. 67 0
      include/verbose.mk
  80. 93 0
      include/version.mk
  81. 196 0
      package/Makefile
  82. 190 0
      package/base-files/Makefile
  83. 14 0
      package/base-files/files/bin/board_detect
  84. 362 0
      package/base-files/files/bin/config_generate
  85. 71 0
      package/base-files/files/bin/ipcalc.sh
  86. 13 0
      package/base-files/files/etc/banner
  87. 13 0
      package/base-files/files/etc/banner.failsafe
  88. 17 0
      package/base-files/files/etc/board.d/99-default_network
  89. 12 0
      package/base-files/files/etc/config/system
  90. 4 0
      package/base-files/files/etc/device_info
  91. 4 0
      package/base-files/files/etc/diag.sh
  92. 10 0
      package/base-files/files/etc/group
  93. 5 0
      package/base-files/files/etc/hosts
  94. 9 0
      package/base-files/files/etc/hotplug.d/net/00-sysctl
  95. 61 0
      package/base-files/files/etc/init.d/boot
  96. 17 0
      package/base-files/files/etc/init.d/done
  97. 42 0
      package/base-files/files/etc/init.d/gpio_switch
  98. 109 0
      package/base-files/files/etc/init.d/led
  99. 9 0
      package/base-files/files/etc/init.d/sysctl
  100. 25 0
      package/base-files/files/etc/init.d/sysfixtime

+ 7 - 0
BSDmakefile

@@ -0,0 +1,7 @@
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+world ${.TARGETS}:
+	@gmake $@

+ 34 - 0
Config.in

@@ -0,0 +1,34 @@
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+mainmenu "OpenWrt Configuration"
+
+config MODULES
+	option modules
+	bool
+	default y
+
+config HAVE_DOT_CONFIG
+	bool
+	default y
+
+source "target/Config.in"
+
+source "config/Config-images.in"
+
+source "config/Config-build.in"
+
+source "config/Config-devel.in"
+
+source "toolchain/Config.in"
+
+source "target/imagebuilder/Config.in"
+
+source "target/sdk/Config.in"
+
+source "target/toolchain/Config.in"
+
+source "tmp/.config-package.in"

+ 340 - 0
LICENSE

@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.

+ 92 - 0
Makefile

@@ -0,0 +1,92 @@
+# Makefile for OpenWrt
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+TOPDIR:=${CURDIR}
+LC_ALL:=C
+LANG:=C
+TZ:=UTC
+export TOPDIR LC_ALL LANG TZ
+
+empty:=
+space:= $(empty) $(empty)
+$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt directory must not include any spaces))
+
+world:
+
+include $(TOPDIR)/include/host.mk
+
+ifneq ($(OPENWRT_BUILD),1)
+  _SINGLE=export MAKEFLAGS=$(space);
+
+  override OPENWRT_BUILD=1
+  export OPENWRT_BUILD
+  GREP_OPTIONS=
+  export GREP_OPTIONS
+  include $(TOPDIR)/include/debug.mk
+  include $(TOPDIR)/include/depends.mk
+  include $(TOPDIR)/include/toplevel.mk
+else
+  include rules.mk
+  include $(INCLUDE_DIR)/depends.mk
+  include $(INCLUDE_DIR)/subdir.mk
+  include target/Makefile
+  include package/Makefile
+  include tools/Makefile
+  include toolchain/Makefile
+
+$(toolchain/stamp-install): $(tools/stamp-install)
+$(target/stamp-compile): $(toolchain/stamp-install) $(tools/stamp-install) $(BUILD_DIR)/.prepared
+$(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
+$(package/stamp-install): $(package/stamp-compile)
+$(target/stamp-install): $(package/stamp-compile) $(package/stamp-install)
+
+printdb:
+	@true
+
+prepare: $(target/stamp-compile)
+
+clean: FORCE
+	rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(BUILD_LOG_DIR)
+
+dirclean: clean
+	rm -rf $(STAGING_DIR_HOST) $(TOOLCHAIN_DIR) $(BUILD_DIR_HOST) $(BUILD_DIR_TOOLCHAIN)
+	rm -rf $(TMP_DIR)
+
+ifndef DUMP_TARGET_DB
+$(BUILD_DIR)/.prepared: Makefile
+	@mkdir -p $$(dirname $@)
+	@touch $@
+
+tmp/.prereq_packages: .config
+	unset ERROR; \
+	for package in $(sort $(prereq-y) $(prereq-m)); do \
+		$(_SINGLE)$(NO_TRACE_MAKE) -s -r -C package/$$package prereq || ERROR=1; \
+	done; \
+	if [ -n "$$ERROR" ]; then \
+		echo "Package prerequisite check failed."; \
+		false; \
+	fi
+	touch $@
+endif
+
+# check prerequisites before starting to build
+prereq: $(target/stamp-prereq) tmp/.prereq_packages
+	@if [ ! -f "$(INCLUDE_DIR)/site/$(ARCH)" ]; then \
+		echo 'ERROR: Missing site config for architecture "$(ARCH)" !'; \
+		echo '       The missing file will cause configure scripts to fail during compilation.'; \
+		echo '       Please provide a "$(INCLUDE_DIR)/site/$(ARCH)" file and restart the build.'; \
+		exit 1; \
+	fi
+
+prepare: .config $(tools/stamp-install) $(toolchain/stamp-install)
+world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
+	$(_SINGLE)$(SUBMAKE) -r package/index
+
+.PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean
+
+endif

+ 35 - 0
README

@@ -0,0 +1,35 @@
+This is the buildsystem for the OpenWrt Linux distribution.
+
+Please use "make menuconfig" to configure your appreciated
+configuration for the toolchain and firmware.
+
+You need to have installed gcc, binutils, bzip2, flex, python, perl, make,
+find, grep, diff, unzip, gawk, getopt, subversion, libz-dev and libc headers.
+
+Run "./scripts/feeds update -a" to get all the latest package definitions
+defined in feeds.conf / feeds.conf.default respectively
+and "./scripts/feeds install -a" to install symlinks of all of them into
+package/feeds/.
+
+Use "make menuconfig" to configure your image.
+
+Simply running "make" will build your firmware.
+It will download all sources, build the cross-compile toolchain, 
+the kernel and all choosen applications.
+
+You can use "scripts/flashing/flash.sh" for remotely updating your embedded
+system via tftp.
+
+The OpenWrt system is documented in docs/. You will need a LaTeX distribution
+and the tex4ht package to build the documentation. Type "make -C docs/" to build it.
+
+To build your own firmware you need to have access to a Linux, BSD or MacOSX system
+(case-sensitive filesystem required). Cygwin will not be supported because of
+the lack of case sensitiveness in the file system.
+
+
+Sunshine!
+	Your OpenWrt Project
+	http://openwrt.org
+
+

+ 296 - 0
config/Config-build.in

@@ -0,0 +1,296 @@
+# Copyright (C) 2006-2013 OpenWrt.org
+# Copyright (C) 2016 LEDE Project
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+menu "Global build settings"
+
+	config ALL_NONSHARED
+		bool "Select all target specific packages by default"
+		default ALL
+
+	config ALL_KMODS
+		bool "Select all kernel module packages by default"
+		default ALL
+
+	config ALL
+		bool "Select all userspace packages by default"
+		default n
+
+	config SIGNED_PACKAGES
+		bool "Cryptographically signed package lists"
+		default y
+
+	comment "General build options"
+
+	config DISPLAY_SUPPORT
+		bool "Show packages that require graphics support (local or remote)"
+		default n
+
+	config BUILD_PATENTED
+		default y
+		bool "Compile with support for patented functionality"
+		help
+		  When this option is disabled, software which provides patented functionality
+		  will not be built.  In case software provides optional support for patented
+		  functionality, this optional support will get disabled for this package.
+
+	config BUILD_NLS
+		default n
+		bool "Compile with full language support"
+		help
+		  When this option is enabled, packages are built with the full versions of
+		  iconv and GNU gettext instead of the default OpenWrt stubs. If uClibc is
+		  used, it is also built with locale support.
+
+	config SHADOW_PASSWORDS
+		bool
+		prompt "Enable shadow password support"
+		default y
+		help
+		  Enable shadow password support.
+
+	config CLEAN_IPKG
+		bool
+		prompt "Remove ipkg/opkg status data files in final images"
+		default n
+		help
+		  This removes all ipkg/opkg status data files from the target directory
+		  before building the root filesystem.
+
+	config COLLECT_KERNEL_DEBUG
+		bool
+		prompt "Collect kernel debug information"
+		select KERNEL_DEBUG_INFO
+		default n
+		help
+		  This collects debugging symbols from the kernel and all compiled modules.
+		  Useful for release builds, so that kernel issues can be debugged offline
+		  later.
+
+	comment "Kernel build options"
+
+	source "config/Config-kernel.in"
+
+	comment "Package build options"
+
+	config DEBUG
+		bool
+		prompt "Compile packages with debugging info"
+		default n
+		help
+		  Adds -g3 to the CFLAGS.
+
+	config IPV6
+		bool
+		prompt "Enable IPv6 support in packages"
+		default y
+		help
+		  Enables IPv6 support in kernel (builtin) and packages.
+
+	config PKG_BUILD_PARALLEL
+		bool
+		prompt "Compile certain packages parallelized"
+		default y
+		help
+		  This adds a -jX option to certain packages that are known to behave well
+		  for parallel build. By default, the package make processes use the main
+		  jobserver, in which case this option only takes effect when you add -jX
+		  to the make command.
+
+		  If you are unsure, select N.
+
+	config PKG_BUILD_USE_JOBSERVER
+		bool
+		prompt "Use top-level make jobserver for packages"
+		depends on PKG_BUILD_PARALLEL
+		default y
+		help
+		  This passes the main make process jobserver fds to package builds,
+		  enabling full parallelization across different packages.
+
+		  Note that disabling this may overcommit CPU resources depending on the
+		  -j level of the main make process, the number of package submake jobs
+		  selected below and the number of actual CPUs present.
+		  Example: If the main make is passed a -j4 and the submake -j
+		  is also set to 4, we may end up with 16 parallel make processes
+		  in the worst case.
+
+	config PKG_BUILD_JOBS
+		int
+		prompt "Number of package submake jobs (2-512)"
+		range 2 512
+		default 2
+		depends on PKG_BUILD_PARALLEL && !PKG_BUILD_USE_JOBSERVER
+		help
+		  The number of jobs (-jX) to pass to packages submake.
+
+	config PKG_DEFAULT_PARALLEL
+		bool
+		prompt "Parallelize the default package build rule (May break build)"
+		depends on PKG_BUILD_PARALLEL
+		depends on BROKEN
+		default n
+		help
+		  Always set the default package build rules to parallel build.
+
+		  WARNING: This may break build or kill your cat, as it builds packages
+		  with multiple jobs that are probably not tested in a parallel build
+		  environment.
+
+		  Only say Y if you don't mind fixing broken packages.  Before reporting
+		  build bugs, set this to N and re-run the build.
+
+	comment "Stripping options"
+
+	choice
+		prompt "Binary stripping method"
+		default USE_STRIP   if EXTERNAL_TOOLCHAIN
+		default USE_STRIP   if USE_GLIBC
+		default USE_SSTRIP
+		help
+		  Select the binary stripping method you wish to use.
+
+		config NO_STRIP
+			bool "none"
+			help
+			  This will install unstripped binaries (useful for native
+			  compiling/debugging).
+
+		config USE_STRIP
+			bool "strip"
+			help
+			  This will install binaries stripped using strip from binutils.
+
+
+		config USE_SSTRIP
+			bool "sstrip"
+			depends on !USE_GLIBC
+			help
+			  This will install binaries stripped using sstrip.
+	endchoice
+
+	config STRIP_ARGS
+		string
+		prompt "Strip arguments"
+		depends on USE_STRIP
+		default "--strip-unneeded --remove-section=.comment --remove-section=.note" if DEBUG
+		default "--strip-all"
+		help
+		  Specifies arguments passed to the strip command when stripping binaries.
+
+	config STRIP_KERNEL_EXPORTS
+		bool "Strip unnecessary exports from the kernel image"
+		help
+		  Reduces kernel size by stripping unused kernel exports from the kernel
+		  image.  Note that this might make the kernel incompatible with any kernel
+		  modules that were not selected at the time the kernel image was created.
+
+	config USE_MKLIBS
+		bool "Strip unnecessary functions from libraries"
+		help
+		  Reduces libraries to only those functions that are necessary for using all
+		  selected packages (including those selected as <M>).  Note that this will
+		  make the system libraries incompatible with most of the packages that are
+		  not selected during the build process.
+
+	choice
+		prompt "Preferred standard C++ library"
+		default USE_LIBSTDCXX if USE_GLIBC
+		default USE_UCLIBCXX
+		help
+		  Select the preferred standard C++ library for all packages that support this.
+
+		config USE_UCLIBCXX
+			bool "uClibc++"
+
+		config USE_LIBSTDCXX
+			bool "libstdc++"
+	endchoice
+
+	comment "Hardening build options"
+
+	config PKG_CHECK_FORMAT_SECURITY
+		bool
+		prompt "Enable gcc format-security"
+		default y
+		help
+		  Add -Wformat -Werror=format-security to the CFLAGS.  You can disable
+		  this per package by adding PKG_CHECK_FORMAT_SECURITY:=0 in the package
+		  Makefile.
+
+	choice
+		prompt "User space Stack-Smashing Protection"
+		depends on USE_MUSL
+		default PKG_CC_STACKPROTECTOR_REGULAR
+		help
+		  Enable GCC Stack Smashing Protection (SSP) for userspace applications
+		config PKG_CC_STACKPROTECTOR_NONE
+			bool "None"
+		config PKG_CC_STACKPROTECTOR_REGULAR
+			bool "Regular"
+			select SSP_SUPPORT if !USE_MUSL
+			depends on KERNEL_CC_STACKPROTECTOR_REGULAR
+		config PKG_CC_STACKPROTECTOR_STRONG
+			bool "Strong"
+			select SSP_SUPPORT if !USE_MUSL
+			depends on GCC_VERSION_5
+			depends on KERNEL_CC_STACKPROTECTOR_STRONG
+	endchoice
+
+	choice
+		prompt "Kernel space Stack-Smashing Protection"
+		default KERNEL_CC_STACKPROTECTOR_REGULAR
+		depends on USE_MUSL || !(x86_64 || i386)
+		help
+		  Enable GCC Stack-Smashing Protection (SSP) for the kernel
+		config KERNEL_CC_STACKPROTECTOR_NONE
+			bool "None"
+		config KERNEL_CC_STACKPROTECTOR_REGULAR
+			bool "Regular"
+		config KERNEL_CC_STACKPROTECTOR_STRONG
+			depends on GCC_VERSION_5
+			bool "Strong"
+	endchoice
+
+	choice
+		prompt "Enable buffer-overflows detection (FORTIFY_SOURCE)"
+		default PKG_FORTIFY_SOURCE_1
+		help
+		  Enable the _FORTIFY_SOURCE macro which introduces additional
+		  checks to detect buffer-overflows in the following standard library
+		  functions: memcpy, mempcpy, memmove, memset, strcpy, stpcpy,
+		  strncpy, strcat, strncat, sprintf, vsprintf, snprintf, vsnprintf,
+		  gets.  "Conservative" (_FORTIFY_SOURCE set to 1) only introduces
+		  checks that shouldn't change the behavior of conforming programs,
+		  while "aggressive" (_FORTIFY_SOURCES set to 2) some more checking is
+		  added, but some conforming programs might fail.
+		config PKG_FORTIFY_SOURCE_NONE
+			bool "None"
+		config PKG_FORTIFY_SOURCE_1
+			bool "Conservative"
+		config PKG_FORTIFY_SOURCE_2
+			bool "Aggressive"
+	endchoice
+
+	choice
+		prompt "Enable RELRO protection"
+		default PKG_RELRO_FULL
+		help
+		  Enable a link-time protection known as RELRO (Relocation Read Only)
+		  which helps to protect from certain type of exploitation techniques
+		  altering the content of some ELF sections. "Partial" RELRO makes the
+		  .dynamic section not writeable after initialization, introducing
+		  almost no performance penalty, while "full" RELRO also marks the GOT
+		  as read-only at the cost of initializing all of it at startup.
+		config PKG_RELRO_NONE
+			bool "None"
+		config PKG_RELRO_PARTIAL
+			bool "Partial"
+		config PKG_RELRO_FULL
+			bool "Full"
+	endchoice
+
+endmenu

+ 112 - 0
config/Config-devel.in

@@ -0,0 +1,112 @@
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+menuconfig DEVEL
+	bool "Advanced configuration options (for developers)"
+	default n
+
+	config BROKEN
+		bool "Show broken platforms / packages" if DEVEL
+		default n
+
+	config BINARY_FOLDER
+		string "Binary folder" if DEVEL
+		default ""
+		help
+		  Store built firmware images and filesystem images in this directory.
+		  If not set, uses './bin/$(BOARD)'
+
+	config DOWNLOAD_FOLDER
+		string "Download folder" if DEVEL
+		default ""
+		help
+		  Store downloaded source bundles in this directory.
+		  If not set then defaults to './dl', which is removed by operations such as
+		  'git clean -xdf' or 'make distclean'.
+		  This option is useful if you have a low bandwidth Internet connection, and by
+		  setting a path outside the OpenWrt tree downloads will be saved.
+
+	config LOCALMIRROR
+		string "Local mirror for source packages" if DEVEL
+		default ""
+
+	config AUTOREBUILD
+		bool "Automatic rebuild of packages" if DEVEL
+		default y
+		help
+		  Automatically rebuild packages when their files change.
+
+	config BUILD_SUFFIX
+		string "Build suffix to append to the target BUILD_DIR variable" if DEVEL
+		default ""
+		help
+		  Build suffix to append to the BUILD_DIR variable, i.e: './build_dir/{target-build-dir}_$(BUILD_SUFFIX)'.
+		  This allows you to switch to a different .config whilst retaining all the build
+		  objects generated by the first .config
+
+	config TARGET_ROOTFS_DIR
+		string "Override the default TARGET_ROOTFS_DIR variable" if DEVEL
+		default ""
+		help
+		  Override the default TARGET_ROOTFS_DIR variable content $(BUILD_DIR) with
+		  custom path.  Use this option to re-define the location of the target
+		  root filesystem directory.
+
+	config CCACHE
+		bool "Use ccache" if DEVEL
+		default n
+		help
+		  Compiler cache; see https://ccache.samba.org/.
+
+	config EXTERNAL_KERNEL_TREE
+		string "Use external kernel tree" if DEVEL
+		default ""
+
+	config KERNEL_GIT_CLONE_URI
+		string "Enter git repository to clone" if DEVEL
+		default ""
+		help
+		  Enter the full git repository path i.e.:
+		  git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+		  This will create a git clone of the kernel in your build directory.
+
+	config KERNEL_GIT_LOCAL_REPOSITORY
+		string "Enter path to local reference repository" if DEVEL
+		depends on (KERNEL_GIT_CLONE_URI != "")
+		default ""
+		help
+		  Enter a full pathname to a local reference git repository.
+		  In this instance, the --reference option of git clone will
+		  be used thus creating a quick local clone of your repo.
+
+	config KERNEL_GIT_BRANCH
+		string "Enter git branch to clone" if DEVEL
+		depends on (KERNEL_GIT_CLONE_URI != "")
+		default ""
+		help
+		  Enter the branch name to checkout after cloning the git repository.
+		  In this instance, the --branch option of git clone will be used.
+		  If unused, the clone's repository HEAD will be checked-out.
+
+	config BUILD_LOG
+		bool "Enable log files during build process" if DEVEL
+		help
+		  If enabled, log files will be written to the ./log directory.
+
+	config SRC_TREE_OVERRIDE
+		bool "Enable package source tree override" if DEVEL
+		help
+		  If enabled, you can force a package to use a git tree as source
+		  code instead of the normal tarball. Create a symlink 'git-src'
+		  in the package directory, pointing to the .git tree that you want
+		  to pull the source code from.
+
+	config EXTRA_OPTIMIZATION
+		string "Additional compiler options" if DEVEL
+		default "-fno-caller-saves -fno-plt" if !CONFIG_EXTERNAL_TOOLCHAIN && !arc
+		default "-fno-caller-saves"
+		help
+		  Extra target-independent optimizations to use when building for the target.

+ 315 - 0
config/Config-images.in

@@ -0,0 +1,315 @@
+# Copyright (C) 2006-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+menu "Target Images"
+
+	menuconfig TARGET_ROOTFS_INITRAMFS
+		bool "ramdisk"
+		default y if USES_INITRAMFS
+		help
+		  Embed the root filesystem into the kernel (initramfs).
+
+		choice
+			prompt "Compression"
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ar71xx
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ramips
+			default TARGET_INITRAMFS_COMPRESSION_NONE
+			depends on TARGET_ROOTFS_INITRAMFS
+			help
+			  Select ramdisk compression.
+
+			config TARGET_INITRAMFS_COMPRESSION_NONE
+				bool "none"
+
+			config TARGET_INITRAMFS_COMPRESSION_GZIP
+				bool "gzip"
+
+			config TARGET_INITRAMFS_COMPRESSION_BZIP2
+				bool "bzip2"
+
+			config TARGET_INITRAMFS_COMPRESSION_LZMA
+				bool "lzma"
+
+			config TARGET_INITRAMFS_COMPRESSION_LZO
+				bool "lzo"
+
+			config TARGET_INITRAMFS_COMPRESSION_LZ4
+				bool "lz4"
+
+			config TARGET_INITRAMFS_COMPRESSION_XZ
+				bool "xz"
+		endchoice
+
+		config EXTERNAL_CPIO
+			string
+			prompt "Use external cpio" if TARGET_ROOTFS_INITRAMFS
+			default ""
+			help
+			  Kernel uses specified external cpio as INITRAMFS_SOURCE.
+
+	comment "Root filesystem archives"
+
+	config TARGET_ROOTFS_CPIOGZ
+		bool "cpio.gz"
+		default y if USES_CPIOGZ
+		help
+		  Build a compressed cpio archive of the root filesystem.
+
+	config TARGET_ROOTFS_TARGZ
+		bool "tar.gz"
+		default y if USES_TARGZ
+		help
+		  Build a compressed tar archive of the root filesystem.
+
+	comment "Root filesystem images"
+
+	menuconfig TARGET_ROOTFS_EXT4FS
+		bool "ext4"
+		default y if USES_EXT4
+		help
+		  Build an ext4 root filesystem.
+
+		config TARGET_EXT4_MAXINODE
+			int "Maximum number of inodes in root filesystem"
+			depends on TARGET_ROOTFS_EXT4FS
+			default 6000
+			help
+			  Select the maximum number of inodes in the root filesystem.
+
+		config TARGET_EXT4_RESERVED_PCT
+			int "Percentage of reserved blocks in root filesystem"
+			depends on TARGET_ROOTFS_EXT4FS
+			default 0
+			help
+			  Select the percentage of reserved blocks in the root filesystem.
+
+		choice
+			prompt "Root filesystem block size"
+			default TARGET_EXT4_BLOCKSIZE_4K
+			depends on TARGET_ROOTFS_EXT4FS
+			help
+			  Select the block size of the root filesystem.
+
+			config TARGET_EXT4_BLOCKSIZE_4K
+				bool "4k"
+
+			config TARGET_EXT4_BLOCKSIZE_2K
+				bool "2k"
+
+			config TARGET_EXT4_BLOCKSIZE_1K
+				bool "1k"
+		endchoice
+
+		config TARGET_EXT4_BLOCKSIZE
+			int
+			default 4096 if TARGET_EXT4_BLOCKSIZE_4K
+			default 2048 if TARGET_EXT4_BLOCKSIZE_2K
+			default 1024 if TARGET_EXT4_BLOCKSIZE_1K
+			depends on TARGET_ROOTFS_EXT4FS
+
+		config TARGET_EXT4_JOURNAL
+			bool "Create a journaling filesystem"
+			depends on TARGET_ROOTFS_EXT4FS
+			default n
+			help
+			  Create an ext4 filesystem with a journal.
+
+	config TARGET_ROOTFS_ISO
+		bool "iso"
+		default n
+		depends on TARGET_x86_generic
+		help
+		  Create a bootable ISO image.
+
+	config TARGET_ROOTFS_JFFS2
+		bool "jffs2"
+		default y if USES_JFFS2
+		help
+		  Build a JFFS2 root filesystem.
+
+	config TARGET_ROOTFS_JFFS2_NAND
+		bool "jffs2 for NAND"
+		default y if USES_JFFS2_NAND
+		depends on USES_JFFS2_NAND
+		help
+		  Build a JFFS2 root filesystem for NAND flash.
+
+	menuconfig TARGET_ROOTFS_SQUASHFS
+		bool "squashfs"
+		default y if USES_SQUASHFS
+		help
+		  Build a squashfs-lzma root filesystem.
+
+		config TARGET_SQUASHFS_BLOCK_SIZE
+			int "Block size (in KiB)"
+			depends on TARGET_ROOTFS_SQUASHFS
+			default 64 if LOW_MEMORY_FOOTPRINT
+			default 256
+
+	menuconfig TARGET_ROOTFS_UBIFS
+		bool "ubifs"
+		default y if USES_UBIFS
+		depends on USES_UBIFS
+		help
+		  Build a UBIFS root filesystem.
+
+		choice
+			prompt "compression"
+			default TARGET_UBIFS_COMPRESSION_ZLIB
+			depends on TARGET_ROOTFS_UBIFS
+			help
+			  Select compression type
+
+			config TARGET_UBIFS_COMPRESSION_NONE
+				bool "none"
+
+			config TARGET_UBIFS_COMPRESSION_LZO
+				bool "lzo"
+
+			config TARGET_UBIFS_COMPRESSION_ZLIB
+				bool "zlib"
+		endchoice
+
+		config TARGET_UBIFS_FREE_SPACE_FIXUP
+			bool "free space fixup" if TARGET_ROOTFS_UBIFS
+			default y
+			help
+			  The filesystem free space has to be fixed up on first mount.
+
+		config TARGET_UBIFS_JOURNAL_SIZE
+			string
+			prompt "journal size" if TARGET_ROOTFS_UBIFS
+			default ""
+
+	config GRUB_IMAGES
+		bool "Build GRUB images (Linux x86 or x86_64 host only)"
+		depends on TARGET_x86_64 || (TARGET_x86 && !TARGET_x86_rdc)
+		depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
+		select PACKAGE_grub2
+		default y
+
+	config GRUB_CONSOLE
+		bool "Use Console Terminal (in addition to Serial)"
+		depends on GRUB_IMAGES
+		default n if (TARGET_x86_generic_Soekris45xx || TARGET_x86_generic_Soekris48xx || TARGET_x86_net5501 || TARGET_x86_geos || TARGET_x86_alix2)
+		default y
+
+	config GRUB_SERIAL
+		string "Serial port device"
+		depends on GRUB_IMAGES
+		default "hvc0" if TARGET_x86_xen_domu
+		default "ttyS0" if ! TARGET_x86_xen_domu
+
+	config GRUB_BAUDRATE
+		int "Serial port baud rate"
+		depends on GRUB_IMAGES
+		default 38400 if TARGET_x86_generic
+		default 38400 if TARGET_x86_geode
+		default 115200
+
+	config GRUB_BOOTOPTS
+		string "Extra kernel boot options"
+		depends on GRUB_IMAGES
+		default "xencons=hvc" if TARGET_x86_xen_domu
+		help
+		  If you don't know, just leave it blank.
+
+	config GRUB_TIMEOUT
+		string "Seconds to wait before booting the default entry"
+		depends on GRUB_IMAGES
+		default "5"
+		help
+		  If you don't know, 5 seconds is a reasonable default.
+
+	config VDI_IMAGES
+		bool "Build VirtualBox image files (VDI)"
+		depends on TARGET_x86 || TARGET_x86_64
+		select GRUB_IMAGES
+		select TARGET_IMAGES_PAD
+		select PACKAGE_kmod-e1000
+
+	config VMDK_IMAGES
+		bool "Build VMware image files (VMDK)"
+		depends on TARGET_x86 || TARGET_x86_64
+		select GRUB_IMAGES
+		select TARGET_IMAGES_PAD
+		select PACKAGE_kmod-e1000
+
+	config TARGET_IMAGES_PAD
+		bool "Pad images to filesystem size (for JFFS2)"
+		depends on GRUB_IMAGES
+
+	config TARGET_IMAGES_GZIP
+		bool "GZip images"
+		depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS
+		default y
+
+	comment "Image Options"
+
+	source "target/linux/*/image/Config.in"
+
+	config TARGET_KERNEL_PARTSIZE
+		int "Kernel partition size (in MB)"
+		depends on GRUB_IMAGES
+		default 4
+
+	config TARGET_ROOTFS_PARTSIZE
+		int "Root filesystem partition size (in MB)"
+		depends on GRUB_IMAGES || TARGET_ROOTFS_EXT4FS || TARGET_rb532
+		default 48
+		help
+		  Select the root filesystem partition size.
+
+	config TARGET_ROOTFS_PARTNAME
+		string "Root partition on target device"
+		depends on GRUB_IMAGES
+		help
+		  Override the root partition on the final device. If left empty,
+		  it will be mounted by PARTUUID which makes the kernel find the
+		  appropriate disk automatically.
+
+
+	menuconfig TARGET_ROOTFS_INCLUDE_KERNEL
+		bool "Include kernel in root filesystem"
+		depends on TARGET_ROOTFS_UBIFS || TARGET_ROOTFS_EXT4FS
+		default n
+		help
+		  Include the kernel image in the rootfs. Typically, the image is placed
+		  below /boot.
+
+		config TARGET_ROOTFS_INCLUDE_UIMAGE
+			bool "include uImage" if TARGET_ROOTFS_INCLUDE_KERNEL
+			default y
+			help
+			  This option might not apply to all targets. Make sure
+			  to check target/linux/<your_target>/image/Makefile to
+			  see if this option will have any effect.
+
+		config TARGET_ROOTFS_INCLUDE_ZIMAGE
+			bool "include zImage" if TARGET_ROOTFS_INCLUDE_KERNEL
+			default y
+			help
+			  This option might not apply to all targets. Make sure
+			  to check target/linux/<your_target>/image/Makefile to
+			  see if this option will have any effect.
+
+		config TARGET_ROOTFS_INCLUDE_FIT
+			bool "include FIT" if TARGET_ROOTFS_INCLUDE_KERNEL
+			default y
+			help
+			  This option might not apply to all targets. Make sure
+			  to check target/linux/<your_target>/image/Makefile to
+			  see if this option will have any effect.
+
+	config TARGET_ROOTFS_INCLUDE_DTB
+		bool "Include DTB in root filesystem"
+		depends on USES_DEVICETREE && (TARGET_ROOTFS_UBIFS || TARGET_ROOTFS_EXT4FS)
+		default n
+		help
+		  Include the device tree blob file(s) in the rootfs. Typically the DTBs
+		  are placed below /boot.
+
+endmenu

+ 632 - 0
config/Config-kernel.in

@@ -0,0 +1,632 @@
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+config KERNEL_BUILD_USER
+	string "Custom Kernel Build User Name"
+	default ""
+	help
+	  Sets the Kernel build user string, which for example will be returned
+	  by 'uname -a' on running systems.
+	  If not set, uses system user at build time.
+
+config KERNEL_BUILD_DOMAIN
+	string "Custom Kernel Build Domain Name"
+	default ""
+	help
+	  Sets the Kernel build domain string, which for example will be
+	  returned by 'uname -a' on running systems.
+	  If not set, uses system hostname at build time.
+
+config KERNEL_PRINTK
+	bool "Enable support for printk"
+	default y
+
+config KERNEL_CRASHLOG
+	bool "Crash logging"
+	depends on !(arm || powerpc || sparc || TARGET_uml)
+	default y
+
+config KERNEL_SWAP
+	bool "Support for paging of anonymous memory (swap)"
+	default y
+
+config KERNEL_DEBUG_FS
+	bool "Compile the kernel with debug filesystem enabled"
+	default y
+	help
+	  debugfs is a virtual file system that kernel developers use to put
+	  debugging files into. Enable this option to be able to read and
+	  write to these files. Many common debugging facilities, such as
+	  ftrace, require the existence of debugfs.
+
+config KERNEL_ARM_PMU
+	bool
+	default n
+	depends on (arm || arm64)
+
+config KERNEL_PERF_EVENTS
+	bool
+	default n
+	select KERNEL_ARM_PMU if (arm || arm64)
+
+config KERNEL_PROFILING
+	bool "Compile the kernel with profiling enabled"
+	default n
+	select KERNEL_PERF_EVENTS
+	help
+	  Enable the extended profiling support mechanisms used by profilers such
+	  as OProfile.
+
+config KERNEL_KALLSYMS
+	bool "Compile the kernel with symbol table information"
+	default y
+	help
+	  This will give you more information in stack traces from kernel oopses.
+
+config KERNEL_FTRACE
+	bool "Compile the kernel with tracing support"
+	depends on !TARGET_uml
+	default n
+
+config KERNEL_FTRACE_SYSCALLS
+	bool "Trace system calls"
+	depends on KERNEL_FTRACE
+	default n
+
+config KERNEL_ENABLE_DEFAULT_TRACERS
+	bool "Trace process context switches and events"
+	depends on KERNEL_FTRACE
+	default n
+
+config KERNEL_FUNCTION_TRACER
+	bool "Function tracer"
+	depends on KERNEL_FTRACE
+	default n
+
+config KERNEL_FUNCTION_GRAPH_TRACER
+	bool "Function graph tracer"
+	depends on KERNEL_FUNCTION_TRACER
+	default n
+
+config KERNEL_DYNAMIC_FTRACE
+	bool "Enable/disable function tracing dynamically"
+	depends on KERNEL_FUNCTION_TRACER
+	default n
+
+config KERNEL_FUNCTION_PROFILER
+	bool "Function profiler"
+	depends on KERNEL_FUNCTION_TRACER
+	default n
+
+config KERNEL_DEBUG_KERNEL
+	bool
+	default n
+
+config KERNEL_DEBUG_INFO
+	bool "Compile the kernel with debug information"
+	default y
+	select KERNEL_DEBUG_KERNEL
+	help
+	  This will compile your kernel and modules with debug information.
+
+config KERNEL_DEBUG_LL_UART_NONE
+	bool
+	default n
+	depends on arm
+
+config KERNEL_DEBUG_LL
+	bool
+	default n
+	depends on arm
+	select KERNEL_DEBUG_LL_UART_NONE
+	help
+	  ARM low level debugging.
+
+config KERNEL_DYNAMIC_DEBUG
+	bool "Compile the kernel with dynamic printk"
+	select KERNEL_DEBUG_FS
+	default n
+	help
+	  Compiles debug level messages into the kernel, which would not
+	  otherwise be available at runtime. These messages can then be
+	  enabled/disabled based on various levels of scope - per source file,
+	  function, module, format string, and line number. This mechanism
+	  implicitly compiles in all pr_debug() and dev_dbg() calls, which
+	  enlarges the kernel text size by about 2%.
+
+config KERNEL_EARLY_PRINTK
+	bool "Compile the kernel with early printk"
+	default y if TARGET_bcm53xx
+	default n
+	depends on arm
+	select KERNEL_DEBUG_KERNEL
+	select KERNEL_DEBUG_LL if arm
+	help
+	  Compile the kernel with early printk support.  This is only useful for
+	  debugging purposes to send messages over the serial console in early boot.
+	  Enable this to debug early boot problems.
+
+config KERNEL_KPROBES
+	bool "Compile the kernel with kprobes support"
+	default n
+	select KERNEL_FTRACE
+	select KERNEL_PERF_EVENTS
+	help
+	  Compiles the kernel with KPROBES support, which allows you to trap
+	  at almost any kernel address and execute a callback function.
+	  register_kprobe() establishes a probepoint and specifies the
+	  callback. Kprobes is useful for kernel debugging, non-intrusive
+	  instrumentation and testing.
+	  If in doubt, say "N".
+
+config KERNEL_KPROBE_EVENT
+	bool
+	default y if KERNEL_KPROBES
+
+config KERNEL_AIO
+	bool "Compile the kernel with asynchronous IO support"
+	default n
+
+config KERNEL_DIRECT_IO
+	bool "Compile the kernel with direct IO support"
+	default n
+
+config KERNEL_FHANDLE
+	bool "Compile the kernel with support for fhandle syscalls"
+	default n
+
+config KERNEL_FANOTIFY
+	bool "Compile the kernel with modern file notification support"
+	default n
+
+config KERNEL_BLK_DEV_BSG
+	bool "Compile the kernel with SCSI generic v4 support for any block device"
+	default n
+
+config KERNEL_MAGIC_SYSRQ
+	bool "Compile the kernel with SysRq support"
+	default y
+
+config KERNEL_COREDUMP
+	bool
+
+config KERNEL_ELF_CORE
+	bool "Enable process core dump support"
+	select KERNEL_COREDUMP
+	default y
+
+config KERNEL_PROVE_LOCKING
+	bool "Enable kernel lock checking"
+	select KERNEL_DEBUG_KERNEL
+	default n
+
+config KERNEL_PRINTK_TIME
+	bool "Enable printk timestamps"
+	default y
+
+config KERNEL_SLUB_DEBUG
+	bool
+
+config KERNEL_SLUB_DEBUG_ON
+	bool
+
+config KERNEL_SLABINFO
+	select KERNEL_SLUB_DEBUG
+	select KERNEL_SLUB_DEBUG_ON
+	bool "Enable /proc slab debug info"
+
+config KERNEL_PROC_PAGE_MONITOR
+	bool "Enable /proc page monitoring"
+
+config KERNEL_RELAY
+	bool
+
+config KERNEL_KEXEC
+	bool "Enable kexec support"
+
+config USE_RFKILL
+	bool "Enable rfkill support"
+	default RFKILL_SUPPORT
+
+config USE_SPARSE
+	bool "Enable sparse check during kernel build"
+	default n
+
+config KERNEL_DEVTMPFS
+	bool "Compile the kernel with device tmpfs enabled"
+	default n
+	help
+	  devtmpfs is a simple, kernel-managed /dev filesystem. The kernel creates
+	  devices nodes for all registered devices ti simplify boot, but leaves more
+	  complex tasks to userspace (e.g. udev).
+
+if KERNEL_DEVTMPFS
+
+	config KERNEL_DEVTMPFS_MOUNT
+		bool "Automatically mount devtmpfs after root filesystem is mounted"
+		default n
+
+endif
+
+#
+# CGROUP support symbols
+#
+
+config KERNEL_CGROUPS
+	bool "Enable kernel cgroups"
+	default n
+
+if KERNEL_CGROUPS
+
+	config KERNEL_CGROUP_DEBUG
+		bool "Example debug cgroup subsystem"
+		default n
+		help
+		  This option enables a simple cgroup subsystem that
+		  exports useful debugging information about the cgroups
+		  framework.
+
+	config KERNEL_FREEZER
+		bool
+		default y if KERNEL_CGROUP_FREEZER
+
+	config KERNEL_CGROUP_FREEZER
+		bool "Freezer cgroup subsystem"
+		default y
+		help
+		  Provides a way to freeze and unfreeze all tasks in a
+		  cgroup.
+
+	config KERNEL_CGROUP_DEVICE
+		bool "Device controller for cgroups"
+		default y
+		help
+		  Provides a cgroup implementing whitelists for devices which
+		  a process in the cgroup can mknod or open.
+
+	config KERNEL_CGROUP_PIDS
+		bool "PIDs cgroup subsystem"
+		default y
+		help
+		  Provides enforcement of process number limits in the scope of a
+		  cgroup.
+
+	config KERNEL_CPUSETS
+		bool "Cpuset support"
+		default n
+		help
+		  This option will let you create and manage CPUSETs which
+		  allow dynamically partitioning a system into sets of CPUs and
+		  Memory Nodes and assigning tasks to run only within those sets.
+		  This is primarily useful on large SMP or NUMA systems.
+
+	config KERNEL_PROC_PID_CPUSET
+		bool "Include legacy /proc/<pid>/cpuset file"
+		default n
+		depends on KERNEL_CPUSETS
+
+	config KERNEL_CGROUP_CPUACCT
+		bool "Simple CPU accounting cgroup subsystem"
+		default n
+		help
+		  Provides a simple Resource Controller for monitoring the
+		  total CPU consumed by the tasks in a cgroup.
+
+	config KERNEL_RESOURCE_COUNTERS
+		bool "Resource counters"
+		default n
+		help
+		  This option enables controller independent resource accounting
+		  infrastructure that works with cgroups.
+
+	config KERNEL_MM_OWNER
+		bool
+		default y if KERNEL_MEMCG
+
+	config KERNEL_MEMCG
+		bool "Memory Resource Controller for Control Groups"
+		default n
+		depends on KERNEL_RESOURCE_COUNTERS || !LINUX_3_18
+		help
+		  Provides a memory resource controller that manages both anonymous
+		  memory and page cache. (See Documentation/cgroups/memory.txt)
+
+		  Note that setting this option increases fixed memory overhead
+		  associated with each page of memory in the system. By this,
+		  20(40)bytes/PAGE_SIZE on 32(64)bit system will be occupied by memory
+		  usage tracking struct at boot. Total amount of this is printed out
+		  at boot.
+
+		  Only enable when you're ok with these tradeoffs and really
+		  sure you need the memory resource controller. Even when you enable
+		  this, you can set "cgroup_disable=memory" at your boot option to
+		  disable memory resource controller and you can avoid overheads
+		  (but lose benefits of memory resource controller).
+
+		  This config option also selects MM_OWNER config option, which
+		  could in turn add some fork/exit overhead.
+
+	config KERNEL_MEMCG_SWAP
+		bool "Memory Resource Controller Swap Extension"
+		default n
+		depends on KERNEL_MEMCG
+		help
+		  Add swap management feature to memory resource controller. When you
+		  enable this, you can limit mem+swap usage per cgroup. In other words,
+		  when you disable this, memory resource controller has no cares to
+		  usage of swap...a process can exhaust all of the swap. This extension
+		  is useful when you want to avoid exhaustion swap but this itself
+		  adds more overheads and consumes memory for remembering information.
+		  Especially if you use 32bit system or small memory system, please
+		  be careful about enabling this. When memory resource controller
+		  is disabled by boot option, this will be automatically disabled and
+		  there will be no overhead from this. Even when you set this config=y,
+		  if boot option "swapaccount=0" is set, swap will not be accounted.
+		  Now, memory usage of swap_cgroup is 2 bytes per entry. If swap page
+		  size is 4096bytes, 512k per 1Gbytes of swap.
+
+	config KERNEL_MEMCG_SWAP_ENABLED
+		bool "Memory Resource Controller Swap Extension enabled by default"
+		default n
+		depends on KERNEL_MEMCG_SWAP
+		help
+		  Memory Resource Controller Swap Extension comes with its price in
+		  a bigger memory consumption. General purpose distribution kernels
+		  which want to enable the feature but keep it disabled by default
+		  and let the user enable it by swapaccount boot command line
+		  parameter should have this option unselected.
+
+		  Those who want to have the feature enabled by default should
+		  select this option (if, for some reason, they need to disable it,
+		  then swapaccount=0 does the trick).
+
+
+	config KERNEL_MEMCG_KMEM
+		bool "Memory Resource Controller Kernel Memory accounting (EXPERIMENTAL)"
+		default n
+		depends on KERNEL_MEMCG
+		help
+		  The Kernel Memory extension for Memory Resource Controller can limit
+		  the amount of memory used by kernel objects in the system. Those are
+		  fundamentally different from the entities handled by the standard
+		  Memory Controller, which are page-based, and can be swapped. Users of
+		  the kmem extension can use it to guarantee that no group of processes
+		  will ever exhaust kernel resources alone.
+
+	config KERNEL_CGROUP_PERF
+		bool "Enable perf_event per-cpu per-container group (cgroup) monitoring"
+		select KERNEL_PERF_EVENTS
+		default n
+		help
+		  This option extends the per-cpu mode to restrict monitoring to
+		  threads which belong to the cgroup specified and run on the
+		  designated cpu.
+
+	menuconfig KERNEL_CGROUP_SCHED
+		bool "Group CPU scheduler"
+		default n
+		help
+		  This feature lets CPU scheduler recognize task groups and control CPU
+		  bandwidth allocation to such task groups. It uses cgroups to group
+		  tasks.
+
+	if KERNEL_CGROUP_SCHED
+
+		config KERNEL_FAIR_GROUP_SCHED
+			bool "Group scheduling for SCHED_OTHER"
+			default n
+
+		config KERNEL_CFS_BANDWIDTH
+			bool "CPU bandwidth provisioning for FAIR_GROUP_SCHED"
+			default n
+			depends on KERNEL_FAIR_GROUP_SCHED
+			help
+			  This option allows users to define CPU bandwidth rates (limits) for
+			  tasks running within the fair group scheduler.  Groups with no limit
+			  set are considered to be unconstrained and will run with no
+			  restriction.
+			  See tip/Documentation/scheduler/sched-bwc.txt for more information.
+
+		config KERNEL_RT_GROUP_SCHED
+			bool "Group scheduling for SCHED_RR/FIFO"
+			default n
+			help
+			  This feature lets you explicitly allocate real CPU bandwidth
+			  to task groups. If enabled, it will also make it impossible to
+			  schedule realtime tasks for non-root users until you allocate
+			  realtime bandwidth for them.
+
+	endif
+
+	config KERNEL_BLK_CGROUP
+		bool "Block IO controller"
+		default y
+		help
+		  Generic block IO controller cgroup interface. This is the common
+		  cgroup interface which should be used by various IO controlling
+		  policies.
+
+		  Currently, CFQ IO scheduler uses it to recognize task groups and
+		  control disk bandwidth allocation (proportional time slice allocation)
+		  to such task groups. It is also used by bio throttling logic in
+		  block layer to implement upper limit in IO rates on a device.
+
+		  This option only enables generic Block IO controller infrastructure.
+		  One needs to also enable actual IO controlling logic/policy. For
+		  enabling proportional weight division of disk bandwidth in CFQ, set
+		  CONFIG_CFQ_GROUP_IOSCHED=y; for enabling throttling policy, set
+		  CONFIG_BLK_DEV_THROTTLING=y.
+
+	config KERNEL_DEBUG_BLK_CGROUP
+		bool "Enable Block IO controller debugging"
+		default n
+		depends on KERNEL_BLK_CGROUP
+		help
+		  Enable some debugging help. Currently it exports additional stat
+		  files in a cgroup which can be useful for debugging.
+
+	config KERNEL_NET_CLS_CGROUP
+		bool "Control Group Classifier"
+		default y
+
+	config KERNEL_NETPRIO_CGROUP
+		bool "Network priority cgroup"
+		default y
+
+endif
+
+#
+# Namespace support symbols
+#
+
+config KERNEL_NAMESPACES
+	bool "Enable kernel namespaces"
+	default n
+
+if KERNEL_NAMESPACES
+
+	config KERNEL_UTS_NS
+		bool "UTS namespace"
+		default y
+		help
+		  In this namespace, tasks see different info provided
+		  with the uname() system call.
+
+	config KERNEL_IPC_NS
+		bool "IPC namespace"
+		default y
+		help
+		  In this namespace, tasks work with IPC ids which correspond to
+		  different IPC objects in different namespaces.
+
+	config KERNEL_USER_NS
+		bool "User namespace (EXPERIMENTAL)"
+		default y
+		help
+		  This allows containers, i.e. vservers, to use user namespaces
+		  to provide different user info for different servers.
+
+	config KERNEL_PID_NS
+		bool "PID Namespaces"
+		default y
+		help
+		  Support process id namespaces. This allows having multiple
+		  processes with the same pid as long as they are in different
+		  pid namespaces. This is a building block of containers.
+
+	config KERNEL_NET_NS
+		bool "Network namespace"
+		default y
+		help
+		  Allow user space to create what appear to be multiple instances
+		  of the network stack.
+
+endif
+
+#
+# LXC related symbols
+#
+
+config KERNEL_LXC_MISC
+	bool "Enable miscellaneous LXC related options"
+	default n
+
+if KERNEL_LXC_MISC
+
+	config KERNEL_DEVPTS_MULTIPLE_INSTANCES
+		bool "Support multiple instances of devpts"
+		default y
+		help
+		  Enable support for multiple instances of devpts filesystem.
+		  If you want to have isolated PTY namespaces (eg: in containers),
+		  say Y here. Otherwise, say N. If enabled, each mount of devpts
+		  filesystem with the '-o newinstance' option will create an
+		  independent PTY namespace.
+
+	config KERNEL_POSIX_MQUEUE
+		bool "POSIX Message Queues"
+		default y
+		help
+		  POSIX variant of message queues is a part of IPC. In POSIX message
+		  queues every message has a priority which decides about succession
+		  of receiving it by a process. If you want to compile and run
+		  programs written e.g. for Solaris with use of its POSIX message
+		  queues (functions mq_*) say Y here.
+
+		  POSIX message queues are visible as a filesystem called 'mqueue'
+		  and can be mounted somewhere if you want to do filesystem
+		  operations on message queues.
+
+endif
+
+config KERNEL_SECCOMP_FILTER
+	bool
+	default n
+
+config KERNEL_SECCOMP
+	bool "Enable seccomp support"
+		depends on !(TARGET_uml)
+		select KERNEL_SECCOMP_FILTER
+		default n
+		help
+		  Build kernel with support for seccomp.
+
+#
+# IPv6 configuration
+#
+
+config KERNEL_IPV6
+	def_bool IPV6
+
+if KERNEL_IPV6
+
+	config KERNEL_IPV6_MULTIPLE_TABLES
+		def_bool y
+
+	config KERNEL_IPV6_SUBTREES
+		def_bool y
+
+	config KERNEL_IPV6_MROUTE
+		def_bool y
+
+	config KERNEL_IPV6_PIMSM_V2
+		def_bool n
+
+endif
+
+#
+# NFS related symbols
+#
+config KERNEL_IP_PNP
+	bool "Compile the kernel with rootfs on NFS"
+	help
+	   If you want to make your kernel boot off a NFS server as root
+	   filesystem, select Y here.
+
+if KERNEL_IP_PNP
+
+	config KERNEL_IP_PNP_DHCP
+		def_bool y
+
+	config KERNEL_IP_PNP_BOOTP
+		def_bool n
+
+	config KERNEL_IP_PNP_RARP
+		def_bool n
+
+	config KERNEL_NFS_FS
+		def_bool y
+
+	config KERNEL_NFS_V2
+		def_bool y
+
+	config KERNEL_NFS_V3
+		def_bool y
+
+	config KERNEL_ROOT_NFS
+		def_bool y
+
+endif

+ 15 - 0
docs/.gitignore

@@ -0,0 +1,15 @@
+*.log
+*.aux
+*.toc
+*.out
+*.lg
+*.dvi
+*.idv
+*.4ct
+*.4tc
+*.xref
+*.tmp
+*.dvi
+*.html
+*.css
+*.pdf

+ 48 - 0
docs/Makefile

@@ -0,0 +1,48 @@
+ifeq ($(TOPDIR),)
+  TOPDIR:=${CURDIR}/..
+endif
+PKG_NAME=docs
+
+all: compile
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/prereq.mk
+
+MAIN = openwrt.tex
+DEPS = $(MAIN) Makefile config.tex network.tex network-scripts.tex network-scripts.tex wireless.tex build.tex adding.tex bugs.tex debugging.tex $(TMP_DIR)/.prereq-docs
+
+compile: $(TMP_DIR)/.prereq-docs
+	$(NO_TRACE_MAKE) cleanup
+	latex $(MAIN)
+	$(NO_TRACE_MAKE) openwrt.pdf openwrt.html
+	$(NO_TRACE_MAKE) cleanup
+
+$(TMP_DIR)/.prereq-docs:
+	mkdir -p $(TMP_DIR)
+	$(NO_TRACE_MAKE) prereq
+	touch $@
+
+openwrt.html: $(DEPS)
+	htlatex $(MAIN)
+
+openwrt.pdf: $(DEPS)
+	pdflatex $(MAIN)
+
+clean: cleanup
+	rm -f openwrt.pdf openwrt.html openwrt.css
+
+cleanup: FORCE
+	rm -f *.log *.aux *.toc *.out *.lg *.dvi *.idv *.4ct *.4tc *.xref *.tmp *.dvi
+
+$(eval $(call RequireCommand,latex, \
+	You need to install LaTeX to build the OpenWrt documentation \
+))
+$(eval $(call RequireCommand,pdflatex, \
+	You need to install PDFLaTeX to build the OpenWrt documentation \
+))
+$(eval $(call RequireCommand,htlatex, \
+	You need to install tex4ht to build the OpenWrt documentation \
+))
+
+FORCE:
+.PHONY: FORCE

+ 590 - 0
docs/adding.tex

@@ -0,0 +1,590 @@
+Linux is now one of the most widespread operating system for embedded devices due
+to its openess as well as the wide variety of platforms it can run on. Many
+manufacturer actually use it in firmware you can find on many devices: DVB-T 
+decoders, routers, print servers, DVD players ... Most of the time the stock 
+firmware is not really open to the consumer, even if it uses open source software.
+
+You might be interested in running a Linux based firmware for your router for
+various reasons: extending the use of a network protocol (such as IPv6), having
+new features, new piece of software inside, or for security reasons. A fully 
+open-source firmware is de-facto needed for such applications, since you want to
+be free to use this or that version of a particular reason, be able to correct a
+particular bug. Few manufacturers do ship their routers with a Sample Development Kit,
+that would allow you to create your own and custom firmware and most of the time,
+when they do, you will most likely not be able to complete the firmware creation process.
+
+This is one of the reasons why OpenWrt and other firmware exists: providing a 
+version independent, and tools independent firmware, that can be run on various 
+platforms, known to be running Linux originally.
+
+\subsection{Which Operating System does this device run?}
+
+There is a lot of methods to ensure your device is running Linux. Some of them do
+need your router to be unscrewed and open, some can be done by probing the device
+using its external network interfaces.
+
+\subsubsection{Operating System fingerprinting and port scanning}
+
+A large bunch of tools over the Internet exists in order to let you do OS 
+fingerprinting, we will show here an example using \textbf{nmap}:
+
+\begin{Verbatim}
+nmap -P0 -O <IP address>
+Starting Nmap 4.20 ( http://insecure.org ) at 2007-01-08 11:05 CET
+Interesting ports on 192.168.2.1:
+Not shown: 1693 closed ports
+PORT   STATE SERVICE
+22/tcp open  ssh
+23/tcp open  telnet
+53/tcp open  domain
+80/tcp open  http
+MAC Address: 00:13:xx:xx:xx:xx (Cisco-Linksys)
+Device type: broadband router
+Running: Linksys embedded
+OS details: Linksys WRT54GS v4 running OpenWrt w/Linux kernel 2.4.30
+Network Distance: 1 hop
+\end{Verbatim}
+
+nmap is able to report whether your device uses a Linux TCP/IP stack, and if so,
+will show you which Linux kernel version is probably runs. This report is quite 
+reliable and it can make the distinction between BSD and Linux TCP/IP stacks and others.
+
+Using the same tool, you can also do port scanning and service version discovery.
+For instance, the following command will report which IP-based services are running
+on the device, and which version of the service is being used:
+
+\begin{verbatim}
+nmap -P0 -sV <IP address>
+Starting Nmap 4.20 ( http://insecure.org ) at 2007-01-08 11:06 CET
+Interesting ports on 192.168.2.1:
+Not shown: 1693 closed ports
+PORT   STATE SERVICE VERSION
+22/tcp open  ssh     Dropbear sshd 0.48 (protocol 2.0)
+23/tcp open  telnet  Busybox telnetd
+53/tcp open  domain  ISC Bind dnsmasq-2.35
+80/tcp open  http    OpenWrt BusyBox httpd
+MAC Address: 00:13:xx:xx:xx:xx (Cisco-Linksys)
+Service Info: Device: WAP
+\end{verbatim}
+
+The web server version, if identified, can be determining in knowing the Operating
+System. For instance, the \textbf{BOA} web server is typical from devices running 
+an open-source Unix or Unix-like.
+
+\subsubsection{Wireless Communications Fingerprinting}
+
+Although this method is not really known and widespread, using a wireless scanner 
+to discover which OS your router or Access Point run can be used. We do not have
+a clear example of how this could be achieved, but you will have to monitor raw 
+802.11 frames and compare them to a very similar device running a Linux based firmware.
+
+\subsubsection{Web server security exploits}
+
+The Linksys WRT54G was originally hacked by using a "ping bug" discovered in the 
+web interface. This tip has not been fixed for months by Linksys, allowing people
+to enable the "boot\_wait" helper process via the web interface. Many web servers
+used in firmwares are open source web server, thus allowing the code to be audited
+to find an exploit. Once you know the web server version that runs on your device,
+by using \textbf{nmap -sV} or so, you might be interested in using exploits to reach 
+shell access on your device.
+
+\subsubsection{Native Telnet/SSH access}
+
+Some firmwares might have restricted or unrestricted Telnet/SSH access, if so,
+try to log in with the web interface login/password and see if you can type in 
+some commands. This is actually the case for some Broadcom BCM963xx based firmwares
+such as the one in Neuf/Cegetel ISP routers, Club-Internet ISP CI-Box and many 
+others. Some commands, like \textbf{cat} might be left here and be used to 
+determine the Linux kernel version.
+
+\subsubsection{Analysing a binary firmware image}
+
+You are very likely to find a firmware binary image on the manufacturer website,
+even if your device runs a proprietary operating system. If so, you can download
+it and use an hexadecimal editor to find printable words such as \textbf{vmlinux},
+\textbf{linux}, \textbf{ramdisk}, \textbf{mtd} and others.
+
+Some Unix tools like \textbf{hexdump} or \textbf{strings} can be used to analyse 
+the firmware. Below there is an example with a binary firmware found other the Internet:
+
+\begin{verbatim}
+hexdump -C <binary image.extension> | less (more)
+00000000  46 49 52 45 32 2e 35 2e  30 00 00 00 00 00 00 00  |FIRE2.5.0.......|
+00000010  00 00 00 00 31 2e 30 2e  30 00 00 00 00 00 00 00  |....1.0.0.......|
+00000020  00 00 00 00 00 00 00 38  00 43 36 29 00 0a e6 dc  |.......8.C6)..??|
+00000030  54 49 44 45 92 89 54 66  1f 8b 08 08 f8 10 68 42  |TIDE..Tf....?.hB|
+00000040  02 03 72 61 6d 64 69 73  6b 00 ec 7d 09 bc d5 d3  |..ramdisk.?}.???|
+00000050  da ff f3 9b f7 39 7b ef  73 f6 19 3b 53 67 ea 44  |???.?9{?s?.;Sg?D|
+\end{verbatim}
+
+Scroll over the firmware to find printable words that can be significant.
+
+\subsubsection{Amount of flash memory}
+
+Linux can hardly fit in a 2MB flash device, once you have opened the device and 
+located the flash chip, try to find its characteristics on the Internet. If
+your flash chip is a 2MB or less device, your device is most likely to run a 
+proprietary OS such as WindRiver VxWorks, or a custom manufacturer OS like Zyxel ZynOS.
+
+OpenWrt does not currently run on devices which have 2MB or less of flash memory.
+This limitation will probably not be worked around since those devices are most 
+of the time micro-routers, or Wireless Access Points, which are not the main 
+OpenWrt target.
+
+\subsubsection{Pluging a serial port}
+
+By using a serial port and a level shifter, you may reach the console that is being shown by the device
+for debugging or flashing purposes. By analysing the output of this device, you can
+easily notice if the device uses a Linux kernel or something different.
+
+\subsection{Finding and using the manufacturer SDK}
+
+Once you are sure your device run a Linux based firmware, you will be able to start
+hacking on it. If the manufacturer respected the GPL, it will have released a Sample
+Development Kit with the device.
+
+\subsubsection{GPL violations}
+
+Some manufacturers do release a Linux based binary firmware, with no sources at all.
+The first step before doing anything is to read the license coming with your device,
+then write them about this lack of Open Source code. If the manufacturer answers
+you they do not have to release a SDK containing Open Source software, then we 
+recommend you get in touch with the gpl-violations.org community.
+
+You will find below a sample letter that can be sent to the manufacturer:
+
+\begin{verse}
+Miss, Mister,
+
+I am using a <device name>, and I cannot find neither on your website nor on the 
+CD-ROM the open source software used to build or modify the firmware.
+
+In conformance to the GPL license, you have to release the following sources:
+
+\begin{itemize}
+\item complete toolchain that made the kernel and applications be compiled (gcc, binutils, libc)
+\item tools to build a custom firmware (mksquashfs, mkcramfs ...)
+\item kernel sources with patches to make it run on this specific hardware, this does not include binary drivers
+\end{itemize}
+
+Thank you very much in advance for your answer.
+
+Best regards, <your name>
+\end{verse}
+
+\subsubsection{Using the SDK}
+
+Once the SDK is available, you are most likely not to be able to build a complete
+or functional firmware using it, but parts of it, like only the kernel, or only
+the root filesystem. Most manufacturers do not really care releasing a tool that
+do work every time you uncompress and use it.
+
+You should anyway be able to use the following components:
+
+\begin{itemize}
+\item kernel sources with more or less functional patches for your hardware
+\item binary drivers linked or to be linked with the shipped kernel version
+\item packages of the toolchain used to compile the whole firmware: gcc, binutils, libc or uClibc
+\item binary tools to create a valid firmware image
+\end{itemize}
+
+Your work can be divided into the following tasks:
+
+\begin{itemize}
+\item create a clean patch of the hardware specific part of the linux kernel
+\item spot potential kernel GPL violations especially on netfilter and USB stack stuff
+\item make the binary drivers work, until there are open source drivers
+\item use standard a GNU toolchain to make working executables
+\item understand and write open source tools to generate a valid firmware image
+\end{itemize}
+
+\subsubsection{Creating a hardware specific kernel patch}
+
+Most of the time, the kernel source that comes along with the SDK is not really 
+clean, and is not a standard Linux version, it also has architecture specific 
+fixes backported from the \textbf{CVS} or the \textbf{git} repository of the 
+kernel development trees. Anyway, some parts can be easily isolated and used as 
+a good start to make a vanilla kernel work your hardware.
+
+Some directories are very likely to have local modifications needed to make your
+hardware be recognized and used under Linux. First of all, you need to find out 
+the linux kernel version that is used by your hardware, this can be found by 
+editing the \textbf{linux/Makefile} file.
+
+\begin{verbatim}
+head -5 linux-2.x.x/Makefile
+VERSION = 2
+PATCHLEVEL = x
+SUBLEVEL = y
+EXTRAVERSION = z
+NAME=A fancy name
+\end{verbatim}
+
+So now, you know that you have to download a standard kernel tarball at 
+\textbf{kernel.org} that matches the version being used by your hardware.
+
+Then you can create a \textbf{diff} file between the two trees, especially for the 
+following directories:
+
+\begin{verbatim}
+diff -urN linux-2.x.x/arch/<sub architecture> linux-2.x.x-modified/arch/<sub architecture> > 01-architecture.patch
+diff -urN linux-2.x.x/include/ linux-2.x.x-modified/include > 02-includes.patch
+diff -urN linux-2.x.x/drivers/ linux-2.x.x-modified/drivers > 03-drivers.patch
+\end{verbatim}
+
+This will constitute a basic set of three patches that are very likely to contain
+any needed modifications that has been made to the stock Linux kernel to run on 
+your specific device. Of course, the content produced by the \textbf{diff -urN} 
+may not always be relevant, so that you have to clean up those patches to only 
+let the "must have" code into them.
+
+The first patch will contain all the code that is needed by the board to be 
+initialized at startup, as well as processor detection and other boot time 
+specific fixes.
+
+The second patch will contain all useful definitions for that board: addresses, 
+kernel granularity, redefinitions, processor family and features ...
+
+The third patch may contain drivers for: serial console, ethernet NIC, wireless 
+NIC, USB NIC ... Most of the time this patch contains nothing else than "glue"
+code that has been added to make the binary driver work with the Linux kernel. 
+This code might not be useful if you plan on writing drivers from scratch for 
+this hardware.
+
+\subsubsection{Using the device bootloader}
+
+The bootloader is the first program that is started right after your device has 
+been powered on. This program, can be more or less sophisticated, some do let you 
+do network booting, USB mass storage booting ... The bootloader is device and 
+architecture specific, some bootloaders were designed to be universal such as 
+RedBoot or U-Boot so that you can meet those loaders on totally different 
+platforms and expect them to behave the same way.
+
+If your device runs a proprietary operating system, you are very likely to deal 
+with a proprietary boot loader as well. This may not always be a limitation, 
+some proprietary bootloaders can even have source code available (i.e : Broadcom CFE).
+
+According to the bootloader features, hacking on the device will be more or less 
+easier. It is very probable that the bootloader, even exotic and rare, has a 
+documentation somewhere over the Internet. In order to know what will be possible 
+with your bootloader and the way you are going to hack the device, look over the 
+following features :
+
+\begin{itemize}
+\item does the bootloader allow net booting via bootp/DHCP/NFS or tftp
+\item does the bootloader accept loading ELF binaries ?
+\item does the bootloader have a kernel/firmware size limitation ?
+\item does the bootloader expect a firmware format to be loaded with ?
+\item are the loaded files executed from RAM or flash ?
+\end{itemize}
+
+Net booting is something very convenient, because you will only have to set up network
+booting servers on your development station, and keep the original firmware on the device
+till you are sure you can replace it. This also prevents your device from being flashed,
+and potentially bricked every time you want to test a modification on the kernel/filesystem.
+
+If your device needs to be flashed every time you load a firmware, the bootlader might
+only accept a specific firmware format to be loaded, so that you will have to 
+understand the firmware format as well.
+
+\subsubsection{Making binary drivers work}
+
+As we have explained before, manufacturers do release binary drivers in their GPL
+tarball. When those drivers are statically linked into the kernel, they become GPL
+as well, fortunately or unfortunately, most of the drivers are not statically linked.
+This anyway lets you a chance to dynamically link the driver with the current kernel
+version, and try to make them work together.
+
+This is one of the most tricky and grey part of the fully open source projects. 
+Some drivers require few modifications to be working with your custom kernel, 
+because they worked with an earlier kernel, and few modifications have been made
+to the kernel in-between those versions. This is for instance the case with the 
+binary driver of the Broadcom BCM43xx Wireless Chipsets, where only few differences
+were made to the network interface structures.
+
+Some general principles can be applied no matter which kernel version is used in
+order to make binary drivers work with your custom kernel:
+
+\begin{itemize}
+\item turn on kernel debugging features such as:
+\begin{itemize}
+\item CONFIG\_DEBUG\_KERNEL
+\item CONFIG\_DETECT\_SOFTLOCKUP
+\item CONFIG\_DEBUG\_KOBJECT
+\item CONFIG\_KALLSYMS
+\item CONFIG\_KALLSYMS\_ALL
+\end{itemize}
+\item link binary drivers when possible to the current kernel version
+\item try to load those binary drivers
+\item catch the lockups and understand them
+\end{itemize}
+
+Most of the time, loading binary drivers will fail, and generate a kernel oops. 
+You can know the last symbol the binary drivers attempted to use, and see in the
+kernel headers file, if you do not have to move some structures field before or 
+after that symbol in order to keep compatibily with both the binary driver and 
+the stock kernel drivers.
+
+\subsubsection{Understanding the firmware format}
+
+You might want to understand the firmware format, even if you are not yet capable
+of running a custom firmware on your device, because this is sometimes a blocking
+part of the flashing process.
+
+A firmware format is most of the time composed of the following fields:
+
+\begin{itemize}
+\item header, containing a firmware version and additional fields: Vendor, Hardware version ...
+\item CRC32 checksum on either the whole file or just part of it
+\item Binary and/or compressed kernel image
+\item Binary and/or compressed root filesystem image
+\item potential garbage
+\end{itemize}
+
+Once you have figured out how the firmware format is partitioned, you will have 
+to write your own tool that produces valid firmware binaries. One thing to be very
+careful here is the endianness of either the machine that produces the binary 
+firmware and the device that will be flashed using this binary firmware.
+
+\subsubsection{Writing a flash map driver}
+
+The flash map driver has an important role in making your custom firmware work 
+because it is responsible of mapping the correct flash regions and associated 
+rights to specific parts of the system such as: bootloader, kernel, user filesystem.
+
+Writing your own flash map driver is not really a hard task once you know how your
+firmware image and flash is structured. You will find below a commented example
+that covers the case of the device where the bootloader can pass to the kernel its partition plan.
+
+First of all, you need to make your flash map driver be visible in the kernel 
+configuration options, this can be done by editing the file \
+\textbf{linux/drivers/mtd/maps/Kconfig}:
+
+\begin{verbatim}
+config MTD_DEVICE_FLASH
+        tristate "Device Flash device"
+        depends on ARCHITECTURE && DEVICE
+        help
+         Flash memory access on DEVICE boards. Currently only works with
+         Bootloader Foo and Bootloader Bar.
+\end{verbatim}
+
+Then add your source file to the \textbf{linux/drivers/mtd/maps/Makefile}, so 
+that it will be compiled along with the kernel.
+
+\begin{verbatim}
+obj-\$(CONFIG_MTD_DEVICE_FLASH)      += device-flash.o
+\end{verbatim}
+
+You can then write the kernel driver itself, by creating a 
+\textbf{linux/drivers/mtd/maps/device-flash.c} C source file.
+
+\begin{verbatim}
+// Includes that are required for the flash map driver to know of the prototypes:
+#include <asm/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/vmalloc.h>
+
+// Put some flash map definitions here:
+#define WINDOW_ADDR 0x1FC00000         /* Real address of the flash */
+#define WINDOW_SIZE 0x400000                /* Size of flash */
+#define BUSWIDTH 2                                   /* Buswidth */
+
+static void __exit device_mtd_cleanup(void);
+
+static struct mtd_info *device_mtd_info;
+
+static struct map_info devicd_map = {
+       .name = "device",
+       .size = WINDOW_SIZE,
+       .bankwidth = BUSWIDTH,
+       .phys = WINDOW_ADDR,
+};
+
+static int __init device_mtd_init(void)
+{
+	  // Display that we found a flash map device 
+       printk("device: 0x\%08x at 0x\%08x\n", WINDOW_SIZE, WINDOW_ADDR);
+	   // Remap the device address to a kernel address
+       device_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
+
+       // If impossible to remap, exit with the EIO error
+       if (!device_map.virt) {
+               printk("device: Failed to ioremap\n");
+               return -EIO;
+       }
+
+	   // Initialize the device map
+       simple_map_init(&device_map);
+
+	   /* MTD informations are closely linked to the flash map device
+	       you might also use "jedec_probe" "amd_probe" or "intel_probe" */
+       device_mtd_info = do_map_probe("cfi_probe", &device_map);
+
+ 		if (device_mtd_info) {
+               device_mtd_info->owner = THIS_MODULE;
+
+				int parsed_nr_parts = 0;
+
+						// We try here to use the partition schema provided by the bootloader specific code
+                       if (parsed_nr_parts == 0) {
+                               int ret = parse_bootloader_partitions(device_mtd_info, &parsed_parts, 0);
+                               if (ret > 0) {
+                                       part_type = "BootLoader";
+                                       parsed_nr_parts = ret;
+                               }
+                       }
+
+                       add_mtd_partitions(devicd_mtd_info, parsed_parts, parsed_nr_parts);
+
+                       return 0;
+               }
+       iounmap(device_map.virt);
+
+       return -ENXIO;
+}
+
+// This function will make the driver clean up the MTD device mapping
+static void __exit device_mtd_cleanup(void)
+{
+	  // If we found a MTD device before
+       if (device_mtd_info) {
+			   // Delete every partitions
+               del_mtd_partitions(device_mtd_info);
+			   // Delete the associated map
+               map_destroy(device_mtd_info);
+       }
+	
+		// If the virtual address is already in use
+       if (device_map.virt) {
+					// Unmap the physical address to a kernel space address
+               iounmap(device_map.virt);
+				// Reset the structure field
+              device_map.virt = 0;
+       }
+}
+
+
+// Macros that indicate which function is called on loading/unloading the module
+module_init(device_mtd_init);
+module_exit(device_mtd_cleanup);
+
+
+// Macros defining license and author, parameters can be defined here too.
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Me, myself and I <memyselfandi@domain.tld");
+\end{verbatim}
+
+\subsection{Adding your target in OpenWrt}
+
+Once you spotted the key changes that were made to the Linux kernel
+to support your target, you will want to create a target in OpenWrt
+for your hardware. This can be useful to benefit from the toolchain
+that OpenWrt builds as well as the resulting user-space and kernel
+configuration options.
+
+Provided that your target is already known to OpenWrt, it will be
+as simple as creating a \texttt{target/linux/board} directory
+where you will be creating the following directories and files.
+
+Here for example, is a \texttt{target/linux/board/Makefile}:
+
+\begin{Verbatim}[frame=single,numbers=left]
+#
+# 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
+
+ARCH:=mips
+BOARD:=board
+BOARDNAME:=Eval board
+FEATURES:=squashfs jffs2 pci usb
+
+LINUX_VERSION:=2.6.27.10
+
+include $(INCLUDE_DIR)/target.mk
+
+DEFAULT_PACKAGES += hostapd-mini
+
+define Target/Description
+        Build firmware images for Evaluation board
+endef
+
+$(eval $(call BuildTarget))
+\end{Verbatim}
+
+\begin{itemize}
+    \item \texttt{ARCH} \\
+        The name of the architecture known by Linux and uClibc
+    \item \texttt{BOARD} \\
+        The name of your board that will be used as a package and build directory identifier
+    \item \texttt{BOARDNAME} \\
+        Expanded name that will appear in menuconfig
+    \item \texttt{FEATURES} \\
+        Set of features to build filesystem images, USB, PCI, VIDEO kernel support
+    \item \texttt{LINUX\_VERSION} \\
+        Linux kernel version to use for this target
+    \item \texttt{DEFAULT\_PACKAGES} \\
+        Set of packages to be built by default
+\end{itemize}
+
+A partial kernel configuration which is either named \texttt{config-default} or which matches the kernel version \texttt{config-2.6.x} should be present in \texttt{target/linux/board/}.
+This kernel configuration will only contain the relevant symbols to support your target and can be changed using \texttt{make kernel\_menuconfig}.
+
+To patch the kernel sources with the patches required to support your hardware, you will have to drop them in \texttt{patches} or in \texttt{patches-2.6.x} if there are specific
+changes between kernel versions. Additionnaly, if you want to avoid creating a patch that will create files, you can put those files into \texttt{files} or \texttt{files-2.6.x}
+with the same directory structure that the kernel uses (e.g: drivers/mtd/maps, arch/mips ..).
+
+The build system will require you to create a \texttt{target/linux/board/image/Makefile}:
+
+\begin{Verbatim}[frame=single,numbers=left]
+#
+# 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
+include $(INCLUDE_DIR)/image.mk
+
+define Image/BuildKernel
+        cp $(KDIR)/vmlinux.elf $(BIN_DIR)/openwrt-$(BOARD)-vmlinux.elf
+        gzip -9n -c $(KDIR)/vmlinux > $(KDIR)/vmlinux.bin.gz
+        $(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.bin.l7
+        dd if=$(KDIR)/vmlinux.bin.l7 of=$(BIN_DIR)/openwrt-$(BOARD)-vmlinux.lzma bs=65536 conv=sync
+        dd if=$(KDIR)/vmlinux.bin.gz of=$(BIN_DIR)/openwrt-$(BOARD)-vmlinux.gz bs=65536 conv=sync
+endef
+
+define Image/Build/squashfs
+    $(call prepare_generic_squashfs,$(KDIR)/root.squashfs)
+endef
+
+define Image/Build
+        $(call Image/Build/$(1))
+        dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/openwrt-$(BOARD)-root.$(1) bs=128k conv=sync
+
+        -$(STAGING_DIR_HOST)/bin/mkfwimage \
+                -B XS2 -v XS2.ar2316.OpenWrt \
+                -k $(BIN_DIR)/openwrt-$(BOARD)-vmlinux.lzma \
+                -r $(BIN_DIR)/openwrt-$(BOARD)-root.$(1) \
+                -o $(BIN_DIR)/openwrt-$(BOARD)-ubnt2-$(1).bin
+endef
+
+$(eval $(call BuildImage))
+
+\end{Verbatim}
+
+\begin{itemize}
+    \item \texttt{Image/BuildKernel} \\
+        This template defines changes to be made to the ELF kernel file
+    \item \texttt{Image/Build} \\
+	This template defines the final changes to apply to the rootfs and kernel, either combined or separated
+	firmware creation tools can be called here as well.
+\end{itemize}

+ 52 - 0
docs/bugs.tex

@@ -0,0 +1,52 @@
+OpenWrt as an open source software opens its development to the community by
+having a publicly browseable subversion repository. The Trac software which
+comes along with a Subversion frontend,  a Wiki and a ticket reporting system 
+is used as an interface between developers, users and contributors in order to 
+make the whole development process much easier and efficient.
+
+We make distinction between two kinds of people within the Trac system:
+
+\begin{itemize}
+\item developers, able to report, close and fix tickets
+\item reporters, able to add a comment, patch, or request ticket status
+\end{itemize}
+
+\subsubsection{Opening a ticket}
+
+A reporter might want to open a ticket for the following reasons:
+
+\begin{itemize}
+\item a bug affects a specific hardware and/or software and needs to be fixed
+\item a specific software package would be seen as part of the official OpenWrt repository
+\item a feature should be added or removed from OpenWrt
+\end{itemize}
+
+Regarding the kind of ticket that is open, a patch is welcome in those cases:
+
+\begin{itemize}
+\item new package to be included in OpenWrt
+\item fix for a bug that works for the reporter and has no known side effect
+\item new features that can be added by modifying existing OpenWrt files
+\end{itemize}
+
+Once the ticket is open, a developer will take care of it, if so, the ticket is marked
+as "accepted" with the developer name. You can add comments at any time to the ticket,
+even when it is closed.
+
+\subsubsection{Closing a ticket}
+
+A ticket might be closed by a developer because:
+
+\begin{itemize}
+\item the problem is already fixed (wontfix)
+\item the problem described is not judged as valid, and comes along with an explanation why (invalid)
+\item the developers know that this bug will be fixed upstream (wontfix)
+\item the problem is very similar to something that has already been reported (duplicate)
+\item the problem cannot be reproduced by the developers (worksforme)
+\end{itemize}
+
+At the same time, the reporter may want to get the ticket closed since he is not 
+longer able to trigger the bug, or found it invalid by himself.
+
+When a ticket is closed by a developer and marked as "fixed", the comment contains 
+the subversion changeset which corrects the bug.

+ 594 - 0
docs/build.tex

@@ -0,0 +1,594 @@
+One of the biggest challenges to getting started with embedded devices is that you
+cannot just install a copy of Linux and expect to be able to compile a firmware.
+Even if you did remember to install a compiler and every development tool offered,
+you still would not have the basic set of tools needed to produce a firmware image.
+The embedded device represents an entirely new hardware platform, which is
+most of the time incompatible with the hardware on your development machine, so in a process called
+cross compiling you need to produce a new compiler capable of generating code for
+your embedded platform, and then use it to compile a basic Linux distribution to
+run on your device.
+
+The process of creating a cross compiler can be tricky, it is not something that is
+regularly attempted and so there is a certain amount of mystery and black magic
+associated with it. In many cases when you are dealing with embedded devices you will
+be provided with a binary copy of a compiler and basic libraries rather than
+instructions for creating your own -- it is a time saving step but at the same time
+often means you will be using a rather dated set of tools. Likewise, it is also common
+to be provided with a patched copy of the Linux kernel from the board or chip vendor,
+but this is also dated and it can be difficult to spot exactly what has been
+modified to make the kernel run on the embedded platform.
+
+\subsection{Building an image}
+
+OpenWrt takes a different approach to building a firmware; downloading, patching
+and compiling everything from scratch, including the cross compiler. To put it
+in simpler terms, OpenWrt does not contain any executables or even sources, it is an
+automated system for downloading the sources, patching them to work with the given
+platform and compiling them correctly for that platform. What this means is that
+just by changing the template, you can change any step in the process.
+
+As an example, if a new kernel is released, a simple change to one of the Makefiles
+will download the latest kernel, patch it to run on the embedded platform and produce
+a new firmware image -- there is no work to be done trying to track down an unmodified
+copy of the existing kernel to see what changes had been made, the patches are
+already provided and the process ends up almost completely transparent. This does not
+just apply to the kernel, but to anything included with OpenWrt -- It is this one
+simple understated concept which is what allows OpenWrt to stay on the bleeding edge
+with the latest compilers, latest kernels and latest applications.
+
+So let's take a look at OpenWrt and see how this all works.
+
+
+\subsubsection{Download OpenWrt}
+
+OpenWrt can be downloaded via subversion using the following command:
+
+\begin{Verbatim}
+$ svn checkout svn://svn.openwrt.org/openwrt/trunk openwrt-trunk
+\end{Verbatim}
+
+Additionally, there is a trac interface on \href{https://dev.openwrt.org/}{https://dev.openwrt.org/}
+which can be used to monitor svn commits and browse the source repository.
+
+
+\subsubsection{The directory structure}
+
+There are four key directories in the base:
+
+\begin{itemize}
+    \item \texttt{tools}
+    \item \texttt{toolchain}
+    \item \texttt{package}
+    \item \texttt{target}
+\end{itemize}
+
+\texttt{tools} and \texttt{toolchain} refer to common tools which will be
+used to build the firmware image, the compiler, and the C library.
+The result of this is three new directories, \texttt{build\_dir/host}, which is a temporary
+directory for building the target independent tools, \texttt{build\_dir/toolchain-\textit{<arch>}*}
+which is used for building the toolchain for a specific architecture, and
+\texttt{staging\_dir/toolchain-\textit{<arch>}*} where the resulting toolchain is installed.
+You will not need to do anything with the toolchain directory unless you intend to
+add a new version of one of the components above.
+
+\begin{itemize}
+    \item \texttt{build\_dir/host}
+    \item \texttt{build\_dir/toolchain-\textit{<arch>}*}
+\end{itemize}
+
+\texttt{package} is for exactly that -- packages. In an OpenWrt firmware, almost everything
+is an \texttt{.ipk}, a software package which can be added to the firmware to provide new
+features or removed to save space. Note that packages are also maintained outside of the main
+trunk and can be obtained from subversion using the package feeds system:
+
+\begin{Verbatim}
+$ ./scripts/feeds update
+\end{Verbatim}
+
+Those packages can be used to extend the functionality of the build system and need to be
+symlinked into the main trunk. Once you do that, the packages will show up in the menu for
+configuration. You would do something like this:
+
+\begin{Verbatim}
+$ ./scripts/feeds search nmap
+Search results in feed 'packages':
+nmap       Network exploration and/or security auditing utility
+
+$ ./scripts/feeds install nmap
+\end{Verbatim}
+
+To include all packages, issue the following command:
+
+\begin{Verbatim}
+$ make package/symlinks
+\end{Verbatim}
+
+\texttt{target} refers to the embedded platform, this contains items which are specific to
+a specific embedded platform. Of particular interest here is the "\texttt{target/linux}"
+directory which is broken down by platform \textit{<arch>} and contains the patches to the
+kernel, profile config, for a particular platform. There's also the "\texttt{target/image}" directory
+which describes how to package a firmware for a specific platform.
+
+Both the target and package steps will use the directory "\texttt{build\_dir/\textit{<arch>}}"
+as a temporary directory for compiling. Additionally, anything downloaded by the toolchain,
+target or package steps will be placed in the "\texttt{dl}" directory.
+
+\begin{itemize}
+    \item \texttt{build\_dir/\textit{<arch>}}
+    \item \texttt{dl}
+\end{itemize}
+
+\subsubsection{Building OpenWrt}
+
+While the OpenWrt build environment was intended mostly for developers, it also has to be
+simple enough that an inexperienced end user can easily build his or her own customized firmware.
+
+Running the command "\texttt{make menuconfig}" will bring up OpenWrt's configuration menu
+screen, through this menu you can select which platform you're targeting, which versions of
+the toolchain you want to use to build and what packages you want to install into the
+firmware image. Note that it will also check to make sure you have the basic dependencies for it
+to run correctly.  If that fails, you will need to install some more tools in your local environment
+before you can begin.
+
+Similar to the linux kernel config, almost every option has three choices,
+\texttt{y/m/n} which are represented as follows:
+
+\begin{itemize}
+    \item{\texttt{<*>} (pressing y)} \\
+        This will be included in the firmware image
+    \item{\texttt{<M>} (pressing m)} \\
+        This will be compiled but not included (for later install)
+    \item{\texttt{< >} (pressing n)} \\
+        This will not be compiled
+\end{itemize}
+
+After you've finished with the menu configuration, exit and when prompted, save your
+configuration changes.
+
+If you want, you can also modify the kernel config for the selected target system.
+simply run "\texttt{make kernel\_menuconfig}" and the build system will unpack the kernel sources
+(if necessary), run menuconfig inside of the kernel tree, and then copy the kernel config
+to \texttt{target/linux/\textit{<platform>}/config} so that it is preserved over
+"\texttt{make clean}" calls.
+
+To begin compiling the firmware, type "\texttt{make}". By default
+OpenWrt will only display a high level overview of the compile process and not each individual
+command.
+
+\subsubsection{Example:}
+
+\begin{Verbatim}
+make[2] toolchain/install
+make[3] -C toolchain install
+make[2] target/compile
+make[3] -C target compile
+make[4] -C target/utils prepare
+
+[...]
+\end{Verbatim}
+
+This makes it easier to monitor which step it's actually compiling and reduces the amount
+of noise caused by the compile output. To see the full output, run the command
+"\texttt{make V=99}".
+
+During the build process, buildroot will download all sources to the "\texttt{dl}"
+directory and will start patching and compiling them in the "\texttt{build\_dir/\textit{<arch>}}"
+directory. When finished, the resulting firmware will be in the "\texttt{bin}" directory
+and packages will be in the "\texttt{bin/packages}" directory.
+
+
+\subsection{Creating packages}
+
+One of the things that we've attempted to do with OpenWrt's template system is make it
+incredibly easy to port software to OpenWrt. If you look at a typical package directory
+in OpenWrt you'll find several things:
+
+\begin{itemize}
+    \item \texttt{package/\textit{<name>}/Makefile}
+    \item \texttt{package/\textit{<name>}/patches}
+    \item \texttt{package/\textit{<name>}/files}
+\end{itemize}
+
+The patches directory is optional and typically contains bug fixes or optimizations to
+reduce the size of the executable. The package makefile is the important item, provides
+the steps actually needed to download and compile the package.
+
+The files directory is also optional and typicall contains package specific startup scripts or default configuration files that can be used out of the box with OpenWrt.
+
+Looking at one of the package makefiles, you'd hardly recognize it as a makefile.
+Through what can only be described as blatant disregard and abuse of the traditional
+make format, the makefile has been transformed into an object oriented template which
+simplifies the entire ordeal.
+
+Here for example, is \texttt{package/bridge/Makefile}:
+
+\begin{Verbatim}[frame=single,numbers=left]
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bridge
+PKG_VERSION:=1.0.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=bridge-utils-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/bridge
+PKG_MD5SUM:=9b7dc52656f5cbec846a7ba3299f73bd
+PKG_CAT:=zcat
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/bridge-utils-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bridge
+  SECTION:=net
+  CATEGORY:=Base system
+  TITLE:=Ethernet bridging configuration utility
+  URL:=http://bridge.sourceforge.net/
+endef
+
+define Package/bridge/description
+  Manage ethernet bridging: 
+  a way to connect networks together to form a larger network.
+endef
+
+define Build/Configure
+    $(call Build/Configure/Default, \
+        --with-linux-headers="$(LINUX_DIR)" \
+    )
+endef
+
+define Package/bridge/install
+    $(INSTALL_DIR) $(1)/usr/sbin
+    $(INSTALL_BIN) $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,bridge))
+\end{Verbatim}
+
+As you can see, there's not much work to be done; everything is hidden in other makefiles
+and abstracted to the point where you only need to specify a few variables.
+
+\begin{itemize}
+    \item \texttt{PKG\_NAME} \\
+        The name of the package, as seen via menuconfig and ipkg
+    \item \texttt{PKG\_VERSION} \\
+        The upstream version number that we are downloading
+    \item \texttt{PKG\_RELEASE} \\
+        The version of this package Makefile
+    \item \texttt{PKG\_SOURCE} \\
+        The filename of the original sources
+    \item \texttt{PKG\_SOURCE\_URL} \\
+        Where to download the sources from (no trailing slash), you can add multiple download sources by separating them with a \textbackslash{} and a carriage return.
+    \item \texttt{PKG\_MD5SUM} \\
+        A checksum to validate the download
+    \item \texttt{PKG\_CAT} \\
+        How to decompress the sources (zcat, bzcat, unzip)
+    \item \texttt{PKG\_BUILD\_DIR} \\
+        Where to compile the package
+\end{itemize}
+
+The \texttt{PKG\_*} variables define where to download the package from;
+\texttt{@SF} is a special keyword for downloading packages from sourceforge. There is also
+another keyword of \texttt{@GNU} for grabbing GNU source releases. If any of the above mentioned download source fails, the OpenWrt mirrors will be used as source.
+
+The md5sum (if present) is used to verify the package was downloaded correctly and
+\texttt{PKG\_BUILD\_DIR} defines where to find the package after the sources are
+uncompressed into \texttt{\$(BUILD\_DIR)}.
+
+At the bottom of the file is where the real magic happens, "BuildPackage" is a macro
+set up by the earlier include statements. BuildPackage only takes one argument directly --
+the name of the package to be built, in this case "\texttt{bridge}". All other information
+is taken from the define blocks. This is a way of providing a level of verbosity, it's
+inherently clear what the contents of the \texttt{description} template in
+\texttt{Package/bridge} is, which wouldn't be the case if we passed this information
+directly as the Nth argument to \texttt{BuildPackage}.
+
+\texttt{BuildPackage} uses the following defines:
+
+\textbf{\texttt{Package/\textit{<name>}}:} \\
+    \texttt{\textit{<name>}} matches the argument passed to buildroot, this describes
+    the package the menuconfig and ipkg entries. Within \texttt{Package/\textit{<name>}}
+    you can define the following variables:
+
+    \begin{itemize}
+        \item \texttt{SECTION} \\
+            The section of package (currently unused)
+        \item \texttt{CATEGORY} \\
+            Which menu it appears in menuconfig: Network, Sound, Utilities, Multimedia ...
+        \item \texttt{TITLE} \\
+            A short description of the package
+        \item \texttt{URL} \\
+            Where to find the original software
+        \item \texttt{MAINTAINER} (optional) \\
+            Who to contact concerning the package
+        \item \texttt{DEPENDS} (optional) \\
+            Which packages must be built/installed before this package. To reference a dependency defined in the
+			same Makefile, use \textit{<dependency name>}. If defined as an external package, use 
+			\textit{+<dependency name>}. For a kernel version dependency use: \textit{@LINUX\_2\_<minor version>}
+		\item \texttt{BUILDONLY} (optional) \\
+			Set this option to 1 if you do NOT want your package to appear in menuconfig.
+			This is useful for packages which are only used as build dependencies.
+    \end{itemize}
+
+\textbf{\texttt{Package/\textit{<name>}/conffiles} (optional):} \\
+   A list of config files installed by this package, one file per line.
+
+\textbf{\texttt{Build/Prepare} (optional):} \\
+   A set of commands to unpack and patch the sources. You may safely leave this
+   undefined.
+
+\textbf{\texttt{Build/Configure} (optional):} \\
+   You can leave this undefined if the source doesn't use configure or has a
+   normal config script, otherwise you can put your own commands here or use
+   "\texttt{\$(call Build/Configure/Default,\textit{<first list of arguments, second list>})}" as above to
+   pass in additional arguments for a standard configure script. The first list of arguments will be passed
+   to the configure script like that: \texttt{--arg 1} \texttt{--arg 2}. The second list contains arguments that should be
+   defined before running the configure script such as autoconf or compiler specific variables.
+   
+   To make it easier to modify the configure command line, you can either extend or completely override the following variables:
+   \begin{itemize}
+     \item \texttt{CONFIGURE\_ARGS} \\
+	     Contains all command line arguments (format: \texttt{--arg 1} \texttt{--arg 2})
+     \item \texttt{CONFIGURE\_VARS} \\
+	     Contains all environment variables that are passed to ./configure (format: \texttt{NAME="value"})
+   \end{itemize}
+
+\textbf{\texttt{Build/Compile} (optional):} \\
+   How to compile the source; in most cases you should leave this undefined.
+   
+   As with \texttt{Build/Configure} there are two variables that allow you to override
+   the make command line environment variables and flags:
+   \begin{itemize}
+     \item \texttt{MAKE\_FLAGS} \\
+	   Contains all command line arguments (typically variable overrides like \texttt{NAME="value"}
+	 \item \texttt{MAKE\_VARS} \\
+	   Contains all environment variables that are passed to the make command
+   \end{itemize}
+
+\textbf{\texttt{Build/InstallDev} (optional):} \\
+	If your package provides a library that needs to be made available to other packages,
+	you can use the \texttt{Build/InstallDev} template to copy it into the staging directory
+	which is used to collect all files that other packages might depend on at build time.
+	When it is called by the build system, two parameters are passed to it. \texttt{\$(1)} points to
+	the regular staging dir, typically \texttt{staging\_dir/\textit{ARCH}}, while \texttt{\$(2)} points
+	to \texttt{staging\_dir/host}. The host staging dir is only used for binaries, which are
+	to be executed or linked against on the host and its \texttt{bin/} subdirectory is included
+	in the \texttt{PATH} which is passed down to the build system processes.
+	Please use \texttt{\$(1)} and \texttt{\$(2)} here instead of the build system variables
+	\texttt{\$(STAGING\_DIR)} and \texttt{\$(STAGING\_DIR\_HOST)}, because the build system behavior
+	when staging libraries might change in the future to include automatic uninstallation.
+
+\textbf{\texttt{Package/\textit{<name>}/install}:} \\
+   A set of commands to copy files out of the compiled source and into the ipkg
+   which is represented by the \texttt{\$(1)} directory. Note that there are currently
+   4 defined install macros:
+   \begin{itemize}
+       \item \texttt{INSTALL\_DIR} \\
+           install -d -m0755
+       \item \texttt{INSTALL\_BIN} \\
+           install -m0755
+       \item \texttt{INSTALL\_DATA} \\
+           install -m0644
+       \item \texttt{INSTALL\_CONF} \\
+           install -m0600
+   \end{itemize}
+
+The reason that some of the defines are prefixed by "\texttt{Package/\textit{<name>}}"
+and others are simply "\texttt{Build}" is because of the possibility of generating
+multiple packages from a single source. OpenWrt works under the assumption of one
+source per package Makefile, but you can split that source into as many packages as
+desired. Since you only need to compile the sources once, there's one global set of
+"\texttt{Build}" defines, but you can add as many "Package/<name>" defines as you want
+by adding extra calls to \texttt{BuildPackage} -- see the dropbear package for an example.
+
+After you have created your \texttt{package/\textit{<name>}/Makefile}, the new package
+will automatically show in the menu the next time you run "make menuconfig" and if selected
+will be built automatically the next time "\texttt{make}" is run.
+
+\subsection{Creating binary packages}
+
+You might want to create binary packages and include them in the resulting images as packages.
+To do so, you can use the following template, which basically sets to nothing the Configure and
+Compile templates.
+
+\begin{Verbatim}[frame=single,numbers=left]
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=binpkg
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=binpkg-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://server
+PKG_MD5SUM:=9b7dc52656f5cbec846a7ba3299f73bd
+PKG_CAT:=zcat
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/binpkg
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Binary package
+endef
+
+define Package/bridge/description
+  Binary package
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/bridge/install
+    $(INSTALL_DIR) $(1)/usr/sbin
+    $(INSTALL_BIN) $(PKG_BUILD_DIR)/* $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,bridge))
+\end{Verbatim}
+
+Provided that the tarball which contains the binaries reflects the final
+directory layout (/usr, /lib ...), it becomes very easy to get your package
+look like one build from sources.
+
+Note that using the same technique, you can easily create binary pcakages
+for your proprietary kernel modules as well.
+
+\subsection{Creating kernel modules packages}
+
+The OpenWrt distribution makes the distinction between two kind of kernel modules, those coming along with the mainline kernel, and the others available as a separate project. We will see later that a common template is used for both of them.
+
+For kernel modules that are part of the mainline kernel source, the makefiles are located in \textit{package/kernel/modules/*.mk} and they appear under the section "Kernel modules"
+
+For external kernel modules, you can add them to the build system just like if they were software packages by defining a KernelPackage section in the package makefile.
+
+Here for instance the Makefile for the I2C subsytem kernel modules :
+
+\begin{Verbatim}[frame=single,numbers=left]
+
+I2CMENU:=I2C Bus
+
+define KernelPackage/i2c-core
+  TITLE:=I2C support
+  DESCRIPTION:=Kernel modules for i2c support
+  SUBMENU:=$(I2CMENU)
+  KCONFIG:=CONFIG_I2C_CORE CONFIG_I2C_DEV
+  FILES:=$(MODULES_DIR)/kernel/drivers/i2c/*.$(LINUX_KMOD_SUFFIX)
+  AUTOLOAD:=$(call AutoLoad,50,i2c-core i2c-dev)
+endef
+$(eval $(call KernelPackage,i2c-core))
+\end{Verbatim}
+
+To group kernel modules under a common description in menuconfig, you might want to define a \textit{<description>MENU} variable on top of the kernel modules makefile.
+
+\begin{itemize}
+    \item \texttt{TITLE} \\
+        The name of the module as seen via menuconfig
+    \item \texttt{DESCRIPTION} \\
+        The description as seen via help in menuconfig
+    \item \texttt{SUBMENU} \\
+        The sub menu under which this package will be seen
+    \item \texttt{KCONFIG} \\
+        Kernel configuration option dependency. For external modules, remove it.
+    \item \texttt{FILES} \\
+        Files you want to inlude to this kernel module package, separate with spaces.
+    \item \texttt{AUTOLOAD} \\
+        Modules that will be loaded automatically on boot, the order you write them is the order they would be loaded.
+\end{itemize}
+
+After you have created your \texttt{package/kernel/modules/\textit{<name>}.mk}, the new kernel modules package
+will automatically show in the menu under "Kernel modules" next time you run "make menuconfig" and if selected
+will be built automatically the next time "\texttt{make}" is run.
+
+\subsection{Conventions}
+
+There are a couple conventions to follow regarding packages:
+
+\begin{itemize}
+    \item \texttt{files}
+    \begin{enumerate}
+        \item configuration files follow the convention \\
+        \texttt{\textit{<name>}.conf}
+        \item init files follow the convention \\
+        \texttt{\textit{<name>}.init}
+    \end{enumerate}
+    \item \texttt{patches}
+    \begin{enumerate}
+        \item patches are numerically prefixed and named related to what they do
+    \end{enumerate}
+\end{itemize}
+
+\subsection{Troubleshooting}
+
+If you find your package doesn't show up in menuconfig, try the following command to
+see if you get the correct description:
+
+\begin{Verbatim}
+  TOPDIR=$PWD make -C package/<name> DUMP=1 V=99
+\end{Verbatim}
+
+If you're just having trouble getting your package to compile, there's a few
+shortcuts you can take. Instead of waiting for make to get to your package, you can
+run one of the following:
+
+\begin{itemize}
+    \item \texttt{make package/\textit{<name>}/clean V=99}
+    \item \texttt{make package/\textit{<name>}/install V=99}
+\end{itemize}
+
+Another nice trick is that if the source directory under \texttt{build\_dir/\textit{<arch>}}
+is newer than the package directory, it won't clobber it by unpacking the sources again.
+If you were working on a patch you could simply edit the sources under the
+\texttt{build\_dir/\textit{<arch>}/\textit{<source>}} directory and run the install command above,
+when satisfied, copy the patched sources elsewhere and diff them with the unpatched
+sources. A warning though - if you go modify anything under \texttt{package/\textit{<name>}}
+it will remove the old sources and unpack a fresh copy.
+
+Other useful targets include:
+
+\begin{itemize}
+    \item \texttt{make package/\textit{<name>}/prepare V=99}
+    \item \texttt{make package/\textit{<name>}/compile V=99}
+    \item \texttt{make package/\textit{<name>}/configure V=99}
+\end{itemize}
+
+
+\subsection{Using build environments}
+OpenWrt provides a means of building images for multiple configurations
+which can use multiple targets in one single checkout. These \emph{environments}
+store a copy of the .config file generated by \texttt{make menuconfig} and the contents
+of the \texttt{./files} folder.
+The script \texttt{./scripts/env} is used to manage these environments, it uses
+\texttt{git} (which needs to be installed on your system) as backend for version control.
+
+The command 
+\begin{Verbatim}
+  ./scripts/env help
+\end{Verbatim}
+produces a short help text with a list of commands.
+
+To create a new environment named \texttt{current}, run the following command
+\begin{Verbatim}
+  ./scripts/env new current
+\end{Verbatim}
+This will move your \texttt{.config} file and \texttt{./files} (if it exists) to
+the \texttt{env/} subdirectory and create symlinks in the base folder.
+
+After running make menuconfig or changing things in files/, your current state will
+differ from what has been saved before. To show these changes, use:
+\begin{Verbatim}
+  ./scripts/env diff
+\end{Verbatim}
+
+If you want to save these changes, run:
+\begin{Verbatim}
+  ./scripts/env save
+\end{Verbatim}
+If you want to revert your changes to the previously saved copy, run:
+\begin{Verbatim}
+  ./scripts/env revert
+\end{Verbatim}
+
+If you want, you can now create a second environment using the \texttt{new} command.
+It will ask you whether you want to make it a clone of the current environment (e.g.
+for minor changes) or if you want to start with a clean version (e.g. for selecting
+a new target).
+
+To switch to a different environment (e.g. \texttt{test1}), use:
+\begin{Verbatim}
+  ./scripts/env switch test1
+\end{Verbatim}
+
+To rename the current branch to a new name (e.g. \texttt{test2}), use:
+\begin{Verbatim}
+  ./scripts/env rename test2
+\end{Verbatim}
+
+If you want to get rid of environment switching and keep everything in the base directory
+again, use:
+\begin{Verbatim}
+  ./scripts/env clear
+\end{Verbatim}

+ 101 - 0
docs/config.tex

@@ -0,0 +1,101 @@
+\subsubsection{Structure of the configuration files}
+
+The config files are divided into sections and options/values.
+
+Every section has a type, but does not necessarily have a name.
+Every option has a name and a value and is assigned to the section
+it was written under.
+
+Syntax:
+
+\begin{Verbatim}
+config      <type> ["<name>"]      # Section
+    option  <name> "<value>"       # Option
+\end{Verbatim}
+
+Every parameter needs to be a single string and is formatted exactly
+like a parameter for a shell function. The same rules for Quoting and
+special characters also apply, as it is parsed by the shell.
+
+\subsubsection{Parsing configuration files in custom scripts}
+
+To be able to load configuration files, you need to include the common
+functions with:
+
+\begin{Verbatim}
+. /lib/functions.sh
+\end{Verbatim}
+
+Then you can use \texttt{config\_load \textit{<name>}} to load config files. The function
+first checks for \textit{<name>} as absolute filename and falls back to loading
+it from \texttt{/etc/config} (which is the most common way of using it).
+
+If you want to use special callbacks for sections and/or options, you
+need to define the following shell functions before running \texttt{config\_load}
+(after including \texttt{/lib/functions.sh}):
+
+\begin{Verbatim}
+config_cb() {
+    local type="$1"
+    local name="$2"
+    # commands to be run for every section
+}
+
+option_cb() {
+    # commands to be run for every option
+}
+\end{Verbatim}
+
+You can also alter \texttt{option\_cb} from \texttt{config\_cb} based on the section type.
+This allows you to process every single config section based on its type
+individually.
+
+\texttt{config\_cb} is run every time a new section starts (before options are being
+processed). You can access the last section through the \texttt{CONFIG\_SECTION}
+variable. Also an extra call to \texttt{config\_cb} (without a new section) is generated
+after \texttt{config\_load} is done.
+That allows you to process sections both before and after all options were
+processed.
+
+Another way of iterating on config sections is using the \texttt{config\_foreach} command.
+
+Syntax:
+\begin{Verbatim}
+config_foreach <function name> [<sectiontype>] [<arguments...>]
+\end{Verbatim}
+
+This command will run the supplied function for every single config section in the currently
+loaded config. The section name will be passed to the function as argument 1.
+If the section type is added to the command line, the function will only be called for
+sections of the given type.
+
+
+You can access already processed options with the \texttt{config\_get} command
+Syntax:
+
+\begin{Verbatim}
+# print the value of the option
+config_get <section> <option>
+
+# store the value inside the variable
+config_get <variable> <section> <option>
+\end{Verbatim}
+
+In busybox ash the three-option \texttt{config\_get} is faster, because it does not
+result in an extra fork, so it is the preferred way.
+
+Additionally you can also modify or add options to sections by using the
+\texttt{config\_set} command.
+
+Syntax:
+
+\begin{Verbatim}
+config_set <section> <option> <value>
+\end{Verbatim}
+
+If a config section is unnamed, an automatically generated name will
+be assigned internally, e.g. \texttt{cfg1}, \texttt{cfg2}, ...
+
+While it is possible, using unnamed sections through these autogenerated names is
+strongly discouraged. Use callbacks or \texttt{config\_foreach} instead.
+

+ 61 - 0
docs/debugging.tex

@@ -0,0 +1,61 @@
+Debugging hardware can be tricky especially when doing kernel and drivers
+development. It might become handy for you to add serial console to your
+device as well as using JTAG to debug your code.
+
+\subsection{Adding a serial port}
+
+Most routers come with an UART integrated into the System-on-chip
+and its pins are routed on the Printed Circuit Board to allow
+debugging, firmware replacement or serial device connection (like
+modems).
+
+Finding an UART on a router is fairly easy since it only needs at
+least 4 signals (without modem signaling) to work : VCC, GND, TX and
+RX. Since your router is very likely to have its I/O pins working at
+3.3V (TTL level), you will need a level shifter such as a Maxim MAX232
+to change the level from 3.3V to your computer level which is usually
+at 12V.
+
+To find out the serial console pins on the PCB, you will be looking
+for a populated or unpopulated 4-pin header, which can be far from
+the SoC (signals are relatively slow) and usually with tracks on
+the top or bottom layer of the PCB, and connected to the TX and RX.
+
+Once found, you can easily check where is GND, which is connected to
+the same ground layer than the power connector. VCC should be fixed
+at 3.3V and connected to the supply layer, TX is also at 3.3V level
+but using a multimeter as an ohm-meter and showing an infinite
+value between TX and VCC pins will tell you about them being different
+signals (or not). RX and GND are by default at 0V, so using the same
+technique you can determine the remaining pins like this.
+
+If you do not have a multimeter a simple trick that usually works is
+using a speaker or a LED to determine the 3.3V signals. Additionnaly
+most PCB designer will draw a square pad to indicate ping number 1.
+
+Once found, just interface your level shifter with the device and the
+serial port on the PC on the other side. Most common baudrates for the
+off-the-shelf devices are 9600, 38400 and 115200 with 8-bits data, no
+parity, 1-bit stop.
+
+\subsection{JTAG}
+
+JTAG stands for Joint Test Action Group, which is an IEEE workgroup
+defining an electrical interface for integrated circuit testing and
+programming.
+
+There is usually a JTAG automate integrated into your System-on-Chip
+or CPU which allows an external software, controlling the JTAG adapter
+to make it perform commands like reads and writes at arbitray locations.
+Additionnaly it can be useful to recover your devices if you erased the
+bootloader resident on the flash.
+
+Different CPUs have different automates behavior and reset sequence,
+most likely you will find ARM and MIPS CPUs, both having their standard
+to allow controlling the CPU behavior using JTAG.
+
+Finding JTAG connector on a PCB can be a little easier than finding the
+UART since most vendors leave those headers unpopulated after production.
+JTAG connectors are usually 12, 14, or 20-pins headers with one side of
+the connector having some signals at 3.3V and the other side being
+connected to GND.

+ 60 - 0
docs/init-scripts.tex

@@ -0,0 +1,60 @@
+Because OpenWrt uses its own init script system, all init scripts must be installed
+as \texttt{/etc/init.d/\textit{name}} use \texttt{/etc/rc.common} as a wrapper.
+
+Example: \texttt{/etc/init.d/httpd}
+
+\begin{Verbatim}
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=50
+start() {
+    [ -d /www ] && httpd -p 80 -h /www -r OpenWrt
+}
+
+stop() {
+    killall httpd
+}
+\end{Verbatim}
+
+as you can see, the script does not actually parse the command line arguments itself.
+This is done by the wrapper script \texttt{/etc/rc.common}.
+
+\texttt{start()} and \texttt{stop()} are the basic functions, which almost any init
+script should provide. \texttt{start()} is called when the user runs \texttt{/etc/init.d/httpd start}
+or (if the script is enabled and does not override this behavior) at system boot time.
+
+Enabling and disabling init scripts is done by running \texttt{/etc/init.d/\textit{name} enable}
+or \texttt{/etc/init.d/\textit{name} disable}. This creates or removes symbolic links to the
+init script in \texttt{/etc/rc.d}, which is processed by \texttt{/etc/init.d/rcS} at boot time.
+
+The order in which these scripts are run is defined in the variable \texttt{START} in the init
+script. Changing it requires running \texttt{/etc/init.d/\textit{name} enable} again.
+
+You can also override these standard init script functions:
+\begin{itemize}
+    \item \texttt{boot()} \\
+        Commands to be run at boot time. Defaults to \texttt{start()}
+
+    \item \texttt{restart()} \\
+        Restart your service. Defaults to \texttt{stop(); start()}
+
+    \item \texttt{reload()} \\
+        Reload the configuration files for your service. Defaults to \texttt{restart()}
+
+\end{itemize}
+
+You can also add custom commands by creating the appropriate functions and referencing them
+in the \texttt{EXTRA\_COMMANDS} variable. Helptext is added in \texttt{EXTRA\_HELP}.
+
+Example:
+
+\begin{Verbatim}
+status() {
+    # print the status info
+}
+
+EXTRA_COMMANDS="status"
+EXTRA_HELP="        status  Print the status of the service"
+\end{Verbatim}
+

+ 55 - 0
docs/network-scripts.tex

@@ -0,0 +1,55 @@
+\subsubsection{Using the network scripts}
+
+To be able to access the network functions, you need to include
+the necessary shell scripts by running:
+
+\begin{Verbatim}
+. /lib/functions.sh      # common functions
+include /lib/network     # include /lib/network/*.sh
+scan_interfaces          # read and parse the network config
+\end{Verbatim}
+
+Some protocols, such as PPP might change the configured interface names
+at run time (e.g. \texttt{eth0} => \texttt{ppp0} for PPPoE). That's why you have to run
+\texttt{scan\_interfaces} instead of reading the values from the config directly.
+After running \texttt{scan\_interfaces}, the \texttt{'ifname'} option will always contain
+the effective interface name (which is used for IP traffic) and if the
+physical device name differs from it, it will be stored in the \texttt{'device'}
+option.
+That means that running \texttt{config\_get lan ifname}
+after \texttt{scan\_interfaces} might not return the same result as running it before.
+
+After running \texttt{scan\_interfaces}, the following functions are available:
+
+\begin{itemize}
+    \item{\texttt{find\_config \textit{interface}}} \\
+        looks for a network configuration that includes
+        the specified network interface.
+
+    \item{\texttt{setup\_interface \textit{interface [config] [protocol]}}} \\
+      will set up the specified interface, optionally overriding the network configuration
+      name or the protocol that it uses.
+\end{itemize}
+
+\subsubsection{Writing protocol handlers}
+
+You can add custom protocol handlers (e.g: PPPoE, PPPoA, ATM, PPTP ...)
+by adding shell scripts to \texttt{/lib/network}. They provide the following
+two shell functions:
+
+\begin{Verbatim}
+scan_<protocolname>() {
+    local config="$1"
+    # change the interface names if necessary
+}
+
+setup_interface_<protocolname>() {
+    local interface="$1"
+    local config="$2"
+    # set up the interface
+}
+\end{Verbatim}
+
+\texttt{scan\_\textit{protocolname}} is optional and only necessary if your protocol
+uses a custom device, e.g. a tunnel or a PPP device.
+

+ 231 - 0
docs/network.tex

@@ -0,0 +1,231 @@
+The network configuration is stored in \texttt{/etc/config/network}
+and is divided into interface configurations.
+Each interface configuration either refers directly to an ethernet/wifi
+interface (\texttt{eth0}, \texttt{wl0}, ..) or to a bridge containing multiple interfaces.
+It looks like this:
+
+\begin{Verbatim}
+config interface     "lan"
+    option ifname    "eth0"
+    option proto     "static"
+    option ipaddr    "192.168.1.1"
+    option netmask   "255.255.255.0"
+    option gateway   "192.168.1.254"
+    option dns       "192.168.1.254"
+\end{Verbatim}
+
+\texttt{ifname} specifies the Linux interface name.
+If you want to use bridging on one or more interfaces, set \texttt{ifname} to a list
+of interfaces and add:
+\begin{Verbatim}
+    option type     "bridge"
+\end{Verbatim}
+
+It is possible to use VLAN tagging on an interface simply by adding the VLAN IDs
+to it, e.g. \texttt{eth0.15}. These can be nested as well. See the switch section for
+this.
+
+\begin{Verbatim}
+config interface
+    option ifname    "eth0.15"
+    option proto     "none"
+\end{Verbatim}
+
+This sets up a simple static configuration for \texttt{eth0}. \texttt{proto} specifies the
+protocol used for the interface. The default image usually provides \texttt{'none'}
+\texttt{'static'}, \texttt{'dhcp'} and \texttt{'pppoe'}. Others can be added by installing additional
+packages.
+
+When using the \texttt{'static'} method like in the example, the  options \texttt{ipaddr} and
+\texttt{netmask} are mandatory, while \texttt{gateway} and \texttt{dns} are optional.
+You can specify more than one DNS server, separated with spaces:
+
+\begin{Verbatim}
+config interface     "lan"
+    option ifname    "eth0"
+    option proto     "static"
+    ...
+    option dns       "192.168.1.254 192.168.1.253" (optional)
+\end{Verbatim}
+
+DHCP currently only accepts \texttt{ipaddr} (IP address to request from the server)
+and \texttt{hostname} (client hostname identify as) - both are optional.
+
+\begin{Verbatim}
+config interface     "lan"
+    option ifname    "eth0"
+    option proto     "dhcp"
+    option ipaddr    "192.168.1.1" (optional)
+    option hostname  "openwrt"     (optional)
+\end{Verbatim}
+
+PPP based protocols (\texttt{pppoe}, \texttt{pptp}, ...) accept these options:
+\begin{itemize}
+    \item{username} \\
+        The PPP username (usually with PAP authentication)
+    \item{password} \\
+        The PPP password
+    \item{keepalive} \\
+        Ping the PPP server (using LCP). The value of this option
+        specifies the maximum number of failed pings before reconnecting.
+        The ping interval defaults to 5, but can be changed by appending
+        ",<interval>" to the keepalive value
+    \item{demand} \\
+        Use Dial on Demand (value specifies the maximum idle time.
+    \item{server: (pptp)} \\
+        The remote pptp server IP
+\end{itemize}
+
+For all protocol types, you can also specify the MTU by using the \texttt{mtu} option.
+A sample PPPoE config would look like this:
+
+\begin{Verbatim}
+config interface     "lan"
+    option ifname    "eth0"
+    option proto     "pppoe"
+    option username  "username"
+    option password  "openwrt"
+    option mtu       "1492"      (optional)
+\end{Verbatim}
+
+\subsubsection{Setting up static routes}
+
+You can set up static routes for a specific interface that will be brought up 
+after the interface is configured.
+
+Simply add a config section like this:
+
+\begin{Verbatim}
+config route foo
+	option interface  "lan"
+	option target     "1.1.1.0"
+	option netmask    "255.255.255.0"
+	option gateway    "192.168.1.1"
+\end{Verbatim}
+
+The name for the route section is optional, the \texttt{interface}, \texttt{target} and 
+\texttt{gateway} options are mandatory.
+Leaving out the \texttt{netmask} option will turn the route into a host route.
+
+\subsubsection{Setting up the switch (broadcom only)}
+
+The switch configuration is set by adding a \texttt{'switch'} config section.
+Example:
+
+\begin{Verbatim}
+config switch       "eth0"
+    option vlan0    "1 2 3 4 5*"
+    option vlan1    "0 5"
+\end{Verbatim}
+
+On Broadcom hardware the section name needs to be eth0, as the switch driver
+does not detect the switch on any other physical device.
+Every vlan option needs to have the name vlan<n> where <n> is the VLAN number
+as used in the switch driver.
+As value it takes a list of ports with these optional suffixes:
+
+\begin{itemize}
+    \item{\texttt{'*'}:}
+        Set the default VLAN (PVID) of the Port to the current VLAN
+    \item{\texttt{'u'}:}
+        Force the port to be untagged
+    \item{\texttt{'t'}:}
+        Force the port to be tagged
+\end{itemize}
+
+The CPU port defaults to tagged, all other ports to untagged.
+On Broadcom hardware the CPU port is always 5. The other ports may vary with
+different hardware.
+
+For instance, if you wish to have 3 vlans, like one 3-port switch, 1 port in a
+DMZ, and another one as your WAN interface, use the following configuration :
+
+\begin{Verbatim}
+config switch       "eth0"
+    option vlan0    "1 2 3 5*"
+    option vlan1    "0 5"
+    option vlan2    "4 5"
+\end{Verbatim}
+
+Three interfaces will be automatically created using this switch layout :
+\texttt{eth0.0} (vlan0), \texttt{eth0.1} (vlan1) and \texttt{eth0.2} (vlan2).
+You can then assign those interfaces to a custom network configuration name
+like \texttt{lan}, \texttt{wan} or \texttt{dmz} for instance.
+
+\subsubsection{Setting up the switch (swconfig)}
+
+\emph{swconfig} based configurations have a different structure with one extra
+section per vlan. The example below shows a typical configuration:
+
+\begin{Verbatim}
+config 'switch' 'eth0'
+        option 'reset' '1'
+        option 'enable_vlan' '1'
+
+config 'switch_vlan' 'eth0_1'
+        option 'device' 'eth0'
+        option 'vlan' '1'
+        option 'ports' '0 1 2 3 5t'
+
+config 'switch_vlan' 'eth0_2'
+        option 'device' 'eth0'
+        option 'vlan' '2'
+        option 'ports' '4 5t'
+\end{Verbatim}
+
+\subsubsection{Setting up IPv6 connectivity}
+
+OpenWrt supports IPv6 connectivity using PPP, Tunnel brokers or static
+assignment.
+
+If you use PPP, IPv6 will be setup using IP6CP and there is nothing to
+configure.
+
+To setup an IPv6 tunnel to a tunnel broker, you can install the
+\texttt{6scripts} package and edit the \texttt{/etc/config/6tunnel}
+file and change the settings accordingly :
+
+\begin{Verbatim}
+config 6tunnel
+        option tnlifname     'sixbone'
+        option remoteip4     '1.0.0.1'
+        option localip4      '1.0.0.2'
+        option localip6      '2001::DEAD::BEEF::1'
+\end{Verbatim}
+
+\begin{itemize}
+    \item{\texttt{'tnlifname'}:}
+        Set the interface name of the IPv6 in IPv4 tunnel
+    \item{\texttt{'remoteip4'}:}
+        IP address of the remote end to establish the 6in4 tunnel.
+	This address is given by the tunnel broker
+    \item{\texttt{'localip4'}:}
+	IP address of your router to establish the 6in4 tunnel.
+	It will usually match your WAN IP address.
+    \item{\texttt{'localip6'}:}
+	IPv6 address to setup on your tunnel side
+	This address is given by the tunnel broker
+\end{itemize}
+
+Using the same package you can also setup an IPv6 bridged connection:
+
+\begin{Verbatim}
+config 6bridge
+	option bridge	'br6'
+\end{Verbatim}
+
+By default the script bridges the WAN interface with the LAN interface
+and uses ebtables to filter anything that is not IPv6 on the bridge.
+This configuration is particularly useful if your router is not
+IPv6 ND proxy capable (see: http://www.rfc-archive.org/getrfc.php?rfc=4389).
+
+IPv6 static addressing is also supported using a similar setup as
+IPv4 but with the \texttt{ip6} prefixing (when applicable).
+
+\begin{Verbatim}
+config interface     "lan"
+    option ifname    "eth0"
+    option proto     "static"
+    option ip6addr   "fe80::200:ff:fe00:0/64"
+    option ip6gw     "2001::DEAF:BEE:1"
+\end{Verbatim}

+ 10 - 0
docs/openwrt.sty

@@ -0,0 +1,10 @@
+\ProvidesPackage{openwrt}
+
+\usepackage[latin9]{inputenc}
+\usepackage[bookmarks=true color=blue colorlinks=true]{hyperref}
+\usepackage[T1]{fontenc}
+\usepackage{ae,aecompl,aeguill}
+\usepackage{fancyvrb}
+\usepackage{enumerate}
+\setlength{\parindent}{0pt}
+\setlength{\parskip}\medskipamount

+ 41 - 0
docs/openwrt.tex

@@ -0,0 +1,41 @@
+\documentclass[a4paper]{book}
+
+\usepackage{openwrt}
+
+\begin{document}
+\tableofcontents
+\chapter{The Router}
+  \section{Getting started}
+    \subsection{Installation}
+    \subsection{Initial configuration}
+    \subsection{Failsafe mode}
+  \section{Configuring OpenWrt}
+    \subsection{Network}
+      \input{network}
+    \subsection{Wireless}
+      \input{wireless}
+  \section{Advanced configuration}
+    \input{config}
+    \subsection{Hotplug}
+    \subsection{Init scripts}
+      \input{init-scripts}
+    \subsection{Network scripts}
+      \input{network-scripts}
+\chapter{Development issues}
+  \section{The build system}
+    \input{build}
+  \section{Extra tools}
+    \subsection{Image Builder}
+    \subsection{SDK}
+  \section{Working with OpenWrt}
+    \input{working}
+  \section{Adding platform support}
+     \input{adding}
+  \section{Debugging and debricking}
+     \input{debugging}
+   \section{Reporting bugs}
+	\subsection{Using the Trac ticket system}
+	\input{bugs}
+   \section{Submitting patches}
+    \input{submitting-patches}
+\end{document}

+ 53 - 0
docs/submitting-patches.tex

@@ -0,0 +1,53 @@
+\subsection{How to contribute}
+OpenWrt is constantly being improved.  We'd like as many people to contribute
+to this as we can get. If you find a change useful, by all means try to get
+it incorporated into the project. This should improve OpenWrt and it should
+help carry your changes forward into future versions
+
+This section tries to lay out a procedure to enable people to submit patches
+in a way that is most effective for all concerned.
+
+It is important to do all these steps repeatedly:
+
+\begin{itemize}
+	\item \textit{listen} to what other people think.
+	\item \textit{talk} explaining what problem you are addressing and your
+		proposed solution.
+	\item \textit{do} write useful patches including documentation.
+    \item \textit{test. test. test.}
+\end{itemize}
+
+\subsection{Where to listen and talk}
+
+\begin{itemize}
+	\item google to find things related to your problem
+	\item Mailing lists: \href{http://lists.openwrt.org/}{http://lists.openwrt.org/}
+	\item Wiki: check the wiki: \href{http://wiki.openwrt.org/OpenWrtDocs}{http://wiki.openwrt.org/OpenWrtDocs}
+	\item Forum: \href{http://forum.openwrt.org/}{http://forum.openwrt.org/}
+	\item IRC: \texttt{irc.freenode.net}, channels \texttt{\#openwrt} and 
+		\texttt{\#openwrt-devel}
+	\item TRAC: \href{https://dev.openwrt.org/}{https://dev.openwrt.org/} the issue/bug/change tracking system
+\end{itemize}
+
+It is often best to document what you are doing before you do it.  The process
+of documentation often exposes possible improvements.  Keep your documentation
+up to date.
+
+\subsection{Patch Submission Process}
+\begin{enumerate}
+	\item Use git or svn to create a patch. Creating patches manually with 
+		\textit{diff -urN} also works, but is usually unnecessary.
+	\item Send a mail to openwrt-devel@lists.openwrt.org with the following contents:
+	\begin{enumerate}
+		\item \texttt{[PATCH] <short description>} in the Subject, followed by:
+		\item (optional) a longer description of your patch in the message body
+        \item \texttt{Signed-off-by: Your name <your@email.address>}
+		\item Your actual patch, inline, not word wrapped or whitespace mangled. 
+	\end{enumerate}
+	\item Please read \href{http://kerneltrap.org/Linux/Email\_Clients\_and\_Patches}{http://kerneltrap.org/Linux/Email\_Clients\_and\_Patches}
+		to find out how to make sure your email client doesn't destroy your patch.
+	\item Please use your real name and email address in the \texttt{Signed-off-by}
+		line, following the same guidelines as in the \href{http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/SubmittingPatches;h=681e2b36195c98ea5271b76383b3a574b190b04f;hb=HEAD}{Linux Kernel patch submission guidelines}
+	\item Example of a properly formatted patch submission: \\
+	\href{http://lists.openwrt.org/pipermail/openwrt-devel/2007-November/001334.html}{http://lists.openwrt.org/pipermail/openwrt-devel/2007-November/001334.html}
+\end{enumerate}

+ 492 - 0
docs/wireless.tex

@@ -0,0 +1,492 @@
+The WiFi settings are configured in the file \texttt{/etc/config/wireless}
+(currently supported on Broadcom, Atheros and mac80211). When booting the router for the first time
+it should detect your card and create a sample configuration file. By default '\texttt{option network  lan}' is
+commented. This prevents unsecured sharing of the network over the wireless interface.
+
+Each wireless driver has its own configuration script in \texttt{/lib/wifi/driver\_name.sh} which handles
+driver specific options and configurations. This script is also calling driver specific binaries like wlc for
+Broadcom, or hostapd and wpa\_supplicant for atheros and mac80211.
+
+The reason for using such architecture, is that it abstracts the driver configuration. 
+
+\paragraph{Generic Broadcom wireless config:}
+
+\begin{Verbatim}
+config wifi-device      "wl0"
+    option type         "broadcom"
+    option channel      "5"
+
+config wifi-iface
+    option device       "wl0"
+#   option network  lan
+    option mode         "ap"
+    option ssid         "OpenWrt"
+    option hidden       "0"
+    option encryption   "none"
+\end{Verbatim}
+
+\paragraph{Generic Atheros wireless config:}
+
+\begin{Verbatim}
+config wifi-device      "wifi0"
+    option type         "atheros"
+    option channel      "5"
+    option hwmode	"11g"
+
+config wifi-iface
+    option device       "wifi0"
+#   option network  lan
+    option mode         "ap"
+    option ssid         "OpenWrt"
+    option hidden       "0"
+    option encryption   "none"
+\end{Verbatim}
+
+\paragraph{Generic mac80211 wireless config:}
+
+\begin{Verbatim}
+config wifi-device      "wifi0"
+    option type         "mac80211"
+    option channel      "5"
+
+config wifi-iface
+    option device       "wlan0"
+#   option network  lan
+    option mode         "ap"
+    option ssid         "OpenWrt"
+    option hidden       "0"
+    option encryption   "none"
+\end{Verbatim}
+
+\paragraph{Generic multi-radio Atheros wireless config:}
+
+\begin{Verbatim}
+config wifi-device  wifi0
+    option type     atheros
+    option channel  1
+
+config wifi-iface
+    option device   wifi0
+#   option network  lan
+    option mode     ap
+    option ssid     OpenWrt_private
+    option hidden   0
+    option encryption none
+
+config wifi-device  wifi1
+    option type     atheros
+    option channel  11
+
+config wifi-iface
+    option device   wifi1
+#   option network  lan
+    option mode     ap
+    option ssid     OpenWrt_public
+    option hidden   1
+    option encryption none
+\end{Verbatim}
+
+There are two types of config sections in this file. The '\texttt{wifi-device}' refers to
+the physical wifi interface and '\texttt{wifi-iface}' configures a virtual interface on top
+of that (if supported by the driver).
+
+A full outline of the wireless configuration file with description of each field:
+
+\begin{Verbatim}
+config wifi-device    wifi device name
+    option type       broadcom, atheros, mac80211
+    option country    us, uk, fr, de, etc.
+    option channel    1-14
+    option maxassoc   1-128 (broadcom only)
+    option distance   1-n (meters)
+    option hwmode     11b, 11g, 11a, 11bg (atheros, mac80211)
+    option rxantenna  0,1,2 (atheros, broadcom)
+    option txantenna  0,1,2 (atheros, broadcom)
+    option txpower  transmission power in dBm
+
+config wifi-iface
+    option network  the interface you want wifi to bridge with
+    option device   wifi0, wifi1, wifi2, wifiN
+    option mode     ap, sta, adhoc, monitor, mesh, or wds
+    option txpower  (deprecated) transmission power in dBm
+    option ssid     ssid name
+    option bssid    bssid address
+    option encryption none, wep, psk, psk2, wpa, wpa2
+    option key      encryption key
+    option key1     key 1
+    option key2     key 2
+    option key3     key 3
+    option key4     key 4
+    option passphrase 0,1
+    option server   ip address
+    option port     port
+    option hidden   0,1
+    option isolate  0,1	(broadcom)
+    option doth     0,1	(atheros, broadcom)
+    option wmm      0,1	(atheros, broadcom)
+\end{Verbatim}
+
+\paragraph{Options for the \texttt{wifi-device}:}
+
+\begin{itemize}
+    \item \texttt{type} \\
+        The driver to use for this interface.
+	
+    \item \texttt{country} \\
+        The country code used to determine the regulatory settings.
+
+    \item \texttt{channel} \\
+        The wifi channel (e.g. 1-14, depending on your country setting).
+
+    \item \texttt{maxassoc} \\
+        Optional: Maximum number of associated clients. This feature is supported only on the Broadcom chipsets.
+
+    \item \texttt{distance} \\
+	Optional: Distance between the ap and the furthest client in meters. This feature is supported only on the Atheros chipsets.
+
+	\item \texttt{mode} \\
+		The frequency band (\texttt{b}, \texttt{g}, \texttt{bg}, \texttt{a}). This feature is only supported on the Atheros chipsets.
+
+    \item \texttt{diversity} \\
+	Optional: Enable diversity for the Wi-Fi device. This feature is supported only on the Atheros chipsets.
+
+    \item \texttt{rxantenna} \\
+	Optional: Antenna identifier (0, 1 or 2) for reception. This feature is supported by Atheros and some Broadcom chipsets.
+
+    \item \texttt{txantenna} \\
+	Optional: Antenna identifier (0, 1 or 2) for emission. This feature is supported by Atheros and some Broadcom chipsets.
+
+    \item \texttt{txpower}
+	Set the transmission power to be used. The amount is specified in dBm.
+
+\end{itemize}
+
+\paragraph{Options for the \texttt{wifi-iface}:}
+
+\begin{itemize}
+    \item \texttt{network} \\
+        Selects the interface section from \texttt{/etc/config/network} to be
+        used with this interface
+
+    \item \texttt{device} \\
+	Set the wifi device name.
+
+    \item \texttt{mode} \\
+        Operating mode:
+
+        \begin{itemize}
+            \item \texttt{ap} \\
+                Access point mode
+
+            \item \texttt{sta} \\
+                Client mode
+
+            \item \texttt{adhoc} \\
+                Ad-Hoc mode
+
+            \item \texttt{monitor} \\
+                Monitor mode
+
+	    \item \texttt{mesh} \\
+		Mesh Point mode (802.11s)
+
+            \item \texttt{wds} \\
+                WDS point-to-point link
+
+        \end{itemize}
+
+    \item \texttt{ssid}
+	Set the SSID to be used on the wifi device.
+
+    \item \texttt{bssid}
+	Set the BSSID address to be used for wds to set the mac address of the other wds unit.
+
+    \item \texttt{txpower}
+	(Deprecated, set in wifi-device) Set the transmission power to be used. The amount is specified in dBm.
+
+    \item \texttt{encryption} \\
+        Encryption setting. Accepts the following values:
+
+        \begin{itemize}
+	    \item \texttt{none}
+	    \item \texttt{wep}
+            \item \texttt{psk}, \texttt{psk2} \\
+                WPA(2) Pre-shared Key
+
+            \item \texttt{wpa}, \texttt{wpa2} \\
+                WPA(2) RADIUS
+        \end{itemize}
+
+    \item \texttt{key, key1, key2, key3, key4} (wep, wpa and psk) \\
+        WEP key, WPA key (PSK mode) or the RADIUS shared secret (WPA RADIUS mode)
+
+    \item \texttt{passphrase} (wpa) \\
+        0 treats the wpa psk as a text passphrase; 1 treats wpa psk as
+        encoded passphrase. You can generate an encoded passphrase with
+        the wpa\_passphrase utility. This is especially useful if your
+        passphrase contains special characters. This option only works
+        when using mac80211 or atheros type devices.
+
+    \item \texttt{server} (wpa) \\
+        The RADIUS server ip address
+
+    \item \texttt{port} (wpa) \\
+        The RADIUS server port (defaults to 1812)
+
+    \item \texttt{hidden} \\
+        0 broadcasts the ssid; 1 disables broadcasting of the ssid
+
+    \item \texttt{isolate} \\
+        Optional: Isolation is a mode usually set on hotspots that limits the clients to communicate only with the AP and not with other wireless clients.
+        0 disables ap isolation (default); 1 enables ap isolation.
+
+    \item \texttt{doth} \\
+        Optional: Toggle 802.11h mode.
+        0 disables 802.11h (default); 1 enables it.
+
+    \item \texttt{wmm} \\
+        Optional: Toggle 802.11e mode.
+        0 disables 802.11e (default); 1 enables it.
+
+\end{itemize}
+
+\paragraph{Mesh Point}
+
+Mesh Point (802.11s) is only supported by some mac80211 drivers. It requires the iw package
+to be installed to setup mesh links. OpenWrt creates mshN mesh point interfaces. A sample
+configuration looks like this:
+
+\begin{Verbatim}
+config wifi-device      "wlan0"
+    option type		"mac80211"
+    option channel      "5"
+
+config wifi-iface
+    option device       "wlan0"
+    option network  	lan
+    option mode         "mesh"
+    option mesh_id     "OpenWrt"
+\end{Verbatim}
+
+\paragraph{Wireless Distribution System}
+
+WDS is a non-standard mode which will be working between two Broadcom devices for instance
+but not between a Broadcom and Atheros device.
+
+\subparagraph{Unencrypted WDS connections}
+
+This configuration example shows you how to setup unencrypted WDS connections.
+We assume that the peer configured as below as the BSSID ca:fe:ba:be:00:01
+and the remote WDS endpoint ca:fe:ba:be:00:02 (option bssid field).
+
+\begin{Verbatim}
+config wifi-device      "wl0"
+    option type		"broadcom"
+    option channel      "5"
+
+config wifi-iface
+    option device       "wl0"
+    option network  	lan
+    option mode         "ap"
+    option ssid         "OpenWrt"
+    option hidden       "0"
+    option encryption   "none"
+
+config wifi-iface
+    option device       "wl0"
+    option network      lan
+    option mode         wds
+    option ssid         "OpenWrt WDS"
+    option bssid        "ca:fe:ba:be:00:02"
+\end{Verbatim}
+
+\subparagraph{Encrypted WDS connections}
+
+It is also possible to encrypt WDS connections. \texttt{psk}, \texttt{psk2} and
+\texttt{psk+psk2} modes are supported. Configuration below is an example
+configuration using Pre-Shared-Keys with AES algorithm.
+
+\begin{Verbatim}
+config wifi-device  wl0
+    option type     broadcom
+    option channel  5
+
+config wifi-iface
+    option device   "wl0"
+    option network  lan
+    option mode     ap
+    option ssid     "OpenWrt"
+    option encryption  psk2
+    option key      "<key for clients>"
+
+config wifi-iface
+    option device   "wl0"
+    option network  lan
+    option mode     wds
+    option bssid    ca:fe:ba:be:00:02
+    option ssid     "OpenWrt WDS"
+    option encryption	psk2
+    option key      "<psk for WDS>"
+\end{Verbatim}
+
+\paragraph{802.1x configurations}
+
+OpenWrt supports both 802.1x client and Access Point
+configurations. 802.1x client is only working with
+drivers supported by wpa-supplicant. Configuration
+only supports EAP types TLS, TTLS or PEAP.
+
+\subparagraph{EAP-TLS}
+
+\begin{Verbatim}
+config wifi-iface
+    option device         "ath0"
+    option network        lan
+    option ssid           OpenWrt
+    option eap_type       tls
+    option ca_cert        "/etc/config/certs/ca.crt"
+    option priv_key       "/etc/config/certs/priv.crt"
+    option priv_key_pwd   "PKCS#12 passphrase"
+\end{Verbatim}
+
+\subparagraph{EAP-PEAP}
+
+\begin{Verbatim}
+config wifi-iface
+    option device         "ath0"
+    option network        lan
+    option ssid           OpenWrt
+    option eap_type       peap
+    option ca_cert        "/etc/config/certs/ca.crt"
+    option auth           MSCHAPV2
+    option identity       username
+    option password       password
+\end{Verbatim}
+
+\paragraph{Limitations:}
+
+There are certain limitations when combining modes.
+Only the following mode combinations are supported:
+
+\begin{itemize}
+    \item \textbf{Broadcom}: \\
+        \begin{itemize}
+            \item 1x \texttt{sta}, 0-3x \texttt{ap}
+            \item 1-4x \texttt{ap}
+            \item 1x \texttt{adhoc}
+            \item 1x \texttt{monitor}
+        \end{itemize}
+
+        WDS links can only be used in pure AP mode and cannot use WEP (except when sharing the
+        settings with the master interface, which is done automatically).
+
+    \item \textbf{Atheros}: \\
+        \begin{itemize}
+            \item 1x \texttt{sta}, 0-Nx \texttt{ap}
+            \item 1-Nx \texttt{ap}
+            \item 1x \texttt{adhoc}
+        \end{itemize}
+
+	N is the maximum number of VAPs that the module allows, it defaults to 4, but can be
+	changed by loading the module with the maxvaps=N parameter.
+\end{itemize}
+
+\paragraph{Adding a new driver configuration}
+
+Since we currently only support thread different wireless drivers : Broadcom, Atheros and mac80211,
+you might be interested in adding support for another driver like Ralink RT2x00, 
+Texas Instruments ACX100/111.
+
+The driver specific script should be placed in \texttt{/lib/wifi/<driver>.sh} and has to
+include several functions providing :
+
+\begin{itemize}
+	\item detection of the driver presence
+	\item enabling/disabling the wifi interface(s)
+	\item configuration reading and setting
+	\item third-party programs calling (nas, supplicant)
+\end{itemize}
+
+Each driver script should append the driver to a global DRIVERS variable :
+
+\begin{Verbatim}
+append DRIVERS "driver name"
+\end{Verbatim}
+
+\subparagraph{\texttt{scan\_<driver>}}
+
+This function will parse the \texttt{/etc/config/wireless} and make sure there
+are no configuration incompatibilities, like enabling hidden SSIDS with ad-hoc mode
+for instance. This can be more complex if your driver supports a lof of configuration
+options. It does not change the state of the interface.
+
+Example:
+\begin{Verbatim}
+scan_dummy() {
+	local device="$1"
+
+	config_get vifs "$device" vifs
+	for vif in $vifs; do
+		# check config consistency for wifi-iface sections
+	done
+	# check mode combination
+}
+\end{Verbatim}
+
+\subparagraph{\texttt{enable\_<driver>}}
+
+This function will bring up the wifi device and optionally create application specific
+configuration files, e.g. for the WPA authenticator or supplicant.
+
+Example:
+\begin{Verbatim}
+enable_dummy() {
+	local device="$1"
+
+	config_get vifs "$device" vifs
+	for vif in $vifs; do
+		# bring up virtual interface belonging to
+		# the wifi-device "$device"
+	done
+}
+\end{Verbatim}
+
+\subparagraph{\texttt{disable\_<driver>}}
+
+This function will bring down the wifi device and all its virtual interfaces (if supported).
+
+Example:
+\begin{Verbatim}
+disable_dummy() {
+	local device="$1"
+
+	# bring down virtual interfaces belonging to
+	# "$device" regardless of whether they are
+	# configured or not. Don't rely on the vifs
+	# variable at this point
+}
+\end{Verbatim}
+
+\subparagraph{\texttt{detect\_<driver>}}
+
+This function looks for interfaces that are usable with the driver. Template config sections
+for new devices should be written to stdout. Must check for already existing config sections
+belonging to the interfaces before creating new templates.
+
+Example:
+\begin{Verbatim}
+detect_dummy() {
+	[ wifi-device = "$(config_get dummydev type)" ] && return 0
+	cat <<EOF
+config wifi-device dummydev
+	option type dummy
+	# REMOVE THIS LINE TO ENABLE WIFI:
+	option disabled 1
+
+config wifi-iface
+	option device dummydev
+	option mode ap
+	option ssid OpenWrt
+EOF
+}
+\end{Verbatim}

+ 112 - 0
docs/working.tex

@@ -0,0 +1,112 @@
+The following section gives some tips and tricks on how to use efficiently
+OpenWrt on a regular basis and for daily work.
+
+\subsection{Compiling/recompiling components}
+
+The buildroot allows you to recompile the full environment or only parts of it
+like the toolchain, the kernel modules, the kernel or some packages.
+
+For instance if you want to recompile the toolchain after you made any change to it
+issue the following command:
+
+\begin{Verbatim}
+make toolchain/{clean,compile,install}
+\end{Verbatim}
+
+Which will clean, compile and install the toolchain. The command actually expands to the
+following:
+
+\begin{Verbatim}
+make[1] toolchain/clean
+make[2] -C toolchain/kernel-headers clean
+make[2] -C toolchain/binutils clean
+make[2] -C toolchain/gcc clean
+make[2] -C toolchain/uClibc clean	(glibc or eglibc when chosen)
+\end{Verbatim}
+
+Of course, you could only choose to recompile one or several of the toolchain components
+(binutils, kernel-headers gcc, C library) individually.
+
+The exact same idea works for packages:
+
+\begin{Verbatim}
+make package/busybox/{clean,compile,install}
+\end{Verbatim}
+
+will clean, compile and install busybox (if selected to be installed on the final rootfs).
+
+Supposing that you made changes to the Linux kernel, but do not want to recompile everything,
+you can recompile only the kernel modules by issuing:
+
+\begin{Verbatim}
+make target/linux/compile
+\end{Verbatim}
+
+To recompile the static part of the kernel use the following command:
+
+\begin{Verbatim}
+make target/linux/install
+\end{Verbatim}
+
+\subsection{Using quilt inside OpenWrt}
+
+OpenWrt integrates quilt in order to ease the package, kernel and toolchain
+patches maintenance when migrating over new versions of the software.
+
+Quilt intends to replace an old workflow, where you would download the new
+source file, create an original copy of it, an a working copy, then try to
+apply by hand old patches and resolve conflicts manually. Additionally, using
+quilt allows you to update and fold patches into other patches easily.
+
+Quilt is used by default to apply Linux kernel patches, but not for the other
+components (toolchain and packages).
+
+\subsubsection{Using quilt with kernel patches}
+
+Assuming that you have everything setup for your new kernel version:
+\begin{itemize}
+\item \texttt{LINUX\_VERSION} set in the target Makefile
+\item config-2.6.x.y existing
+\item patches-2.6.x.y containing the previous patches
+\end{itemize}
+
+Some patches are likely to fail since the vanilla kernel we are patching
+received modifications so some hunks of the patches are no longer applying.
+We will use quilt to get them applying cleanly again. Follow this procedure
+whenever you want to upgrade the kernel using previous patches:
+
+\begin{enumerate}
+\item make target/linux/clean (removes the old version)
+\item make target/linux/compile (uncompress the kernel and try to apply patches)
+\item if patches failed to apply:
+\item cd build\_dir/linux-target/linux-2.6.x.y
+\item quilt push -a (to apply patches where quilt stopped)
+\item quilt push -f (to force applying patches)
+\item edit .rej files, apply the necessary changes to the files
+\item remove .rej files
+\item quilt refresh
+\item repeat operation 3 and following until all patches have been applied
+\item when all patches did apply cleanly: make target/linux/refresh
+\end{enumerate}
+
+Note that generic (target/linux/generic-2.6/linux-2.6.x/) patches can be found in 
+\texttt{build\_dir/linux-target/linux-2.6.x.y/patches/generic} and platform specific
+patches in \texttt{build\_dir/linux-target/linux-2.6.x.y/patches/platform}.
+
+\subsubsection{Using quilt with packages}
+
+As we mentioned earlier, quilt is enabled by default for kernel patches, but not for
+packages. If you want to use quilt in the same way, you should set the QUILT environment
+variable to 1, e.g:
+
+\begin{Verbatim}
+make package/busybox/{clean,compile} QUILT=1
+\end{Verbatim}
+
+Will generate the patch series file and allow you to update patches just like we described
+before in the kernel case. Note that once all patches apply cleanly you should refresh them
+as well using the following command:
+
+\begin{Verbatim}
+make package/busybox/refresh QUILT=1
+\end{Verbatim}

+ 8 - 0
feeds.conf.default

@@ -0,0 +1,8 @@
+src-git packages https://github.com/openwrt/packages.git
+src-git luci https://github.com/openwrt/luci.git
+src-git routing https://github.com/openwrt-routing/packages.git
+src-git telephony https://github.com/openwrt/telephony.git
+src-git management https://github.com/openwrt-management/packages.git
+src-git targets https://github.com/openwrt/targets.git
+#src-git oldpackages http://git.openwrt.org/packages.git
+#src-link custom /usr/src/openwrt/custom-feed

+ 170 - 0
include/autotools.mk

@@ -0,0 +1,170 @@
+#
+# Copyright (C) 2007-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+autoconf_bool = $(patsubst %,$(if $($(1)),--enable,--disable)-%,$(2))
+
+# delete *.la-files from staging_dir - we can not yet remove respective lines within all package
+# Makefiles, since backfire still uses libtool v1.5.x which (may) require those files
+define libtool_remove_files
+	find $(1) -name '*.la' | $(XARGS) rm -f;
+endef
+
+
+AM_TOOL_PATHS:= \
+	AUTOM4TE=$(STAGING_DIR_HOST)/bin/autom4te \
+	AUTOCONF=$(STAGING_DIR_HOST)/bin/autoconf \
+	AUTOMAKE=$(STAGING_DIR_HOST)/bin/automake \
+	ACLOCAL=$(STAGING_DIR_HOST)/bin/aclocal \
+	AUTOHEADER=$(STAGING_DIR_HOST)/bin/autoheader \
+	LIBTOOLIZE=$(STAGING_DIR_HOST)/bin/libtoolize \
+	LIBTOOL=$(STAGING_DIR_HOST)/bin/libtool \
+	M4=$(STAGING_DIR_HOST)/bin/m4 \
+	AUTOPOINT=true
+
+# 1: build dir
+# 2: remove files
+# 3: automake paths
+# 4: libtool paths
+# 5: extra m4 dirs
+define autoreconf
+	(cd $(1); \
+		$(patsubst %,rm -f %;,$(2)) \
+		$(foreach p,$(3), \
+			if [ -f $(p)/configure.ac ] || [ -f $(p)/configure.in ]; then \
+				[ -d $(p)/autom4te.cache ] && rm -rf autom4te.cache; \
+				[ -e $(p)/config.rpath ] || \
+						ln -s $(SCRIPT_DIR)/config.rpath $(p)/config.rpath; \
+				touch NEWS AUTHORS COPYING ABOUT-NLS ChangeLog; \
+				$(AM_TOOL_PATHS) $(STAGING_DIR_HOST)/bin/autoreconf -v -f -i -s \
+					$(if $(word 2,$(3)),--no-recursive) \
+					-B $(STAGING_DIR_HOST)/share/aclocal \
+					$(patsubst %,-I %,$(5)) \
+					$(patsubst %,-I %,$(4)) $(p) || true; \
+			fi; \
+		) \
+	);
+endef
+
+# 1: build dir
+define patch_libtool
+	@(cd $(1); \
+		for lt in $$$$($$(STAGING_DIR_HOST)/bin/find . -name ltmain.sh); do \
+			lt_version="$$$$($$(STAGING_DIR_HOST)/bin/sed -ne 's,^[[:space:]]*VERSION="\?\([0-9]\.[0-9]\+\).*,\1,p' $$$$lt)"; \
+			case "$$$$lt_version" in \
+				1.5|2.2|2.4) echo "autotools.mk: Found libtool v$$$$lt_version - applying patch to $$$$lt"; \
+					(cd $$$$(dirname $$$$lt) && $$(PATCH) -N -s -p1 < $$(TOPDIR)/tools/libtool/files/libtool-v$$$$lt_version.patch || true) ;; \
+				*) echo "autotools.mk: error: Unsupported libtool version v$$$$lt_version - cannot patch $$$$lt"; exit 1 ;; \
+			esac; \
+		done; \
+	);
+endef
+
+
+PKG_LIBTOOL_PATHS?=$(CONFIGURE_PATH)
+PKG_AUTOMAKE_PATHS?=$(CONFIGURE_PATH)
+PKG_MACRO_PATHS?=m4
+PKG_REMOVE_FILES?=aclocal.m4
+
+Hooks/InstallDev/Post += libtool_remove_files
+
+define autoreconf_target
+  $(strip $(call autoreconf, \
+    $(PKG_BUILD_DIR), $(PKG_REMOVE_FILES), \
+    $(PKG_AUTOMAKE_PATHS), $(PKG_LIBTOOL_PATHS), \
+    $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS)))
+endef
+
+define patch_libtool_target
+  $(strip $(call patch_libtool, \
+    $(PKG_BUILD_DIR)))
+endef
+
+define gettext_version_target
+	(cd $(PKG_BUILD_DIR) && \
+		GETTEXT_VERSION=$(shell $(STAGING_DIR)/host/bin/gettext -V | $(STAGING_DIR_HOST)/bin/sed -ne '1s/.* //p') && \
+		$(STAGING_DIR_HOST)/bin/sed \
+			-i $(PKG_BUILD_DIR)/configure.ac \
+			-e "s/AM_GNU_GETTEXT_VERSION(.*)/AM_GNU_GETTEXT_VERSION(\[$$$$GETTEXT_VERSION\])/g" && \
+		$(STAGING_DIR)/host/bin/autopoint --force \
+	);
+endef
+
+ifneq ($(filter gettext-version,$(PKG_FIXUP)),)
+  Hooks/Configure/Pre += gettext_version_target
+ ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
+  Hooks/Configure/Pre += autoreconf_target
+ endif
+endif
+
+ifneq ($(filter patch-libtool,$(PKG_FIXUP)),)
+  Hooks/Configure/Pre += patch_libtool_target
+endif
+
+ifneq ($(filter libtool,$(PKG_FIXUP)),)
+  PKG_BUILD_DEPENDS += libtool libintl libiconv
+ ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
+  Hooks/Configure/Pre += autoreconf_target
+ endif
+endif
+
+ifneq ($(filter libtool-ucxx,$(PKG_FIXUP)),)
+  PKG_BUILD_DEPENDS += libtool libintl libiconv
+ ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
+  Hooks/Configure/Pre += autoreconf_target
+ endif
+endif
+
+ifneq ($(filter autoreconf,$(PKG_FIXUP)),)
+  ifeq ($(filter autoreconf,$(Hooks/Configure/Pre)),)
+    Hooks/Configure/Pre += autoreconf_target
+  endif
+endif
+
+
+HOST_FIXUP?=$(PKG_FIXUP)
+HOST_LIBTOOL_PATHS?=$(if $(PKG_LIBTOOL_PATHS),$(PKG_LIBTOOL_PATHS),.)
+HOST_AUTOMAKE_PATHS?=$(if $(PKG_AUTOMAKE_PATHS),$(PKG_AUTOMAKE_PATHS),.)
+HOST_MACRO_PATHS?=$(if $(PKG_MACRO_PATHS),$(PKG_MACRO_PATHS),m4)
+HOST_REMOVE_FILES?=$(PKG_REMOVE_FILES)
+
+define autoreconf_host
+  $(strip $(call autoreconf, \
+    $(HOST_BUILD_DIR), $(HOST_REMOVE_FILES), \
+    $(HOST_AUTOMAKE_PATHS), $(HOST_LIBTOOL_PATHS), \
+    $(HOST_MACRO_PATHS)))
+endef
+
+define patch_libtool_host
+  $(strip $(call patch_libtool, \
+    $(HOST_BUILD_DIR)))
+endef
+
+ifneq ($(filter patch-libtool,$(PKG_FIXUP)),)
+  Hooks/HostConfigure/Pre += patch_libtool_host
+endif
+
+ifneq ($(filter patch-libtool,$(HOST_FIXUP)),)
+  Hooks/HostConfigure/Pre += $(strip $(call patch_libtool,$(HOST_BUILD_DIR)))
+endif
+
+ifneq ($(filter libtool,$(HOST_FIXUP)),)
+ ifeq ($(filter no-autoreconf,$(HOST_FIXUP)),)
+  Hooks/HostConfigure/Pre += autoreconf_host
+ endif
+endif
+
+ifneq ($(filter libtool-ucxx,$(HOST_FIXUP)),)
+ ifeq ($(filter no-autoreconf,$(HOST_FIXUP)),)
+  Hooks/HostConfigure/Pre += autoreconf_host
+ endif
+endif
+
+ifneq ($(filter autoreconf,$(HOST_FIXUP)),)
+  ifeq ($(filter autoreconf,$(Hooks/HostConfigure/Pre)),)
+    Hooks/HostConfigure/Pre += autoreconf_host
+  endif
+endif

+ 105 - 0
include/cmake.mk

@@ -0,0 +1,105 @@
+cmake_bool = $(patsubst %,-D%:BOOL=$(if $($(1)),ON,OFF),$(2))
+
+PKG_INSTALL:=1
+
+ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+  MAKE_FLAGS+=VERBOSE=1
+endif
+
+CMAKE_SOURCE_DIR:=.
+
+ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
+  cmake_tool=$(TOOLCHAIN_DIR)/bin/$(1)
+else
+  cmake_tool=$(shell which $(1))
+endif
+
+ifeq ($(CONFIG_CCACHE),)
+ CMAKE_C_COMPILER:=$(call cmake_tool,$(TARGET_CC))
+ CMAKE_CXX_COMPILER:=$(call cmake_tool,$(TARGET_CXX))
+ CMAKE_C_COMPILER_ARG1:=
+ CMAKE_CXX_COMPILER_ARG1:=
+else
+  CCACHE:=$(STAGING_DIR_HOST)/bin/ccache
+  CMAKE_C_COMPILER:=$(CCACHE)
+  CMAKE_C_COMPILER_ARG1:=$(TARGET_CC_NOCACHE)
+  CMAKE_CXX_COMPILER:=$(CCACHE)
+  CMAKE_CXX_COMPILER_ARG1:=$(TARGET_CXX_NOCACHE)
+endif
+CMAKE_AR:=$(call cmake_tool,$(TARGET_AR))
+CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
+CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB))
+
+CMAKE_FIND_ROOT_PATH:=$(STAGING_DIR)/usr;$(TOOLCHAIN_DIR)$(if $(CONFIG_EXTERNAL_TOOLCHAIN),;$(CONFIG_TOOLCHAIN_ROOT))
+CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOST)
+CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
+
+define Build/Configure/Default
+	(cd $(PKG_BUILD_DIR); \
+		CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
+		CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
+		LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \
+		cmake \
+			-DCMAKE_SYSTEM_NAME=Linux \
+			-DCMAKE_SYSTEM_VERSION=1 \
+			-DCMAKE_SYSTEM_PROCESSOR=$(ARCH) \
+			-DCMAKE_BUILD_TYPE=Release \
+			-DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" \
+			-DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" \
+			-DCMAKE_C_COMPILER="$(CMAKE_C_COMPILER)" \
+			-DCMAKE_C_COMPILER_ARG1="$(CMAKE_C_COMPILER_ARG1)" \
+			-DCMAKE_CXX_COMPILER="$(CMAKE_CXX_COMPILER)" \
+			-DCMAKE_CXX_COMPILER_ARG1="$(CMAKE_CXX_COMPILER_ARG1)" \
+			-DCMAKE_ASM_COMPILER="$(CMAKE_C_COMPILER)" \
+			-DCMAKE_ASM_COMPILER_ARG1="$(CMAKE_C_COMPILER_ARG1)" \
+			-DCMAKE_EXE_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS)" \
+			-DCMAKE_MODULE_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS) $(CMAKE_SHARED_LDFLAGS)" \
+			-DCMAKE_SHARED_LINKER_FLAGS:STRING="$(TARGET_LDFLAGS) $(CMAKE_SHARED_LDFLAGS)" \
+			-DCMAKE_AR="$(CMAKE_AR)" \
+			-DCMAKE_NM="$(CMAKE_NM)" \
+			-DCMAKE_RANLIB="$(CMAKE_RANLIB)" \
+			-DCMAKE_FIND_ROOT_PATH="$(CMAKE_FIND_ROOT_PATH)" \
+			-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=BOTH \
+			-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
+			-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
+			-DCMAKE_STRIP=: \
+			-DCMAKE_INSTALL_PREFIX=/usr \
+			-DDL_LIBRARY=$(STAGING_DIR) \
+			-DCMAKE_PREFIX_PATH=$(STAGING_DIR) \
+			-DCMAKE_SKIP_RPATH=TRUE  \
+			$(CMAKE_OPTIONS) \
+		$(CMAKE_SOURCE_DIR) \
+	)
+endef
+
+define Build/InstallDev/cmake
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+Build/InstallDev = $(if $(CMAKE_INSTALL),$(Build/InstallDev/cmake))
+
+define Host/Configure/Default
+	(cd $(HOST_BUILD_DIR); \
+		CFLAGS="$(HOST_CFLAGS)" \
+		CXXFLAGS="$(HOST_CFLAGS)" \
+		LDFLAGS="$(HOST_LDFLAGS)" \
+		cmake \
+			-DCMAKE_BUILD_TYPE=Release \
+			-DCMAKE_C_FLAGS_RELEASE="-DNDEBUG" \
+			-DCMAKE_CXX_FLAGS_RELEASE="-DNDEBUG" \
+			-DCMAKE_EXE_LINKER_FLAGS:STRING="$(HOST_LDFLAGS)" \
+			-DCMAKE_MODULE_LINKER_FLAGS:STRING="$(HOST_LDFLAGS)" \
+			-DCMAKE_SHARED_LINKER_FLAGS:STRING="$(HOST_LDFLAGS)" \
+			-DCMAKE_FIND_ROOT_PATH="$(CMAKE_HOST_FIND_ROOT_PATH)" \
+			-DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=BOTH \
+			-DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY \
+			-DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY \
+			-DCMAKE_STRIP=: \
+			-DCMAKE_INSTALL_PREFIX=$(HOST_BUILD_PREFIX) \
+			-DCMAKE_PREFIX_PATH=$(HOST_BUILD_PREFIX) \
+			-DCMAKE_SKIP_RPATH=TRUE  \
+			$(CMAKE_HOST_OPTIONS) \
+		$(CMAKE_SOURCE_DIR) \
+	)
+endef

+ 51 - 0
include/debug.mk

@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# debug flags:
+#
+# d: show subdirectory tree
+# t: show added targets
+# l: show legacy targets
+# r: show autorebuild messages
+# v: verbose (no .SILENCE for common targets)
+
+ifeq ($(DUMP),)
+  ifeq ($(DEBUG),all)
+    build_debug:=dltvr
+  else
+    build_debug:=$(DEBUG)
+  endif
+endif
+
+ifneq ($(DEBUG),)
+
+define debug
+$$(findstring $(2),$$(if $$(DEBUG_SCOPE_DIR),$$(if $$(filter $$(DEBUG_SCOPE_DIR)%,$(1)),$(build_debug)),$(build_debug)))
+endef
+
+define warn
+$$(if $(call debug,$(1),$(2)),$$(warning $(3)))
+endef
+
+define debug_eval
+$$(if $(call debug,$(1),$(2)),$(3))
+endef
+
+define warn_eval
+$(call warn,$(1),$(2),$(3)	$(4))
+$(4)
+endef
+
+else
+
+debug:=
+warn:=
+debug_eval:=
+warn_eval = $(4)
+
+endif
+

+ 48 - 0
include/depends.mk

@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# define a dependency on a subtree
+# parameters:
+#	1: directories/files
+#	2: directory dependency
+#	3: tempfile for file listings
+#	4: find options
+
+DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp"
+
+find_md5=$(SH_FUNC) find $(1) -type f $(patsubst -x,-and -not -path,$(DEP_FINDPARAMS) $(2)) | md5s
+
+define rdep
+  .PRECIOUS: $(2)
+  .SILENT: $(2)_check
+
+  $(2): $(2)_check
+
+ifneq ($(wildcard $(2)),)
+  $(2)_check::
+	$(if $(3), \
+		$(call find_md5,$(1),$(4)) > $(3).1; \
+		{ [ \! -f "$(3)" ] || diff $(3) $(3).1 >/dev/null; } && \
+	) \
+	{ \
+		[ -f "$(2)_check.1" ] && mv "$(2)_check.1"; \
+	    $(TOPDIR)/scripts/timestamp.pl $(DEP_FINDPARAMS) $(4) -n $(2) $(1) && { \
+			$(call debug_eval,$(SUBDIR),r,echo "No need to rebuild $(2)";) \
+			touch -r "$(2)" "$(2)_check"; \
+		} \
+	} || { \
+		$(call debug_eval,$(SUBDIR),r,echo "Need to rebuild $(2)";) \
+		touch "$(2)_check"; \
+	}
+	$(if $(3), mv $(3).1 $(3))
+else
+  $(2)_check::
+	$(if $(3), rm -f $(3) $(3).1)
+	$(call debug_eval,$(SUBDIR),r,echo "Target $(2) not built")
+endif
+
+endef
+

+ 5 - 0
include/device_table.txt

@@ -0,0 +1,5 @@
+# minimal device table file for OpenWrt
+
+#<name>		<type>	<mode>	<uid>	<gid>	<major>	<minor>	<start>	<inc>	<count>
+/dev		d	755	0	0	-	-	-	-	-
+/dev/console	c	600	0	0	5	1	0	0	-

+ 209 - 0
include/download.mk

@@ -0,0 +1,209 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+OPENWRT_GIT = http://git.openwrt.org
+
+ifdef PKG_SOURCE_VERSION
+PKG_VERSION ?= $(if $(PKG_SOURCE_DATE),$(PKG_SOURCE_DATE)-)$(call version_abbrev,$(PKG_SOURCE_VERSION))
+PKG_SOURCE_SUBDIR ?= $(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE ?= $(PKG_SOURCE_SUBDIR).tar.xz
+endif
+
+DOWNLOAD_RDEP=$(STAMP_PREPARED) $(HOST_STAMP_PREPARED)
+
+# Try to guess the download method from the URL
+define dl_method
+$(strip \
+  $(if $(2),$(2), \
+    $(if $(filter @APACHE/% @GITHUB/% @GNOME/% @GNU/% @KERNEL/% @SF/% @SAVANNAH/% ftp://% http://% https://% file://%,$(1)),default, \
+      $(if $(filter git://%,$(1)),git, \
+        $(if $(filter svn://%,$(1)),svn, \
+          $(if $(filter cvs://%,$(1)),cvs, \
+            $(if $(filter hg://%,$(1)),hg, \
+              $(if $(filter sftp://%,$(1)),bzr, \
+                unknown \
+              ) \
+            ) \
+          ) \
+        ) \
+      ) \
+    ) \
+  ) \
+)
+endef
+
+# code for creating tarballs from cvs/svn/git/bzr/hg/darcs checkouts - useful for mirror support
+dl_pack/bz2=$(TAR) cjf $(1) $(2)
+dl_pack/gz=$(TAR) czf $(1) $(2)
+dl_pack/xz=$(TAR) c $(2) | xz -zc > $(1)
+dl_pack/unknown=echo "ERROR: Unknown pack format for file $(1)"; false
+define dl_pack
+	$(if $(dl_pack/$(call ext,$(1))),$(dl_pack/$(call ext,$(1))),$(dl_pack/unknown))
+endef
+
+define DownloadMethod/unknown
+	@echo "ERROR: No download method available"; false
+endef
+
+define DownloadMethod/default
+	$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(HASH)" "$(URL_FILE)" $(foreach url,$(URL),"$(url)")
+endef
+
+define wrap_mirror
+$(if $(if $(MIRROR),$(filter-out x,$(MIRROR_HASH))),$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(MIRROR_HASH)" "" || ( $(1) ),$(1))
+endef
+
+define DownloadMethod/cvs
+	$(call wrap_mirror, \
+		echo "Checking out files from the cvs repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		cvs -d $(URL) export $(VERSION) $(SUBDIR) && \
+		echo "Packing checkout..." && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+define DownloadMethod/svn
+	$(call wrap_mirror, \
+		echo "Checking out files from the svn repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		( svn help export | grep -q trust-server-cert && \
+		svn export --non-interactive --trust-server-cert -r$(VERSION) $(URL) $(SUBDIR) || \
+		svn export --non-interactive -r$(VERSION) $(URL) $(SUBDIR) ) && \
+		echo "Packing checkout..." && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+define DownloadMethod/git
+	$(call wrap_mirror, \
+		echo "Checking out files from the git repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		git clone $(URL) $(SUBDIR) && \
+		(cd $(SUBDIR) && git checkout $(VERSION) && \
+		git submodule update --init --recursive) && \
+		echo "Packing checkout..." && \
+		rm -rf $(SUBDIR)/.git && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+define DownloadMethod/bzr
+	$(call wrap_mirror, \
+		echo "Checking out files from the bzr repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		bzr export -r$(VERSION) $(SUBDIR) $(URL) && \
+		echo "Packing checkout..." && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+define DownloadMethod/hg
+	$(call wrap_mirror, \
+		echo "Checking out files from the hg repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		hg clone -r $(VERSION) $(URL) $(SUBDIR) && \
+		find $(SUBDIR) -name .hg | xargs rm -rf && \
+		echo "Packing checkout..." && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+define DownloadMethod/darcs
+	$(call wrap_mirror, \
+		echo "Checking out files from the darcs repository..."; \
+		mkdir -p $(TMP_DIR)/dl && \
+		cd $(TMP_DIR)/dl && \
+		rm -rf $(SUBDIR) && \
+		[ \! -d $(SUBDIR) ] && \
+		darcs get -t $(VERSION) $(URL) $(SUBDIR) && \
+		find $(SUBDIR) -name _darcs | xargs rm -rf && \
+		echo "Packing checkout..." && \
+		$(call dl_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+		rm -rf $(SUBDIR); \
+	)
+endef
+
+Validate/cvs=VERSION SUBDIR
+Validate/svn=VERSION SUBDIR
+Validate/git=VERSION SUBDIR
+Validate/bzr=VERSION SUBDIR
+Validate/hg=VERSION SUBDIR
+Validate/darcs=VERSION SUBDIR
+
+define Download/Defaults
+  URL:=
+  FILE:=
+  URL_FILE:=
+  PROTO:=
+  HASH=$$(MD5SUM)
+  MD5SUM:=x
+  SUBDIR:=
+  MIRROR:=1
+  MIRROR_HASH=$$(MIRROR_MD5SUM)
+  MIRROR_MD5SUM:=x
+  VERSION:=
+endef
+
+define Download/default
+  FILE:=$(PKG_SOURCE)
+  URL:=$(PKG_SOURCE_URL)
+  SUBDIR:=$(PKG_SOURCE_SUBDIR)
+  PROTO:=$(PKG_SOURCE_PROTO)
+  $(if $(PKG_SOURCE_MIRROR),MIRROR:=$(filter 1,$(PKG_MIRROR)))
+  $(if $(PKG_MIRROR_MD5SUM),MIRROR_MD5SUM:=$(PKG_MIRROR_MD5SUM))
+  $(if $(PKG_MIRROR_HASH),MIRROR_HASH:=$(PKG_MIRROR_HASH))
+  VERSION:=$(PKG_SOURCE_VERSION)
+  $(if $(PKG_MD5SUM),MD5SUM:=$(PKG_MD5SUM))
+  $(if $(PKG_HASH),HASH:=$(PKG_HASH))
+endef
+
+define Download
+  $(eval $(Download/Defaults))
+  $(eval $(Download/$(1)))
+  $(foreach FIELD,URL FILE $(Validate/$(call dl_method,$(URL),$(PROTO))),
+    ifeq ($($(FIELD)),)
+      $$(error Download/$(1) is missing the $(FIELD) field.)
+    endif
+  )
+
+  $(foreach dep,$(DOWNLOAD_RDEP),
+    $(dep): $(DL_DIR)/$(FILE)
+  )
+  download: $(DL_DIR)/$(FILE)
+
+  $(DL_DIR)/$(FILE):
+	mkdir -p $(DL_DIR)
+	$(call locked,$(if $(DownloadMethod/$(call dl_method,$(URL),$(PROTO))),$(DownloadMethod/$(call dl_method,$(URL),$(PROTO))),$(DownloadMethod/unknown)),$(FILE))
+
+endef

+ 39 - 0
include/feeds.mk

@@ -0,0 +1,39 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+-include $(TMP_DIR)/.packagesubdirs
+
+FEEDS_AVAILABLE:=$(shell $(SCRIPT_DIR)/feeds list -n)
+FEEDS_INSTALLED:=$(notdir $(wildcard $(TOPDIR)/package/feeds/*))
+FEEDS_ENABLED:=$(foreach feed,$(FEEDS_INSTALLED),$(if $(CONFIG_FEED_$(feed)),$(feed)))
+FEEDS_DISABLED:=$(filter-out $(FEEDS_ENABLED),$(FEEDS_AVAILABLE))
+
+PKG_CONFIG_DEPENDS += \
+	CONFIG_PER_FEED_REPO \
+	CONFIG_PER_FEED_REPO_ADD_DISABLED \
+	CONFIG_PER_FEED_REPO_ADD_COMMENTED \
+	$(foreach feed,$(FEEDS_INSTALLED),CONFIG_FEED_$(feed))
+
+# 1: package name
+define FeedPackageDir
+$(strip $(if $(CONFIG_PER_FEED_REPO), \
+  $(abspath $(PACKAGE_DIR)/$(if $(Package/$(1)/subdir),$(Package/$(1)/subdir),base)), \
+  $(PACKAGE_DIR)))
+endef
+
+# 1: destination file
+define FeedSourcesAppend
+( \
+  $(strip $(if $(CONFIG_PER_FEED_REPO), \
+	$(foreach feed,base kernel $(FEEDS_ENABLED),echo "src/gz %n_$(feed) %U/$(feed)";) \
+	$(if $(CONFIG_PER_FEED_REPO_ADD_DISABLED), \
+		$(foreach feed,$(FEEDS_DISABLED),echo "$(if $(CONFIG_PER_FEED_REPO_ADD_COMMENTED),# )src/gz %n_$(feed) %U/$(feed)";)) \
+  , \
+	echo "src/gz %n %U"; \
+  )) \
+) >> $(1)
+endef

+ 50 - 0
include/hardening.mk

@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PKG_CHECK_FORMAT_SECURITY ?= 1
+PKG_SSP ?= 1
+PKG_FORTIFY_SOURCE ?= 1
+PKG_RELRO ?= 1
+
+ifdef CONFIG_PKG_CHECK_FORMAT_SECURITY
+  ifeq ($(strip $(PKG_CHECK_FORMAT_SECURITY)),1)
+    TARGET_CFLAGS += -Wformat -Werror=format-security
+  endif
+endif
+ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR
+  ifeq ($(strip $(PKG_SSP)),1)
+    TARGET_CFLAGS += -fstack-protector
+  endif
+endif
+ifdef CONFIG_PKG_CC_STACKPROTECTOR_STRONG
+  ifeq ($(strip $(PKG_SSP)),1)
+    TARGET_CFLAGS += -fstack-protector-strong
+  endif
+endif
+ifdef CONFIG_PKG_FORTIFY_SOURCE_1
+  ifeq ($(strip $(PKG_FORTIFY_SOURCE)),1)
+    TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
+  endif
+endif
+ifdef CONFIG_PKG_FORTIFY_SOURCE_2
+  ifeq ($(strip $(PKG_FORTIFY_SOURCE)),1)
+    TARGET_CFLAGS += -D_FORTIFY_SOURCE=2
+  endif
+endif
+ifdef CONFIG_PKG_RELRO_PARTIAL
+  ifeq ($(strip $(PKG_RELRO)),1)
+    TARGET_CFLAGS += -Wl,-z,relro
+    TARGET_LDFLAGS += -zrelro
+  endif
+endif
+ifdef CONFIG_PKG_RELRO_FULL
+  ifeq ($(strip $(PKG_RELRO)),1)
+    TARGET_CFLAGS += -Wl,-z,now -Wl,-z,relro
+    TARGET_LDFLAGS += -znow -zrelro
+  endif
+endif
+

+ 200 - 0
include/host-build.mk

@@ -0,0 +1,200 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(INCLUDE_DIR)/download.mk
+
+HOST_BUILD_DIR ?= $(BUILD_DIR_HOST)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
+HOST_INSTALL_DIR ?= $(HOST_BUILD_DIR)/host-install
+HOST_BUILD_PARALLEL ?=
+
+ifneq ($(CONFIG_PKG_BUILD_USE_JOBSERVER),)
+  HOST_MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) $(if $(filter 3.% 4.0 4.1,$(MAKE_VERSION)),-j))
+else
+  HOST_MAKE_J:=-j$(CONFIG_PKG_BUILD_JOBS)
+endif
+
+ifeq ($(strip $(HOST_BUILD_PARALLEL)),0)
+HOST_JOBS?=-j1
+else
+HOST_JOBS?=$(if $(HOST_BUILD_PARALLEL)$(CONFIG_PKG_DEFAULT_PARALLEL),\
+	$(if $(CONFIG_PKG_BUILD_PARALLEL),$(HOST_MAKE_J),-j1),-j1)
+endif
+
+include $(INCLUDE_DIR)/host.mk
+include $(INCLUDE_DIR)/unpack.mk
+include $(INCLUDE_DIR)/depends.mk
+
+BUILD_TYPES += host
+HOST_STAMP_PREPARED=$(HOST_BUILD_DIR)/.prepared$(if $(HOST_QUILT)$(DUMP),,$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),)))
+HOST_STAMP_CONFIGURED:=$(HOST_BUILD_DIR)/.configured
+HOST_STAMP_BUILT:=$(HOST_BUILD_DIR)/.built
+HOST_BUILD_PREFIX:=$(if $(IS_PACKAGE_BUILD),$(STAGING_DIR_HOSTPKG),$(STAGING_DIR_HOST))
+HOST_STAMP_INSTALLED:=$(HOST_BUILD_PREFIX)/stamp/.$(PKG_NAME)_installed
+
+override MAKEFLAGS=
+
+include $(INCLUDE_DIR)/quilt.mk
+include $(INCLUDE_DIR)/autotools.mk
+
+Host/Patch:=$(Host/Patch/Default)
+ifneq ($(strip $(HOST_UNPACK)),)
+  define Host/Prepare/Default
+	$(HOST_UNPACK)
+	$(Host/Patch)
+  endef
+endif
+
+define Host/Prepare
+  $(call Host/Prepare/Default)
+endef
+
+ifeq ($(HOST_OS),Darwin)
+  HOST_CFLAGS += -I/usr/local/opt/openssl/include
+  HOST_LDFLAGS += -L/usr/local/opt/openssl/lib
+endif
+
+HOST_CONFIGURE_VARS = \
+	CC="$(HOSTCC)" \
+	CFLAGS="$(HOST_CFLAGS)" \
+	CPPFLAGS="$(HOST_CPPFLAGS)" \
+	LDFLAGS="$(HOST_LDFLAGS)" \
+	SHELL="$(SHELL)"
+
+HOST_CONFIGURE_ARGS = \
+	--target=$(GNU_HOST_NAME) \
+	--host=$(GNU_HOST_NAME) \
+	--build=$(GNU_HOST_NAME) \
+	--program-prefix="" \
+	--program-suffix="" \
+	--prefix=$(HOST_BUILD_PREFIX) \
+	--exec-prefix=$(HOST_BUILD_PREFIX) \
+	--sysconfdir=$(HOST_BUILD_PREFIX)/etc \
+	--localstatedir=$(HOST_BUILD_PREFIX)/var \
+	--sbindir=$(HOST_BUILD_PREFIX)/bin
+
+HOST_MAKE_FLAGS =
+
+HOST_CONFIGURE_CMD = $(BASH) ./configure
+
+define Host/Configure/Default
+	$(if $(HOST_CONFIGURE_PARALLEL),+)(cd $(HOST_BUILD_DIR)/$(3); \
+		if [ -x configure ]; then \
+			$(CP) $(SCRIPT_DIR)/config.{guess,sub} $(HOST_BUILD_DIR)/$(3)/ && \
+			$(2) \
+			$(HOST_CONFIGURE_CMD) \
+			$(HOST_CONFIGURE_VARS) \
+			$(HOST_CONFIGURE_ARGS) \
+			$(1); \
+		fi \
+	)
+endef
+
+define Host/Configure
+  $(call Host/Configure/Default)
+endef
+
+define Host/Compile/Default
+	+$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) \
+		$(HOST_MAKE_FLAGS) \
+		$(1)
+endef
+
+define Host/Compile
+  $(call Host/Compile/Default)
+endef
+
+define Host/Install/Default
+	$(_SINGLE)$(MAKE) -C $(HOST_BUILD_DIR) install
+endef
+
+define Host/Install
+  $(call Host/Install/Default,$(HOST_BUILD_PREFIX))
+endef
+
+
+ifneq ($(if $(HOST_QUILT),,$(CONFIG_AUTOREBUILD)),)
+  define HostHost/Autoclean
+    $(call rdep,${CURDIR} $(PKG_FILE_DEPENDS),$(HOST_STAMP_PREPARED))
+    $(if $(if $(Host/Compile),$(filter prepare,$(MAKECMDGOALS)),1),,$(call rdep,$(HOST_BUILD_DIR),$(HOST_STAMP_BUILT)))
+  endef
+endif
+
+define Host/Exports/Default
+  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR_HOST)/share/aclocal $$(STAGING_DIR_HOST)/share/aclocal-* $(if $(IS_PACKAGE_BUILD),$$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*)),-I $$(p))
+  $(1) : export STAGING_PREFIX=$$(HOST_BUILD_PREFIX)
+  $(1) : export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig:$$(HOST_BUILD_PREFIX)/lib/pkgconfig
+  $(1) : export PKG_CONFIG_LIBDIR=$$(HOST_BUILD_PREFIX)/lib/pkgconfig
+  $(1) : export CCACHE_DIR:=$(STAGING_DIR_HOST)/ccache
+  $(if $(IS_PACKAGE_BUILD),$(1) : export PATH=$$(TARGET_PATH_PKG))
+endef
+Host/Exports=$(Host/Exports/Default)
+
+.NOTPARALLEL:
+
+ifndef DUMP
+  define HostBuild
+  $(if $(HOST_QUILT),$(Host/Quilt))
+  $(if $(if $(PKG_HOST_ONLY),,$(STAMP_PREPARED)),,$(if $(strip $(PKG_SOURCE_URL)),$(call Download,default)))
+  $(if $(DUMP),,$(call HostHost/Autoclean))
+
+  $(HOST_STAMP_PREPARED):
+	@-rm -rf $(HOST_BUILD_DIR)
+	@mkdir -p $(HOST_BUILD_DIR)
+	$(foreach hook,$(Hooks/HostPrepare/Pre),$(call $(hook))$(sep))
+	$(call Host/Prepare)
+	$(foreach hook,$(Hooks/HostPrepare/Post),$(call $(hook))$(sep))
+	touch $$@
+
+  $(call Host/Exports,$(HOST_STAMP_CONFIGURED))
+  $(HOST_STAMP_CONFIGURED): $(HOST_STAMP_PREPARED)
+	$(foreach hook,$(Hooks/HostConfigure/Pre),$(call $(hook))$(sep))
+	$(call Host/Configure)
+	$(foreach hook,$(Hooks/HostConfigure/Post),$(call $(hook))$(sep))
+	touch $$@
+
+  $(call Host/Exports,$(HOST_STAMP_BUILT))
+  $(HOST_STAMP_BUILT): $(HOST_STAMP_CONFIGURED)
+		$(foreach hook,$(Hooks/HostCompile/Pre),$(call $(hook))$(sep))
+		$(call Host/Compile)
+		$(foreach hook,$(Hooks/HostCompile/Post),$(call $(hook))$(sep))
+		touch $$@
+
+  $(call Host/Exports,$(HOST_STAMP_INSTALLED))
+  $(HOST_STAMP_INSTALLED): $(HOST_STAMP_BUILT) $(if $(FORCE_HOST_INSTALL),FORCE)
+		$(call Host/Install,$(HOST_BUILD_PREFIX))
+		$(foreach hook,$(Hooks/HostInstall/Post),$(call $(hook))$(sep))
+		mkdir -p $$(shell dirname $$@)
+		touch $(HOST_STAMP_BUILT)
+		touch $$@
+
+  ifndef STAMP_BUILT
+    prepare: host-prepare
+    compile: host-compile
+    install: host-install
+    clean: host-clean
+    update: host-update
+    refresh: host-refresh
+  endif
+
+  host-prepare: $(HOST_STAMP_PREPARED)
+  host-configure: $(HOST_STAMP_CONFIGURED)
+  host-compile: $(HOST_STAMP_BUILT) $(if $(STAMP_BUILT),$(HOST_STAMP_INSTALLED))
+  host-install: $(HOST_STAMP_INSTALLED)
+  host-clean: FORCE
+	$(call Host/Clean)
+	$(call Host/Uninstall)
+	rm -rf $(HOST_BUILD_DIR) $(HOST_STAMP_INSTALLED) $(HOST_STAMP_BUILT)
+
+  endef
+
+  download:
+  prepare:
+  compile:
+  install:
+  clean:
+
+endif

+ 51 - 0
include/host.mk

@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2007-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+TMP_DIR ?= $(TOPDIR)/tmp
+ifeq ($(if $(TARGET_BUILD),,$(DUMP)),)
+  -include $(TMP_DIR)/.host.mk
+endif
+
+ifneq ($(__host_inc),1)
+__host_inc:=1
+
+export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
+
+try-run = $(shell set -e; \
+	TMP_F="$(TMP_DIR)/try-run.$$$$.tmp"; \
+	if ($(1)) >/dev/null 2>&1; then echo "$(2)"; else echo "$(3)"; fi; \
+	rm -f "$$TMP_F"; \
+)
+
+host-cc-option = $(call try-run, \
+	$(HOSTCC) $(HOST_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP_F",$(1),$(2) \
+)
+
+.PRECIOUS: $(TMP_DIR)/.host.mk
+$(TMP_DIR)/.host.mk: $(TOPDIR)/include/host.mk
+	@mkdir -p $(TMP_DIR)
+	@( \
+		HOST_OS=`uname`; \
+		case "$$HOST_OS" in \
+			Linux) HOST_ARCH=`uname -m`;; \
+			Darwin) HOST_ARCH=`uname -m`;; \
+			*) HOST_ARCH=`uname -p`;; \
+		esac; \
+		GNU_HOST_NAME=`gcc -dumpmachine`; \
+		[ -z "$$GNU_HOST_NAME" -o "$$HOST_OS" = "Darwin" ] && \
+			GNU_HOST_NAME=`$(TOPDIR)/scripts/config.guess`; \
+		echo "HOST_OS:=$$HOST_OS" > $@; \
+		echo "HOST_ARCH:=$$HOST_ARCH" >> $@; \
+		echo "GNU_HOST_NAME:=$$GNU_HOST_NAME" >> $@; \
+		if gfind -L /dev/null || find -L /dev/null; then \
+			echo "FIND_L=find -L \$$(1)" >> $@; \
+		else \
+			echo "FIND_L=find \$$(1) -follow" >> $@; \
+		fi \
+	) >/dev/null 2>/dev/null
+
+endif

+ 615 - 0
include/image.mk

@@ -0,0 +1,615 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+override TARGET_BUILD=
+include $(INCLUDE_DIR)/prereq.mk
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/host.mk
+include $(INCLUDE_DIR)/version.mk
+
+override MAKE:=$(_SINGLE)$(SUBMAKE)
+override NO_TRACE_MAKE:=$(_SINGLE)$(NO_TRACE_MAKE)
+
+KDIR=$(KERNEL_BUILD_DIR)
+KDIR_TMP=$(KDIR)/tmp
+DTS_DIR:=$(LINUX_DIR)/arch/$(LINUX_KARCH)/boot/dts
+
+sanitize = $(call tolower,$(subst _,-,$(1)))
+
+DIST_SANITIZED:=$(call sanitize,$(VERSION_DIST))
+EXTRA_NAME_SANITIZED=$(call sanitize,$(EXTRA_IMAGE_NAME))
+
+IMG_PREFIX:=$(DIST_SANITIZED)-$(if $(CONFIG_VERSION_FILENAMES),$(VERSION_NUMBER)-)$(if $(EXTRA_NAME_SANITIZED),$(EXTRA_NAME_SANITIZED)-)$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET))
+
+MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
+
+ifneq ($(CONFIG_BIG_ENDIAN),)
+  JFFS2OPTS     :=  --big-endian --squash-uids -v
+else
+  JFFS2OPTS     :=  --little-endian --squash-uids -v
+endif
+
+ifeq ($(CONFIG_JFFS2_RTIME),y)
+  JFFS2OPTS += -X rtime
+endif
+ifeq ($(CONFIG_JFFS2_ZLIB),y)
+  JFFS2OPTS += -X zlib
+endif
+ifeq ($(CONFIG_JFFS2_LZMA),y)
+  JFFS2OPTS += -X lzma --compression-mode=size
+endif
+ifneq ($(CONFIG_JFFS2_RTIME),y)
+  JFFS2OPTS += -x rtime
+endif
+ifneq ($(CONFIG_JFFS2_ZLIB),y)
+  JFFS2OPTS += -x zlib
+endif
+ifneq ($(CONFIG_JFFS2_LZMA),y)
+  JFFS2OPTS += -x lzma
+endif
+
+JFFS2OPTS += $(MKFS_DEVTABLE_OPT)
+
+SQUASHFS_BLOCKSIZE := $(CONFIG_TARGET_SQUASHFS_BLOCK_SIZE)k
+SQUASHFSOPT := -b $(SQUASHFS_BLOCKSIZE)
+SQUASHFSOPT += -p '/dev d 755 0 0' -p '/dev/console c 600 0 0 5 1'
+SQUASHFSCOMP := gzip
+LZMA_XZ_OPTIONS := -Xpreset 9 -Xe -Xlc 0 -Xlp 2 -Xpb 2
+ifeq ($(CONFIG_SQUASHFS_LZMA),y)
+  SQUASHFSCOMP := lzma $(LZMA_XZ_OPTIONS)
+endif
+ifeq ($(CONFIG_SQUASHFS_XZ),y)
+  ifneq ($(filter arm x86 powerpc sparc,$(LINUX_KARCH)),)
+    BCJ_FILTER:=-Xbcj $(LINUX_KARCH)
+  endif
+  SQUASHFSCOMP := xz $(LZMA_XZ_OPTIONS) $(BCJ_FILTER)
+endif
+
+JFFS2_BLOCKSIZE ?= 64k 128k
+
+fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
+fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
+fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
+fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
+fs-types-$(CONFIG_TARGET_ROOTFS_ISO) += iso
+fs-subtypes-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addsuffix -raw,$(addprefix jffs2-,$(JFFS2_BLOCKSIZE)))
+fs-subtypes-$(CONFIG_TARGET_ROOTFS_CPIOGZ) += cpiogz
+fs-subtypes-$(CONFIG_TARGET_ROOTFS_TARGZ) += targz
+
+TARGET_FILESYSTEMS := $(fs-types-y)
+
+FS_64K := $(filter-out jffs2-%,$(TARGET_FILESYSTEMS)) jffs2-64k
+FS_128K := $(filter-out jffs2-%,$(TARGET_FILESYSTEMS)) jffs2-128k
+FS_256K := $(filter-out jffs2-%,$(TARGET_FILESYSTEMS)) jffs2-256k
+
+define add_jffs2_mark
+	echo -ne '\xde\xad\xc0\xde' >> $(1)
+endef
+
+PROFILE_SANITIZED := $(call sanitize,$(PROFILE))
+
+define split_args
+$(foreach data, \
+	$(subst |,$(space),\
+		$(subst $(space),^,$(1))), \
+	$(call $(2),$(strip $(subst ^,$(space),$(data)))))
+endef
+
+define build_cmd
+$(if $(Build/$(word 1,$(1))),,$(error Missing Build/$(word 1,$(1))))
+$(call Build/$(word 1,$(1)),$(wordlist 2,$(words $(1)),$(1)))
+
+endef
+
+define concat_cmd
+$(call split_args,$(1),build_cmd)
+endef
+
+# pad to 4k, 8k, 16k, 64k, 128k, 256k and add jffs2 end-of-filesystem mark
+define prepare_generic_squashfs
+	$(STAGING_DIR_HOST)/bin/padjffs2 $(1) 4 8 16 64 128 256
+endef
+
+define Image/BuildKernel/Initramfs
+	$(call Image/Build/Initramfs)
+endef
+
+define Image/BuildKernel/MkuImage
+	mkimage -A $(ARCH) -O linux -T kernel -C $(1) -a $(2) -e $(3) \
+		-n '$(call toupper,$(ARCH)) OpenWrt Linux-$(LINUX_VERSION)' -d $(4) $(5)
+endef
+
+define Image/BuildKernel/MkFIT
+	$(TOPDIR)/scripts/mkits.sh \
+		-D $(1) -o $(KDIR)/fit-$(1).its -k $(2) $(if $(3),-d $(3)) -C $(4) -a $(5) -e $(6) \
+		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
+	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $(KDIR)/fit-$(1).its $(KDIR)/fit-$(1)$(7).itb
+endef
+
+# $(1) source dts file
+# $(2) target dtb file
+# $(3) extra CPP flags
+# $(4) extra DTC flags
+define Image/BuildDTB
+	$(TARGET_CROSS)cpp -nostdinc -x assembler-with-cpp \
+		-I$(DTS_DIR) \
+		-I$(DTS_DIR)/include \
+		-undef -D__DTS__ $(3) \
+		-o $(2).tmp $(1)
+	$(LINUX_DIR)/scripts/dtc/dtc -O dtb \
+		-i$(dir $(1)) $(4) \
+		-o $(2) $(2).tmp
+	$(RM) $(2).tmp
+endef
+
+define Image/mkfs/jffs2/sub
+		$(STAGING_DIR_HOST)/bin/mkfs.jffs2 $(3) --pad -e $(patsubst %k,%KiB,$(1)) -o $(KDIR)/root.jffs2-$(2) -d $(TARGET_DIR) -v 2>&1 1>/dev/null | awk '/^.+$$$$/'
+		$(call add_jffs2_mark,$(KDIR)/root.jffs2-$(2))
+endef
+
+define Image/mkfs/jffs2/sub-raw
+		$(STAGING_DIR_HOST)/bin/mkfs.jffs2 $(3) -e $(patsubst %k,%KiB,$(1)) -o $(KDIR)/root.jffs2-$(2)-raw -d $(TARGET_DIR) -v 2>&1 1>/dev/null | awk '/^.+$$$$/'
+endef
+
+define Image/mkfs/jffs2/template
+  Image/mkfs/jffs2-$(1) = $$(call Image/mkfs/jffs2/sub,$(1),$(1),$(JFFS2OPTS))
+  Image/mkfs/jffs2-$(1)-raw = $$(call Image/mkfs/jffs2/sub-raw,$(1),$(1),$(JFFS2OPTS))
+
+endef
+
+define Image/mkfs/jffs2-nand/template
+  Image/mkfs/jffs2-nand-$(1) = \
+	$$(call Image/mkfs/jffs2/sub, \
+		$(word 2,$(subst -, ,$(1))),nand-$(1), \
+			$(JFFS2OPTS) --no-cleanmarkers --pagesize=$(word 1,$(subst -, ,$(1))))
+
+endef
+
+$(eval $(foreach S,$(JFFS2_BLOCKSIZE),$(call Image/mkfs/jffs2/template,$(S))))
+$(eval $(foreach S,$(NAND_BLOCKSIZE),$(call Image/mkfs/jffs2-nand/template,$(S))))
+
+define Image/mkfs/squashfs
+	$(STAGING_DIR_HOST)/bin/mksquashfs4 $(TARGET_DIR) $(KDIR)/root.squashfs -nopad -noappend -root-owned -comp $(SQUASHFSCOMP) $(SQUASHFSOPT) -processors $(if $(CONFIG_PKG_BUILD_JOBS),$(CONFIG_PKG_BUILD_JOBS),1) $(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
+endef
+
+# $(1): board name
+# $(2): rootfs type
+# $(3): kernel image
+ifneq ($(CONFIG_NAND_SUPPORT),)
+   define Image/Build/SysupgradeNAND
+	mkdir -p "$(KDIR_TMP)/sysupgrade-$(1)/"
+	echo "BOARD=$(1)" > "$(KDIR_TMP)/sysupgrade-$(1)/CONTROL"
+	[ -z "$(2)" ] || $(CP) "$(KDIR)/root.$(2)" "$(KDIR_TMP)/sysupgrade-$(1)/root"
+	[ -z "$(3)" ] || $(CP) "$(3)" "$(KDIR_TMP)/sysupgrade-$(1)/kernel"
+	(cd "$(KDIR_TMP)"; $(TAR) cvf \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-sysupgrade.tar" sysupgrade-$(1) \
+			$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
+	)
+   endef
+
+# $(1) board name
+# $(2) ubinize-image options (e.g. --uboot-env and/or --kernel kernelimage)
+# $(3) rootfstype (e.g. squashfs or ubifs)
+# $(4) options to pass-through to ubinize (i.e. $($(PROFILE)_UBI_OPTS)))
+   define Image/Build/UbinizeImage
+	sh $(TOPDIR)/scripts/ubinize-image.sh $(2) \
+		"$(KDIR)/root.$(3)" \
+		"$(KDIR)/$(IMG_PREFIX)-$(1)-$(3)-ubinized.bin" \
+		$(4)
+   endef
+
+endif
+
+ifneq ($(CONFIG_TARGET_ROOTFS_UBIFS),)
+    define Image/mkfs/ubifs/generate
+	$(CP) ./ubinize$(1).cfg $(KDIR)
+	( cd $(KDIR); \
+		$(STAGING_DIR_HOST)/bin/ubinize \
+		$(if $($(PROFILE)_UBI_OPTS), \
+			$(shell echo $($(PROFILE)_UBI_OPTS)), \
+			$(shell echo $(UBI_OPTS)) \
+		) \
+		-o $(KDIR)/root$(1).ubi \
+		ubinize$(1).cfg \
+	)
+    endef
+
+    define Image/mkfs/ubifs
+
+        ifneq ($($(PROFILE)_UBIFS_OPTS)$(UBIFS_OPTS),)
+		$(STAGING_DIR_HOST)/bin/mkfs.ubifs \
+			$(if $($(PROFILE)_UBIFS_OPTS), \
+				$(shell echo $($(PROFILE)_UBIFS_OPTS)), \
+				$(shell echo $(UBIFS_OPTS)) \
+			) \
+			$(if $(CONFIG_TARGET_UBIFS_FREE_SPACE_FIXUP),--space-fixup) \
+			$(if $(CONFIG_TARGET_UBIFS_COMPRESSION_NONE),--force-compr=none) \
+			$(if $(CONFIG_TARGET_UBIFS_COMPRESSION_LZO),--force-compr=lzo) \
+			$(if $(CONFIG_TARGET_UBIFS_COMPRESSION_ZLIB),--force-compr=zlib) \
+			$(if $(shell echo $(CONFIG_TARGET_UBIFS_JOURNAL_SIZE)),--jrn-size=$(CONFIG_TARGET_UBIFS_JOURNAL_SIZE)) \
+			--squash-uids \
+			-o $(KDIR)/root.ubifs \
+			-d $(TARGET_DIR)
+        endif
+	$(call Image/Build,ubifs)
+
+        ifneq ($($(PROFILE)_UBI_OPTS)$(UBI_OPTS),)
+		$(if $(wildcard ./ubinize.cfg),$(call Image/mkfs/ubifs/generate,))
+		$(if $(wildcard ./ubinize-overlay.cfg),$(call Image/mkfs/ubifs/generate,-overlay))
+        endif
+	$(if $(wildcard ./ubinize.cfg),$(call Image/Build,ubi))
+    endef
+endif
+
+define Image/mkfs/cpiogz
+	( cd $(TARGET_DIR); find . | cpio -o -H newc | gzip -9n >$(BIN_DIR)/$(IMG_PREFIX)-rootfs.cpio.gz )
+endef
+
+define Image/mkfs/targz
+	$(TAR) -cp --numeric-owner --owner=0 --group=0 --sort=name \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
+		-C $(TARGET_DIR)/ . | gzip -9n > $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED))-rootfs.tar.gz
+endef
+
+E2SIZE=$(shell echo $$(($(CONFIG_TARGET_ROOTFS_PARTSIZE)*1024*1024)))
+
+define Image/mkfs/ext4
+	$(STAGING_DIR_HOST)/bin/make_ext4fs \
+		-l $(E2SIZE) -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \
+		-i $(CONFIG_TARGET_EXT4_MAXINODE) \
+		-m $(CONFIG_TARGET_EXT4_RESERVED_PCT) \
+		$(if $(CONFIG_TARGET_EXT4_JOURNAL),,-J) \
+		$(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \
+		$(KDIR)/root.ext4 $(TARGET_DIR)/
+endef
+
+define Image/mkfs/prepare/default
+	# Use symbolic permissions to avoid clobbering SUID/SGID/sticky bits
+	- $(FIND) $(TARGET_DIR) -type f -not -perm /0100 -not -name 'ssh_host*' -not -name 'shadow' -print0 | $(XARGS) -0 chmod u+rw,g+r,o+r
+	- $(FIND) $(TARGET_DIR) -type f -perm /0100 -print0 | $(XARGS) -0 chmod u+rwx,g+rx,o+rx
+	- $(FIND) $(TARGET_DIR) -type d -print0 | $(XARGS) -0 chmod u+rwx,g+rx,o+rx
+	$(INSTALL_DIR) $(TARGET_DIR)/tmp $(TARGET_DIR)/overlay
+	chmod 1777 $(TARGET_DIR)/tmp
+endef
+
+define Image/mkfs/prepare
+	$(call Image/mkfs/prepare/default)
+endef
+
+
+define Image/Checksum
+	( cd ${BIN_DIR} ; \
+		$(FIND) -maxdepth 1 -type f \! -name 'md5sums'  -printf "%P\n" | sort | xargs $1 > $2 \
+	)
+endef
+
+define BuildImage/mkfs
+  install: mkfs-$(1)
+  .PHONY: mkfs-$(1)
+  mkfs-$(1): kernel_prepare
+	$(Image/mkfs/$(1))
+	$(call Build/mkfs/default,$(1))
+	$(call Build/mkfs/$(1),$(1))
+  $(KDIR)/root.$(1): mkfs-$(1)
+
+endef
+
+# Build commands that can be called from Device/* templates
+define Build/uImage
+	mkimage -A $(LINUX_KARCH) \
+		-O linux -T kernel \
+		-C $(1) -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
+		-n '$(call toupper,$(LINUX_KARCH)) OpenWrt Linux-$(LINUX_VERSION)' -d $@ $@.new
+	@mv $@.new $@
+endef
+
+define Build/netgear-chk
+	$(STAGING_DIR_HOST)/bin/mkchkimg \
+		-o $@.new \
+		-k $@ \
+		-b $(NETGEAR_BOARD_ID) \
+		-r $(NETGEAR_REGION)
+	mv $@.new $@
+endef
+
+define Build/netgear-dni
+	$(STAGING_DIR_HOST)/bin/mkdniimg \
+		-B $(NETGEAR_BOARD_ID) -v OpenWrt.$(REVISION) \
+		$(if $(NETGEAR_HW_ID),-H $(NETGEAR_HW_ID)) \
+		-r "$(1)" \
+		-i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/tplink-safeloader
+       -$(STAGING_DIR_HOST)/bin/tplink-safeloader \
+		-B $(TPLINK_BOARD_NAME) \
+		-V $(REVISION) \
+		-k $(word 1,$^) \
+		-r $@ \
+		-o $@.new \
+		-j \
+		$(wordlist 2,$(words $(1)),$(1)) \
+		$(if $(findstring sysupgrade,$(word 1,$(1))),-S) && mv $@.new $@ || rm -f $@
+endef
+
+define Build/fit
+	$(TOPDIR)/scripts/mkits.sh \
+		-D $(DEVICE_NAME) -o $@.its -k $@ \
+		$(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \
+		-a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
+		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
+	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
+	@mv $@.new $@
+endef
+
+define Build/lzma
+	$(call Build/lzma-no-dict,-lc1 -lp2 -pb2 $(1))
+endef
+
+define Build/lzma-no-dict
+	$(STAGING_DIR_HOST)/bin/lzma e $@ $(1) $@.new
+	@mv $@.new $@
+endef
+
+define Build/gzip
+	gzip -9n -c $@ $(1) > $@.new
+	@mv $@.new $@
+endef
+
+define Build/jffs2
+	rm -rf $(KDIR_TMP)/$(DEVICE_NAME)/jffs2 && \
+		mkdir -p $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/$$(dirname $(1)) && \
+		cp $@ $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/$(1) && \
+		$(STAGING_DIR_HOST)/bin/mkfs.jffs2 --pad \
+			$(if $(CONFIG_BIG_ENDIAN),--big-endian,--little-endian) \
+			--squash-uids -v -e $(patsubst %k,%KiB,$(BLOCKSIZE)) \
+			-o $@.new \
+			-d $(KDIR_TMP)/$(DEVICE_NAME)/jffs2 \
+			2>&1 1>/dev/null | awk '/^.+$$$$/' && \
+		$(STAGING_DIR_HOST)/bin/padjffs2 $@.new -J $(patsubst %k,,$(BLOCKSIZE))
+	-rm -rf $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/
+	@mv $@.new $@
+endef
+
+define Build/kernel-bin
+	rm -f $@
+	cp $< $@
+endef
+
+define Build/patch-cmdline
+	$(STAGING_DIR_HOST)/bin/patch-cmdline $@ '$(CMDLINE)'
+endef
+
+define Build/append-kernel
+	dd if=$(word 1,$^) $(if $(1),bs=$(1) conv=sync) >> $@
+endef
+
+define Build/append-rootfs
+	dd if=$(word 2,$^) $(if $(1),bs=$(1) conv=sync) >> $@
+endef
+
+define Build/append-ubi
+	sh $(TOPDIR)/scripts/ubinize-image.sh \
+		$(if $(UBOOTENV_IN_UBI),--uboot-env) \
+		$(if $(KERNEL_IN_UBI),--kernel $(word 1,$^)) \
+		$(word 2,$^) \
+		$@.tmp \
+		-p $(BLOCKSIZE) -m $(PAGESIZE) -E 5 \
+		$(if $(SUBPAGESIZE),-s $(SUBPAGESIZE))
+	cat $@.tmp >> $@
+	rm $@.tmp
+endef
+
+define Build/pad-to
+	dd if=$@ of=$@.new bs=$(1) conv=sync
+	mv $@.new $@
+endef
+
+define Build/pad-rootfs
+	$(call prepare_generic_squashfs,$@ $(1))
+endef
+
+define Build/pad-offset
+	let \
+		size="$$(stat -c%s $@)" \
+		pad="$(word 1, $(1))" \
+		offset="$(word 2, $(1))" \
+		pad="(pad - ((size + offset) % pad)) % pad" \
+		newsize='size + pad'; \
+		dd if=$@ of=$@.new bs=$$newsize count=1 conv=sync
+	mv $@.new $@
+endef
+
+define Build/check-size
+	@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $@)" ] || { \
+		echo "WARNING: Image file $@ is too big" >&2; \
+		rm -f $@; \
+	}
+endef
+
+define Build/combined-image
+	-sh $(TOPDIR)/scripts/combined-image.sh \
+		"$(word 1,$^)" \
+		"$@" \
+		"$@.new"
+	@mv $@.new $@
+endef
+
+define Build/sysupgrade-nand
+	sh $(TOPDIR)/scripts/sysupgrade-nand.sh \
+		--board $(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)) \
+		--kernel $(word 1,$^) \
+		--rootfs $(word 2,$^) \
+		$@
+endef
+
+define Device/Init
+  PROFILES := $(PROFILE)
+  DEVICE_NAME := $(1)
+  KERNEL:=
+  KERNEL_INITRAMFS = $$(KERNEL)
+  KERNEL_SIZE:=
+  CMDLINE:=
+
+  IMAGE_PREFIX := $(IMG_PREFIX)-$(1)
+  IMAGE_NAME = $$(IMAGE_PREFIX)-$$(1)-$$(2)
+  KERNEL_PREFIX = $(1)
+  KERNEL_SUFFIX := -kernel.bin
+  KERNEL_IMAGE = $$(KERNEL_PREFIX)$$(KERNEL_SUFFIX)
+  KERNEL_INITRAMFS_PREFIX = $$(IMAGE_PREFIX)-initramfs
+  KERNEL_INITRAMFS_IMAGE = $$(KERNEL_INITRAMFS_PREFIX)$$(KERNEL_SUFFIX)
+  KERNEL_INITRAMFS_NAME = $$(KERNEL_NAME)-initramfs
+  KERNEL_INSTALL :=
+  KERNEL_NAME := vmlinux
+  KERNEL_DEPENDS :=
+  KERNEL_SIZE :=
+
+  FILESYSTEMS := $(TARGET_FILESYSTEMS)
+endef
+
+define Device/ExportVar
+  $(1) : $(2):=$$($(2))
+
+endef
+define Device/Export
+  $(foreach var,$(DEVICE_VARS) DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_INITRAMFS_IMAGE,$(call Device/ExportVar,$(1),$(var)))
+  $(1) : FILESYSTEM:=$(2)
+endef
+
+define Device/Check
+  _TARGET = $$(if $$(filter $(PROFILE),$$(PROFILES)),install,install-disabled)
+  _COMPILE_TARGET = $$(if $(if $(IB),,$(CONFIG_IB)$$(filter $(PROFILE),$$(PROFILES))),compile,compile-disabled)
+endef
+
+ifndef IB
+define Device/Build/initramfs
+  $(call Device/Export,$(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE),$(1))
+  $$(_TARGET): $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE)
+
+  $(KDIR)/$$(KERNEL_INITRAMFS_NAME):: image_prepare
+  $(BIN_DIR)/$$(KERNEL_INITRAMFS_IMAGE): $(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE)
+	cp $$^ $$@
+
+  $(KDIR)/tmp/$$(KERNEL_INITRAMFS_IMAGE): $(KDIR)/$$(KERNEL_INITRAMFS_NAME) $(CURDIR)/Makefile $$(KERNEL_DEPENDS)
+	@rm -f $$@
+	$$(call concat_cmd,$$(KERNEL_INITRAMFS))
+endef
+endif
+
+define Device/Build/check_size
+	@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $@)" ] || { \
+		echo "WARNING: Image file $@ is too big" >&2; \
+		rm -f $@; \
+	}
+endef
+
+define Device/Build/compile
+  $$(_COMPILE_TARGET): $(KDIR)/$(1)
+  $(eval $(call Device/Export,$(KDIR)/$(1)))
+  $(KDIR)/$(1):
+	$$(call concat_cmd,$(COMPILE/$(1)))
+
+endef
+
+define Device/Build/kernel
+  _KERNEL_IMAGES += $(KDIR)/$$(KERNEL_NAME)
+  $(KDIR)/$$(KERNEL_NAME):: image_prepare
+  $$(_TARGET): $$(if $$(KERNEL_INSTALL),$(BIN_DIR)/$$(KERNEL_IMAGE))
+  $(call Device/Export,$(KDIR)/$$(KERNEL_IMAGE),$(1))
+  $(BIN_DIR)/$$(KERNEL_IMAGE): $(KDIR)/$$(KERNEL_IMAGE)
+	cp $$^ $$@
+  ifndef IB
+    ifdef CONFIG_IB
+      install: $(KDIR)/$$(KERNEL_IMAGE)
+    endif
+    $(KDIR)/$$(KERNEL_IMAGE): $(KDIR)/$$(KERNEL_NAME) $(CURDIR)/Makefile $$(KERNEL_DEPENDS)
+	@rm -f $$@
+	$$(call concat_cmd,$$(KERNEL))
+	$$(if $$(KERNEL_SIZE),$$(call Device/Build/check_size,$$(KERNEL_SIZE)))
+  endif
+endef
+
+define Device/Build/image
+  $$(_TARGET): $(BIN_DIR)/$(call IMAGE_NAME,$(1),$(2))
+  $(eval $(call Device/Export,$(KDIR)/tmp/$(call IMAGE_NAME,$(1),$(2)),$(1)))
+  $(KDIR)/tmp/$(call IMAGE_NAME,$(1),$(2)): $(KDIR)/$$(KERNEL_IMAGE) $(KDIR)/root.$(1)
+	@rm -f $$@
+	[ -f $$(word 1,$$^) -a -f $$(word 2,$$^) ]
+	$$(call concat_cmd,$(if $(IMAGE/$(2)/$(1)),$(IMAGE/$(2)/$(1)),$(IMAGE/$(2))))
+
+  .IGNORE: $(BIN_DIR)/$(call IMAGE_NAME,$(1),$(2))
+  $(BIN_DIR)/$(call IMAGE_NAME,$(1),$(2)): $(KDIR)/tmp/$(call IMAGE_NAME,$(1),$(2))
+	cp $$^ $$@
+
+endef
+
+define Device/Build
+  $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Device/Build/initramfs,$(1)))
+  $(call Device/Build/kernel,$(1))
+
+  $$(eval $$(foreach compile,$$(COMPILE), \
+    $$(call Device/Build/compile,$$(compile),$(1))))
+
+  $$(eval $$(foreach image,$$(IMAGES), \
+    $$(foreach fs,$$(filter $(TARGET_FILESYSTEMS),$$(FILESYSTEMS)), \
+      $$(call Device/Build/image,$$(fs),$$(image),$(1)))))
+endef
+
+define Device
+  $(call Device/Init,$(1))
+  $(call Device/Default,$(1))
+  $(call Device/Check,$(1))
+  $(call Device/$(1),$(1))
+  $(call Device/Build,$(1))
+
+endef
+
+define BuildImage
+
+  download:
+  prepare:
+  compile:
+  clean:
+  image_prepare:
+
+  ifeq ($(IB),)
+    .PHONY: download prepare compile clean image_prepare mkfs_prepare kernel_prepare install
+    compile:
+		$(call Build/Compile)
+
+    clean:
+		$(call Build/Clean)
+
+    image_prepare: compile
+		mkdir -p $(KDIR)/tmp
+		$(call Image/Prepare)
+  else
+    image_prepare:
+		mkdir -p $(KDIR)/tmp
+  endif
+
+  mkfs_prepare: image_prepare
+	$(call Image/mkfs/prepare)
+
+  kernel_prepare: mkfs_prepare
+	$(call Image/BuildKernel)
+	$(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(if $(IB),,$(call Image/BuildKernel/Initramfs)))
+	$(call Image/InstallKernel)
+
+  $(foreach device,$(TARGET_DEVICES),$(call Device,$(device)))
+  $(foreach fs,$(TARGET_FILESYSTEMS) $(fs-subtypes-y),$(call BuildImage/mkfs,$(fs)))
+
+  install: kernel_prepare
+	$(foreach fs,$(TARGET_FILESYSTEMS),
+		$(call Image/Build,$(fs))
+	)
+	$(call Image/mkfs/ubifs)
+	$(call Image/Checksum,md5sum --binary,md5sums)
+	$(call Image/Checksum,openssl dgst -sha256,sha256sums)
+
+endef

+ 147 - 0
include/kernel-build.mk

@@ -0,0 +1,147 @@
+#
+# Copyright (C) 2006-2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(INCLUDE_DIR)/host.mk
+include $(INCLUDE_DIR)/prereq.mk
+
+ifneq ($(DUMP),1)
+  all: compile
+endif
+
+export QUILT=1
+STAMP_PREPARED:=$(LINUX_DIR)/.prepared
+STAMP_CONFIGURED:=$(LINUX_DIR)/.configured
+include $(INCLUDE_DIR)/download.mk
+include $(INCLUDE_DIR)/quilt.mk
+include $(INCLUDE_DIR)/kernel-defaults.mk
+
+define Kernel/Prepare
+	$(call Kernel/Prepare/Default)
+endef
+
+define Kernel/Configure
+	$(call Kernel/Configure/Default)
+endef
+
+define Kernel/CompileModules
+	$(call Kernel/CompileModules/Default)
+endef
+
+define Kernel/CompileImage
+	$(call Kernel/CompileImage/Default)
+	$(call Kernel/CompileImage/Initramfs)
+endef
+
+define Kernel/Clean
+	$(call Kernel/Clean/Default)
+endef
+
+define Download/kernel
+  URL:=$(LINUX_SITE)
+  FILE:=$(LINUX_SOURCE)
+  MD5SUM:=$(LINUX_KERNEL_MD5SUM)
+endef
+
+ifdef CONFIG_COLLECT_KERNEL_DEBUG
+  define Kernel/CollectDebug
+	rm -rf $(KERNEL_BUILD_DIR)/debug
+	mkdir -p $(KERNEL_BUILD_DIR)/debug/modules
+	$(CP) $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/debug/
+	-$(CP) \
+		$(STAGING_DIR_ROOT)/lib/modules/$(LINUX_VERSION)/* \
+		$(KERNEL_BUILD_DIR)/debug/modules/
+	$(FIND) $(KERNEL_BUILD_DIR)/debug -type f | $(XARGS) $(KERNEL_CROSS)strip --only-keep-debug
+	$(TAR) c -C $(KERNEL_BUILD_DIR) debug \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
+		| bzip2 -c -9 > $(BIN_DIR)/kernel-debug.tar.bz2
+  endef
+endif
+
+define BuildKernel
+  $(if $(QUILT),$(Build/Quilt))
+  $(if $(LINUX_SITE),$(call Download,kernel))
+
+  .NOTPARALLEL:
+
+  $(STAMP_PREPARED): $(if $(LINUX_SITE),$(DL_DIR)/$(LINUX_SOURCE))
+	-rm -rf $(KERNEL_BUILD_DIR)
+	-mkdir -p $(KERNEL_BUILD_DIR)
+	$(Kernel/Prepare)
+	touch $$@
+
+  $(KERNEL_BUILD_DIR)/symtab.h: FORCE
+	rm -f $(KERNEL_BUILD_DIR)/symtab.h
+	touch $(KERNEL_BUILD_DIR)/symtab.h
+	+$(MAKE) $(KERNEL_MAKEOPTS) vmlinux
+	find $(LINUX_DIR) $(STAGING_DIR_ROOT)/lib/modules -name \*.ko | \
+		xargs $(TARGET_CROSS)nm | \
+		awk '$$$$1 == "U" { print $$$$2 } ' | \
+		sort -u > $(KERNEL_BUILD_DIR)/mod_symtab.txt
+	$(TARGET_CROSS)nm -n $(LINUX_DIR)/vmlinux.o | grep ' [rR] __ksymtab' | sed -e 's,........ [rR] __ksymtab_,,' > $(KERNEL_BUILD_DIR)/kernel_symtab.txt
+	grep -Ff $(KERNEL_BUILD_DIR)/mod_symtab.txt $(KERNEL_BUILD_DIR)/kernel_symtab.txt > $(KERNEL_BUILD_DIR)/sym_include.txt
+	grep -Fvf $(KERNEL_BUILD_DIR)/mod_symtab.txt $(KERNEL_BUILD_DIR)/kernel_symtab.txt > $(KERNEL_BUILD_DIR)/sym_exclude.txt
+	( \
+		echo '#define SYMTAB_KEEP \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_include.txt | \
+			awk '{print "KEEP(*(___ksymtab+" $$$$1 ")) \\" }'; \
+		echo; \
+		echo '#define SYMTAB_KEEP_GPL \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_include.txt | \
+			awk '{print "KEEP(*(___ksymtab_gpl+" $$$$1 ")) \\" }'; \
+		echo; \
+		echo '#define SYMTAB_DISCARD \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_exclude.txt | \
+			awk '{print "*(___ksymtab+" $$$$1 ") \\" }'; \
+		echo; \
+		echo '#define SYMTAB_DISCARD_GPL \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_exclude.txt | \
+			awk '{print "*(___ksymtab_gpl+" $$$$1 ") \\" }'; \
+		echo; \
+	) > $$@
+
+  $(STAMP_CONFIGURED): $(STAMP_PREPARED) $(LINUX_KCONFIG_LIST) $(TOPDIR)/.config
+	$(Kernel/Configure)
+	touch $$@
+
+  $(LINUX_DIR)/.modules: $(STAMP_CONFIGURED) $(LINUX_DIR)/.config FORCE
+	$(Kernel/CompileModules)
+	touch $$@
+
+  $(LINUX_DIR)/.image: $(STAMP_CONFIGURED) $(if $(CONFIG_STRIP_KERNEL_EXPORTS),$(KERNEL_BUILD_DIR)/symtab.h) FORCE
+	$(Kernel/CompileImage)
+	$(Kernel/CollectDebug)
+	touch $$@
+	
+  mostlyclean: FORCE
+	$(Kernel/Clean)
+
+  define BuildKernel
+  endef
+
+  download: $(if $(LINUX_SITE),$(DL_DIR)/$(LINUX_SOURCE))
+  prepare: $(STAMP_CONFIGURED)
+  compile: $(LINUX_DIR)/.modules
+	$(MAKE) -C image compile TARGET_BUILD=
+
+  oldconfig menuconfig nconfig: $(STAMP_PREPARED) $(STAMP_CHECKED) FORCE
+	rm -f $(LINUX_DIR)/.config.prev
+	rm -f $(STAMP_CONFIGURED)
+	$(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config
+	$(_SINGLE)$(MAKE) -C $(LINUX_DIR) $(KERNEL_MAKEOPTS) $$@
+	$(LINUX_RECONF_DIFF) $(LINUX_DIR)/.config > $(LINUX_RECONFIG_TARGET)
+
+  install: $(LINUX_DIR)/.image
+	+$(MAKE) -C image compile install TARGET_BUILD=
+
+  clean: FORCE
+	rm -rf $(KERNEL_BUILD_DIR)
+
+  image-prereq:
+	@+$(NO_TRACE_MAKE) -s -C image prereq TARGET_BUILD=
+
+  prereq: image-prereq
+
+endef

+ 179 - 0
include/kernel-defaults.mk

@@ -0,0 +1,179 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+KERNEL_MAKEOPTS := -C $(LINUX_DIR) \
+	HOSTCFLAGS="$(HOST_CFLAGS) -Wall -Wmissing-prototypes -Wstrict-prototypes" \
+	CROSS_COMPILE="$(KERNEL_CROSS)" \
+	ARCH="$(LINUX_KARCH)" \
+	KBUILD_HAVE_NLS=no \
+	KBUILD_BUILD_USER="$(call qstrip,$(CONFIG_KERNEL_BUILD_USER))" \
+	KBUILD_BUILD_HOST="$(call qstrip,$(CONFIG_KERNEL_BUILD_DOMAIN))" \
+	CONFIG_SHELL="$(BASH)" \
+	$(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
+	$(if $(PKG_BUILD_ID),LDFLAGS_MODULE=--build-id=0x$(PKG_BUILD_ID))
+
+ifdef CONFIG_STRIP_KERNEL_EXPORTS
+  KERNEL_MAKEOPTS += \
+	EXTRA_LDSFLAGS="-I$(KERNEL_BUILD_DIR) -include symtab.h"
+endif
+
+INITRAMFS_EXTRA_FILES ?= $(GENERIC_PLATFORM_DIR)/image/initramfs-base-files.txt
+
+ifneq (,$(KERNEL_CC))
+  KERNEL_MAKEOPTS += CC="$(KERNEL_CC)"
+endif
+
+ifdef CONFIG_USE_SPARSE
+  KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse
+endif
+
+export HOST_EXTRACFLAGS=-I$(STAGING_DIR_HOST)/include
+
+# defined in quilt.mk
+Kernel/Patch:=$(Kernel/Patch/Default)
+
+KERNEL_GIT_OPTS:=
+ifneq ($(strip $(CONFIG_KERNEL_GIT_LOCAL_REPOSITORY)),"")
+  KERNEL_GIT_OPTS+=--reference $(CONFIG_KERNEL_GIT_LOCAL_REPOSITORY)
+endif
+
+ifneq ($(strip $(CONFIG_KERNEL_GIT_BRANCH)),"")
+  KERNEL_GIT_OPTS+=--branch $(CONFIG_KERNEL_GIT_BRANCH)
+endif
+
+ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")
+  ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
+    define Kernel/Prepare/Default
+	xzcat $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
+	$(Kernel/Patch)
+	touch $(LINUX_DIR)/.quilt_used
+    endef
+  else
+    define Kernel/Prepare/Default
+	git clone $(KERNEL_GIT_OPTS) $(CONFIG_KERNEL_GIT_CLONE_URI) $(LINUX_DIR)
+    endef
+  endif
+else
+  define Kernel/Prepare/Default
+	mkdir -p $(KERNEL_BUILD_DIR)
+	if [ -d $(LINUX_DIR) ]; then \
+		rmdir $(LINUX_DIR); \
+	fi
+	ln -s $(CONFIG_EXTERNAL_KERNEL_TREE) $(LINUX_DIR)
+  endef
+endif
+
+ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
+  ifeq ($(strip $(CONFIG_EXTERNAL_CPIO)),"")
+    define Kernel/SetInitramfs/PreConfigure
+	grep -v -e INITRAMFS -e CONFIG_RD_ -e CONFIG_BLK_DEV_INITRD $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config
+	echo 'CONFIG_BLK_DEV_INITRD=y' >> $(LINUX_DIR)/.config
+	echo 'CONFIG_INITRAMFS_SOURCE="$(strip $(TARGET_DIR) $(INITRAMFS_EXTRA_FILES))"' >> $(LINUX_DIR)/.config
+    endef
+  else
+    define Kernel/SetInitramfs/PreConfigure
+	grep -v INITRAMFS $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config
+	echo 'CONFIG_INITRAMFS_SOURCE="$(call qstrip,$(CONFIG_EXTERNAL_CPIO))"' >> $(LINUX_DIR)/.config
+    endef
+  endif
+
+  define Kernel/SetInitramfs
+	rm -f $(LINUX_DIR)/.config.prev
+	mv $(LINUX_DIR)/.config $(LINUX_DIR)/.config.old
+	$(call Kernel/SetInitramfs/PreConfigure)
+	echo 'CONFIG_INITRAMFS_ROOT_UID=$(shell id -u)' >> $(LINUX_DIR)/.config
+	echo 'CONFIG_INITRAMFS_ROOT_GID=$(shell id -g)' >> $(LINUX_DIR)/.config
+	echo "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_NONE),CONFIG_INITRAMFS_COMPRESSION_NONE=y,# CONFIG_INITRAMFS_COMPRESSION_NONE is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_GZIP),CONFIG_INITRAMFS_COMPRESSION_GZIP=y\nCONFIG_RD_GZIP=y,# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set\n# CONFIG_RD_GZIP is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_BZIP2),CONFIG_INITRAMFS_COMPRESSION_BZIP2=y\nCONFIG_RD_BZIP2=y,# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set\n# CONFIG_RD_BZIP2 is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZMA),CONFIG_INITRAMFS_COMPRESSION_LZMA=y\nCONFIG_RD_LZMA=y,# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set\n# CONFIG_RD_LZMA is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZO),CONFIG_INITRAMFS_COMPRESSION_LZO=y\nCONFIG_RD_LZO=y,# CONFIG_INITRAMFS_COMPRESSION_LZO is not set\n# CONFIG_RD_LZO is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_XZ),CONFIG_INITRAMFS_COMPRESSION_XZ=y\nCONFIG_RD_XZ=y,# CONFIG_INITRAMFS_COMPRESSION_XZ is not set\n# CONFIG_RD_XZ is not set)" >> $(LINUX_DIR)/.config
+	echo -e "$(if $(CONFIG_TARGET_INITRAMFS_COMPRESSION_LZ4),CONFIG_INITRAMFS_COMPRESSION_LZ4=y\nCONFIG_RD_LZ4=y,# CONFIG_INITRAMFS_COMPRESSION_LZ4 is not set\n# CONFIG_RD_LZ4 is not set)" >> $(LINUX_DIR)/.config
+  endef
+else
+endif
+
+define Kernel/SetNoInitramfs
+	mv $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.old
+	grep -v INITRAMFS $(LINUX_DIR)/.config.old > $(LINUX_DIR)/.config.set
+	echo 'CONFIG_INITRAMFS_SOURCE=""' >> $(LINUX_DIR)/.config.set
+endef
+
+define Kernel/Configure/Default
+	$(LINUX_CONF_CMD) > $(LINUX_DIR)/.config.target
+# copy CONFIG_KERNEL_* settings over to .config.target
+	awk '/^(#[[:space:]]+)?CONFIG_KERNEL/{sub("CONFIG_KERNEL_","CONFIG_");print}' $(TOPDIR)/.config >> $(LINUX_DIR)/.config.target
+	echo "# CONFIG_KALLSYMS_EXTRA_PASS is not set" >> $(LINUX_DIR)/.config.target
+	echo "# CONFIG_KALLSYMS_ALL is not set" >> $(LINUX_DIR)/.config.target
+	echo "CONFIG_KALLSYMS_UNCOMPRESSED=y" >> $(LINUX_DIR)/.config.target
+	$(SCRIPT_DIR)/metadata.pl kconfig $(TMP_DIR)/.packageinfo $(TOPDIR)/.config $(KERNEL_PATCHVER) > $(LINUX_DIR)/.config.override
+	$(SCRIPT_DIR)/kconfig.pl 'm+' '+' $(LINUX_DIR)/.config.target /dev/null $(LINUX_DIR)/.config.override > $(LINUX_DIR)/.config.set
+	$(call Kernel/SetNoInitramfs)
+	rm -rf $(KERNEL_BUILD_DIR)/modules
+	cmp -s $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.prev || { \
+		cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config; \
+		cp $(LINUX_DIR)/.config.set $(LINUX_DIR)/.config.prev; \
+	}
+	$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(MAKE) $(KERNEL_MAKEOPTS) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
+	$(SH_FUNC) grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | md5s > $(LINUX_DIR)/.vermagic
+endef
+
+define Kernel/Configure/Initramfs
+	$(call Kernel/SetInitramfs)
+endef
+
+define Kernel/CompileModules/Default
+	rm -f $(LINUX_DIR)/vmlinux $(LINUX_DIR)/System.map
+	+$(MAKE) $(KERNEL_MAKEOPTS) modules
+endef
+
+OBJCOPY_STRIP = -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id
+
+# AMD64 shares the location with x86
+ifeq ($(LINUX_KARCH),x86_64)
+IMAGES_DIR:=../../x86/boot
+endif
+
+define Kernel/CopyImage
+	cmp -s $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).debug || { \
+		$(KERNEL_CROSS)objcopy -O binary $(OBJCOPY_STRIP) -S $(LINUX_DIR)/vmlinux $(LINUX_KERNEL)$(1); \
+		$(KERNEL_CROSS)objcopy $(OBJCOPY_STRIP) -S $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).elf; \
+		$(CP) $(LINUX_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux$(1).debug; \
+		$(foreach k, \
+			$(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out dtbs,$(KERNELNAME))), \
+			$(CP) $(LINUX_DIR)/arch/$(LINUX_KARCH)/boot/$(IMAGES_DIR)/$(k) $(KERNEL_BUILD_DIR)/$(k)$(1); \
+		) \
+	}
+endef
+
+define Kernel/CompileImage/Default
+	rm -f $(TARGET_DIR)/init
+	+$(MAKE) $(KERNEL_MAKEOPTS) $(if $(KERNELNAME),$(KERNELNAME),all) modules
+	$(call Kernel/CopyImage)
+endef
+
+ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
+define Kernel/CompileImage/Initramfs
+	$(call Kernel/Configure/Initramfs)
+	$(CP) $(GENERIC_PLATFORM_DIR)/base-files/init $(TARGET_DIR)/init
+	rm -rf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/usr/initramfs_data.cpio*
+	+$(MAKE) $(KERNEL_MAKEOPTS) $(if $(KERNELNAME),$(KERNELNAME),all) modules
+	$(call Kernel/CopyImage,-initramfs)
+endef
+else
+define Kernel/CompileImage/Initramfs
+endef
+endif
+
+define Kernel/Clean/Default
+	rm -f $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/.configured
+	rm -f $(LINUX_KERNEL)
+	$(_SINGLE)$(MAKE) -C $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION) clean
+endef
+
+

+ 25 - 0
include/kernel-version.mk

@@ -0,0 +1,25 @@
+# Use the default kernel version if the Makefile doesn't override it
+
+LINUX_RELEASE?=1
+
+LINUX_VERSION-3.18 = .44
+LINUX_VERSION-4.1 = .35
+LINUX_VERSION-4.4 = .14
+
+LINUX_KERNEL_MD5SUM-3.18.44 = 7c52da2f54381a84960118b5bf23381a
+LINUX_KERNEL_MD5SUM-4.1.35 = 14ca049674ee83a651be1dc69f5b8d2c
+LINUX_KERNEL_MD5SUM-4.4.14 = 59e99c3bf5d495f1f95d26257962ca3e
+
+ifdef KERNEL_PATCHVER
+  LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
+endif
+
+split_version=$(subst ., ,$(1))
+merge_version=$(subst $(space),.,$(1))
+KERNEL_BASE=$(firstword $(subst -, ,$(LINUX_VERSION)))
+KERNEL=$(call merge_version,$(wordlist 1,2,$(call split_version,$(KERNEL_BASE))))
+KERNEL_PATCHVER ?= $(KERNEL)
+
+# disable the md5sum check for unknown kernel versions
+LINUX_KERNEL_MD5SUM:=$(LINUX_KERNEL_MD5SUM-$(strip $(LINUX_VERSION)))
+LINUX_KERNEL_MD5SUM?=x

+ 243 - 0
include/kernel.mk

@@ -0,0 +1,243 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifeq ($(__target_inc),)
+  include $(INCLUDE_DIR)/target.mk
+endif
+
+ifeq ($(DUMP),1)
+  KERNEL?=<KERNEL>
+  BOARD?=<BOARD>
+  LINUX_VERSION?=<LINUX_VERSION>
+  LINUX_VERMAGIC?=<LINUX_VERMAGIC>
+else
+  ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
+    export GCC_HONOUR_COPTS=s
+  endif
+
+  LINUX_KMOD_SUFFIX=ko
+
+  ifneq (,$(findstring uml,$(BOARD)))
+    KERNEL_CC?=$(HOSTCC)
+    KERNEL_CROSS?=
+  else
+    KERNEL_CC?=$(TARGET_CC)
+    KERNEL_CROSS?=$(TARGET_CROSS)
+  endif
+
+  ifeq ($(TARGET_BUILD),1)
+    PATCH_DIR ?= ./patches$(if $(wildcard ./patches-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+    FILES_DIR ?= $(foreach dir,$(wildcard ./files ./files-$(KERNEL_PATCHVER)),"$(dir)")
+  endif
+  KERNEL_BUILD_DIR ?= $(BUILD_DIR)/linux-$(BOARD)$(if $(SUBTARGET),_$(SUBTARGET))
+  LINUX_DIR ?= $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)
+  LINUX_UAPI_DIR=uapi/
+  LINUX_VERMAGIC:=$(strip $(shell cat $(LINUX_DIR)/.vermagic 2>/dev/null))
+  LINUX_VERMAGIC:=$(if $(LINUX_VERMAGIC),$(LINUX_VERMAGIC),unknown)
+
+  LINUX_UNAME_VERSION:=$(if $(word 3,$(subst ., ,$(KERNEL_BASE))),$(KERNEL_BASE),$(KERNEL_BASE).0)
+  ifneq ($(findstring -rc,$(LINUX_VERSION)),)
+    LINUX_UNAME_VERSION:=$(LINUX_UNAME_VERSION)-$(strip $(lastword $(subst -, ,$(LINUX_VERSION))))
+  endif
+
+  MODULES_SUBDIR:=lib/modules/$(LINUX_UNAME_VERSION)
+  TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
+
+  LINUX_KERNEL:=$(KERNEL_BUILD_DIR)/vmlinux
+
+  LINUX_SOURCE:=linux-$(LINUX_VERSION).tar.xz
+  TESTING:=$(if $(findstring -rc,$(LINUX_VERSION)),/testing,)
+  ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+      LINUX_SITE:=@KERNEL/linux/kernel/v$(word 1,$(subst ., ,$(KERNEL_BASE))).x$(TESTING)
+  endif
+
+  ifneq ($(TARGET_BUILD),1)
+    PKG_BUILD_DIR ?= $(KERNEL_BUILD_DIR)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
+  endif
+endif
+
+ifneq (,$(findstring uml,$(BOARD)))
+  LINUX_KARCH=um
+else ifneq (,$(findstring $(ARCH) , aarch64 aarch64_be ))
+  LINUX_KARCH := arm64
+else ifneq (,$(findstring $(ARCH) , arceb ))
+  LINUX_KARCH := arc
+else ifneq (,$(findstring $(ARCH) , armeb ))
+  LINUX_KARCH := arm
+else ifneq (,$(findstring $(ARCH) , mipsel mips64 mips64el ))
+  LINUX_KARCH := mips
+else ifneq (,$(findstring $(ARCH) , sh2 sh3 sh4 ))
+  LINUX_KARCH := sh
+else ifneq (,$(findstring $(ARCH) , i386 x86_64 ))
+  LINUX_KARCH := x86
+else
+  LINUX_KARCH := $(ARCH)
+endif
+
+define KernelPackage/Defaults
+  FILES:=
+  AUTOLOAD:=
+endef
+
+define ModuleAutoLoad
+	$(SH_FUNC) \
+	export modules=; \
+	probe_module() { \
+		mods="$$$$$$$$1"; \
+		boot="$$$$$$$$2"; \
+		shift 2; \
+		for mod in $(sort $$$$$$$$mods); do \
+			mkdir -p $(2)/etc/modules.d; \
+			echo "$$$$$$$$mod" >> $(2)/etc/modules.d/$(1); \
+		done; \
+		if [ -e $(2)/etc/modules.d/$(1) ]; then \
+			if [ "$$$$$$$$boot" = "1" ]; then \
+				mkdir -p $(2)/etc/modules-boot.d; \
+				ln -s ../modules.d/$(1) $(2)/etc/modules-boot.d/; \
+			fi; \
+			modules="$$$$$$$${modules:+$$$$$$$$modules }$$$$$$$$mods"; \
+		fi; \
+	}; \
+	add_module() { \
+		priority="$$$$$$$$1"; \
+		mods="$$$$$$$$2"; \
+		boot="$$$$$$$$3"; \
+		shift 3; \
+		for mod in $(sort $$$$$$$$mods); do \
+			mkdir -p $(2)/etc/modules.d; \
+			echo "$$$$$$$$mod" >> $(2)/etc/modules.d/$$$$$$$$priority-$(1); \
+		done; \
+		if [ -e $(2)/etc/modules.d/$$$$$$$$priority-$(1) ]; then \
+			if [ "$$$$$$$$boot" = "1" ]; then \
+				mkdir -p $(2)/etc/modules-boot.d; \
+				ln -s ../modules.d/$$$$$$$$priority-$(1) $(2)/etc/modules-boot.d/; \
+			fi; \
+			modules="$$$$$$$${modules:+$$$$$$$$modules }$$$$$$$$priority-$(1)"; \
+		fi; \
+	}; \
+	$(3) \
+	if [ -n "$$$$$$$$modules" ]; then \
+		mkdir -p $(2)/etc/modules.d; \
+		mkdir -p $(2)/CONTROL; \
+		echo "#!/bin/sh" > $(2)/CONTROL/postinst-pkg; \
+		echo "[ -z \"\$$$$$$$$IPKG_INSTROOT\" ] || exit 0" >> $(2)/CONTROL/postinst-pkg; \
+		echo ". /lib/functions.sh" >> $(2)/CONTROL/postinst-pkg; \
+		echo "insert_modules $$$$$$$$modules" >> $(2)/CONTROL/postinst-pkg; \
+		chmod 0755 $(2)/CONTROL/postinst-pkg; \
+	fi
+endef
+
+ifeq ($(DUMP)$(TARGET_BUILD),)
+  -include $(LINUX_DIR)/.config
+endif
+
+define KernelPackage/depends
+  $(STAMP_BUILT): $(LINUX_DIR)/.config
+  define KernelPackage/depends
+  endef
+endef
+
+define KernelPackage
+  NAME:=$(1)
+  $(eval $(call Package/Default))
+  $(eval $(call KernelPackage/Defaults))
+  $(eval $(call KernelPackage/$(1)))
+  $(eval $(call KernelPackage/$(1)/$(BOARD)))
+
+  define Package/kmod-$(1)
+    TITLE:=$(TITLE)
+    SECTION:=kernel
+    CATEGORY:=Kernel modules
+    DESCRIPTION:=$(DESCRIPTION)
+    EXTRA_DEPENDS:=kernel (=$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC))
+    VERSION:=$(LINUX_VERSION)$(if $(PKG_VERSION),+$(PKG_VERSION))-$(if $(PKG_RELEASE),$(PKG_RELEASE),$(LINUX_RELEASE))
+    PACKAGE_SUBDIR:=$(if $(FEED),$(FEED),kernel)
+    $(call KernelPackage/$(1))
+    $(call KernelPackage/$(1)/$(BOARD))
+  endef
+
+  ifdef KernelPackage/$(1)/conffiles
+    define Package/kmod-$(1)/conffiles
+$(call KernelPackage/$(1)/conffiles)
+    endef
+  endif
+
+  ifdef KernelPackage/$(1)/description
+    define Package/kmod-$(1)/description
+$(call KernelPackage/$(1)/description)
+    endef
+  endif
+
+  ifdef KernelPackage/$(1)/config
+    define Package/kmod-$(1)/config
+$(call KernelPackage/$(1)/config)
+    endef
+  endif
+
+  $(call KernelPackage/depends)
+
+  ifneq ($(if $(filter-out %=y %=n %=m,$(KCONFIG)),$(filter m y,$(foreach c,$(filter-out %=y %=n %=m,$(KCONFIG)),$($(c)))),.),)
+    ifneq ($(strip $(FILES)),)
+      define Package/kmod-$(1)/install
+		  @for mod in $$(call version_filter,$$(FILES)); do \
+			if grep -q "$$$$$$$${mod##$(LINUX_DIR)/}" "$(LINUX_DIR)/modules.builtin"; then \
+				echo "NOTICE: module '$$$$$$$$mod' is built-in."; \
+			elif [ -e $$$$$$$$mod ]; then \
+				mkdir -p $$(1)/$(MODULES_SUBDIR) ; \
+				$(CP) -L $$$$$$$$mod $$(1)/$(MODULES_SUBDIR)/ ; \
+			else \
+				echo "ERROR: module '$$$$$$$$mod' is missing." >&2; \
+				exit 1; \
+			fi; \
+		  done;
+		  $(call ModuleAutoLoad,$(1),$$(1),$(AUTOLOAD))
+		  $(call KernelPackage/$(1)/install,$$(1))
+      endef
+    endif
+  $(if $(CONFIG_PACKAGE_kmod-$(1)),
+    else
+      compile: $(1)-disabled
+      $(1)-disabled:
+		@echo "WARNING: kmod-$(1) is not available in the kernel config - generating empty package" >&2
+
+      define Package/kmod-$(1)/install
+		true
+      endef
+  )
+  endif
+  $$(eval $$(call BuildPackage,kmod-$(1)))
+
+  $$(IPKG_kmod-$(1)): $$(wildcard $$(FILES))
+endef
+
+version_filter=$(if $(findstring @,$(1)),$(shell $(SCRIPT_DIR)/metadata.pl version_filter $(KERNEL_PATCHVER) $(1)),$(1))
+
+define AutoLoad
+  add_module "$(1)" "$(call version_filter,$(2))" "$(3)";
+endef
+
+define AutoProbe
+  probe_module "$(call version_filter,$(1))" "$(2)";
+endef
+
+version_field=$(if $(word $(1),$(2)),$(word $(1),$(2)),0)
+kernel_version_merge=$$(( ($(call version_field,1,$(1)) << 24) + ($(call version_field,2,$(1)) << 16) + ($(call version_field,3,$(1)) << 8) + $(call version_field,4,$(1)) ))
+
+ifdef DUMP
+  kernel_version_cmp=
+else
+  kernel_version_cmp=$(shell [ $(call kernel_version_merge,$(call split_version,$(2))) $(1) $(call kernel_version_merge,$(call split_version,$(3))) ] && echo 1 )
+endif
+
+CompareKernelPatchVer=$(if $(call kernel_version_cmp,-$(2),$(1),$(3)),1,0)
+
+kernel_patchver_gt=$(call kernel_version_cmp,-gt,$(KERNEL_PATCHVER),$(1))
+kernel_patchver_ge=$(call kernel_version_cmp,-ge,$(KERNEL_PATCHVER),$(1))
+kernel_patchver_eq=$(call kernel_version_cmp,-eq,$(KERNEL_PATCHVER),$(1))
+kernel_patchver_le=$(call kernel_version_cmp,-le,$(KERNEL_PATCHVER),$(1))
+kernel_patchver_lt=$(call kernel_version_cmp,-lt,$(KERNEL_PATCHVER),$(1))
+

+ 382 - 0
include/netfilter.mk

@@ -0,0 +1,382 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifneq ($(__inc_netfilter),1)
+__inc_netfilter:=1
+
+ifeq ($(NF_KMOD),1)
+P_V4:=ipv4/netfilter/
+P_V6:=ipv6/netfilter/
+P_XT:=netfilter/
+P_EBT:=bridge/netfilter/
+endif
+
+# 1: variable
+# 2: kconfig symbols
+# 3: file list
+# 4: version dependency
+define nf_add
+ $(if $(4),ifeq ($$(strip $$(call CompareKernelPatchVer,$$(KERNEL_PATCHVER),$(firstword $(4)),$(lastword $(4)))),1))
+  $(1)-$$($(2)) += $(3)
+ $(if $(4),endif)
+ KCONFIG_$(1) = $(filter-out $(2),$(KCONFIG_$(1))) $(2)
+endef
+
+
+# core
+
+# kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT,CONFIG_IP_NF_IPTABLES, $(P_V4)ip_tables),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT,CONFIG_NETFILTER_XTABLES, $(P_XT)x_tables),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_CORE,CONFIG_NETFILTER_XTABLES, $(P_XT)xt_tcpudp),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_CORE,CONFIG_IP_NF_FILTER, $(P_V4)iptable_filter),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_CORE,CONFIG_IP_NF_MANGLE, $(P_V4)iptable_mangle),))
+
+# userland only
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_CORE,CONFIG_IP_NF_IPTABLES, xt_standard ipt_icmp xt_tcp xt_udp xt_comment xt_set xt_SET)))
+
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MATCH_LIMIT, $(P_XT)xt_limit))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MATCH_MAC, $(P_XT)xt_mac))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MATCH_MULTIPORT, $(P_XT)xt_multiport))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MATCH_COMMENT, $(P_XT)xt_comment))
+
+#cluster
+$(eval $(call nf_add,IPT_CLUSTER,CONFIG_NETFILTER_XT_MATCH_CLUSTER, $(P_XT)xt_cluster))
+
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_TARGET_LOG, $(P_XT)xt_LOG))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_TARGET_LOG, $(P_XT)nf_log_common))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_TARGET_LOG, $(P_V4)nf_log_ipv4))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_TARGET_TCPMSS, $(P_XT)xt_TCPMSS))
+$(eval $(call nf_add,IPT_CORE,CONFIG_IP_NF_TARGET_REJECT, $(P_V4)ipt_REJECT))
+$(eval $(call nf_add,IPT_CORE,CONFIG_IP_NF_TARGET_REJECT, $(P_V4)nf_reject_ipv4))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MATCH_TIME, $(P_XT)xt_time))
+$(eval $(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MARK, $(P_XT)xt_mark))
+
+# kernel has xt_MARK.ko merged into xt_mark.ko, userspace is still separate
+# userland: xt_MARK.so
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_CORE,CONFIG_NETFILTER_XT_MARK, $(P_XT)xt_MARK)))
+
+
+# conntrack
+
+# kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK,CONFIG_NF_CONNTRACK, $(P_XT)nf_conntrack),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK,CONFIG_NF_CONNTRACK_RTCACHE, $(P_XT)nf_conntrack_rtcache),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK,CONFIG_NF_DEFRAG_IPV4, $(P_V4)nf_defrag_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK,CONFIG_NF_CONNTRACK_IPV4, $(P_V4)nf_conntrack_ipv4),))
+
+$(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_MATCH_STATE, $(P_XT)xt_state))
+$(eval $(call nf_add,IPT_CONNTRACK,CONFIG_IP_NF_RAW, $(P_V4)iptable_raw))
+$(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_TARGET_CT, $(P_XT)xt_CT))
+$(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_MATCH_CONNTRACK, $(P_XT)xt_conntrack))
+
+
+# conntrack-extra
+
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_CONNBYTES, $(P_XT)xt_connbytes))
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_CONNLIMIT, $(P_XT)xt_connlimit))
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_CONNMARK, $(P_XT)xt_connmark))
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_HELPER, $(P_XT)xt_helper))
+$(eval $(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_MATCH_RECENT, $(P_XT)xt_recent))
+
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_CONNTRACK_EXTRA,CONFIG_NETFILTER_XT_CONNMARK, $(P_XT)xt_CONNMARK)))
+
+# extra
+
+$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_ADDRTYPE, $(if $(NF_KMOD),$(P_XT)xt_addrtype,$(P_XT)ipt_addrtype)))
+$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_OWNER, $(P_XT)xt_owner))
+$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
+$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_PKTTYPE, $(P_XT)xt_pkttype))
+$(eval $(call nf_add,IPT_EXTRA,CONFIG_NETFILTER_XT_MATCH_QUOTA, $(P_XT)xt_quota))
+
+#$(eval $(call nf_add,IPT_EXTRA,CONFIG_IP_NF_TARGET_ROUTE, $(P_V4)ipt_ROUTE))
+
+
+# filter
+
+$(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_string))
+
+
+# ipopt
+
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_DSCP, $(P_XT)xt_dscp))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_DSCP, $(P_XT)xt_DSCP))
+$(eval $(call nf_add,IPT_HASHLIMIT,CONFIG_NETFILTER_XT_MATCH_HASHLIMIT, $(P_XT)xt_hashlimit))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_LENGTH, $(P_XT)xt_length))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_STATISTIC, $(P_XT)xt_statistic))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_TCPMSS, $(P_XT)xt_tcpmss))
+
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_CLASSIFY, $(P_XT)xt_CLASSIFY))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_IP_NF_MATCH_DSCP, $(P_V4)ipt_dscp))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_IP_NF_TARGET_ECN, $(P_V4)ipt_ECN))
+
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_ECN, $(P_XT)xt_ecn))
+
+# userland only
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_DSCP, xt_tos)))
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_DSCP, xt_TOS)))
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_HL, ipt_ttl)))
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_HL, ipt_TTL)))
+
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_HL, $(P_XT)xt_hl))
+$(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_TARGET_HL, $(P_XT)xt_HL))
+
+# iprange
+$(eval $(call nf_add,IPT_IPRANGE,CONFIG_NETFILTER_XT_MATCH_IPRANGE, $(P_XT)xt_iprange))
+
+#clusterip
+$(eval $(call nf_add,IPT_CLUSTERIP,CONFIG_IP_NF_TARGET_CLUSTERIP, $(P_V4)ipt_CLUSTERIP))
+
+# ipsec
+$(eval $(call nf_add,IPT_IPSEC,CONFIG_IP_NF_MATCH_AH, $(P_V4)ipt_ah))
+$(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_ESP, $(P_XT)xt_esp))
+$(eval $(call nf_add,IPT_IPSEC,CONFIG_NETFILTER_XT_MATCH_POLICY, $(P_XT)xt_policy))
+
+
+# IPv6
+
+# kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_IPT6,CONFIG_IP6_NF_IPTABLES, $(P_V6)ip6_tables),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_CONNTRACK_IPV6, $(P_V6)nf_conntrack_ipv6),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_FILTER, $(P_V6)ip6table_filter),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_MANGLE, $(P_V6)ip6table_mangle),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_QUEUE, $(P_V6)ip6_queue),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_RAW, $(P_V6)ip6table_raw),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_IPV6,CONFIG_NF_LOG_IPV6, $(P_V6)nf_log_ipv6),))
+
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_IPV6,CONFIG_IP6_NF_IPTABLES, ip6t_icmp6)))
+
+
+$(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_LOG, $(P_V6)ip6t_LOG))
+$(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_REJECT, $(P_V6)ip6t_REJECT))
+$(eval $(call nf_add,IPT_IPV6,CONFIG_IP6_NF_TARGET_REJECT, $(P_V6)nf_reject_ipv6))
+
+# ipv6 extra
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_IPV6HEADER, $(P_V6)ip6t_ipv6header))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_AH, $(P_V6)ip6t_ah))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_MH, $(P_V6)ip6t_mh))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_EUI64, $(P_V6)ip6t_eui64))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_OPTS, $(P_V6)ip6t_hbh))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_FRAG, $(P_V6)ip6t_frag))
+$(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_RT, $(P_V6)ip6t_rt))
+
+# nat
+
+# kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT, $(P_XT)nf_nat),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_REDIRECT, $(P_XT)nf_nat_redirect, ge 3.19.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_IPV4, $(P_V4)nf_nat_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT6,CONFIG_NF_NAT_IPV6, $(P_V6)nf_nat_ipv6),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_NETFILTER_XT_NAT, $(P_XT)xt_nat),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT,CONFIG_IP_NF_NAT, $(P_V4)iptable_nat),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_NAT, $(P_V6)ip6table_nat),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_NAT, $(P_V6)nf_nat_masquerade_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_MASQUERADE, $(P_V6)ip6t_MASQUERADE),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, $(P_V6)ip6t_NPT),))
+
+# userland only
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT,CONFIG_NF_NAT, ipt_SNAT ipt_DNAT)))
+$(eval $(if $(NF_KMOD),,$(call nf_add,IPT_NAT6,CONFIG_IP6_NF_TARGET_NPT, ip6t_DNPT ip6t_SNPT)))
+
+$(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_MASQUERADE, $(P_V4)ipt_MASQUERADE))
+$(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_MASQUERADE, $(P_V4)nf_nat_masquerade_ipv4))
+$(eval $(call nf_add,IPT_NAT,CONFIG_IP_NF_TARGET_REDIRECT, $(P_XT)xt_REDIRECT))
+
+
+# nat-extra
+
+$(eval $(call nf_add,IPT_NAT_EXTRA,CONFIG_IP_NF_TARGET_NETMAP, $(P_XT)xt_NETMAP))
+
+
+# nathelper
+
+$(eval $(call nf_add,NF_NATHELPER,CONFIG_NF_CONNTRACK_FTP, $(P_XT)nf_conntrack_ftp))
+$(eval $(call nf_add,NF_NATHELPER,CONFIG_NF_NAT_FTP, $(P_XT)nf_nat_ftp))
+
+
+# nathelper-extra
+
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_BROADCAST, $(P_XT)nf_conntrack_broadcast))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_AMANDA, $(P_XT)nf_conntrack_amanda))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_AMANDA, $(P_XT)nf_nat_amanda))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CT_PROTO_GRE, $(P_XT)nf_conntrack_proto_gre))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_PROTO_GRE, $(P_V4)nf_nat_proto_gre))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_H323, $(P_XT)nf_conntrack_h323))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_H323, $(P_V4)nf_nat_h323))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_PPTP, $(P_XT)nf_conntrack_pptp))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_PPTP, $(P_V4)nf_nat_pptp))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_SIP, $(P_XT)nf_conntrack_sip))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_SIP, $(P_XT)nf_nat_sip))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_SNMP, $(P_XT)nf_conntrack_snmp))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_SNMP_BASIC, $(P_V4)nf_nat_snmp_basic))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_TFTP, $(P_XT)nf_conntrack_tftp))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_TFTP, $(P_XT)nf_nat_tftp))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_CONNTRACK_IRC, $(P_XT)nf_conntrack_irc))
+$(eval $(call nf_add,NF_NATHELPER_EXTRA,CONFIG_NF_NAT_IRC, $(P_XT)nf_nat_irc))
+
+
+# ulog
+
+$(eval $(call nf_add,IPT_ULOG,CONFIG_IP_NF_TARGET_ULOG, $(P_V4)ipt_ULOG))
+
+
+# nflog
+
+$(eval $(call nf_add,IPT_NFLOG,CONFIG_NETFILTER_XT_TARGET_NFLOG, $(P_XT)xt_NFLOG))
+
+
+# nfqueue
+
+$(eval $(call nf_add,IPT_NFQUEUE,CONFIG_NETFILTER_XT_TARGET_NFQUEUE, $(P_XT)xt_NFQUEUE))
+
+
+# debugging
+
+$(eval $(call nf_add,IPT_DEBUG,CONFIG_NETFILTER_XT_TARGET_TRACE, $(P_XT)xt_TRACE))
+
+# tproxy
+
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_MATCH_SOCKET, $(P_XT)xt_socket))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_TARGET_TPROXY, $(P_XT)xt_TPROXY))
+
+# led
+$(eval $(call nf_add,IPT_LED,CONFIG_NETFILTER_XT_TARGET_LED, $(P_XT)xt_LED))
+
+# tee
+
+$(eval $(call nf_add,IPT_TEE,CONFIG_NETFILTER_XT_TARGET_TEE, $(P_XT)xt_TEE))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_TEE,CONFIG_NF_DUP_IPV4, $(P_V4)nf_dup_ipv4, ge 4.3),))
+$(eval $(if $(NF_KMOD),$(call nf_add,IPT_TEE,CONFIG_NF_DUP_IPV6, $(P_V6)nf_dup_ipv6, ge 4.3),))
+
+# u32
+
+$(eval $(call nf_add,IPT_U32,CONFIG_NETFILTER_XT_MATCH_U32, $(P_XT)xt_u32))
+
+# checksum
+
+$(eval $(call nf_add,IPT_CHECKSUM,CONFIG_NETFILTER_XT_TARGET_CHECKSUM, $(P_XT)xt_CHECKSUM))
+
+
+# netlink
+
+$(eval $(call nf_add,NFNETLINK,CONFIG_NETFILTER_NETLINK, $(P_XT)nfnetlink))
+
+# nflog
+
+$(eval $(call nf_add,NFNETLINK_LOG,CONFIG_NETFILTER_NETLINK_LOG, $(P_XT)nfnetlink_log))
+
+# nfqueue
+
+$(eval $(call nf_add,NFNETLINK_QUEUE,CONFIG_NETFILTER_NETLINK_QUEUE, $(P_XT)nfnetlink_queue))
+
+#
+# ebtables
+#
+
+$(eval $(if $(NF_KMOD),$(call nf_add,EBTABLES,CONFIG_BRIDGE_NF_EBTABLES, $(P_EBT)ebtables),))
+
+# ebtables: tables
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_BROUTE, $(P_EBT)ebtable_broute))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_T_FILTER, $(P_EBT)ebtable_filter))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_T_NAT, $(P_EBT)ebtable_nat))
+
+# ebtables: matches
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_802_3, $(P_EBT)ebt_802_3))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_AMONG, $(P_EBT)ebt_among))
+$(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_ARP, $(P_EBT)ebt_arp))
+$(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_IP, $(P_EBT)ebt_ip))
+$(eval $(call nf_add,EBTABLES_IP6,CONFIG_BRIDGE_EBT_IP6, $(P_EBT)ebt_ip6))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_LIMIT, $(P_EBT)ebt_limit))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_MARK, $(P_EBT)ebt_mark_m))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_PKTTYPE, $(P_EBT)ebt_pkttype))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_STP, $(P_EBT)ebt_stp))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_VLAN, $(P_EBT)ebt_vlan))
+
+# targets
+$(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_ARPREPLY, $(P_EBT)ebt_arpreply))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_MARK_T, $(P_EBT)ebt_mark))
+$(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_DNAT, $(P_EBT)ebt_dnat))
+$(eval $(call nf_add,EBTABLES,CONFIG_BRIDGE_EBT_REDIRECT, $(P_EBT)ebt_redirect))
+$(eval $(call nf_add,EBTABLES_IP4,CONFIG_BRIDGE_EBT_SNAT, $(P_EBT)ebt_snat))
+
+# watchers
+$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_LOG, $(P_EBT)ebt_log))
+$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_ULOG, $(P_EBT)ebt_ulog))
+$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFLOG, $(P_EBT)ebt_nflog))
+$(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFQUEUE, $(P_EBT)ebt_nfqueue))
+
+# nftables
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES, $(P_XT)nf_tables),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_INET, $(P_XT)nf_tables_inet),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_EXTHDR, $(P_XT)nft_exthdr),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_META, $(P_XT)nft_meta),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CT, $(P_XT)nft_ct),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_RBTREE, $(P_XT)nft_rbtree),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_HASH, $(P_XT)nft_hash),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_COUNTER, $(P_XT)nft_counter),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_LOG, $(P_XT)nft_log),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_LIMIT, $(P_XT)nft_limit),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REJECT, $(P_XT)nft_reject $(P_V4)nft_reject_ipv4 $(P_V6)nft_reject_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REJECT_INET, $(P_XT)nft_reject_inet),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_REJECT_IPV4, $(P_V4)nf_reject_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_REJECT_IPV6, $(P_V6)nf_reject_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV4, $(P_V4)nf_tables_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CHAIN_ROUTE_IPV4, $(P_V4)nft_chain_route_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV6, $(P_V6)nf_tables_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_CHAIN_ROUTE_IPV6, $(P_V6)nft_chain_route_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_REDIR, $(P_XT)nft_redir, ge 3.19.0),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_NAT, $(P_XT)nft_nat),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NF_NAT_MASQUERADE_IPV4, $(P_V4)nf_nat_masquerade_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NF_NAT_MASQUERADE_IPV6, $(P_V6)nf_nat_masquerade_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_CHAIN_NAT_IPV4, $(P_V4)nft_chain_nat_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_REDIR_IPV4, $(P_V4)nft_redir_ipv4, ge 3.19.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_REDIR_IPV6, $(P_V6)nft_redir_ipv6, ge 3.19.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT6,CONFIG_NFT_CHAIN_NAT_IPV6, $(P_V6)nft_chain_nat_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ, $(P_XT)nft_masq),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ_IPV4, $(P_V4)nft_masq_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_NAT,CONFIG_NFT_MASQ_IPV6, $(P_V6)nft_masq_ipv6),))
+
+# userland only
+IPT_BUILTIN += $(NF_IPT-y) $(NF_IPT-m)
+IPT_BUILTIN += $(IPT_CORE-y) $(IPT_CORE-m)
+IPT_BUILTIN += $(NF_CONNTRACK-y)
+IPT_BUILTIN += $(NF_CONNTRACK6-y)
+IPT_BUILTIN += $(IPT_CONNTRACK-y)
+IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
+IPT_BUILTIN += $(IPT_EXTRA-y)
+IPT_BUILTIN += $(IPT_FILTER-y)
+IPT_BUILTIN += $(IPT_IPOPT-y)
+IPT_BUILTIN += $(IPT_IPRANGE-y)
+IPT_BUILTIN += $(IPT_CLUSTER-y)
+IPT_BUILTIN += $(IPT_CLUSTERIP-y)
+IPT_BUILTIN += $(IPT_IPSEC-y)
+IPT_BUILTIN += $(IPT_IPV6-y) $(IPT_IPV6-m)
+IPT_BUILTIN += $(NF_NAT-y)
+IPT_BUILTIN += $(NF_NAT6-y)
+IPT_BUILTIN += $(IPT_NAT-y)
+IPT_BUILTIN += $(IPT_NAT6-y)
+IPT_BUILTIN += $(IPT_NAT_EXTRA-y)
+IPT_BUILTIN += $(NF_NATHELPER-y)
+IPT_BUILTIN += $(NF_NATHELPER_EXTRA-y)
+IPT_BUILTIN += $(IPT_ULOG-y)
+IPT_BUILTIN += $(IPT_DEBUG-y)
+IPT_BUILTIN += $(IPT_TPROXY-y)
+IPT_BUILTIN += $(NFNETLINK-y)
+IPT_BUILTIN += $(NFNETLINK_LOG-y)
+IPT_BUILTIN += $(NFNETLINK_QUEUE-y)
+IPT_BUILTIN += $(EBTABLES-y)
+IPT_BUILTIN += $(EBTABLES_IP4-y)
+IPT_BUILTIN += $(EBTABLES_IP6-y)
+IPT_BUILTIN += $(EBTABLES_WATCHERS-y)
+
+endif # __inc_netfilter

+ 40 - 0
include/nls.mk

@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2011-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# iconv full
+ifeq ($(CONFIG_BUILD_NLS),y)
+	ICONV_PREFIX:=$(STAGING_DIR)/usr/lib/libiconv-full
+	ICONV_FULL:=1
+
+	INTL_PREFIX:=$(STAGING_DIR)/usr/lib/libintl-full
+	INTL_FULL:=1
+
+# iconv stub
+else
+	ICONV_PREFIX:=$(STAGING_DIR)/usr/lib/libiconv-stub
+	ICONV_FULL:=
+
+	INTL_PREFIX:=$(STAGING_DIR)/usr/lib/libintl-stub
+	INTL_FULL:=
+endif
+
+PKG_CONFIG_DEPENDS += CONFIG_BUILD_NLS
+PKG_BUILD_DEPENDS += !BUILD_NLS:libiconv !BUILD_NLS:libintl
+
+ICONV_DEPENDS:=+BUILD_NLS:libiconv-full
+ICONV_CFLAGS:=-I$(ICONV_PREFIX)/include
+ICONV_CPPFLAGS:=-I$(ICONV_PREFIX)/include
+ICONV_LDFLAGS:=-L$(ICONV_PREFIX)/lib -Wl,-rpath-link=$(ICONV_PREFIX)/lib
+
+INTL_DEPENDS:=+BUILD_NLS:libintl-full
+INTL_CFLAGS:=-I$(INTL_PREFIX)/include
+INTL_CPPFLAGS:=-I$(INTL_PREFIX)/include
+INTL_LDFLAGS:=-L$(INTL_PREFIX)/lib -Wl,-rpath-link=$(INTL_PREFIX)/lib
+
+TARGET_CFLAGS += $(ICONV_CFLAGS) $(INTL_CFLAGS)
+TARGET_CPPFLAGS += $(ICONV_CPPFLAGS) $(INTL_CPPFLAGS)
+TARGET_LDFLAGS += $(ICONV_LDFLAGS) $(INTL_LDFLAGS)

+ 33 - 0
include/package-bin.mk

@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2007-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifeq ($(DUMP),)
+  define BuildTarget/bin
+    ifeq ($(if $(VARIANT),$(BUILD_VARIANT)),$(VARIANT))
+    ifdef Package/$(1)/install
+      ifneq ($(CONFIG_PACKAGE_$(1))$(DEVELOPER),)
+        compile: install-bin-$(1)
+      else
+        compile: $(1)-disabled
+        $(1)-disabled:
+		@echo "WARNING: skipping $(1) -- package not selected" >&2
+      endif
+    endif
+    endif
+
+    install-bin-$(1): $(STAMP_BUILT)
+	  rm -rf $(BIN_DIR)/$(1)
+	  $(INSTALL_DIR) $(BIN_DIR)/$(1)
+	  $(call Package/$(1)/install,$(BIN_DIR)/$(1))
+
+    clean-$(1):
+	  rm -rf $(BIN_DIR)/$(1)
+
+    clean: clean-$(1)
+    .PHONY: install-bin-$(1)
+  endef
+endif

+ 162 - 0
include/package-defaults.mk

@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PKG_DEFAULT_DEPENDS = +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread
+
+ifneq ($(PKG_NAME),toolchain)
+  PKG_FIXUP_DEPENDS = $(if $(filter kmod-%,$(1)),$(2),$(PKG_DEFAULT_DEPENDS) $(filter-out $(PKG_DEFAULT_DEPENDS),$(2)))
+else
+  PKG_FIXUP_DEPENDS = $(2)
+endif
+
+define Package/Default
+  CONFIGFILE:=
+  SECTION:=opt
+  CATEGORY:=Extra packages
+  PACKAGE_SUBDIR:=$(FEED)
+  DEPENDS:=
+  MDEPENDS:=
+  CONFLICTS:=
+  PROVIDES:=
+  EXTRA_DEPENDS:=
+  MAINTAINER:=$(PKG_MAINTAINER)
+  SOURCE:=$(patsubst $(TOPDIR)/%,%,$(CURDIR))
+  ifneq ($(PKG_VERSION),)
+    ifneq ($(PKG_RELEASE),)
+      VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
+    else
+      VERSION:=$(PKG_VERSION)
+    endif
+  else
+    VERSION:=$(PKG_RELEASE)
+  endif
+  ABI_VERSION:=
+  ifneq ($(PKG_FLAGS),)
+    PKGFLAGS:=$(PKG_FLAGS)
+  else
+    PKGFLAGS:=
+  endif
+  ifneq ($(ARCH_PACKAGES),)
+    PKGARCH:=$(ARCH_PACKAGES)
+  else
+    PKGARCH:=$(BOARD)
+  endif
+  DEFAULT:=
+  MENU:=
+  SUBMENU:=
+  SUBMENUDEP:=
+  TITLE:=
+  KCONFIG:=
+  BUILDONLY:=
+  HIDDEN:=
+  URL:=
+  VARIANT:=
+  DEFAULT_VARIANT:=
+  USERID:=
+endef
+
+Build/Patch:=$(Build/Patch/Default)
+ifneq ($(strip $(PKG_UNPACK)),)
+  define Build/Prepare/Default
+	$(PKG_UNPACK)
+	$(Build/Patch)
+  endef
+endif
+
+EXTRA_CXXFLAGS = $(EXTRA_CFLAGS)
+ifeq ($(CONFIG_BUILD_NLS),y)
+    DISABLE_NLS:=
+else
+    DISABLE_NLS:=--disable-nls
+endif
+
+CONFIGURE_PREFIX:=/usr
+CONFIGURE_ARGS = \
+		--target=$(GNU_TARGET_NAME) \
+		--host=$(GNU_TARGET_NAME) \
+		--build=$(GNU_HOST_NAME) \
+		--program-prefix="" \
+		--program-suffix="" \
+		--prefix=$(CONFIGURE_PREFIX) \
+		--exec-prefix=$(CONFIGURE_PREFIX) \
+		--bindir=$(CONFIGURE_PREFIX)/bin \
+		--sbindir=$(CONFIGURE_PREFIX)/sbin \
+		--libexecdir=$(CONFIGURE_PREFIX)/lib \
+		--sysconfdir=/etc \
+		--datadir=$(CONFIGURE_PREFIX)/share \
+		--localstatedir=/var \
+		--mandir=$(CONFIGURE_PREFIX)/man \
+		--infodir=$(CONFIGURE_PREFIX)/info \
+		$(DISABLE_NLS) \
+		$(DISABLE_LARGEFILE) \
+		$(DISABLE_IPV6)
+
+CONFIGURE_VARS = \
+		$(TARGET_CONFIGURE_OPTS) \
+		CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
+		CXXFLAGS="$(TARGET_CXXFLAGS) $(EXTRA_CFLAGS)" \
+		CPPFLAGS="$(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
+		LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \
+
+CONFIGURE_PATH = .
+CONFIGURE_CMD = ./configure
+
+replace_script=$(FIND) $(1) -name $(2) | $(XARGS) chmod u+w; \
+	       $(FIND) $(1) -name $(2) | $(XARGS) -n1 cp --remove-destination \
+	       $(SCRIPT_DIR)/$(2);
+
+define Build/Configure/Default
+	(cd $(PKG_BUILD_DIR)/$(CONFIGURE_PATH)/$(strip $(3)); \
+	if [ -x $(CONFIGURE_CMD) ]; then \
+		$(call replace_script,$(PKG_BUILD_DIR)/$(3),config.guess) \
+		$(call replace_script,$(PKG_BUILD_DIR)/$(3),config.sub) \
+		$(CONFIGURE_VARS) \
+		$(2) \
+		$(CONFIGURE_CMD) \
+		$(CONFIGURE_ARGS) \
+		$(1); \
+	fi; \
+	)
+endef
+
+MAKE_VARS = \
+	CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
+	CXXFLAGS="$(TARGET_CXXFLAGS) $(EXTRA_CXXFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
+	LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)"
+
+MAKE_FLAGS = \
+	$(TARGET_CONFIGURE_OPTS) \
+	CROSS="$(TARGET_CROSS)" \
+	ARCH="$(ARCH)"
+
+MAKE_INSTALL_FLAGS = \
+	$(MAKE_FLAGS) \
+	DESTDIR="$(PKG_INSTALL_DIR)"
+
+MAKE_PATH = .
+
+define Build/Compile/Default
+	+$(MAKE_VARS) \
+	$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) \
+		$(MAKE_FLAGS) \
+		$(1);
+endef
+
+define Build/Install/Default
+	$(MAKE_VARS) \
+	$(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) \
+		$(MAKE_INSTALL_FLAGS) \
+		$(if $(1), $(1), install);
+endef
+
+define Build/Dist/Default
+	$(call Build/Compile/Default, DESTDIR="$(PKG_BUILD_DIR)/tmp" CC="$(TARGET_CC)" dist)
+endef
+
+define Build/DistCheck/Default
+	$(call Build/Compile/Default, DESTDIR="$(PKG_BUILD_DIR)/tmp" CC="$(TARGET_CC)" distcheck)
+endef

+ 91 - 0
include/package-dumpinfo.mk

@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifneq ($(DUMP),)
+
+dumpinfo: FORCE
+
+define Config/template
+Preconfig: $(1)
+Preconfig-Type: $(2)
+Preconfig-Default: $(3)
+Preconfig-Label: $(4)
+
+endef
+
+define Config
+  Preconfig/$(1) = $$(call Config/template,$(1),$(2),$(3),$(4))
+  preconfig_$$(1) += $(1)
+endef
+
+define Dumpinfo/Package
+$(info Package: $(1)
+$(if $(MENU),Menu: $(MENU)
+)$(if $(SUBMENU),Submenu: $(SUBMENU)
+)$(if $(SUBMENUDEP),Submenu-Depends: $(SUBMENUDEP)
+)$(if $(DEFAULT),Default: $(DEFAULT)
+)$(if $(findstring $(PREREQ_CHECK),1),Prereq-Check: 1
+)Version: $(VERSION)
+Depends: $(call PKG_FIXUP_DEPENDS,$(1),$(DEPENDS))
+Conflicts: $(CONFLICTS)
+Menu-Depends: $(MDEPENDS)
+Provides: $(PROVIDES)
+$(if $(VARIANT),Build-Variant: $(VARIANT)
+$(if $(DEFAULT_VARIANT),Default-Variant: $(VARIANT)
+))$(if $(PKG_BUILD_DEPENDS),Build-Depends: $(PKG_BUILD_DEPENDS)
+)$(if $(HOST_BUILD_DEPENDS),Build-Depends/host: $(HOST_BUILD_DEPENDS)
+)$(if $(BUILD_TYPES),Build-Types: $(BUILD_TYPES)
+)Section: $(SECTION)
+Category: $(CATEGORY)
+Title: $(TITLE)
+Maintainer: $(MAINTAINER)
+$(if $(USERID),Require-User: $(USERID)
+)Source: $(PKG_SOURCE)
+$(if $(PKG_LICENSE),License: $(PKG_LICENSE)
+)$(if $(PKG_LICENSE_FILES),LicenseFiles: $(PKG_LICENSE_FILES)
+)Type: $(if $(Package/$(1)/targets),$(Package/$(1)/targets),$(if $(PKG_TARGETS),$(PKG_TARGETS),ipkg))
+$(if $(KCONFIG),Kernel-Config: $(KCONFIG)
+)$(if $(BUILDONLY),Build-Only: $(BUILDONLY)
+)$(if $(HIDDEN),Hidden: $(HIDDEN)
+)$(if $(PACKAGE_SUBDIR),Package-Subdir: $(PACKAGE_SUBDIR)
+)Description: $(if $(Package/$(1)/description),$(Package/$(1)/description),$(TITLE))
+$(if $(URL),$(URL)
+)$(MAINTAINER)
+@@
+$(if $(Package/$(1)/config),Config:
+$(Package/$(1)/config)
+@@
+)$(foreach pc,$(preconfig_$(1)),
+$(Preconfig/$(pc))))
+endef
+
+define Feature/Default
+  TARGET_NAME:=
+  TARGET_TITLE:=
+  PRIORITY:=
+  NAME:=
+endef
+
+define Feature
+  $(eval $(Feature/Default))
+  $(eval $(Feature/$(1)))
+  $(if $(DUMP),$(call Dumpinfo/Feature,$(1)))
+endef
+
+define Dumpinfo/Feature
+$(info Feature: $(TARGET_NAME)_$(1)
+Target-Name: $(TARGET_NAME)
+Target-Title: $(TARGET_TITLE)
+Feature-Name: $(NAME)
+$(if $(PRIORITY),Feature-Priority: $(PRIORITY)
+)Feature-Description:
+$(Feature/$(1)/description)
+@@
+)
+endef
+
+endif

+ 236 - 0
include/package-ipkg.mk

@@ -0,0 +1,236 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(INCLUDE_DIR)/feeds.mk
+
+# invoke ipkg-build with some default options
+IPKG_BUILD:= \
+  $(SCRIPT_DIR)/ipkg-build -c -o 0 -g 0
+
+IPKG_STATE_DIR:=$(TARGET_DIR)/usr/lib/opkg
+
+# 1: package name
+# 2: variable name
+# 3: variable suffix
+# 4: file is a script
+define BuildIPKGVariable
+ifdef Package/$(1)/$(2)
+  $$(IPKG_$(1)) : VAR_$(2)$(3)=$$(Package/$(1)/$(2))
+  $(call shexport,Package/$(1)/$(2))
+  $(1)_COMMANDS += echo "$$$$$$$$$(call shvar,Package/$(1)/$(2))" > $(2)$(3); $(if $(4),chmod 0755 $(2)$(3);)
+endif
+endef
+
+PARENL :=(
+PARENR :=)
+
+dep_split=$(subst :,$(space),$(1))
+dep_rem=$(subst !,,$(subst $(strip $(PARENL)),,$(subst $(strip $(PARENR)),,$(word 1,$(call dep_split,$(1))))))
+dep_confvar=$(strip $(foreach cond,$(subst ||, ,$(call dep_rem,$(1))),$(CONFIG_$(cond))))
+dep_pos=$(if $(call dep_confvar,$(1)),$(call dep_val,$(1)))
+dep_neg=$(if $(call dep_confvar,$(1)),,$(call dep_val,$(1)))
+dep_if=$(if $(findstring !,$(1)),$(call dep_neg,$(1)),$(call dep_pos,$(1)))
+dep_val=$(word 2,$(call dep_split,$(1)))
+strip_deps=$(strip $(subst +,,$(filter-out @%,$(1))))
+filter_deps=$(foreach dep,$(call strip_deps,$(1)),$(if $(findstring :,$(dep)),$(call dep_if,$(dep)),$(dep)))
+
+define AddDependency
+  $$(if $(1),$$(if $(2),$$(foreach pkg,$(1),$$(IPKG_$$(pkg))): $$(foreach pkg,$(2),$$(IPKG_$$(pkg)))))
+endef
+
+define FixupReverseDependencies
+  DEPS := $$(filter %:$(1),$$(IDEPEND))
+  DEPS := $$(patsubst %:$(1),%,$$(DEPS))
+  DEPS := $$(filter $$(DEPS),$$(IPKGS))
+  $(call AddDependency,$$(DEPS),$(1))
+endef
+
+define FixupDependencies
+  DEPS := $$(filter $(1):%,$$(IDEPEND))
+  DEPS := $$(patsubst $(1):%,%,$$(DEPS))
+  DEPS := $$(filter $$(DEPS),$$(IPKGS))
+  $(call AddDependency,$(1),$$(DEPS))
+endef
+
+ifneq ($(PKG_NAME),toolchain)
+  define CheckDependencies
+	@( \
+		rm -f $(PKG_INFO_DIR)/$(1).missing; \
+		( \
+			export \
+				READELF=$(TARGET_CROSS)readelf \
+				OBJCOPY=$(TARGET_CROSS)objcopy \
+				XARGS="$(XARGS)"; \
+			$(SCRIPT_DIR)/gen-dependencies.sh "$$(IDIR_$(1))"; \
+		) | while read FILE; do \
+			grep -qxF "$$$$FILE" $(PKG_INFO_DIR)/$(1).provides || \
+				echo "$$$$FILE" >> $(PKG_INFO_DIR)/$(1).missing; \
+		done; \
+		if [ -f "$(PKG_INFO_DIR)/$(1).missing" ]; then \
+			echo "Package $(1) is missing dependencies for the following libraries:" >&2; \
+			cat "$(PKG_INFO_DIR)/$(1).missing" >&2; \
+			false; \
+		fi; \
+	)
+  endef
+endif
+
+_addsep=$(word 1,$(1))$(foreach w,$(wordlist 2,$(words $(1)),$(1)),$(strip $(2) $(w)))
+_cleansep=$(subst $(space)$(2)$(space),$(2)$(space),$(1))
+mergelist=$(call _cleansep,$(call _addsep,$(1),$(comma)),$(comma))
+addfield=$(if $(strip $(2)),$(1): $(2))
+_define=define
+_endef=endef
+
+ifeq ($(DUMP),)
+  define BuildTarget/ipkg
+    PDIR_$(1):=$(call FeedPackageDir,$(1))
+    IPKG_$(1):=$$(PDIR_$(1))/$(1)_$(VERSION)_$(PKGARCH).ipk
+    IDIR_$(1):=$(PKG_BUILD_DIR)/ipkg-$(PKGARCH)/$(1)
+    KEEP_$(1):=$(strip $(call Package/$(1)/conffiles))
+
+    ifeq ($(BUILD_VARIANT),$$(if $$(VARIANT),$$(VARIANT),$(BUILD_VARIANT)))
+    ifdef Package/$(1)/install
+      ifneq ($(CONFIG_PACKAGE_$(1))$(DEVELOPER),)
+        IPKGS += $(1)
+        compile: $$(IPKG_$(1)) $(PKG_INFO_DIR)/$(1).provides $(STAGING_DIR_ROOT)/stamp/.$(1)_installed
+        ifneq ($(ABI_VERSION),)
+        compile: $(PKG_INFO_DIR)/$(1).version
+        endif
+
+        ifeq ($(CONFIG_PACKAGE_$(1)),y)
+          .PHONY: $(PKG_INSTALL_STAMP).$(1)
+          compile: $(PKG_INSTALL_STAMP).$(1)
+          $(PKG_INSTALL_STAMP).$(1):
+			if [ -f $(PKG_INSTALL_STAMP).clean ]; then \
+				rm -f \
+					$(PKG_INSTALL_STAMP) \
+					$(PKG_INSTALL_STAMP).clean; \
+			fi; \
+			echo "$(1)" >> $(PKG_INSTALL_STAMP)
+        endif
+      else
+        $(if $(CONFIG_PACKAGE_$(1)),$$(info WARNING: skipping $(1) -- package not selected))
+      endif
+    endif
+    endif
+
+    DEPENDS:=$(call PKG_FIXUP_DEPENDS,$(1),$(DEPENDS))
+    IDEPEND_$(1):=$$(call filter_deps,$$(DEPENDS))
+    IDEPEND += $$(patsubst %,$(1):%,$$(IDEPEND_$(1)))
+    $(FixupDependencies)
+    $(FixupReverseDependencies)
+
+    $(eval $(call BuildIPKGVariable,$(1),conffiles))
+    $(eval $(call BuildIPKGVariable,$(1),preinst,,1))
+    $(eval $(call BuildIPKGVariable,$(1),postinst,-pkg,1))
+    $(eval $(call BuildIPKGVariable,$(1),prerm,-pkg,1))
+    $(eval $(call BuildIPKGVariable,$(1),postrm,,1))
+
+    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed : export PATH=$$(TARGET_PATH_PKG)
+    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed: $(STAMP_BUILT)
+	rm -rf $(STAGING_DIR_ROOT)/tmp-$(1)
+	mkdir -p $(STAGING_DIR_ROOT)/stamp $(STAGING_DIR_ROOT)/tmp-$(1)
+	$(call Package/$(1)/install,$(STAGING_DIR_ROOT)/tmp-$(1))
+	$(call Package/$(1)/install_lib,$(STAGING_DIR_ROOT)/tmp-$(1))
+	$(call locked,$(CP) $(STAGING_DIR_ROOT)/tmp-$(1)/. $(STAGING_DIR_ROOT)/,root-copy)
+	rm -rf $(STAGING_DIR_ROOT)/tmp-$(1)
+	touch $$@
+
+    $(PKG_INFO_DIR)/$(1).version: $$(IPKG_$(1))
+	echo '$(ABI_VERSION)' | cmp -s - $$@ || \
+		echo '$(ABI_VERSION)' > $$@
+
+    Package/$(1)/DEPENDS := $$(call mergelist,$$(filter-out @%,$$(IDEPEND_$(1))))
+    ifneq ($$(EXTRA_DEPENDS),)
+      Package/$(1)/DEPENDS := $$(EXTRA_DEPENDS)$$(if $$(Package/$(1)/DEPENDS),$$(comma) $$(Package/$(1)/DEPENDS))
+    endif
+
+$(_define) Package/$(1)/CONTROL
+Package: $(1)
+Version: $(VERSION)
+$$(call addfield,Depends,$$(Package/$(1)/DEPENDS)
+)$$(call addfield,Conflicts,$$(call mergelist,$(CONFLICTS))
+)$$(call addfield,Provides,$(PROVIDES)
+)$$(call addfield,Source,$(SOURCE)
+)$$(call addfield,License,$$(PKG_LICENSE)
+)$$(call addfield,LicenseFiles,$$(PKG_LICENSE_FILES)
+)$$(call addfield,Section,$(SECTION)
+)$$(call addfield,Require-User,$(USERID)
+)$(if $(filter hold,$(PKG_FLAGS)),Status: unknown hold not-installed
+)$(if $(filter essential,$(PKG_FLAGS)),Essential: yes
+)$(if $(MAINTAINER),Maintainer: $(MAINTAINER)
+)Architecture: $(PKGARCH)
+Installed-Size: 0
+$(_endef)
+
+    $(PKG_INFO_DIR)/$(1).provides: $$(IPKG_$(1))
+    $$(IPKG_$(1)) : export CONTROL=$$(Package/$(1)/CONTROL)
+    $$(IPKG_$(1)) : export DESCRIPTION=$$(Package/$(1)/description)
+    $$(IPKG_$(1)) : export PATH=$$(TARGET_PATH_PKG)
+    $$(IPKG_$(1)): $(STAMP_BUILT) $(INCLUDE_DIR)/package-ipkg.mk
+	@rm -rf $$(PDIR_$(1))/$(1)_* $$(IDIR_$(1))
+	mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/CONTROL $(PKG_INFO_DIR)
+	$(call Package/$(1)/install,$$(IDIR_$(1)))
+	-find $$(IDIR_$(1)) -name 'CVS' -o -name '.svn' -o -name '.#*' -o -name '*~'| $(XARGS) rm -rf
+	@( \
+		find $$(IDIR_$(1)) -name lib\*.so\* -or -name \*.ko | awk -F/ '{ print $$$$NF }'; \
+		for file in $$(patsubst %,$(PKG_INFO_DIR)/%.provides,$$(IDEPEND_$(1))); do \
+			if [ -f "$$$$file" ]; then \
+				cat $$$$file; \
+			fi; \
+		done; $(Package/$(1)/extra_provides) \
+	) | sort -u > $(PKG_INFO_DIR)/$(1).provides
+	$(if $(PROVIDES),@for pkg in $(PROVIDES); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
+	$(CheckDependencies)
+
+	$(RSTRIP) $$(IDIR_$(1))
+	(cd $$(IDIR_$(1))/CONTROL; \
+		( \
+			echo "$$$$CONTROL"; \
+			printf "Description: "; echo "$$$$DESCRIPTION" | sed -e 's,^[[:space:]]*, ,g'; \
+		) > control; \
+		chmod 644 control; \
+		( \
+			echo "#!/bin/sh"; \
+			echo "[ \"\$$$${IPKG_NO_SCRIPT}\" = \"1\" ] && exit 0"; \
+			echo ". \$$$${IPKG_INSTROOT}/lib/functions.sh"; \
+			echo "default_postinst \$$$$0 \$$$$@"; \
+		) > postinst; \
+		( \
+			echo "#!/bin/sh"; \
+			echo ". \$$$${IPKG_INSTROOT}/lib/functions.sh"; \
+			echo "default_prerm \$$$$0 \$$$$@"; \
+		) > prerm; \
+		chmod 0755 postinst prerm; \
+		$($(1)_COMMANDS) \
+	)
+
+    ifneq ($$(KEEP_$(1)),)
+		@( \
+			keepfiles=""; \
+			for x in $$(KEEP_$(1)); do \
+				[ -f "$$(IDIR_$(1))/$$$$x" ] || keepfiles="$$$${keepfiles:+$$$$keepfiles }$$$$x"; \
+			done; \
+			[ -z "$$$$keepfiles" ] || { \
+				mkdir -p $$(IDIR_$(1))/lib/upgrade/keep.d; \
+				for x in $$$$keepfiles; do echo $$$$x >> $$(IDIR_$(1))/lib/upgrade/keep.d/$(1); done; \
+			}; \
+		)
+    endif
+
+	$(INSTALL_DIR) $$(PDIR_$(1))
+	$(IPKG_BUILD) $$(IDIR_$(1)) $$(PDIR_$(1))
+	@[ -f $$(IPKG_$(1)) ]
+
+    $(1)-clean:
+	rm -f $$(PDIR_$(1))/$(1)_*
+
+    clean: $(1)-clean
+
+  endef
+endif

+ 15 - 0
include/package-seccomp.mk

@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+PKG_CONFIG_DEPENDS+= CONFIG_KERNEL_SECCOMP
+
+ifeq ($(CONFIG_KERNEL_SECCOMP),y)
+  define InstallSeccomp
+	$(INSTALL_DIR) $(1)/etc/seccomp
+	$(INSTALL_DATA) $(2) $(1)/etc/seccomp/
+  endef
+endif

+ 309 - 0
include/package.mk

@@ -0,0 +1,309 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+__package_mk:=1
+
+all: $(if $(DUMP),dumpinfo,compile)
+
+include $(INCLUDE_DIR)/download.mk
+
+PKG_BUILD_DIR ?= $(BUILD_DIR)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
+PKG_INSTALL_DIR ?= $(PKG_BUILD_DIR)/ipkg-install
+PKG_BUILD_PARALLEL ?=
+PKG_USE_MIPS16 ?= 1
+PKG_IREMAP ?= 1
+
+ifneq ($(CONFIG_PKG_BUILD_USE_JOBSERVER),)
+  MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) $(if $(filter 3.% 4.0 4.1,$(MAKE_VERSION)),-j))
+else
+  MAKE_J:=-j$(CONFIG_PKG_BUILD_JOBS)
+endif
+
+ifeq ($(strip $(PKG_BUILD_PARALLEL)),0)
+PKG_JOBS?=-j1
+else
+PKG_JOBS?=$(if $(PKG_BUILD_PARALLEL)$(CONFIG_PKG_DEFAULT_PARALLEL),\
+	$(if $(CONFIG_PKG_BUILD_PARALLEL),$(MAKE_J),-j1),-j1)
+endif
+ifdef CONFIG_USE_MIPS16
+  ifeq ($(strip $(PKG_USE_MIPS16)),1)
+    TARGET_ASFLAGS_DEFAULT = $(filter-out -mips16 -minterlink-mips16,$(TARGET_CFLAGS))
+    TARGET_CFLAGS += -mips16 -minterlink-mips16
+  endif
+endif
+ifeq ($(strip $(PKG_IREMAP)),1)
+  IREMAP_CFLAGS = $(call iremap,$(PKG_BUILD_DIR),$(notdir $(PKG_BUILD_DIR)))
+  TARGET_CFLAGS += $(IREMAP_CFLAGS)
+endif
+
+include $(INCLUDE_DIR)/hardening.mk
+include $(INCLUDE_DIR)/prereq.mk
+include $(INCLUDE_DIR)/host.mk
+include $(INCLUDE_DIR)/unpack.mk
+include $(INCLUDE_DIR)/depends.mk
+
+find_library_dependencies = $(wildcard $(patsubst %,$(STAGING_DIR)/pkginfo/%.version, \
+	$(filter-out $(BUILD_PACKAGES),$(foreach dep, \
+		$(filter-out @%, $(patsubst +%,%,$(1))), \
+		$(if $(findstring :,$(dep)), \
+			$(word 2,$(subst :,$(space),$(dep))), \
+			$(dep) \
+		) \
+	))))
+
+PKG_DIR_NAME:=$(lastword $(subst /,$(space),$(CURDIR)))
+STAMP_NO_AUTOREBUILD=$(wildcard $(PKG_BUILD_DIR)/.no_autorebuild)
+PREV_STAMP_PREPARED:=$(if $(STAMP_NO_AUTOREBUILD),$(wildcard $(PKG_BUILD_DIR)/.prepared*))
+ifneq ($(PREV_STAMP_PREPARED),)
+  STAMP_PREPARED:=$(PREV_STAMP_PREPARED)
+  CONFIG_AUTOREBUILD:=
+else
+  STAMP_PREPARED=$(PKG_BUILD_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))$(call confvar,$(PKG_PREPARED_DEPENDS)))
+endif
+STAMP_CONFIGURED=$(PKG_BUILD_DIR)/.configured$(if $(DUMP),,_$(call confvar,$(PKG_CONFIG_DEPENDS)))
+STAMP_CONFIGURED_WILDCARD=$(patsubst %_$(call confvar,$(PKG_CONFIG_DEPENDS)),%_*,$(STAMP_CONFIGURED))
+STAMP_BUILT:=$(PKG_BUILD_DIR)/.built
+STAMP_INSTALLED:=$(STAGING_DIR)/stamp/.$(PKG_DIR_NAME)$(if $(BUILD_VARIANT),.$(BUILD_VARIANT),)_installed
+
+STAGING_FILES_LIST:=$(PKG_DIR_NAME)$(if $(BUILD_VARIANT),.$(BUILD_VARIANT),).list
+
+define CleanStaging
+	rm -f $(STAMP_INSTALLED)
+	@-(\
+		cd "$(STAGING_DIR)"; \
+		if [ -f packages/$(STAGING_FILES_LIST) ]; then \
+			cat packages/$(STAGING_FILES_LIST) | xargs -r rm -f 2>/dev/null; \
+		fi; \
+	)
+endef
+
+ifneq ($(if $(CONFIG_SRC_TREE_OVERRIDE),$(wildcard ./git-src)),)
+  USE_GIT_TREE:=1
+  QUILT:=1
+endif
+ifdef USE_SOURCE_DIR
+  QUILT:=1
+endif
+ifneq ($(wildcard $(PKG_BUILD_DIR)/.source_dir),)
+  QUILT:=1
+endif
+
+PKG_INSTALL_STAMP:=$(PKG_INFO_DIR)/$(PKG_DIR_NAME).$(if $(BUILD_VARIANT),$(BUILD_VARIANT),default).install
+
+include $(INCLUDE_DIR)/quilt.mk
+include $(INCLUDE_DIR)/package-defaults.mk
+include $(INCLUDE_DIR)/package-dumpinfo.mk
+include $(INCLUDE_DIR)/package-ipkg.mk
+include $(INCLUDE_DIR)/package-bin.mk
+include $(INCLUDE_DIR)/autotools.mk
+
+override MAKEFLAGS=
+CONFIG_SITE:=$(INCLUDE_DIR)/site/$(ARCH)
+CUR_MAKEFILE:=$(filter-out Makefile,$(firstword $(MAKEFILE_LIST)))
+SUBMAKE:=$(NO_TRACE_MAKE) $(if $(CUR_MAKEFILE),-f $(CUR_MAKEFILE))
+PKG_CONFIG_PATH=$(STAGING_DIR)/usr/lib/pkgconfig:$(STAGING_DIR)/usr/share/pkgconfig
+unexport QUIET CONFIG_SITE
+
+ifeq ($(DUMP)$(filter prereq clean refresh update,$(MAKECMDGOALS)),)
+  ifneq ($(if $(QUILT),,$(CONFIG_AUTOREBUILD)),)
+    define Build/Autoclean
+      $(PKG_BUILD_DIR)/.dep_files: $(STAMP_PREPARED)
+      $(call rdep,${CURDIR} $(PKG_FILE_DEPENDS),$(STAMP_PREPARED),$(PKG_BUILD_DIR)/.dep_files,-x "*/.dep_*")
+      $(if $(filter prepare,$(MAKECMDGOALS)),,$(call rdep,$(PKG_BUILD_DIR),$(STAMP_BUILT),,-x "*/.dep_*" -x "*/ipkg*"))
+    endef
+  endif
+endif
+
+ifdef USE_GIT_TREE
+  define Build/Prepare/Default
+	mkdir -p $(PKG_BUILD_DIR)
+	ln -s $(CURDIR)/git-src $(PKG_BUILD_DIR)/.git
+	( cd $(PKG_BUILD_DIR); git checkout .)
+  endef
+endif
+ifdef USE_SOURCE_DIR
+  define Build/Prepare/Default
+	rm -rf $(PKG_BUILD_DIR)
+	$(if $(wildcard $(USE_SOURCE_DIR)/*),,@echo "Error: USE_SOURCE_DIR=$(USE_SOURCE_DIR) path not found"; false)
+	ln -snf $(USE_SOURCE_DIR) $(PKG_BUILD_DIR)
+	touch $(PKG_BUILD_DIR)/.source_dir
+  endef
+endif
+
+define Build/Exports/Default
+  $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*),-I $$(p))
+  $(1) : export STAGING_PREFIX=$$(STAGING_DIR)/usr
+  $(1) : export PATH=$$(TARGET_PATH_PKG)
+  $(1) : export CONFIG_SITE:=$$(CONFIG_SITE)
+  $(1) : export PKG_CONFIG_PATH:=$$(PKG_CONFIG_PATH)
+  $(1) : export PKG_CONFIG_LIBDIR:=$$(PKG_CONFIG_PATH)
+  $(1) : export CCACHE_DIR:=$(STAGING_DIR)/ccache
+endef
+Build/Exports=$(Build/Exports/Default)
+
+define Build/DefaultTargets
+  $(if $(QUILT),$(Build/Quilt))
+  $(if $(USE_SOURCE_DIR)$(USE_GIT_TREE),,$(if $(strip $(PKG_SOURCE_URL)),$(call Download,default)))
+  $(call Build/Autoclean)
+
+  download:
+	$(foreach hook,$(Hooks/Download),
+		$(call $(hook))$(sep)
+	)
+
+  $(STAMP_PREPARED) : export PATH=$$(TARGET_PATH_PKG)
+  $(STAMP_PREPARED):
+	@-rm -rf $(PKG_BUILD_DIR)
+	@mkdir -p $(PKG_BUILD_DIR)
+	$(foreach hook,$(Hooks/Prepare/Pre),$(call $(hook))$(sep))
+	$(Build/Prepare)
+	$(foreach hook,$(Hooks/Prepare/Post),$(call $(hook))$(sep))
+	touch $$@
+
+  $(call Build/Exports,$(STAMP_CONFIGURED))
+  $(STAMP_CONFIGURED): $(STAMP_PREPARED)
+	$(CleanStaging)
+	$(foreach hook,$(Hooks/Configure/Pre),$(call $(hook))$(sep))
+	$(Build/Configure)
+	$(foreach hook,$(Hooks/Configure/Post),$(call $(hook))$(sep))
+	rm -f $(STAMP_CONFIGURED_WILDCARD)
+	touch $$@
+
+  $(call Build/Exports,$(STAMP_BUILT))
+  $(STAMP_BUILT): $(STAMP_CONFIGURED)
+	$(foreach hook,$(Hooks/Compile/Pre),$(call $(hook))$(sep))
+	$(Build/Compile)
+	$(foreach hook,$(Hooks/Compile/Post),$(call $(hook))$(sep))
+	$(Build/Install)
+	$(foreach hook,$(Hooks/Install/Post),$(call $(hook))$(sep))
+	touch $$@
+
+  $(STAMP_INSTALLED) : export PATH=$$(TARGET_PATH_PKG)
+  $(STAMP_INSTALLED): $(STAMP_BUILT)
+	rm -rf $(TMP_DIR)/stage-$(PKG_DIR_NAME)
+	mkdir -p $(TMP_DIR)/stage-$(PKG_DIR_NAME)/host $(STAGING_DIR)/packages $(STAGING_DIR_HOST)/packages
+	$(foreach hook,$(Hooks/InstallDev/Pre),\
+		$(call $(hook),$(TMP_DIR)/stage-$(PKG_DIR_NAME),$(TMP_DIR)/stage-$(PKG_DIR_NAME)/host)$(sep)\
+	)
+	$(call Build/InstallDev,$(TMP_DIR)/stage-$(PKG_DIR_NAME),$(TMP_DIR)/stage-$(PKG_DIR_NAME)/host)
+	$(foreach hook,$(Hooks/InstallDev/Post),\
+		$(call $(hook),$(TMP_DIR)/stage-$(PKG_DIR_NAME),$(TMP_DIR)/stage-$(PKG_DIR_NAME)/host)$(sep)\
+	)
+	if [ -f $(STAGING_DIR)/packages/$(STAGING_FILES_LIST) ]; then \
+		$(SCRIPT_DIR)/clean-package.sh \
+			"$(STAGING_DIR)/packages/$(STAGING_FILES_LIST)" \
+			"$(STAGING_DIR)"; \
+	fi
+	if [ -d $(TMP_DIR)/stage-$(PKG_DIR_NAME) ]; then \
+		(cd $(TMP_DIR)/stage-$(PKG_DIR_NAME); find ./ > $(TMP_DIR)/stage-$(PKG_DIR_NAME).files); \
+		$(call locked, \
+			mv $(TMP_DIR)/stage-$(PKG_DIR_NAME).files $(STAGING_DIR)/packages/$(STAGING_FILES_LIST) && \
+			$(CP) $(TMP_DIR)/stage-$(PKG_DIR_NAME)/* $(STAGING_DIR)/; \
+		,staging-dir); \
+	fi
+	rm -rf $(TMP_DIR)/stage-$(PKG_DIR_NAME)
+	touch $$@
+
+  ifdef Build/InstallDev
+    compile: $(STAMP_INSTALLED)
+  endif
+
+  define Build/DefaultTargets
+  endef
+
+  prepare: $(STAMP_PREPARED)
+  configure: $(STAMP_CONFIGURED)
+  dist: $(STAMP_CONFIGURED)
+  distcheck: $(STAMP_CONFIGURED)
+endef
+
+define Build/IncludeOverlay
+  $(eval -include $(wildcard $(TOPDIR)/overlay/*/$(PKG_DIR_NAME).mk))
+  define Build/IncludeOverlay
+  endef
+endef
+
+define BuildPackage
+  $(Build/IncludeOverlay)
+  $(eval $(Package/Default))
+  $(eval $(Package/$(1)))
+
+ifdef DESCRIPTION
+$$(error DESCRIPTION:= is obsolete, use Package/PKG_NAME/description)
+endif
+
+ifndef Package/$(1)/description
+define Package/$(1)/description
+	$(TITLE)
+endef
+endif
+
+  BUILD_PACKAGES += $(1)
+  $(STAMP_PREPARED): $$(if $(QUILT)$(DUMP),,$(call find_library_dependencies,$(DEPENDS)))
+
+  $(foreach FIELD, TITLE CATEGORY SECTION VERSION,
+    ifeq ($($(FIELD)),)
+      $$(error Package/$(1) is missing the $(FIELD) field)
+    endif
+  )
+
+  $(if $(DUMP), \
+    $(Dumpinfo/Package), \
+    $(foreach target, \
+      $(if $(Package/$(1)/targets),$(Package/$(1)/targets), \
+        $(if $(PKG_TARGETS),$(PKG_TARGETS), ipkg) \
+      ), $(BuildTarget/$(target)) \
+    ) \
+  )
+  $(if $(PKG_HOST_ONLY)$(DUMP),,$(call Build/DefaultTargets,$(1)))
+endef
+
+define pkg_install_files
+	$(foreach install_file,$(1),$(INSTALL_DIR) $(3)/`dirname $(install_file)`; $(INSTALL_DATA) $(2)/$(install_file) $(3)/`dirname $(install_file)`;)
+endef
+
+define pkg_install_bin
+	$(foreach install_apps,$(1),$(INSTALL_DIR) $(3)/`dirname $(install_apps)`; $(INSTALL_BIN) $(2)/$(install_apps) $(3)/`dirname $(install_apps)`;)
+endef
+
+Build/Prepare=$(call Build/Prepare/Default,)
+Build/Configure=$(call Build/Configure/Default,)
+Build/Compile=$(call Build/Compile/Default,)
+Build/Install=$(if $(PKG_INSTALL),$(call Build/Install/Default,))
+Build/Dist=$(call Build/Dist/Default,)
+Build/DistCheck=$(call Build/DistCheck/Default,)
+
+.NOTPARALLEL:
+
+.PHONY: prepare-package-install
+prepare-package-install:
+	@mkdir -p $(PKG_INFO_DIR)
+	@touch $(PKG_INSTALL_STAMP).clean
+	@echo "$(filter-out essential,$(PKG_FLAGS))" > $(PKG_INSTALL_STAMP).flags
+
+$(PACKAGE_DIR):
+	mkdir -p $@
+	
+dumpinfo:
+download:
+prepare:
+configure:
+compile: prepare-package-install
+install: compile
+
+clean: FORCE
+	$(CleanStaging)
+	$(call Build/UninstallDev,$(STAGING_DIR),$(STAGING_DIR_HOST))
+	$(Build/Clean)
+	rm -f $(STAGING_DIR)/packages/$(STAGING_FILES_LIST) $(STAGING_DIR_HOST)/packages/$(STAGING_FILES_LIST)
+	rm -rf $(PKG_BUILD_DIR)
+
+dist:
+	$(Build/Dist)
+
+distcheck:
+	$(Build/DistCheck)

+ 170 - 0
include/prereq-build.mk

@@ -0,0 +1,170 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/prereq.mk
+include $(INCLUDE_DIR)/host.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+SHELL:=sh
+PKG_NAME:=Build dependency
+
+
+# Required for the toolchain
+$(eval $(call TestHostCommand,working-make, \
+	Please install GNU make v3.81 or later. (This version has bugs), \
+	$(MAKE) -v | grep -E 'Make (3\.8[1-9]|3\.9[0-9]|[4-9]\.)'))
+
+$(eval $(call TestHostCommand,case-sensitive-fs, \
+	OpenWrt can only be built on a case-sensitive filesystem, \
+	rm -f $(TMP_DIR)/test.*; touch $(TMP_DIR)/test.fs; \
+		test ! -f $(TMP_DIR)/test.FS))
+
+$(eval $(call SetupHostCommand,gcc, \
+	Please install the GNU C Compiler (gcc), \
+	$(CC) --version | grep gcc, \
+	gcc --version | grep gcc, \
+	gcc49 --version | grep gcc, \
+	gcc48 --version | grep gcc, \
+	gcc47 --version | grep gcc, \
+	gcc46 --version | grep gcc, \
+	gcc --version | grep Apple.LLVM ))
+
+$(eval $(call TestHostCommand,working-gcc, \
+	Please reinstall the GNU C Compiler - it appears to be broken, \
+	echo 'int main(int argc, char **argv) { return 0; }' | \
+		gcc -x c -o $(TMP_DIR)/a.out -))
+
+$(eval $(call SetupHostCommand,g++, \
+	Please install the GNU C++ Compiler (g++), \
+	$(CXX) --version | grep g++, \
+	g++ --version | grep g++, \
+	g++49 --version | grep g++, \
+	g++48 --version | grep g++, \
+	g++47 --version | grep g++, \
+	g++46 --version | grep g++, \
+	g++ --version | grep Apple.LLVM ))
+
+$(eval $(call TestHostCommand,working-g++, \
+	Please reinstall the GNU C++ Compiler - it appears to be broken, \
+	echo 'int main(int argc, char **argv) { return 0; }' | \
+		g++ -x c++ -o $(TMP_DIR)/a.out - -lstdc++ && \
+		$(TMP_DIR)/a.out))
+
+$(eval $(call TestHostCommand,ncurses, \
+	Please install ncurses. (Missing libncurses.so or ncurses.h), \
+	echo 'int main(int argc, char **argv) { initscr(); return 0; }' | \
+		gcc -include ncurses.h -x c -o $(TMP_DIR)/a.out - -lncurses))
+
+ifeq ($(HOST_OS),Linux)
+  zlib_link_flags := -Wl,-Bstatic -lz -Wl,-Bdynamic
+else
+  zlib_link_flags := -lz
+endif
+
+$(eval $(call TestHostCommand,zlib, \
+	Please install a static zlib. (Missing libz.a or zlib.h), \
+	echo 'int main(int argc, char **argv) { gzdopen(0, "rb"); return 0; }' | \
+		gcc -include zlib.h -x c -o $(TMP_DIR)/a.out - $(zlib_link_flags)))
+
+$(eval $(call TestHostCommand,libssl, \
+	Please install the openssl library (with development headers), \
+	echo 'int main(int argc, char **argv) { SSL_library_init(); return 0; }' | \
+		gcc $(HOST_CFLAGS) -include openssl/ssl.h -x c -o $(TMP_DIR)/a.out - -lcrypto -lssl $(HOST_LDFLAGS)))
+
+$(eval $(call TestHostCommand,perl-thread-queue, \
+	Please install the Perl Thread::Queue module, \
+	perl -MThread::Queue -e 1))
+
+
+$(eval $(call SetupHostCommand,tar,Please install GNU 'tar', \
+	gtar --version 2>&1 | grep GNU, \
+	gnutar --version 2>&1 | grep GNU, \
+	tar --version 2>&1 | grep GNU))
+
+$(eval $(call SetupHostCommand,find,Please install GNU 'find', \
+	gfind --version 2>&1 | grep GNU, \
+	find --version 2>&1 | grep GNU))
+
+$(eval $(call SetupHostCommand,bash,Please install GNU 'bash', \
+	bash --version 2>&1 | grep GNU))
+
+$(eval $(call SetupHostCommand,patch,Please install GNU 'patch', \
+	gpatch --version 2>&1 | grep 'Free Software Foundation', \
+	patch --version 2>&1 | grep 'Free Software Foundation'))
+
+$(eval $(call SetupHostCommand,diff,Please install diffutils, \
+	gdiff --version 2>&1 | grep diff, \
+	diff --version 2>&1 | grep diff))
+
+$(eval $(call SetupHostCommand,cp,Please install GNU fileutils, \
+	gcp --help, \
+	cp --help))
+
+$(eval $(call SetupHostCommand,seq,, \
+	gseq --version, \
+	seq --version))
+
+$(eval $(call SetupHostCommand,awk,Please install GNU 'awk', \
+	gawk --version 2>&1 | grep GNU, \
+	awk --version 2>&1 | grep GNU))
+
+$(eval $(call SetupHostCommand,grep,Please install GNU 'grep', \
+	ggrep --version 2>&1 | grep GNU, \
+	grep --version 2>&1 | grep GNU))
+
+$(eval $(call SetupHostCommand,getopt, \
+	Please install an extended getopt version that supports --long, \
+	gnugetopt -o t --long test -- --test | grep '^ *--test *--', \
+	/usr/local/bin/getopt -o t --long test -- --test | grep '^ *--test *--', \
+	getopt -o t --long test -- --test | grep '^ *--test *--'))
+
+$(eval $(call SetupHostCommand,stat,Cannot find a file stat utility, \
+	gnustat -c%s $(TMP_DIR)/.host.mk, \
+	gstat -c%s $(TMP_DIR)/.host.mk, \
+	stat -c%s $(TMP_DIR)/.host.mk))
+
+$(eval $(call SetupHostCommand,md5sum,, \
+	gmd5sum /dev/null | grep d41d8cd98f00b204e9800998ecf8427e, \
+	md5sum /dev/null | grep d41d8cd98f00b204e9800998ecf8427e, \
+	$(SCRIPT_DIR)/md5sum /dev/null | grep d41d8cd98f00b204e9800998ecf8427e))
+
+$(eval $(call SetupHostCommand,unzip,Please install 'unzip', \
+	unzip 2>&1 | grep zipfile, \
+	unzip))
+
+$(eval $(call SetupHostCommand,bzip2,Please install 'bzip2', \
+	bzip2 --version </dev/null))
+
+$(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \
+	wget --version | grep GNU))
+
+$(eval $(call SetupHostCommand,perl,Please install Perl 5.x, \
+	perl --version | grep "perl.*v5"))
+
+$(eval $(call SetupHostCommand,python,Please install Python 2.x, \
+	python2.7 -V 2>&1 | grep Python, \
+	python2 -V 2>&1 | grep Python, \
+	python -V 2>&1 | grep Python))
+
+$(eval $(call SetupHostCommand,svn,Please install the Subversion client, \
+	svn --version | grep Subversion))
+
+$(eval $(call SetupHostCommand,git,Please install Git (git-core) >= 1.7.12.2, \
+	git --exec-path | xargs -I % -- grep -q -- --recursive %/git-submodule))
+
+$(eval $(call SetupHostCommand,file,Please install the 'file' package, \
+	file --version 2>&1 | grep file))
+
+$(eval $(call SetupHostCommand,openssl,Please install the 'openssl' utility, \
+	openssl version | grep '\(OpenSSL\|LibreSSL\)'))
+
+
+# Install ldconfig stub
+$(eval $(call TestHostCommand,ldconfig-stub,Failed to install stub, \
+	touch $(STAGING_DIR_HOST)/bin/ldconfig && \
+	chmod +x $(STAGING_DIR_HOST)/bin/ldconfig))

+ 108 - 0
include/prereq.mk

@@ -0,0 +1,108 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifneq ($(__prereq_inc),1)
+__prereq_inc:=1
+
+prereq:
+	if [ -f $(TMP_DIR)/.prereq-error ]; then \
+		echo; \
+		cat $(TMP_DIR)/.prereq-error; \
+		rm -f $(TMP_DIR)/.prereq-error; \
+		echo; \
+		false; \
+	fi
+
+.SILENT: prereq
+endif
+
+PREREQ_PREV=
+
+# 1: display name
+# 2: error message
+define Require
+  export PREREQ_CHECK=1
+  ifeq ($$(CHECK_$(1)),)
+    prereq: prereq-$(1)
+
+    prereq-$(1): $(if $(PREREQ_PREV),prereq-$(PREREQ_PREV)) FORCE
+		printf "Checking '$(1)'... "
+		if $(NO_TRACE_MAKE) -f $(firstword $(MAKEFILE_LIST)) check-$(1) >/dev/null 2>/dev/null; then \
+			echo 'ok.'; \
+		else \
+			echo 'failed.'; \
+			echo "$(PKG_NAME): $(strip $(2))" >> $(TMP_DIR)/.prereq-error; \
+		fi
+
+    check-$(1): FORCE
+	  $(call Require/$(1))
+    CHECK_$(1):=1
+
+    .SILENT: prereq-$(1) check-$(1)
+    .NOTPARALLEL:
+  endif
+
+  PREREQ_PREV=$(1)
+endef
+
+
+define RequireCommand
+  define Require/$(1)
+    which $(1)
+  endef
+
+  $$(eval $$(call Require,$(1),$(2)))
+endef
+
+define RequireHeader
+  define Require/$(1)
+    [ -e "$(1)" ]
+  endef
+
+  $$(eval $$(call Require,$(1),$(2)))
+endef
+
+define QuoteHostCommand
+'$(subst ','"'"',$(strip $(1)))'
+endef
+
+# 1: display name
+# 2: failure message
+# 3: test
+define TestHostCommand
+  define Require/$(1)
+	($(3)) >/dev/null 2>/dev/null
+  endef
+
+  $$(eval $$(call Require,$(1),$(2)))
+endef
+
+# 1: canonical name
+# 2: failure message
+# 3+: candidates
+define SetupHostCommand
+  define Require/$(1)
+	[ -f "$(STAGING_DIR_HOST)/bin/$(strip $(1))" ] && exit 0; \
+	for cmd in $(call QuoteHostCommand,$(3)) $(call QuoteHostCommand,$(4)) \
+	           $(call QuoteHostCommand,$(5)) $(call QuoteHostCommand,$(6)) \
+	           $(call QuoteHostCommand,$(7)) $(call QuoteHostCommand,$(8)) \
+			   $(call QuoteHostCommand,$(9)); do \
+		if [ -n "$$$$$$$$cmd" ]; then \
+			bin="$$$$$$$$(PATH="$(subst $(space),:,$(filter-out $(STAGING_DIR_HOST)/%,$(subst :,$(space),$(PATH))))" \
+				which "$$$$$$$${cmd%% *}")"; \
+			if [ -x "$$$$$$$$bin" ] && eval "$$$$$$$$cmd" >/dev/null 2>/dev/null; then \
+				mkdir -p "$(STAGING_DIR_HOST)/bin"; \
+				ln -sf "$$$$$$$$bin" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \
+				exit 0; \
+			fi; \
+		fi; \
+	done; \
+	exit 1
+  endef
+
+  $$(eval $$(call Require,$(1),$(if $(2),$(2),Missing $(1) command)))
+endef

+ 171 - 0
include/quilt.mk

@@ -0,0 +1,171 @@
+#
+# Copyright (C) 2007-2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+ifneq ($(if $(DUMP),1,$(__quilt_inc)),1)
+__quilt_inc:=1
+
+ifeq ($(TARGET_BUILD),1)
+  PKG_BUILD_DIR:=$(LINUX_DIR)
+endif
+PATCH_DIR?=./patches
+FILES_DIR?=./files
+HOST_PATCH_DIR?=$(PATCH_DIR)
+HOST_FILES_DIR?=$(FILES_DIR)
+
+ifeq ($(MAKECMDGOALS),refresh)
+  override QUILT=1
+  override HOST_QUILT=1
+endif
+
+QUILT_CMD:=quilt --quiltrc=-
+
+define filter_series
+sed -e s,\\\#.*,, $(1) | grep -E \[a-zA-Z0-9\]
+endef
+
+define PatchDir/Quilt
+	@mkdir -p "$(1)/patches$(if $(3),/$(patsubst %/,%,$(3)))"
+	@if [ -s "$(2)/series" ]; then \
+		mkdir -p "$(1)/patches/$(3)"; \
+		cp "$(2)/series" "$(1)/patches/$(3)"; \
+	fi
+	@for patch in $$$$( (cd "$(2)" && if [ -f series ]; then $(call filter_series,series); else ls | sort; fi; ) 2>/dev/null ); do ( \
+		cp "$(2)/$$$$patch" "$(1)/patches/$(3)"; \
+		echo "$(3)$$$$patch" >> "$(1)/patches/series"; \
+	); done
+	$(if $(3),@echo $(3) >> "$(1)/patches/.subdirs")
+endef
+
+define PatchDir/Default
+	@if [ -d "$(2)" ] && [ "$$$$(ls $(2) | wc -l)" -gt 0 ]; then \
+		export PATCH="$(PATCH)"; \
+		if [ -s "$(2)/series" ]; then \
+			$(call filter_series,$(2)/series) | xargs -n1 \
+				$(KPATCH) "$(1)" "$(2)"; \
+		else \
+			$(KPATCH) "$(1)" "$(2)"; \
+		fi; \
+	fi
+endef
+
+define PatchDir
+$(call PatchDir/$(if $(strip $(QUILT)),Quilt,Default),$(strip $(1)),$(strip $(2)),$(strip $(3)))
+endef
+
+define HostPatchDir
+$(call PatchDir/$(if $(strip $(HOST_QUILT)),Quilt,Default),$(strip $(1)),$(strip $(2)),$(strip $(3)))
+endef
+
+ifneq ($(PKG_BUILD_DIR),)
+  QUILT?=$(if $(wildcard $(PKG_BUILD_DIR)/.quilt_used),y)
+  ifneq ($(QUILT),)
+    STAMP_CHECKED:=$(PKG_BUILD_DIR)/.quilt_checked
+    override CONFIG_AUTOREBUILD=
+    quilt-check: $(STAMP_CHECKED)
+  endif
+endif
+
+ifneq ($(HOST_BUILD_DIR),)
+  HOST_QUILT?=$(if $(findstring command,$(origin QUILT)),$(QUILT),$(if $(wildcard $(HOST_BUILD_DIR)/.quilt_used),y))
+  ifneq ($(HOST_QUILT),)
+    HOST_STAMP_CHECKED:=$(HOST_BUILD_DIR)/.quilt_checked
+    override CONFIG_AUTOREBUILD=
+    host-quilt-check: $(HOST_STAMP_CHECKED)
+  endif
+endif
+
+define Host/Patch/Default
+	$(if $(HOST_QUILT),rm -rf $(HOST_BUILD_DIR)/patches; mkdir -p $(HOST_BUILD_DIR)/patches)
+	$(call HostPatchDir,$(HOST_BUILD_DIR),$(HOST_PATCH_DIR),)
+	$(if $(HOST_QUILT),touch $(HOST_BUILD_DIR)/.quilt_used)
+endef
+
+define Build/Patch/Default
+	$(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches)
+	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR),)
+	$(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used)
+endef
+
+kernel_files=$(foreach fdir,$(GENERIC_FILES_DIR) $(FILES_DIR),$(fdir)/.)
+define Kernel/Patch/Default
+	rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches
+	$(if $(kernel_files),$(CP) $(kernel_files) $(LINUX_DIR)/)
+	find $(LINUX_DIR)/ -name \*.rej -or -name \*.orig | $(XARGS) rm -f
+	$(call PatchDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
+endef
+
+define Quilt/RefreshDir
+	mkdir -p $(2)
+	-rm -f $(2)/* 2>/dev/null >/dev/null
+	@( \
+		for patch in $$$$($(if $(3),grep "^$(3)",cat) $(1)/patches/series | awk '{print $$$$1}'); do \
+			$(CP) -v "$(1)/patches/$$$$patch" $(2); \
+		done; \
+	)
+endef
+
+define Quilt/Refresh/Host
+	$(call Quilt/RefreshDir,$(HOST_BUILD_DIR),$(PATCH_DIR))
+endef
+
+define Quilt/Refresh/Package
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR))
+endef
+
+define Quilt/Refresh/Kernel
+	@[ -z "$$(grep -v '^generic/' $(PKG_BUILD_DIR)/patches/series | grep -v '^platform/')" ] || { \
+		echo "All kernel patches must start with either generic/ or platform/"; \
+		false; \
+	}
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
+endef
+
+define Quilt/Template
+  $($(2)STAMP_CONFIGURED): $($(2)STAMP_CHECKED)
+  $(if $(NO_RECONFIGURE),$($(2)STAMP_BUILT),$($(2)STAMP_CONFIGURED)): FORCE
+  $($(2)STAMP_CHECKED): $($(2)STAMP_PREPARED)
+	if [ -s "$(1)/patches/series" ]; then \
+		(cd "$(1)"; \
+			if $(QUILT_CMD) next >/dev/null 2>&1; then \
+				$(QUILT_CMD) push -a; \
+			else \
+				$(QUILT_CMD) top >/dev/null 2>&1; \
+			fi \
+		); \
+	fi
+	touch "$$@"
+
+  $(3)quilt-check: $($(2)STAMP_PREPARED) FORCE
+	@[ -f "$(1)/.quilt_used" ] || { \
+		echo "The source directory was not unpacked using quilt. Please rebuild with QUILT=1"; \
+		false; \
+	}
+	@[ -f "$(1)/patches/series" ] || { \
+		echo "The source directory contains no quilt patches."; \
+		false; \
+	}
+	@[ -n "$$$$(ls $(1)/patches/series)" -o "$$$$(cat $(1)/patches/series | md5sum)" = "$$(sort $(1)/patches/series | md5sum)" ] || { \
+		echo "The patches are not sorted in the right order. Please fix."; \
+		false; \
+	}
+
+  $(3)refresh: $(3)quilt-check
+	@cd "$(1)"; $(QUILT_CMD) pop -a -f >/dev/null 2>/dev/null
+	@cd "$(1)"; while $(QUILT_CMD) next 2>/dev/null >/dev/null && $(QUILT_CMD) push; do \
+		QUILT_DIFF_OPTS="-p" $(QUILT_CMD) refresh -p ab --no-index --no-timestamps; \
+	done; ! $(QUILT_CMD) next 2>/dev/null >/dev/null
+	$(Quilt/Refresh/$(4))
+	
+  $(3)update: $(3)quilt-check
+	$(Quilt/Refresh/$(4))
+endef
+
+Build/Quilt=$(call Quilt/Template,$(PKG_BUILD_DIR),,,$(if $(TARGET_BUILD),Kernel,Package))
+Host/Quilt=$(call Quilt/Template,$(HOST_BUILD_DIR),HOST_,host-,Host)
+
+endif

+ 19 - 0
include/scan.awk

@@ -0,0 +1,19 @@
+BEGIN { FS="/" }
+$1 ~ /^feeds/ { FEEDS[$NF]=$0 }
+$1 !~ /^feeds/ { PKGS[$NF]=$0 }
+END {
+	# Filter-out OpenWrt packages which have a feeds equivalent
+	for (pkg in PKGS)
+		if (pkg in FEEDS) {
+			print PKGS[pkg] > of
+			delete PKGS[pkg]
+		}
+	n = asort(PKGS)
+	for (i=1; i <= n; i++) {
+		print PKGS[i]
+	}
+	n = asort(FEEDS)
+	for (i=1; i <= n; i++){
+		print FEEDS[i]
+	}
+}

+ 102 - 0
include/scan.mk

@@ -0,0 +1,102 @@
+include $(TOPDIR)/include/verbose.mk
+TMP_DIR:=$(TOPDIR)/tmp
+
+all: $(TMP_DIR)/.$(SCAN_TARGET)
+
+include $(TOPDIR)/include/host.mk
+
+SCAN_TARGET ?= packageinfo
+SCAN_NAME ?= package
+SCAN_DIR ?= package
+TARGET_STAMP:=$(TMP_DIR)/info/.files-$(SCAN_TARGET).stamp
+FILELIST:=$(TMP_DIR)/info/.files-$(SCAN_TARGET)-$(SCAN_COOKIE)
+OVERRIDELIST:=$(TMP_DIR)/info/.overrides-$(SCAN_TARGET)-$(SCAN_COOKIE)
+
+ifeq ($(IS_TTY),1)
+  define progress
+	printf "\033[M\r$(1)" >&2;
+  endef
+else
+  define progress
+	:;
+  endef
+endif
+
+define feedname
+$(if $(patsubst feeds/%,,$(1)),,$(word 2,$(subst /, ,$(1))))
+endef
+
+define PackageDir
+  $(TMP_DIR)/.$(SCAN_TARGET): $(TMP_DIR)/info/.$(SCAN_TARGET)-$(1)
+  $(TMP_DIR)/info/.$(SCAN_TARGET)-$(1): $(SCAN_DIR)/$(2)/Makefile $(SCAN_STAMP) $(foreach DEP,$(DEPS_$(SCAN_DIR)/$(2)/Makefile) $(SCAN_DEPS),$(wildcard $(if $(filter /%,$(DEP)),$(DEP),$(SCAN_DIR)/$(2)/$(DEP))))
+	{ \
+		$$(call progress,Collecting $(SCAN_NAME) info: $(SCAN_DIR)/$(2)) \
+		echo Source-Makefile: $(SCAN_DIR)/$(2)/Makefile; \
+		$(if $(3),echo Override: $(3),true); \
+		$(NO_TRACE_MAKE) --no-print-dir -r DUMP=1 FEED="$(call feedname,$(2))" -C $(SCAN_DIR)/$(2) $(SCAN_MAKEOPTS) 2>/dev/null || { \
+			mkdir -p "$(TOPDIR)/logs/$(SCAN_DIR)/$(2)"; \
+			$(NO_TRACE_MAKE) --no-print-dir -r DUMP=1 FEED="$(call feedname,$(2))" -C $(SCAN_DIR)/$(2) $(SCAN_MAKEOPTS) > $(TOPDIR)/logs/$(SCAN_DIR)/$(2)/dump.txt 2>&1; \
+			$$(call progress,ERROR: please fix $(SCAN_DIR)/$(2)/Makefile - see logs/$(SCAN_DIR)/$(2)/dump.txt for details\n) \
+			rm -f $$@; \
+		}; \
+		echo; \
+	} > $$@ || true
+endef
+
+$(OVERRIDELIST):
+	rm -f $(TMP_DIR)/info/.overrides-$(SCAN_TARGET)-*
+	touch $@
+
+ifeq ($(SCAN_NAME),target)
+  GREP_STRING=BuildTarget
+else
+  GREP_STRING=(Build/DefaultTargets|BuildPackage|.+Package)
+endif
+
+$(FILELIST): $(OVERRIDELIST)
+	rm -f $(TMP_DIR)/info/.files-$(SCAN_TARGET)-*
+	$(call FIND_L, $(SCAN_DIR)) $(SCAN_EXTRA) -mindepth 1 $(if $(SCAN_DEPTH),-maxdepth $(SCAN_DEPTH)) -name Makefile | xargs grep -aHE 'call $(GREP_STRING)' | sed -e 's#^$(SCAN_DIR)/##' -e 's#/Makefile:.*##' | uniq | awk -v of=$(OVERRIDELIST) -f include/scan.awk > $@
+
+$(TMP_DIR)/info/.files-$(SCAN_TARGET).mk: $(FILELIST)
+	( \
+		cat $< | awk '{print "$(SCAN_DIR)/" $$0 "/Makefile" }' | xargs grep -HE '^ *SCAN_DEPS *= *' | awk -F: '{ gsub(/^.*DEPS *= */, "", $$2); print "DEPS_" $$1 "=" $$2 }'; \
+		awk -F/ -v deps="$$DEPS" -v of="$(OVERRIDELIST)" ' \
+		BEGIN { \
+			while (getline < (of)) \
+				override[$$NF]=$$0; \
+			close(of) \
+		} \
+		{ \
+			info=$$0; \
+			gsub(/\//, "_", info); \
+			dir=$$0; \
+			pkg=""; \
+			if($$NF in override) \
+				pkg=override[$$NF]; \
+			print "$$(eval $$(call PackageDir," info "," dir "," pkg "))"; \
+		} ' < $<; \
+		true; \
+	) > $@
+
+-include $(TMP_DIR)/info/.files-$(SCAN_TARGET).mk
+
+$(TARGET_STAMP)::
+	+( \
+		$(NO_TRACE_MAKE) $(FILELIST); \
+		MD5SUM=$$(cat $(FILELIST) $(OVERRIDELIST) | (md5sum || md5) 2>/dev/null | awk '{print $$1}'); \
+		[ -f "$@.$$MD5SUM" ] || { \
+			rm -f $@.*; \
+			touch $@.$$MD5SUM; \
+			touch $@; \
+		} \
+	)
+
+$(TMP_DIR)/.$(SCAN_TARGET): $(TARGET_STAMP) $(SCAN_STAMP)
+	$(call progress,Collecting $(SCAN_NAME) info: merging...)
+	-cat $(FILELIST) | awk '{gsub(/\//, "_", $$0);print "$(TMP_DIR)/info/.$(SCAN_TARGET)-" $$0}' | xargs cat > $@ 2>/dev/null
+	$(call progress,Collecting $(SCAN_NAME) info: done)
+	echo
+
+FORCE:
+.PHONY: FORCE
+.NOTPARALLEL:

+ 23 - 0
include/scons.mk

@@ -0,0 +1,23 @@
+export PLATFORM=posix
+
+SCONS_VARS = \
+	CC="$(TARGET_CC_NOCACHE)" \
+	CXX="$(TARGET_CXX_NOCACHE)" \
+	CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
+	CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
+	CPPFLAGS="$(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS)" \
+	LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \
+	DESTDIR="$(PKG_INSTALL_DIR)"
+
+define Build/Configure/Default
+	(cd $(PKG_BUILD_DIR); \
+		$(SCONS_VARS) \
+		scons \
+			prefix=/usr \
+			$(SCONS_OPTIONS) \
+		install \
+	)
+endef
+
+define Build/Compile
+endef

+ 37 - 0
include/shell.sh

@@ -0,0 +1,37 @@
+getvar() {
+	eval "echo \"\${$1}\""
+}
+
+var2file() {
+	local var
+	eval "var=\"\${$1}\""
+	if [ -n "$var" ]; then echo "$var" > "$2"; fi
+}
+
+isset() {
+	local var
+	eval "var=\"\${$1}\""
+	[ -n "$var" ]
+}
+
+trapret() {(
+	local retvals="$1"; shift
+	local cmd="$1"; shift
+	for retval in $(echo $retvals); do
+		local trap_$retval=1
+	done
+	"$cmd" "$@" || {
+		local retval="$?"
+		eval "trapped=\${trap_$retval}"
+		[ -n "$trapped" ] || {
+			return $retval
+		}
+	}
+)}
+
+md5s() {
+	cat "$@" | (
+		md5sum 2>/dev/null ||
+		md5
+	) | awk '{print $1}'
+}

+ 30 - 0
include/site/aarch64

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=8
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8

+ 30 - 0
include/site/aarch64_be

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=8
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8

+ 30 - 0
include/site/arc

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/arm

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/armeb

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 3 - 0
include/site/i386

@@ -0,0 +1,3 @@
+#!/bin/sh
+. $TOPDIR/include/site/i486
+

+ 30 - 0
include/site/i486

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 3 - 0
include/site/i686

@@ -0,0 +1,3 @@
+#!/bin/sh
+. $TOPDIR/include/site/i486
+

+ 78 - 0
include/site/linux

@@ -0,0 +1,78 @@
+ac_atomic_add=yes
+ac_atomic_sub=yes
+ac_cv_c_gettext_without_libintl=yes
+ac_cv_c_long_double=no
+ac_cv_conv_longlong_to_float=yes
+ac_cv_file__dev_zero=yes
+ac_cv_func___va_copy=no
+ac_cv_func__exit=yes
+ac_cv_func_bcopy=yes
+ac_cv_func_bzero=yes
+ac_cv_func_bcmp=yes
+ac_cv_func_creal=yes
+ac_cv_func_cimag=yes
+ac_cv_func_fchmod=yes
+ac_cv_func_getaddrinfo=yes
+ac_cv_func_getcwd=yes
+ac_cv_func_getdomainname=yes
+ac_cv_func_getpgrp_void=yes
+ac_cv_func_getpwuid_r=yes
+ac_cv_func_gettimeofday=yes
+ac_cv_func_index=yes
+ac_cv_func_lstat_dereferences_slashed_symlink=yes
+ac_cv_func_lstat_empty_string_bug=no
+ac_cv_func_lstat=yes
+ac_cv_func_malloc_0_nonnull=yes
+ac_cv_func_malloc_works=yes
+ac_cv_func_memcmp_clean=yes
+ac_cv_func_memcmp_working=yes
+ac_cv_func_posix_getgrgid_r=yes
+ac_cv_func_posix_getpwuid_r=yes
+ac_cv_func_psignal=yes
+ac_cv_func_pthread_key_delete=yes
+ac_cv_func_realloc_0_nonnull=yes
+ac_cv_func_realloc_works=yes
+ac_cv_func_rename=yes
+ac_cv_func_rindex=yes
+ac_cv_func_setlocale=yes
+ac_cv_func_setgrent_void=yes
+ac_cv_func_setpgrp_void=yes
+ac_cv_func_setresuid=no
+ac_cv_func_setvbuf_reversed=no
+ac_cv_func_stat_empty_string_bug=no
+ac_cv_func_stat_ignores_trailing_slash=no
+ac_cv_func_strerror=yes
+ac_cv_func_strftime=yes
+ac_cv_func_utimes=yes
+ac_cv_func___adjtimex=yes
+ac_cv_func_va_copy=no
+ac_cv_func_vsnprintf=yes
+ac_cv_have_accrights_in_msghdr=no
+ac_cv_have_broken_snprintf=no
+ac_cv_have_control_in_msghdr=yes
+ac_cv_have_decl_sys_siglist=no
+ac_cv_have_openpty_ctty_bug=yes
+ac_cv_have_space_d_name_in_struct_dirent=yes
+ac_cv_header_netinet_sctp_h=no
+ac_cv_header_netinet_sctp_uio_h=no
+ac_cv_int64_t=yes
+ac_cv_lbl_unaligned_fail=no
+ac_cv_linux_kernel_pppoe=yes
+ac_cv_linux_vers=2
+ac_cv_pack_bitfields_reversed=yes
+ac_cv_path_LDCONFIG=
+ac_cv_regexec_segfault_emptystr=no
+ac_cv_sctp=no
+ac_cv_sys_restartable_syscalls=yes
+ac_cv_time_r_type=POSIX
+ac_cv_type_suseconds_t=yes
+ac_cv_uchar=no
+ac_cv_uint=yes
+ac_cv_uint64_t=yes
+ac_cv_ulong=yes
+ac_cv_ushort=yes
+ac_cv_va_copy=C99
+ac_cv_va_val_copy=yes
+as_cv_unaligned_access=yes
+ac_cv_func_malloc_0_nonnull=yes
+ac_cv_func_realloc_0_nonnull=yes

+ 28 - 0
include/site/m68k

@@ -0,0 +1,28 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/mips

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/mips64

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=8
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8

+ 30 - 0
include/site/mips64el

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=8
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8

+ 30 - 0
include/site/mipsel

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/powerpc

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/sparc

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=no}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=yes}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=4
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=4
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=4
+ac_cv_sizeof_ssize_t=4
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=4
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=4

+ 30 - 0
include/site/x86_64

@@ -0,0 +1,30 @@
+#!/bin/sh
+. $TOPDIR/include/site/linux
+ac_cv_c_littleendian=${ac_cv_c_littleendian=yes}
+ac_cv_c_bigendian=${ac_cv_c_bigendian=no}
+
+ac_cv_sizeof___int64=0
+ac_cv_sizeof_char=1
+ac_cv_sizeof_int=4
+ac_cv_sizeof_int16_t=2
+ac_cv_sizeof_int32_t=4
+ac_cv_sizeof_int64_t=8
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long=8
+ac_cv_sizeof_off_t=8
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_short=2
+ac_cv_sizeof_size_t=8
+ac_cv_sizeof_ssize_t=8
+ac_cv_sizeof_u_int16_t=2
+ac_cv_sizeof_u_int32_t=4
+ac_cv_sizeof_u_int64_t=8
+ac_cv_sizeof_uint16_t=2
+ac_cv_sizeof_uint32_t=4
+ac_cv_sizeof_uint64_t=8
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_long=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_void_p=8

+ 92 - 0
include/subdir.mk

@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifeq ($(MAKECMDGOALS),prereq)
+  SUBTARGETS:=prereq
+  PREREQ_ONLY:=1
+else
+  SUBTARGETS:=clean download prepare compile install update refresh prereq dist distcheck configure
+endif
+
+subtarget-default = $(filter-out ., \
+	$(if $($(1)/builddirs-$(2)),$($(1)/builddirs-$(2)), \
+	$(if $($(1)/builddirs-default),$($(1)/builddirs-default), \
+	$($(1)/builddirs))))
+
+define subtarget
+  $(call warn_eval,$(1),t,T,$(1)/$(2): $($(1)/) $(foreach bd,$(call subtarget-default,$(1),$(2)),$(1)/$(bd)/$(2)))
+
+endef
+
+define ERROR
+	($(call MESSAGE, $(2)); $(if $(BUILD_LOG), echo "$(2)" >> $(BUILD_LOG_DIR)/$(1)/error.txt))
+endef
+
+lastdir=$(word $(words $(subst /, ,$(1))),$(subst /, ,$(1)))
+diralias=$(if $(findstring $(1),$(call lastdir,$(1))),,$(call lastdir,$(1)))
+
+# 1: subdir
+# 2: target
+# 3: build type
+# 4: build variant
+log_make = \
+	 $(if $(call debug,$(1),v),,@)+ \
+	 $(if $(BUILD_LOG), \
+		set -o pipefail; \
+		mkdir -p $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4));) \
+	$$(SUBMAKE) -r -C $(1) $(if $(3),$(3)-)$(2) \
+		BUILD_SUBDIR="$(1)" \
+		BUILD_VARIANT="$(4)" \
+		$(if $(BUILD_LOG),SILENT= 2>&1 | tee $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4))/$(if $(3),$(3)-)$(2).txt)
+
+# Parameters: <subdir>
+define subdir
+  $(call warn,$(1),d,D $(1))
+  $(foreach bd,$($(1)/builddirs),
+    $(call warn,$(1),d,BD $(1)/$(bd))
+    $(foreach target,$(SUBTARGETS),
+      $(foreach btype,$(buildtypes-$(bd)),
+        $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btype)/$(target),$(1)/$(bd)/$(btype))))
+		  $(call log_make,$(1)/$(bd),$(target),$(btype),$(filter-out __default,$(variant))) \
+			$(if $(findstring $(bd),$($(1)/builddirs-ignore-$(btype)-$(target))), || $(call ERROR,$(1),   ERROR: $(1)/$(bd) [$(btype)] failed to build.))
+        $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(btype)/$(target): $(1)/$(bd)/$(btype)/$(target)))
+      )
+      $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd))))
+        $(foreach variant,$(if $(BUILD_VARIANT),$(BUILD_VARIANT),$(if $(strip $($(1)/$(bd)/variants)),$($(1)/$(bd)/variants),$(if $($(1)/$(bd)/default-variant),$($(1)/$(bd)/default-variant),__default))),
+			$(if $(BUILD_LOG),@mkdir -p $(BUILD_LOG_DIR)/$(1)/$(bd)/$(filter-out __default,$(variant)))
+			$(call log_make,$(1)/$(bd),$(target),,$(filter-out __default,$(variant))) \
+				$(if $(findstring $(bd),$($(1)/builddirs-ignore-$(target))), || $(call ERROR,$(1),   ERROR: $(1)/$(bd) failed to build$(if $(filter-out __default,$(variant)), (build variant: $(variant))).))
+        )
+      $(if $(PREREQ_ONLY)$(DUMP_TARGET_DB),,
+        # aliases
+        $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(target): $(1)/$(bd)/$(target)))
+	  )
+	)
+  )
+  $(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target)))
+endef
+
+ifndef DUMP_TARGET_DB
+# Parameters: <subdir> <name> <target> <depends> <config options> <stampfile location>
+define stampfile
+  $(1)/stamp-$(3):=$(if $(6),$(6),$(STAGING_DIR))/stamp/.$(2)_$(3)$(5)
+  $$($(1)/stamp-$(3)): $(TMP_DIR)/.build $(4)
+	@+$(SCRIPT_DIR)/timestamp.pl -n $$($(1)/stamp-$(3)) $(1) $(4) || \
+		$(MAKE) $(if $(QUIET),--no-print-directory) $$($(1)/flags-$(3)) $(1)/$(3)
+	@mkdir -p $$$$(dirname $$($(1)/stamp-$(3)))
+	@touch $$($(1)/stamp-$(3))
+
+  $$(if $(call debug,$(1),v),,.SILENT: $$($(1)/stamp-$(3)))
+
+  .PRECIOUS: $$($(1)/stamp-$(3)) # work around a make bug
+
+  $(1)//clean:=$(1)/stamp-$(3)/clean
+  $(1)/stamp-$(3)/clean: FORCE
+	@rm -f $$($(1)/stamp-$(3))
+
+endef
+endif

+ 307 - 0
include/target.mk

@@ -0,0 +1,307 @@
+#
+# Copyright (C) 2007-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifneq ($(__target_inc),1)
+__target_inc=1
+
+# default device type
+DEVICE_TYPE?=router
+
+# Default packages - the really basic set
+DEFAULT_PACKAGES:=base-files libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd
+# For nas targets
+DEFAULT_PACKAGES.nas:=block-mount fdisk lsblk mdadm
+# For router targets
+DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables ppp ppp-mod-pppoe firewall odhcpd odhcp6c
+DEFAULT_PACKAGES.bootloader:=
+
+ifneq ($(DUMP),)
+  all: dumpinfo
+endif
+
+target_conf=$(subst .,_,$(subst -,_,$(subst /,_,$(1))))
+ifeq ($(DUMP),)
+  PLATFORM_DIR:=$(TOPDIR)/target/linux/$(BOARD)
+  SUBTARGET:=$(strip $(foreach subdir,$(patsubst $(PLATFORM_DIR)/%/target.mk,%,$(wildcard $(PLATFORM_DIR)/*/target.mk)),$(if $(CONFIG_TARGET_$(call target_conf,$(BOARD)_$(subdir))),$(subdir))))
+else
+  PLATFORM_DIR:=${CURDIR}
+  ifeq ($(SUBTARGETS),)
+    SUBTARGETS:=$(strip $(patsubst $(PLATFORM_DIR)/%/target.mk,%,$(wildcard $(PLATFORM_DIR)/*/target.mk)))
+  endif
+endif
+
+TARGETID:=$(BOARD)$(if $(SUBTARGET),/$(SUBTARGET))
+PLATFORM_SUBDIR:=$(PLATFORM_DIR)$(if $(SUBTARGET),/$(SUBTARGET))
+
+ifneq ($(TARGET_BUILD),1)
+  ifndef DUMP
+    include $(PLATFORM_DIR)/Makefile
+    ifneq ($(PLATFORM_DIR),$(PLATFORM_SUBDIR))
+      include $(PLATFORM_SUBDIR)/target.mk
+    endif
+  endif
+else
+  ifneq ($(SUBTARGET),)
+    -include ./$(SUBTARGET)/target.mk
+  endif
+endif
+
+# Add device specific packages (here below to allow device type set from subtarget)
+DEFAULT_PACKAGES += $(DEFAULT_PACKAGES.$(DEVICE_TYPE))
+
+filter_packages = $(filter-out -% $(patsubst -%,%,$(filter -%,$(1))),$(1))
+extra_packages = $(if $(filter wpad-mini wpad nas,$(1)),iwinfo)
+
+define ProfileDefault
+  NAME:=
+  PACKAGES:=
+endef
+
+ifndef Profile
+define Profile
+  $(eval $(call ProfileDefault))
+  $(eval $(call Profile/$(1)))
+  dumpinfo : $(call shexport,Profile/$(1)/Config)
+  dumpinfo : $(call shexport,Profile/$(1)/Description)
+  DUMPINFO += \
+	echo "Target-Profile: $(1)"; \
+	echo "Target-Profile-Name: $(NAME)"; \
+	echo "Target-Profile-Packages: $(PACKAGES) $(call extra_packages,$(DEFAULT_PACKAGES) $(PACKAGES))"; \
+	if [ -f ./config/profile-$(1) ]; then \
+		echo "Target-Profile-Kconfig: yes"; \
+	fi; \
+	echo "Target-Profile-Config: "; \
+	echo "$$$$$$$$$(call shvar,Profile/$(1)/Config)"; \
+	echo "@@"; \
+	echo "Target-Profile-Description:"; \
+	echo "$$$$$$$$$(call shvar,Profile/$(1)/Description)"; \
+	echo "@@"; \
+	echo;
+  ifeq ($(CONFIG_TARGET_$(call target_conf,$(BOARD)_$(if $(SUBTARGET),$(SUBTARGET)_))$(1)),y)
+    PROFILE=$(1)
+  endif
+endef
+endif
+
+ifneq ($(PLATFORM_DIR),$(PLATFORM_SUBDIR))
+  define IncludeProfiles
+    -include $(sort $(wildcard $(PLATFORM_DIR)/profiles/*.mk))
+    -include $(sort $(wildcard $(PLATFORM_SUBDIR)/profiles/*.mk))
+  endef
+else
+  define IncludeProfiles
+    -include $(sort $(wildcard $(PLATFORM_DIR)/profiles/*.mk))
+  endef
+endif
+
+ifeq ($(TARGET_BUILD),1)
+  $(eval $(call IncludeProfiles))
+else
+  ifeq ($(DUMP),)
+    $(eval $(call IncludeProfiles))
+  endif
+endif
+
+ifneq ($(TARGET_BUILD)$(if $(DUMP),,1),)
+  include $(INCLUDE_DIR)/kernel-version.mk
+endif
+
+GENERIC_PLATFORM_DIR := $(TOPDIR)/target/linux/generic
+GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/patches$(if $(wildcard $(GENERIC_PLATFORM_DIR)/patches-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_FILES_DIR := $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(KERNEL_PATCHVER)),"$(dir)")
+
+__config_name_list = $(1)/config-$(KERNEL_PATCHVER) $(1)/config-default
+__config_list = $(firstword $(wildcard $(call __config_name_list,$(1))))
+find_kernel_config=$(if $(__config_list),$(__config_list),$(lastword $(__config_name_list)))
+
+GENERIC_LINUX_CONFIG = $(call find_kernel_config,$(GENERIC_PLATFORM_DIR))
+LINUX_TARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_DIR))
+ifneq ($(PLATFORM_DIR),$(PLATFORM_SUBDIR))
+  LINUX_SUBTARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_SUBDIR))
+endif
+
+# config file list used for compiling
+LINUX_KCONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_TARGET_CONFIG) $(LINUX_SUBTARGET_CONFIG) $(TOPDIR)/env/kernel-config)
+
+# default config list for reconfiguring
+# defaults to subtarget if subtarget exists and target does not
+# defaults to target otherwise
+USE_SUBTARGET_CONFIG = $(if $(wildcard $(LINUX_TARGET_CONFIG)),,$(if $(LINUX_SUBTARGET_CONFIG),1))
+
+LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_TARGET_CONFIG) $(if $(USE_SUBTARGET_CONFIG),$(LINUX_SUBTARGET_CONFIG)))
+LINUX_RECONFIG_TARGET = $(if $(USE_SUBTARGET_CONFIG),$(LINUX_SUBTARGET_CONFIG),$(LINUX_TARGET_CONFIG))
+
+# select the config file to be changed by kernel_menuconfig/kernel_oldconfig
+ifeq ($(CONFIG_TARGET),platform)
+  LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_TARGET_CONFIG))
+  LINUX_RECONFIG_TARGET = $(LINUX_TARGET_CONFIG)
+endif
+ifeq ($(CONFIG_TARGET),subtarget)
+  LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_TARGET_CONFIG) $(LINUX_SUBTARGET_CONFIG))
+  LINUX_RECONFIG_TARGET = $(LINUX_SUBTARGET_CONFIG)
+endif
+ifeq ($(CONFIG_TARGET),subtarget_platform)
+  LINUX_RECONFIG_LIST = $(wildcard $(GENERIC_LINUX_CONFIG) $(LINUX_SUBTARGET_CONFIG) $(LINUX_TARGET_CONFIG))
+  LINUX_RECONFIG_TARGET = $(LINUX_TARGET_CONFIG)
+endif
+ifeq ($(CONFIG_TARGET),env)
+  LINUX_RECONFIG_LIST = $(LINUX_KCONFIG_LIST)
+  LINUX_RECONFIG_TARGET = $(TOPDIR)/env/kernel-config
+endif
+
+__linux_confcmd = $(SCRIPT_DIR)/kconfig.pl $(2) $(patsubst %,+,$(wordlist 2,9999,$(1))) $(1)
+
+LINUX_CONF_CMD = $(call __linux_confcmd,$(LINUX_KCONFIG_LIST),)
+LINUX_RECONF_CMD = $(call __linux_confcmd,$(LINUX_RECONFIG_LIST),)
+LINUX_RECONF_DIFF = $(call __linux_confcmd,$(filter-out $(LINUX_RECONFIG_TARGET),$(LINUX_RECONFIG_LIST)),'>')
+
+ifeq ($(DUMP),1)
+  BuildTarget=$(BuildTargets/DumpCurrent)
+
+  ifneq ($(BOARD),)
+    TMP_CONFIG:=$(TMP_DIR)/.kconfig-$(call target_conf,$(TARGETID))
+    $(TMP_CONFIG): $(LINUX_KCONFIG_LIST)
+		$(LINUX_CONF_CMD) > $@ || rm -f $@
+    -include $(TMP_CONFIG)
+    .SILENT: $(TMP_CONFIG)
+    .PRECIOUS: $(TMP_CONFIG)
+
+    ifneq ($(CONFIG_OF),)
+      FEATURES += dt
+    endif
+    ifneq ($(CONFIG_GENERIC_GPIO)$(CONFIG_GPIOLIB),)
+      FEATURES += gpio
+    endif
+    ifneq ($(CONFIG_PCI),)
+      FEATURES += pci
+    endif
+    ifneq ($(CONFIG_PCIEPORTBUS),)
+      FEATURES += pcie
+    endif
+    ifneq ($(CONFIG_USB)$(CONFIG_USB_SUPPORT),)
+      ifneq ($(CONFIG_USB_ARCH_HAS_HCD)$(CONFIG_USB_EHCI_HCD),)
+        FEATURES += usb
+      endif
+    endif
+    ifneq ($(CONFIG_PCMCIA)$(CONFIG_PCCARD),)
+      FEATURES += pcmcia
+    endif
+    ifneq ($(CONFIG_VGA_CONSOLE)$(CONFIG_FB),)
+      FEATURES += display
+    endif
+    ifneq ($(CONFIG_RTC_CLASS),)
+      FEATURES += rtc
+    endif
+    FEATURES += $(foreach v,v4 v5 v6 v7,$(if $(findstring -march=arm$(v),$(CFLAGS)),arm_$(v)))
+
+    # remove duplicates
+    FEATURES:=$(sort $(FEATURES))
+  endif
+  CPU_CFLAGS = -Os -pipe
+  ifneq ($(findstring mips,$(ARCH)),)
+    ifneq ($(findstring mips64,$(ARCH)),)
+      CPU_TYPE ?= mips64
+    else
+      CPU_TYPE ?= mips32
+    endif
+    CPU_CFLAGS += -mno-branch-likely
+    CPU_CFLAGS_mips32 = -mips32 -mtune=mips32
+    CPU_CFLAGS_mips32r2 = -mips32r2 -mtune=mips32r2
+    CPU_CFLAGS_mips64 = -mips64 -mtune=mips64 -mabi=64
+    CPU_CFLAGS_24kc = -mips32r2 -mtune=24kc
+    CPU_CFLAGS_24kec = -mips32r2 -mtune=24kec
+    CPU_CFLAGS_34kc = -mips32r2 -mtune=34kc
+    CPU_CFLAGS_74kc = -mips32r2 -mtune=74kc
+    CPU_CFLAGS_1004kc = -mips32r2 -mtune=1004kc
+    CPU_CFLAGS_octeon = -march=octeon -mabi=64
+    CPU_CFLAGS_dsp = -mdsp
+    CPU_CFLAGS_dsp2 = -mdspr2
+  endif
+  ifeq ($(ARCH),i386)
+    CPU_TYPE ?= i486
+    CPU_CFLAGS_i486 = -march=i486
+    CPU_CFLAGS_pentium4 = -march=pentium4
+    CPU_CFLAGS_geode = -march=geode -mmmx -m3dnow
+  endif
+  ifneq ($(findstring arm,$(ARCH)),)
+    CPU_TYPE ?= xscale
+    CPU_CFLAGS_arm920t = -march=armv4t -mtune=arm920t
+    CPU_CFLAGS_arm926ej-s = -march=armv5te -mtune=arm926ej-s
+    CPU_CFLAGS_arm1136j-s = -march=armv6 -mtune=arm1136j-s
+    CPU_CFLAGS_arm1176jzf-s = -march=armv6 -mtune=arm1176jzf-s
+    CPU_CFLAGS_cortex-a5 = -march=armv7-a -mtune=cortex-a5
+    CPU_CFLAGS_cortex-a7 = -march=armv7-a -mtune=cortex-a7
+    CPU_CFLAGS_cortex-a8 = -march=armv7-a -mtune=cortex-a8
+    CPU_CFLAGS_cortex-a9 = -march=armv7-a -mtune=cortex-a9
+    CPU_CFLAGS_cortex-a15 = -march=armv7-a -mtune=cortex-a15
+    CPU_CFLAGS_cortex-a53 = -march=armv8-a -mtune=cortex-a53
+    CPU_CFLAGS_fa526 = -march=armv4 -mtune=fa526
+    CPU_CFLAGS_mpcore = -march=armv6k -mtune=mpcore
+    CPU_CFLAGS_xscale = -march=armv5te -mtune=xscale
+    ifeq ($(CONFIG_SOFT_FLOAT),)
+      CPU_CFLAGS_neon = -mfpu=neon
+      CPU_CFLAGS_vfp = -mfpu=vfp
+      CPU_CFLAGS_vfpv3 = -mfpu=vfpv3-d16
+      CPU_CFLAGS_neon-vfpv4 = -mfpu=neon-vfpv4
+    endif
+  endif
+  ifeq ($(ARCH),powerpc)
+    CPU_CFLAGS_603e:=-mcpu=603e
+    CPU_CFLAGS_8540:=-mcpu=8540
+    CPU_CFLAGS_405:=-mcpu=405
+    CPU_CFLAGS_440:=-mcpu=440
+  endif
+  ifeq ($(ARCH),sparc)
+    CPU_TYPE = sparc
+    CPU_CFLAGS_ultrasparc = -mcpu=ultrasparc
+  endif
+  ifeq ($(ARCH),aarch64)
+    CPU_TYPE ?= armv8-a
+    CPU_CFLAGS_armv8-a = -mcpu=armv8-a
+  endif
+  ifeq ($(ARCH),arc)
+    CPU_TYPE ?= arc700
+    CPU_CFLAGS += -matomic
+    CPU_CFLAGS_arc700 = -marc700
+    CPU_CFLAGS_archs = -marchs
+  endif
+  DEFAULT_CFLAGS=$(strip $(CPU_CFLAGS) $(CPU_CFLAGS_$(CPU_TYPE)) $(CPU_CFLAGS_$(CPU_SUBTYPE)))
+endif
+
+define BuildTargets/DumpCurrent
+  .PHONY: dumpinfo
+  dumpinfo : export DESCRIPTION=$$(Target/Description)
+  dumpinfo:
+	@echo 'Target: $(TARGETID)'; \
+	 echo 'Target-Board: $(BOARD)'; \
+	 echo 'Target-Name: $(BOARDNAME)$(if $(SUBTARGETS),$(if $(SUBTARGET),))'; \
+	 echo 'Target-Path: $(subst $(TOPDIR)/,,$(PWD))'; \
+	 echo 'Target-Arch: $(ARCH)'; \
+	 echo 'Target-Arch-Packages: $(if $(ARCH_PACKAGES),$(ARCH_PACKAGES),$(BOARD))'; \
+	 echo 'Target-Features: $(FEATURES)'; \
+	 echo 'Target-Depends: $(DEPENDS)'; \
+	 echo 'Target-Optimization: $(if $(CFLAGS),$(CFLAGS),$(DEFAULT_CFLAGS))'; \
+	 echo 'CPU-Type: $(CPU_TYPE)$(if $(CPU_SUBTYPE),+$(CPU_SUBTYPE))'; \
+	 echo 'Linux-Version: $(LINUX_VERSION)'; \
+	 echo 'Linux-Release: $(LINUX_RELEASE)'; \
+	 echo 'Linux-Kernel-Arch: $(LINUX_KARCH)'; \
+	$(if $(SUBTARGET),,$(if $(DEFAULT_SUBTARGET), echo 'Default-Subtarget: $(DEFAULT_SUBTARGET)'; )) \
+	 echo 'Target-Description:'; \
+	 echo "$$$$DESCRIPTION"; \
+	 echo '@@'; \
+	 echo 'Default-Packages: $(DEFAULT_PACKAGES) $(call extra_packages,$(DEFAULT_PACKAGES))'; \
+	 $(DUMPINFO)
+	$(if $(SUBTARGET),,@$(foreach SUBTARGET,$(SUBTARGETS),$(SUBMAKE) -s DUMP=1 SUBTARGET=$(SUBTARGET); ))
+endef
+
+include $(INCLUDE_DIR)/kernel.mk
+ifeq ($(TARGET_BUILD),1)
+  include $(INCLUDE_DIR)/kernel-build.mk
+  BuildTarget?=$(BuildKernel)
+endif
+
+endif #__target_inc

+ 25 - 0
include/toolchain-build.mk

@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+override CONFIG_AUTOREBUILD=
+
+REAL_STAGING_DIR_HOST:=$(STAGING_DIR_HOST)
+STAGING_DIR_HOST:=$(TOOLCHAIN_DIR)
+BUILD_DIR_HOST:=$(BUILD_DIR_TOOLCHAIN)
+
+include $(INCLUDE_DIR)/host-build.mk
+
+HOST_STAMP_PREPARED=$(HOST_BUILD_DIR)/.prepared
+
+define FixupLibdir
+	if [ -d $(1)/lib64 -a \! -L $(1)/lib64 ]; then \
+		mkdir -p $(1)/lib; \
+		mv $(1)/lib64/* $(1)/lib/; \
+		rm -rf $(1)/lib64; \
+	fi
+	ln -sf lib $(1)/lib64
+endef

+ 239 - 0
include/toplevel.mk

@@ -0,0 +1,239 @@
+# Makefile for OpenWrt
+#
+# Copyright (C) 2007-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+RELEASE:=Designated Driver
+PREP_MK= OPENWRT_BUILD= QUIET=0
+
+export IS_TTY=$(shell tty -s && echo 1 || echo 0)
+
+include $(TOPDIR)/include/verbose.mk
+
+ifeq ($(SDK),1)
+  include $(TOPDIR)/include/version.mk
+else
+  REVISION:=$(shell $(TOPDIR)/scripts/getver.sh)
+endif
+
+HOSTCC ?= $(CC)
+export RELEASE
+export REVISION
+export GIT_CONFIG_PARAMETERS='core.autocrlf=false'
+export MAKE_JOBSERVER=$(filter --jobserver%,$(MAKEFLAGS))
+export SOURCE_DATE_EPOCH:=$(shell $(TOPDIR)/scripts/get_source_date_epoch.sh)
+
+# prevent perforce from messing with the patch utility
+unexport P4PORT P4USER P4CONFIG P4CLIENT
+
+# prevent user defaults for quilt from interfering
+unexport QUILT_PATCHES QUILT_PATCH_OPTS
+
+unexport C_INCLUDE_PATH CROSS_COMPILE ARCH
+
+# prevent distro default LPATH from interfering
+unexport LPATH
+
+# make sure that a predefined CFLAGS variable does not disturb packages
+export CFLAGS=
+export LDFLAGS=
+
+empty:=
+space:= $(empty) $(empty)
+path:=$(subst :,$(space),$(PATH))
+path:=$(filter-out .%,$(path))
+path:=$(subst $(space),:,$(path))
+export PATH:=$(path)
+
+unexport TAR_OPTIONS
+
+ifneq ($(shell $(HOSTCC) 2>&1 | grep clang),)
+  export HOSTCC_REAL?=$(HOSTCC)
+  export HOSTCC_WRAPPER:=$(TOPDIR)/scripts/clang-gcc-wrapper
+else
+  export HOSTCC_WRAPPER:=$(HOSTCC)
+endif
+
+ifeq ($(FORCE),)
+  .config scripts/config/conf scripts/config/mconf: staging_dir/host/.prereq-build
+endif
+
+SCAN_COOKIE?=$(shell echo $$$$)
+export SCAN_COOKIE
+
+SUBMAKE:=umask 022; $(SUBMAKE)
+
+ULIMIT_FIX=_limit=`ulimit -n`; [ "$$_limit" = "unlimited" -o "$$_limit" -ge 1024 ] || ulimit -n 1024;
+
+prepare-mk: FORCE ;
+
+ifdef SDK
+  IGNORE_PACKAGES = linux
+endif
+
+_ignore = $(foreach p,$(IGNORE_PACKAGES),--ignore $(p))
+
+prepare-tmpinfo: FORCE
+	@+$(MAKE) -r -s staging_dir/host/.prereq-build $(PREP_MK)
+	mkdir -p tmp/info
+	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_DEPTH=5 SCAN_EXTRA=""
+	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
+	for type in package target; do \
+		f=tmp/.$${type}info; t=tmp/.config-$${type}.in; \
+		[ "$$t" -nt "$$f" ] || ./scripts/metadata.pl $(_ignore) $${type}_config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
+	done
+	[ tmp/.config-feeds.in -nt tmp/.packagesubdirs ] || ./scripts/feeds feed_config > tmp/.config-feeds.in
+	./scripts/metadata.pl package_mk tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; }
+	./scripts/metadata.pl package_subdirs tmp/.packageinfo > tmp/.packagesubdirs || { rm -f tmp/.packagesubdirs; false; }
+	touch $(TOPDIR)/tmp/.build
+
+.config: ./scripts/config/conf $(if $(CONFIG_HAVE_DOT_CONFIG),,prepare-tmpinfo)
+	@+if [ \! -e .config ] || ! grep CONFIG_HAVE_DOT_CONFIG .config >/dev/null; then \
+		[ -e $(HOME)/.openwrt/defconfig ] && cp $(HOME)/.openwrt/defconfig .config; \
+		$(_SINGLE)$(NO_TRACE_MAKE) menuconfig $(PREP_MK); \
+	fi
+
+scripts/config/mconf:
+	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config all CC="$(HOSTCC_WRAPPER)"
+
+$(eval $(call rdep,scripts/config,scripts/config/mconf))
+
+scripts/config/conf:
+	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config conf CC="$(HOSTCC_WRAPPER)"
+
+config: scripts/config/conf prepare-tmpinfo FORCE
+	$< Config.in
+
+config-clean: FORCE
+	$(_SINGLE)$(NO_TRACE_MAKE) -C scripts/config clean
+
+defconfig: scripts/config/conf prepare-tmpinfo FORCE
+	touch .config
+	@if [ -e $(HOME)/.openwrt/defconfig ]; then cp $(HOME)/.openwrt/defconfig .config; fi
+	$< --defconfig=.config Config.in
+
+confdefault-y=allyes
+confdefault-m=allmod
+confdefault-n=allno
+confdefault:=$(confdefault-$(CONFDEFAULT))
+
+oldconfig: scripts/config/conf prepare-tmpinfo FORCE
+	$< --$(if $(confdefault),$(confdefault),old)config Config.in
+
+menuconfig: scripts/config/mconf prepare-tmpinfo FORCE
+	if [ \! -e .config -a -e $(HOME)/.openwrt/defconfig ]; then \
+		cp $(HOME)/.openwrt/defconfig .config; \
+	fi
+	$< Config.in
+
+prepare_kernel_conf: .config FORCE
+
+ifeq ($(wildcard staging_dir/host/bin/quilt),)
+  prepare_kernel_conf:
+	@+$(SUBMAKE) -r tools/quilt/install
+else
+  prepare_kernel_conf: ;
+endif
+
+kernel_oldconfig: prepare_kernel_conf
+	$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux oldconfig
+
+kernel_menuconfig: prepare_kernel_conf
+	$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux menuconfig
+
+kernel_nconfig: prepare_kernel_conf
+	$(_SINGLE)$(NO_TRACE_MAKE) -C target/linux nconfig
+
+staging_dir/host/.prereq-build: include/prereq-build.mk
+	mkdir -p tmp
+	rm -f tmp/.host.mk
+	@$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f $(TOPDIR)/include/prereq-build.mk prereq 2>/dev/null || { \
+		echo "Prerequisite check failed. Use FORCE=1 to override."; \
+		false; \
+	}
+  ifneq ($(realpath $(TOPDIR)/include/prepare.mk),)
+	@$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f $(TOPDIR)/include/prepare.mk prepare 2>/dev/null || { \
+		echo "Preparation failed."; \
+		false; \
+	}
+  endif
+	touch $@
+
+printdb: FORCE
+	@$(_SINGLE)$(NO_TRACE_MAKE) -p $@ V=99 DUMP_TARGET_DB=1 2>&1
+
+download: .config FORCE
+	@+$(SUBMAKE) tools/download
+	@+$(SUBMAKE) toolchain/download
+	@+$(SUBMAKE) package/download
+	@+$(SUBMAKE) target/download
+
+clean dirclean: .config
+	@+$(SUBMAKE) -r $@
+
+prereq:: prepare-tmpinfo .config
+	@+$(NO_TRACE_MAKE) -r -s $@
+
+WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(OPENWRT_VERBOSE))))
+
+ifeq ($(SDK),1)
+
+%::
+	@+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq
+	@./scripts/config/conf --defconfig=.config Config.in
+	@+$(ULIMIT_FIX) $(SUBMAKE) -r $@
+
+else
+
+%::
+	@+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq
+	@( \
+		cp .config tmp/.config; \
+		./scripts/config/conf --defconfig=tmp/.config -w tmp/.config Config.in > /dev/null 2>&1; \
+		if ./scripts/kconfig.pl '>' .config tmp/.config | grep -q CONFIG; then \
+			printf "$(_R)WARNING: your configuration is out of sync. Please run make menuconfig, oldconfig or defconfig!$(_N)\n" >&2; \
+		fi \
+	)
+	@+$(ULIMIT_FIX) $(SUBMAKE) -r $@ $(if $(WARN_PARALLEL_ERROR), || { \
+		printf "$(_R)Build failed - please re-run with -j1 to see the real error message$(_N)\n" >&2; \
+		false; \
+	} )
+
+endif
+
+# update all feeds, re-create index files, install symlinks
+package/symlinks:
+	./scripts/feeds update -a
+	./scripts/feeds install -a
+
+# re-create index files, install symlinks
+package/symlinks-install:
+	./scripts/feeds update -i
+	./scripts/feeds install -a
+
+# remove all symlinks, don't touch ./feeds
+package/symlinks-clean:
+	./scripts/feeds uninstall -a
+
+help:
+	cat README
+
+docs docs/compile: FORCE
+	@$(_SINGLE)$(SUBMAKE) -C docs compile
+
+docs/clean: FORCE
+	@$(_SINGLE)$(SUBMAKE) -C docs clean
+
+distclean:
+	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/openwrt-packages staging_dir tmp
+	@$(_SINGLE)$(SUBMAKE) -C scripts/config clean
+
+ifeq ($(findstring v,$(DEBUG)),)
+  .SILENT: symlinkclean clean dirclean distclean config-clean download help tmpinfo-clean .config scripts/config/mconf scripts/config/conf menuconfig staging_dir/host/.prereq-build tmp/.prereq-package prepare-tmpinfo
+endif
+.PHONY: help FORCE
+.NOTPARALLEL:
+

+ 16 - 0
include/uclibc++.mk

@@ -0,0 +1,16 @@
+ifndef DUMP
+  ifdef __package_mk
+    $(error uclibc++.mk must be included before package.mk)
+  endif
+endif
+
+PKG_PREPARED_DEPENDS += CONFIG_USE_UCLIBCXX
+CXX_DEPENDS = +USE_UCLIBCXX:uclibcxx +USE_LIBSTDCXX:libstdcpp
+
+ifneq ($(CONFIG_USE_UCLIBCXX),)
+ ifneq ($(CONFIG_CCACHE),)
+  TARGET_CXX_NOCACHE=g++-uc
+ else
+  TARGET_CXX=g++-uc
+ endif
+endif

+ 81 - 0
include/unpack.mk

@@ -0,0 +1,81 @@
+#
+# Copyright (C) 2006-2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# unpacking files with +s may break on some platforms. this typically emits error code 2
+ifneq ($(HOST_OS),Linux)
+  HOST_TAR:=trapret 2 $(TAR)
+else
+  HOST_TAR:=$(TAR)
+endif
+TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS)
+UNZIP_CMD=unzip -d $(1)/.. $(DL_DIR)/$(PKG_SOURCE)
+
+ifeq ($(PKG_SOURCE),)
+  PKG_UNPACK ?= true
+else
+
+ifeq ($(strip $(UNPACK_CMD)),)
+  ifeq ($(strip $(PKG_CAT)),)
+    # try to autodetect file type
+    EXT:=$(call ext,$(PKG_SOURCE))
+    EXT1:=$(EXT)
+
+    ifeq ($(filter gz tgz,$(EXT)),$(EXT))
+      EXT:=$(call ext,$(PKG_SOURCE:.$(EXT)=))
+      DECOMPRESS_CMD:=gzip -dc $(DL_DIR)/$(PKG_SOURCE) |
+    endif
+    ifeq ($(filter bzip2 bz2 bz tbz2 tbz,$(EXT)),$(EXT))
+      EXT:=$(call ext,$(PKG_SOURCE:.$(EXT)=))
+      DECOMPRESS_CMD:=bzcat $(DL_DIR)/$(PKG_SOURCE) |
+    endif
+    ifeq ($(filter xz txz,$(EXT)),$(EXT))
+      EXT:=$(call ext,$(PKG_SOURCE:.$(EXT)=))
+      DECOMPRESS_CMD:=xzcat $(DL_DIR)/$(PKG_SOURCE) |
+    endif
+    ifeq ($(filter tgz tbz tbz2 txz,$(EXT1)),$(EXT1))
+      EXT:=tar
+    endif
+    DECOMPRESS_CMD ?= cat $(DL_DIR)/$(PKG_SOURCE) |
+    ifeq ($(EXT),tar)
+      UNPACK_CMD=$(DECOMPRESS_CMD) $(TAR_CMD)
+    endif
+    ifeq ($(EXT),cpio)
+      UNPACK_CMD=$(DECOMPRESS_CMD) (cd $(1)/..; cpio -i -d)
+    endif
+    ifeq ($(EXT),zip)
+      UNPACK_CMD=$(UNZIP_CMD)
+    endif
+  endif
+
+  # compatibility code for packages that set PKG_CAT
+  ifeq ($(strip $(UNPACK_CMD)),)
+    # use existing PKG_CAT
+    UNPACK_CMD=$(PKG_CAT) $(DL_DIR)/$(PKG_SOURCE) | $(TAR_CMD)
+    ifeq ($(PKG_CAT),unzip)
+      UNPACK_CMD=$(UNZIP_CMD)
+    endif
+    # replace zcat with $(ZCAT), because some system don't support it properly
+    ifeq ($(PKG_CAT),zcat)
+      UNPACK_CMD=gzip -dc $(DL_DIR)/$(PKG_SOURCE) | $(TAR_CMD)
+    endif
+  endif
+  ifneq ($(strip $(CRLF_WORKAROUND)),)
+    CRLF_CMD := && find $(PKG_BUILD_DIR) -type f -print0 | xargs -0 perl -pi -e 's!\r$$$$!!g'
+  else
+    CRLF_CMD :=
+  endif
+endif
+
+ifdef PKG_BUILD_DIR
+  PKG_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(PKG_BUILD_DIR)) $(call CRLF_CMD,$(PKG_BUILD_DIR))
+endif
+ifdef HOST_BUILD_DIR
+  HOST_UNPACK ?= $(SH_FUNC) $(call UNPACK_CMD,$(HOST_BUILD_DIR)) $(call CRLF_CMD,$(HOST_BUILD_DIR))
+endif
+
+endif # PKG_SOURCE
+

+ 67 - 0
include/verbose.mk

@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+ifndef OPENWRT_VERBOSE
+  OPENWRT_VERBOSE:=
+endif
+ifeq ("$(origin V)", "command line")
+  OPENWRT_VERBOSE:=$(V)
+endif
+
+ifeq ($(OPENWRT_VERBOSE),1)
+  OPENWRT_VERBOSE:=w
+endif
+ifeq ($(OPENWRT_VERBOSE),99)
+  OPENWRT_VERBOSE:=s
+endif
+
+ifeq ($(NO_TRACE_MAKE),)
+NO_TRACE_MAKE := $(MAKE) V=s$(OPENWRT_VERBOSE)
+export NO_TRACE_MAKE
+endif
+
+ifeq ($(IS_TTY),1)
+  ifneq ($(strip $(NO_COLOR)),1)
+    _Y:=\\033[33m
+    _R:=\\033[31m
+    _N:=\\033[m
+  endif
+endif
+
+ifeq ($(findstring s,$(OPENWRT_VERBOSE)),)
+  define MESSAGE
+	printf "$(_Y)%s$(_N)\n" "$(1)" >&8
+  endef
+
+  define ERROR_MESSAGE
+	printf "$(_R)%s$(_N)\n" "$(1)" >&8
+  endef
+
+  ifeq ($(QUIET),1)
+    ifneq ($(CURDIR),$(TOPDIR))
+      _DIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR})
+    else
+      _DIR:=
+    endif
+    _NULL:=$(if $(MAKECMDGOALS),$(shell \
+		$(call MESSAGE, make[$(MAKELEVEL)]$(if $(_DIR), -C $(_DIR)) $(MAKECMDGOALS)); \
+    ))
+    SUBMAKE=$(MAKE)
+  else
+    SILENT:=>/dev/null $(if $(findstring w,$(OPENWRT_VERBOSE)),,2>&1)
+    export QUIET:=1
+    SUBMAKE=cmd() { $(SILENT) $(MAKE) -s $$* < /dev/null || { echo "make $$*: build failed. Please re-run make with -j1 V=s to see what's going on"; false; } } 8>&1 9>&2; cmd
+  endif
+
+  .SILENT: $(MAKECMDGOALS)
+else
+  SUBMAKE=$(MAKE) -w
+  define MESSAGE
+    printf "%s\n" "$(1)"
+  endef
+  ERROR_MESSAGE=$(MESSAGE)
+endif

+ 93 - 0
include/version.mk

@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2012-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+# Substituted by SDK, do not remove
+# REVISION:=x
+
+PKG_CONFIG_DEPENDS += \
+	CONFIG_VERSION_NUMBER \
+	CONFIG_VERSION_NICK \
+	CONFIG_VERSION_REPO \
+	CONFIG_VERSION_DIST \
+	CONFIG_VERSION_MANUFACTURER \
+	CONFIG_VERSION_MANUFACTURER_URL \
+	CONFIG_VERSION_PRODUCT \
+	CONFIG_VERSION_HWREV \
+
+qstrip_escape=$(subst ','\'',$(call qstrip,$(1)))
+#'
+
+VERSION_NUMBER:=$(call qstrip_escape,$(CONFIG_VERSION_NUMBER))
+VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),$(REVISION))
+
+VERSION_CODE:=$(call qstrip_escape,$(CONFIG_VERSION_NUMBER))
+VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),Bleeding Edge)
+
+VERSION_NICK:=$(call qstrip_escape,$(CONFIG_VERSION_NICK))
+VERSION_NICK:=$(if $(VERSION_NICK),$(VERSION_NICK),$(RELEASE))
+
+VERSION_REPO:=$(call qstrip_escape,$(CONFIG_VERSION_REPO))
+VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),http://downloads.openwrt.org/snapshots/trunk/%S/packages)
+
+VERSION_DIST:=$(call qstrip_escape,$(CONFIG_VERSION_DIST))
+VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),OpenWrt)
+
+VERSION_MANUFACTURER:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER))
+VERSION_MANUFACTURER:=$(if $(VERSION_MANUFACTURER),$(VERSION_MANUFACTURER),OpenWrt)
+
+VERSION_MANUFACTURER_URL:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER_URL))
+VERSION_MANUFACTURER_URL:=$(if $(VERSION_MANUFACTURER_URL),$(VERSION_MANUFACTURER_URL),http://www.openwrt.org/)
+
+VERSION_PRODUCT:=$(call qstrip_escape,$(CONFIG_VERSION_PRODUCT))
+VERSION_PRODUCT:=$(if $(VERSION_PRODUCT),$(VERSION_PRODUCT),Generic)
+
+VERSION_HWREV:=$(call qstrip_escape,$(CONFIG_VERSION_HWREV))
+VERSION_HWREV:=$(if $(VERSION_HWREV),$(VERSION_HWREV),v0)
+
+define taint2sym
+$(CONFIG_$(firstword $(subst :, ,$(subst +,,$(subst -,,$(1))))))
+endef
+
+define taint2name
+$(lastword $(subst :, ,$(1)))
+endef
+
+VERSION_TAINT_SPECS := \
+	-ALL_KMODS:no-all \
+	-IPV6:no-ipv6 \
+	+USE_GLIBC:glibc \
+	+USE_MKLIBS:mklibs \
+	+BUSYBOX_CUSTOM:busybox \
+	+OVERRIDE_PKGS:override \
+
+VERSION_TAINTS := $(strip $(foreach taint,$(VERSION_TAINT_SPECS), \
+	$(if $(findstring +,$(taint)), \
+		$(if $(call taint2sym,$(taint)),$(call taint2name,$(taint))), \
+		$(if $(call taint2sym,$(taint)),,$(call taint2name,$(taint))) \
+	)))
+
+PKG_CONFIG_DEPENDS += $(foreach taint,$(VERSION_TAINT_SPECS),$(call taint2sym,$(taint)))
+
+VERSION_SED:=$(SED) 's,%U,$(VERSION_REPO),g' \
+	-e 's,%V,$(VERSION_NUMBER),g' \
+	-e 's,%v,\L$(subst $(space),_,$(VERSION_NUMBER)),g' \
+	-e 's,%C,$(VERSION_CODE),g' \
+	-e 's,%c,\L$(subst $(space),_,$(VERSION_CODE)),g' \
+	-e 's,%N,$(VERSION_NICK),g' \
+	-e 's,%n,\L$(subst $(space),_,$(VERSION_NICK)),g' \
+	-e 's,%D,$(VERSION_DIST),g' \
+	-e 's,%d,\L$(subst $(space),_,$(VERSION_DIST)),g' \
+	-e 's,%R,$(REVISION),g' \
+	-e 's,%T,$(BOARD),g' \
+	-e 's,%S,$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic),g' \
+	-e 's,%t,$(VERSION_TAINTS),g' \
+	-e 's,%M,$(VERSION_MANUFACTURER),g' \
+	-e 's,%m,$(VERSION_MANUFACTURER_URL),g' \
+	-e 's,%P,$(VERSION_PRODUCT),g' \
+	-e 's,%h,$(VERSION_HWREV),g'
+
+VERSION_SED_SCRIPT:=$(subst '\'','\'\\\\\'\'',$(VERSION_SED))

+ 196 - 0
package/Makefile

@@ -0,0 +1,196 @@
+#
+# Copyright (C) 2006-2010 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+curdir:=package
+
+include $(INCLUDE_DIR)/feeds.mk
+
+-include $(TMP_DIR)/.packagedeps
+$(curdir)/builddirs:=$(sort $(package-) $(package-y) $(package-m))
+$(curdir)/builddirs-install:=.
+$(curdir)/builddirs-default:=. $(sort $(package-y) $(package-m))
+$(curdir)/builddirs-prereq:=. $(sort $(prereq-y) $(prereq-m))
+ifneq ($(IGNORE_ERRORS),)
+  package-y-filter := $(package-y)
+  package-m-filter := $(filter-out $(package-y),$(package-m))
+  package-n-filter := $(filter-out $(package-y) $(package-m),$(package-))
+  package-ignore-errors := $(filter n m y,$(IGNORE_ERRORS))
+  package-ignore-errors := $(if $(package-ignore-errors),$(package-ignore-errors),n m)
+  package-ignore-subdirs := $(sort $(foreach m,$(package-ignore-errors),$(package-$(m)-filter)))
+  $(curdir)/builddirs-ignore-download := $(package-ignore-subdirs)
+  $(curdir)/builddirs-ignore-compile := $(package-ignore-subdirs)
+  $(curdir)/builddirs-ignore-host-download := $(package-ignore-subdirs)
+  $(curdir)/builddirs-ignore-host-compile := $(package-ignore-subdirs)
+endif
+
+ifdef CONFIG_USE_MKLIBS
+  define mklibs
+	rm -rf $(TMP_DIR)/mklibs-progs $(TMP_DIR)/mklibs-out
+	# first find all programs and add them to the mklibs list
+	find $(STAGING_DIR_ROOT) -type f -perm /100 -exec \
+		file -r -N -F '' {} + | \
+		awk ' /executable.*dynamically/ { print $$1 }' > $(TMP_DIR)/mklibs-progs
+	# find all loadable objects that are not regular libraries and add them to the list as well
+	find $(STAGING_DIR_ROOT) -type f -name \*.so\* -exec \
+		file -r -N -F '' {} + | \
+		awk ' /shared object/ { print $$1 }' > $(TMP_DIR)/mklibs-libs
+	mkdir -p $(TMP_DIR)/mklibs-out
+	$(STAGING_DIR_HOST)/bin/mklibs -D \
+		-d $(TMP_DIR)/mklibs-out \
+		--sysroot $(STAGING_DIR_ROOT) \
+		`cat $(TMP_DIR)/mklibs-libs | sed 's:/*[^/]\+/*$$::' | uniq | sed 's:^$(STAGING_DIR_ROOT):-L :'` \
+		--ldlib $(patsubst $(STAGING_DIR_ROOT)/%,/%,$(firstword $(wildcard \
+			$(foreach name,ld-uClibc.so.* ld-linux.so.* ld-*.so ld-musl-*.so.*, \
+			  $(STAGING_DIR_ROOT)/lib/$(name) \
+			)))) \
+		--target $(REAL_GNU_TARGET_NAME) \
+		`cat $(TMP_DIR)/mklibs-progs $(TMP_DIR)/mklibs-libs` 2>&1
+	$(RSTRIP) $(TMP_DIR)/mklibs-out
+	for lib in `ls $(TMP_DIR)/mklibs-out/*.so.* 2>/dev/null`; do \
+		LIB="$${lib##*/}"; \
+		DEST="`ls "$(TARGET_DIR)/lib/$$LIB" "$(TARGET_DIR)/usr/lib/$$LIB" 2>/dev/null`"; \
+		[ -n "$$DEST" ] || continue; \
+		echo "Copying stripped library $$lib to $$DEST"; \
+		cp "$$lib" "$$DEST" || exit 1; \
+	done
+  endef
+endif
+
+# where to build (and put) .ipk packages
+OPKG:= \
+  IPKG_NO_SCRIPT=1 \
+  IPKG_TMP=$(TMP_DIR)/ipkg \
+  IPKG_INSTROOT=$(TARGET_DIR) \
+  IPKG_CONF_DIR=$(STAGING_DIR)/etc \
+  IPKG_OFFLINE_ROOT=$(TARGET_DIR) \
+  $(XARGS) $(STAGING_DIR_HOST)/bin/opkg \
+	--offline-root $(TARGET_DIR) \
+	--force-depends \
+	--force-overwrite \
+	--force-postinstall \
+	--force-maintainer \
+	--add-dest root:/ \
+	--add-arch all:100 \
+	--add-arch $(if $(ARCH_PACKAGES),$(ARCH_PACKAGES),$(BOARD)):200
+
+PACKAGE_INSTALL_FILES:= \
+	$(foreach pkg,$(sort $(package-y)), \
+		$(foreach variant, \
+			$(if $(strip $(package/$(pkg)/variants)), \
+				$(package/$(pkg)/variants), \
+				$(if $(package/$(pkg)/default-variant), \
+					$(package/$(pkg)/default-variant), \
+					default \
+				) \
+			), \
+			$(PKG_INFO_DIR)/$(lastword $(subst /,$(space),$(pkg))).$(variant).install \
+		) \
+	)
+
+$(curdir)/cleanup: $(TMP_DIR)/.build
+	rm -rf $(STAGING_DIR_ROOT)
+
+$(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/install
+	- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
+	rm -rf $(TARGET_DIR)
+	[ -d $(TARGET_DIR)/tmp ] || mkdir -p $(TARGET_DIR)/tmp
+	@$(FIND) `sed -e 's|.*|$(PACKAGE_DIR)$(if $(CONFIG_PER_FEED_REPO),/*)/&_*.ipk|' $(PACKAGE_INSTALL_FILES)` | sort -u | $(OPKG) install
+	@for file in $(PACKAGE_INSTALL_FILES); do \
+		[ -s $$file.flags ] || continue; \
+		for flag in `cat $$file.flags`; do \
+			$(OPKG) flag $$flag < $$file; \
+		done; \
+	done || true
+	@-$(MAKE) package/preconfig
+	@if [ -d $(TOPDIR)/files ]; then \
+		$(call file_copy,$(TOPDIR)/files/.,$(TARGET_DIR)); \
+	fi
+	@mkdir -p $(TARGET_DIR)/etc/rc.d
+	@( \
+		cd $(TARGET_DIR); \
+		for script in ./usr/lib/opkg/info/*.postinst; do \
+			IPKG_INSTROOT=$(TARGET_DIR) $$(which bash) $$script; \
+		done; \
+		for script in ./etc/init.d/*; do \
+			grep '#!/bin/sh /etc/rc.common' $$script >/dev/null || continue; \
+			IPKG_INSTROOT=$(TARGET_DIR) $$(which bash) ./etc/rc.common $$script enable; \
+		done || true \
+	)
+	$(if $(SOURCE_DATE_EPOCH),sed -i "s/Installed-Time: .*/Installed-Time: $(SOURCE_DATE_EPOCH)/" $(TARGET_DIR)/usr/lib/opkg/status)
+	@-find $(TARGET_DIR) -name CVS   | $(XARGS) rm -rf
+	@-find $(TARGET_DIR) -name .svn  | $(XARGS) rm -rf
+	@-find $(TARGET_DIR) -name .git  | $(XARGS) rm -rf
+	@-find $(TARGET_DIR) -name '.#*' | $(XARGS) rm -f
+	rm -f $(TARGET_DIR)/usr/lib/opkg/info/*.postinst*
+	rm -f $(TARGET_DIR)/usr/lib/opkg/info/*.prerm*
+	$(if $(CONFIG_CLEAN_IPKG),rm -rf $(TARGET_DIR)/usr/lib/opkg)
+	$(call mklibs)
+
+PASSOPT=""
+PASSARG=""
+ifndef CONFIG_OPKGSMIME_PASSPHRASE
+  ifneq ($(call qstrip,$(CONFIG_OPKGSMIME_PASSFILE)),)
+    PASSOPT="-passin"
+    PASSARG="file:$(call qstrip,$(CONFIG_OPKGSMIME_PASSFILE))"
+  endif
+endif
+
+PACKAGE_SUBDIRS=.
+ifneq ($(CONFIG_PER_FEED_REPO),)
+  ifneq ($(CONFIG_PER_FEED_REPO_ADD_DISABLED),)
+    PACKAGE_SUBDIRS=base kernel $(FEEDS_AVAILABLE)
+  else
+    PACKAGE_SUBDIRS=base kernel $(FEEDS_ENABLED)
+  endif
+endif
+
+$(curdir)/index: FORCE
+	@echo Generating package index...
+	@for d in $(PACKAGE_SUBDIRS); do ( \
+		mkdir -p $(PACKAGE_DIR)/$$d; \
+		cd $(PACKAGE_DIR)/$$d || continue; \
+		$(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages && \
+			gzip -9nc Packages > Packages.gz; \
+	); done
+ifdef CONFIG_SIGNED_PACKAGES
+	@echo Signing package index...
+	@for d in $(PACKAGE_SUBDIRS); do ( \
+		[ -d $(PACKAGE_DIR)/$$d ] && \
+			cd $(PACKAGE_DIR)/$$d || continue; \
+		$(STAGING_DIR_HOST)/bin/usign -S -m Packages -s $(BUILD_KEY); \
+	); done
+else
+ifeq ($(call qstrip,$(CONFIG_OPKGSMIME_KEY)),)
+	@echo Signing key has not been configured
+else
+ifeq ($(call qstrip,$(CONFIG_OPKGSMIME_CERT)),)
+	@echo Certificate has not been configured
+else
+	@echo Signing package index...
+	@for d in $(PACKAGE_SUBDIRS); do ( \
+		[ -d $(PACKAGE_DIR)/$$d ] && \
+			cd $(PACKAGE_DIR)/$$d || continue; \
+		openssl smime -binary -in Packages.gz \
+			-out Packages.sig -outform PEM -sign \
+			-signer $(CONFIG_OPKGSMIME_CERT) \
+			-inkey $(CONFIG_OPKGSMIME_KEY) \
+			$(PASSOPT) $(PASSARG); \
+	); done
+endif
+endif
+endif
+
+$(curdir)/preconfig:
+
+$(curdir)/flags-install:= -j1
+
+$(eval $(call stampfile,$(curdir),package,prereq,.config))
+$(eval $(call stampfile,$(curdir),package,cleanup,$(TMP_DIR)/.build))
+$(eval $(call stampfile,$(curdir),package,compile,$(TMP_DIR)/.build))
+$(eval $(call stampfile,$(curdir),package,install,$(TMP_DIR)/.build))
+
+$(eval $(call subdir,$(curdir)))

+ 190 - 0
package/base-files/Makefile

@@ -0,0 +1,190 @@
+#
+# Copyright (C) 2007-2016 OpenWrt.org
+# Copyright (C) 2010 Vertical Communications
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/version.mk
+
+PKG_NAME:=base-files
+PKG_RELEASE:=169
+
+PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
+PKG_BUILD_DEPENDS:=usign/host
+PKG_LICENSE:=GPL-2.0
+
+PKG_CONFIG_DEPENDS := CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE
+
+include $(INCLUDE_DIR)/package.mk
+
+ifneq ($(DUMP),1)
+  STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell $(SH_FUNC) echo $(CONFIG_TARGET_INIT_PATH) | md5s)
+  TARGET:=-$(BOARD)
+  ifneq ($(wildcard $(PLATFORM_DIR)/base-files-$(PROFILE) $(PLATFORM_SUBDIR)/base-files-$(PROFILE)),)
+    TARGET:=$(TARGET)-$(PROFILE)
+  endif
+endif
+
+define Package/base-files
+  SECTION:=base
+  CATEGORY:=Base system
+  DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +fstools
+  TITLE:=Base filesystem for OpenWrt
+  URL:=http://openwrt.org/
+  VERSION:=$(PKG_RELEASE)-$(REVISION)
+endef
+
+define Package/base-files/conffiles
+/etc/config/network
+/etc/config/system
+/etc/hosts
+/etc/inittab
+/etc/group
+/etc/passwd
+/etc/shadow
+/etc/profile
+/etc/protocols
+/etc/services
+/etc/shells
+/etc/sysctl.conf
+/etc/rc.local
+/etc/sysupgrade.conf
+/etc/config/
+/etc/dropbear/
+/etc/crontabs/
+/etc/sysctl.d/local.conf
+/etc/sysctl.d/
+/etc/iproute2/rt_tables
+$(call $(TARGET)/conffiles)
+endef
+
+define Package/base-files/description
+ This package contains a base filesystem and system scripts for OpenWrt.
+endef
+
+ifneq ($(CONFIG_PREINITOPT),)
+define ImageConfigOptions
+	mkdir -p $(1)/lib/preinit
+	echo 'pi_suppress_stderr="$(CONFIG_TARGET_PREINIT_SUPPRESS_STDERR)"' >$(1)/lib/preinit/00_preinit.conf
+	echo 'fs_failsafe_wait_timeout=$(if $(CONFIG_TARGET_PREINIT_TIMEOUT),$(CONFIG_TARGET_PREINIT_TIMEOUT),2)' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_init_path="$(TARGET_INIT_PATH)"' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_init_env=$(if $(CONFIG_TARGET_INIT_ENV),$(CONFIG_TARGET_INIT_ENV),"")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_init_cmd=$(if $(CONFIG_TARGET_INIT_CMD),$(CONFIG_TARGET_INIT_CMD),"/sbin/init")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_init_suppress_stderr="$(CONFIG_TARGET_INIT_SUPPRESS_STDERR)"' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_ifname=$(if $(CONFIG_TARGET_PREINIT_IFNAME),$(CONFIG_TARGET_PREINIT_IFNAME),"")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_ip=$(if $(CONFIG_TARGET_PREINIT_IP),$(CONFIG_TARGET_PREINIT_IP),"192.168.1.1")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_netmask=$(if $(CONFIG_TARGET_PREINIT_NETMASK),$(CONFIG_TARGET_PREINIT_NETMASK),"255.255.255.0")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_broadcast=$(if $(CONFIG_TARGET_PREINIT_BROADCAST),$(CONFIG_TARGET_PREINIT_BROADCAST),"192.168.1.255")' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_preinit_net_messages="$(CONFIG_TARGET_PREINIT_SHOW_NETMSG)"' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_preinit_no_failsafe_netmsg="$(CONFIG_TARGET_PREINIT_SUPPRESS_FAILSAFE_NETMSG)"' >>$(1)/lib/preinit/00_preinit.conf
+	echo 'pi_preinit_no_failsafe="$(CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE)"' >>$(1)/lib/preinit/00_preinit.conf
+endef
+endif
+
+define Build/Prepare
+	mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Compile/Default
+
+endef
+Build/Compile = $(Build/Compile/Default)
+
+ifdef CONFIG_SIGNED_PACKAGES
+  define Build/Configure
+	[ -s $(BUILD_KEY) -a -s $(BUILD_KEY).pub ] || \
+		$(STAGING_DIR_HOST)/bin/usign -G -s $(BUILD_KEY) -p $(BUILD_KEY).pub -c "Local build key"
+
+  endef
+
+  define Package/base-files/install-key
+	mkdir -p $(1)/etc/opkg/keys
+	$(CP) $(BUILD_KEY).pub $(1)/etc/opkg/keys/`$(STAGING_DIR_HOST)/bin/usign -F -p $(BUILD_KEY).pub`
+
+  endef
+endif
+
+define Package/base-files/install
+	$(CP) ./files/* $(1)/
+	$(Package/base-files/install-key)
+	if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
+		$(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
+	fi
+	if [ -d $(PLATFORM_DIR)/base-files/. ]; then \
+		$(CP) $(PLATFORM_DIR)/base-files/* $(1)/; \
+	fi
+	if [ -d $(PLATFORM_DIR)/base-files-$(PROFILE)/. ]; then \
+		$(CP) $(PLATFORM_DIR)/base-files-$(PROFILE)/* $(1)/; \
+	fi
+	if [ -d $(PLATFORM_DIR)/$(PROFILE)/base-files/. ]; then \
+		$(CP) $(PLATFORM_DIR)/$(PROFILE)/base-files/* $(1)/; \
+	fi
+	$(if $(filter-out $(PLATFORM_DIR),$(PLATFORM_SUBDIR)), \
+		if [ -d $(PLATFORM_SUBDIR)/base-files/. ]; then \
+			$(CP) $(PLATFORM_SUBDIR)/base-files/* $(1)/; \
+		fi; \
+		if [ -d $(PLATFORM_SUBDIR)/base-files-$(PROFILE)/. ]; then \
+			$(CP) $(PLATFORM_SUBDIR)/base-files-$(PROFILE)/* $(1)/; \
+		fi; \
+		if [ -d $(PLATFORM_SUBDIR)/$(PROFILE)/base-files/. ]; then \
+			$(CP) $(PLATFORM_SUBDIR)/$(PROFILE)/base-files/* $(1)/; \
+		fi \
+	)
+
+	$(VERSION_SED) \
+		$(1)/etc/banner \
+		$(1)/etc/openwrt_version
+
+	$(VERSION_SED_SCRIPT) \
+		$(1)/etc/openwrt_release \
+		$(1)/etc/device_info
+
+	$(SED) "s#%PATH%#$(TARGET_INIT_PATH)#g" \
+		$(1)/sbin/hotplug-call \
+		$(1)/etc/preinit \
+		$(1)/etc/profile
+
+	mkdir -p $(1)/CONTROL
+	mkdir -p $(1)/dev
+	mkdir -p $(1)/etc/crontabs
+	mkdir -p $(1)/etc/rc.d
+	mkdir -p $(1)/overlay
+	mkdir -p $(1)/lib/firmware
+	$(if $(LIB_SUFFIX),-$(LN) lib $(1)/lib$(LIB_SUFFIX))
+	mkdir -p $(1)/mnt
+	mkdir -p $(1)/proc
+	mkdir -p $(1)/tmp
+	mkdir -p $(1)/usr/lib
+	$(if $(LIB_SUFFIX),-$(LN) lib $(1)/usr/lib$(LIB_SUFFIX))
+	mkdir -p $(1)/usr/bin
+	mkdir -p $(1)/sys
+	mkdir -p $(1)/www
+	mkdir -p $(1)/root
+	$(LN) /proc/mounts $(1)/etc/mtab
+	rm -f $(1)/var
+	$(LN) /tmp $(1)/var
+	mkdir -p $(1)/etc
+	$(LN) /tmp/resolv.conf /tmp/fstab /tmp/TZ /tmp/localtime $(1)/etc/
+
+	chmod 0600 $(1)/etc/shadow
+	chmod 1777 $(1)/tmp
+
+	$(call ImageConfigOptions,$(1))
+	$(call Package/base-files/install-target,$(1))
+	for conffile in $(1)/etc/config/*; do \
+		if [ -f "$$$$conffile" ]; then \
+			grep "$$$${conffile##$(1)}" $(1)/CONTROL/conffiles || \
+				echo "$$$${conffile##$(1)}" >> $(1)/CONTROL/conffiles; \
+		fi \
+	done
+endef
+
+ifneq ($(DUMP),1)
+  -include $(PLATFORM_DIR)/base-files.mk
+endif
+
+$(eval $(call BuildPackage,base-files))

+ 14 - 0
package/base-files/files/bin/board_detect

@@ -0,0 +1,14 @@
+#!/bin/sh
+
+[ -d "/etc/board.d/" -a ! -f "/etc/board.json" ] && {
+	for a in `ls /etc/board.d/*`; do
+		[ -x $a ] || continue;
+		$(. $a)
+	done
+}
+
+[ -f "/etc/board.json" ] || return 1
+[ -f "/etc/config/network" ] || {
+	touch /etc/config/network
+	/bin/config_generate
+}

+ 362 - 0
package/base-files/files/bin/config_generate

@@ -0,0 +1,362 @@
+#!/bin/sh
+
+CFG=/etc/board.json
+
+. /usr/share/libubox/jshn.sh
+
+[ -f $CFG ] || exit 1
+
+generate_static_network() {
+	uci -q batch <<-EOF
+		delete network.loopback
+		set network.loopback='interface'
+		set network.loopback.ifname='lo'
+		set network.loopback.proto='static'
+		set network.loopback.ipaddr='127.0.0.1'
+		set network.loopback.netmask='255.0.0.0'
+		delete network.globals
+		set network.globals='globals'
+		set network.globals.ula_prefix='auto'
+	EOF
+
+	if json_is_a dsl object; then
+		json_select dsl
+			if json_is_a atmbridge object; then
+				json_select atmbridge
+					local vpi vci encaps payload
+					json_get_vars vpi vci encaps payload
+					uci -q batch <<-EOF
+						delete network.atm
+						set network.atm='atm-bridge'
+						set network.atm.vpi='$vpi'
+						set network.atm.vci='$vci'
+						set network.atm.encaps='$encaps'
+						set network.atm.payload='$payload'
+					EOF
+				json_select ..
+			fi
+
+			if json_is_a modem object; then
+				json_select modem
+					local type annex firmware tone xfer_mode
+					json_get_vars type annex firmware tone xfer_mode
+					uci -q batch <<-EOF
+						delete network.dsl
+						set network.dsl='dsl'
+						set network.dsl.annex='$annex'
+						set network.dsl.firmware='$firmware'
+						set network.dsl.tone='$tone'
+						set network.dsl.xfer_mode='$xfer_mode'
+					EOF
+				json_select ..
+			fi
+		json_select ..
+	fi
+}
+
+addr_offset=2
+generate_network() {
+	local ifname macaddr protocol type ipaddr netmask
+
+	json_select network
+		json_select "$1"
+			json_get_vars ifname macaddr protocol ipaddr netmask
+		json_select ..
+	json_select ..
+
+	[ -n "$ifname" ] || return
+
+	# force bridge for multi-interface devices (and lan)
+	case "$1:$ifname" in
+		*\ * | lan:*) type="bridge" ;;
+	esac
+
+	uci -q batch <<-EOF
+		delete network.$1
+		set network.$1='interface'
+		set network.$1.type='$type'
+		set network.$1.ifname='$ifname'
+		set network.$1.proto='none'
+	EOF
+
+	[ -n "$macaddr" ] && uci -q batch <<-EOF
+		delete network.$1_dev
+		set network.$1_dev='device'
+		set network.$1_dev.name='$ifname'
+		set network.$1_dev.macaddr='$macaddr'
+	EOF
+
+	case "$protocol" in
+		static)
+			local ipad
+			case "$1" in
+				lan) ipad=${ipaddr:-"192.168.1.1"} ;;
+				*) ipad=${ipaddr:-"192.168.$((addr_offset++)).1"} ;;
+			esac
+
+			netm=${netmask:-"255.255.255.0"}
+
+			uci -q batch <<-EOF
+				set network.$1.proto='static'
+				set network.$1.ipaddr='$ipad'
+				set network.$1.netmask='$netm'
+				set network.$1.ip6assign='60'
+			EOF
+		;;
+
+		dhcp)
+			# fixup IPv6 slave interface if parent is a bridge
+			[ "$type" = "bridge" ] && ifname="br-$1"
+
+			uci -q batch <<-EOF
+				set network.$1.proto='dhcp'
+				delete network.${1}6
+				set network.${1}6='interface'
+				set network.${1}6.ifname='$ifname'
+				set network.${1}6.proto='dhcpv6'
+			EOF
+		;;
+
+		pppoe)
+			# fixup IPv6 slave interface
+			ifname="pppoe-$1"
+
+			uci -q batch <<-EOF
+				set network.$1.proto='pppoe'
+				set network.$1.username='username'
+				set network.$1.password='password'
+				set network.$1.ipv6='auto'
+				delete network.${1}6
+				set network.${1}6='interface'
+				set network.${1}6.ifname='$ifname'
+				set network.${1}6.proto='dhcpv6'
+			EOF
+		;;
+	esac
+}
+
+generate_switch_vlans_ports() {
+	local switch="$1"
+	local port ports role roles num attr val
+
+	#
+	# autogenerate vlans
+	#
+
+	json_get_keys roles roles
+	json_select roles
+
+	for role in $roles; do
+		json_select "$role"
+			json_get_vars ports
+		json_select ..
+
+		uci -q batch <<-EOF
+			add network switch_vlan
+			set network.@switch_vlan[-1].device='$switch'
+			set network.@switch_vlan[-1].vlan='$role'
+			set network.@switch_vlan[-1].ports='$ports'
+		EOF
+	done
+
+	json_select ..
+
+
+	#
+	# write port specific settings
+	#
+
+	json_get_keys ports ports
+	json_select ports
+
+	for port in $ports; do
+		json_select "$port"
+			json_get_vars num
+
+			if json_is_a attr object; then
+				json_get_keys attr attr
+				json_select attr
+					uci -q batch <<-EOF
+						add network switch_port
+						set network.@switch_port[-1].device='$switch'
+						set network.@switch_port[-1].port=$num
+					EOF
+
+					for attr in $attr; do
+						json_get_var val "$attr"
+						uci -q set network.@switch_port[-1].$attr="$val"
+					done
+				json_select ..
+			fi
+		json_select ..
+	done
+
+	json_select ..
+}
+
+generate_switch() {
+	local key="$1"
+	local vlans
+
+	json_select switch
+	json_select "$key"
+	json_get_vars enable reset blinkrate cpu_port
+
+	uci -q batch <<-EOF
+		add network switch
+		set network.@switch[-1].name='$key'
+		set network.@switch[-1].reset='$reset'
+		set network.@switch[-1].enable_vlan='$enable'
+		set network.@switch[-1].blinkrate='$blinkrate'
+	EOF
+
+	generate_switch_vlans_ports "$1"
+
+	json_select ..
+	json_select ..
+}
+
+generate_rssimon() {
+	local key="$1"
+	local cfg="rssid_$key"
+	local refresh threshold
+
+	json_select rssimon
+	json_select "$key"
+	json_get_vars refresh threshold
+	json_select ..
+	json_select ..
+
+	uci -q batch <<-EOF
+		delete system.$cfg
+		set system.$cfg='rssid'
+		set system.$cfg.dev='$key'
+		set system.$cfg.refresh='$refresh'
+		set system.$cfg.threshold='$threshold'
+	EOF
+}
+
+generate_led() {
+	local key="$1"
+	local cfg="led_$key"
+
+	json_select led
+	json_select "$key"
+	json_get_vars name sysfs type trigger default
+
+	uci -q batch <<-EOF
+		delete system.$cfg
+		set system.$cfg='led'
+		set system.$cfg.name='$name'
+		set system.$cfg.sysfs='$sysfs'
+		set system.$cfg.trigger='$trigger'
+		set system.$cfg.default='$default'
+	EOF
+
+	case "$type" in
+		gpio)
+			local gpio inverted
+			json_get_vars gpio inverted
+			uci -q batch <<-EOF
+				set system.$cfg.trigger='gpio'
+				set system.$cfg.gpio='$gpio'
+				set system.$cfg.inverted='$inverted'
+			EOF
+		;;
+
+		netdev)
+			local device mode
+			json_get_vars device mode
+			uci -q batch <<-EOF
+				set system.$cfg.trigger='netdev'
+				set system.$cfg.mode='$mode'
+				set system.$cfg.dev='$device'
+			EOF
+		;;
+
+		usb)
+			local device
+			json_get_vars device
+			uci -q batch <<-EOF
+				set system.$cfg.trigger='usbdev'
+				set system.$cfg.interval='50'
+				set system.$cfg.dev='$device'
+			EOF
+		;;
+
+		rssi)
+			local iface minq maxq offset factor
+			json_get_vars iface minq maxq offset factor
+			uci -q batch <<-EOF
+				set system.$cfg.trigger='rssi'
+				set system.$cfg.iface='rssid_$iface'
+				set system.$cfg.minq='$minq'
+				set system.$cfg.maxq='$maxq'
+				set system.$cfg.offset='$offset'
+				set system.$cfg.factor='$factor'
+			EOF
+		;;
+
+		switch)
+			local port_mask speed_mask
+			json_get_vars port_mask speed_mask
+			uci -q batch <<-EOF
+				set system.$cfg.port_mask='$port_mask'
+				set system.$cfg.speed_mask='$speed_mask'
+			EOF
+		;;
+
+		timer|oneshot)
+			local delayon delayoff
+			json_get_vars delayon delayoff
+			uci -q batch <<-EOF
+				set system.$cfg.trigger='$type'
+				set system.$cfg.delayon='$delayon'
+				set system.$cfg.delayoff='$delayoff'
+			EOF
+		;;
+	esac
+
+	json_select ..
+	json_select ..
+}
+
+generate_gpioswitch() {
+	local cfg="$1"
+
+	json_select gpioswitch
+		json_select "$cfg"
+			local name pin default
+			json_get_vars name pin default
+			uci -q batch <<-EOF
+				delete system.$cfg
+				set system.$cfg='gpio_switch'
+				set system.$cfg.name='$name'
+				set system.$cfg.gpio_pin='$pin'
+				set system.$cfg.default='$default'
+			EOF
+		json_select ..
+	json_select ..
+}
+
+json_init
+json_load "$(cat ${CFG})"
+
+generate_static_network
+
+json_get_keys keys network
+for key in $keys; do generate_network $key; done
+
+json_get_keys keys switch
+for key in $keys; do generate_switch $key; done
+
+json_get_keys keys rssimon
+for key in $keys; do generate_rssimon $key; done
+
+json_get_keys keys gpioswitch
+for key in $keys; do generate_gpioswitch $key; done
+
+json_get_keys keys led
+for key in $keys; do generate_led $key; done
+
+uci commit

+ 71 - 0
package/base-files/files/bin/ipcalc.sh

@@ -0,0 +1,71 @@
+#!/bin/sh
+
+awk -f - $* <<EOF
+function bitcount(c) {
+	c=and(rshift(c, 1),0x55555555)+and(c,0x55555555)
+	c=and(rshift(c, 2),0x33333333)+and(c,0x33333333)
+	c=and(rshift(c, 4),0x0f0f0f0f)+and(c,0x0f0f0f0f)
+	c=and(rshift(c, 8),0x00ff00ff)+and(c,0x00ff00ff)
+	c=and(rshift(c,16),0x0000ffff)+and(c,0x0000ffff)
+	return c
+}
+
+function ip2int(ip) {
+	for (ret=0,n=split(ip,a,"\."),x=1;x<=n;x++) ret=or(lshift(ret,8),a[x])
+	return ret
+}
+
+function int2ip(ip,ret,x) {
+	ret=and(ip,255)
+	ip=rshift(ip,8)
+	for(;x<3;ret=and(ip,255)"."ret,ip=rshift(ip,8),x++);
+	return ret
+}
+
+function compl32(v) {
+	ret=xor(v, 0xffffffff)
+	return ret
+}
+
+BEGIN {
+	slpos=index(ARGV[1],"/")
+	if (slpos == 0) {
+		ipaddr=ip2int(ARGV[1])
+		dotpos=index(ARGV[2],".")
+		if (dotpos == 0)
+			netmask=compl32(2**(32-int(ARGV[2]))-1)
+		else
+			netmask=ip2int(ARGV[2])
+	} else {
+		ipaddr=ip2int(substr(ARGV[1],0,slpos-1))
+		netmask=compl32(2**(32-int(substr(ARGV[1],slpos+1)))-1)
+		ARGV[4]=ARGV[3]
+		ARGV[3]=ARGV[2]
+	}
+
+	network=and(ipaddr,netmask)
+	broadcast=or(network,compl32(netmask))
+
+	start=or(network,and(ip2int(ARGV[3]),compl32(netmask)))
+	limit=network+1
+	if (start<limit) start=limit
+
+	end=start+ARGV[4]
+	limit=or(network,compl32(netmask))-1
+	if (end>limit) end=limit
+
+	print "IP="int2ip(ipaddr)
+	print "NETMASK="int2ip(netmask)
+	print "BROADCAST="int2ip(broadcast)
+	print "NETWORK="int2ip(network)
+	print "PREFIX="32-bitcount(compl32(netmask))
+
+	# range calculations:
+	# ipcalc <ip> <netmask> <start> <num>
+
+	if (ARGC > 3) {
+		print "START="int2ip(start)
+		print "END="int2ip(end)
+	}
+}
+EOF

+ 13 - 0
package/base-files/files/etc/banner

@@ -0,0 +1,13 @@
+  _______                     ________        __
+ |       |.-----.-----.-----.|  |  |  |.----.|  |_
+ |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
+ |_______||   __|_____|__|__||________||__|  |____|
+          |__| W I R E L E S S   F R E E D O M
+ -----------------------------------------------------
+ DESIGNATED DRIVER (%C, %R)
+ -----------------------------------------------------
+  * 2 oz. Orange Juice         Combine all juices in a
+  * 2 oz. Pineapple Juice      tall glass filled with
+  * 2 oz. Grapefruit Juice     ice, stir well.
+  * 2 oz. Cranberry Juice
+ -----------------------------------------------------

+ 13 - 0
package/base-files/files/etc/banner.failsafe

@@ -0,0 +1,13 @@
+================= FAILSAFE MODE active ================
+special commands:
+* firstboot	     reset settings to factory defaults
+* mount_root	 mount root-partition with config files
+
+after mount_root:
+* passwd			 change root's password
+* /etc/config		    directory with config files
+
+for more help see:
+http://wiki.openwrt.org/doc/howto/generic.failsafe
+=======================================================
+

+ 17 - 0
package/base-files/files/etc/board.d/99-default_network

@@ -0,0 +1,17 @@
+#!/bin/sh
+#
+# Copyright (C) 2013-2015 OpenWrt.org
+#
+
+. /lib/functions/uci-defaults.sh
+
+board_config_update
+
+json_is_a network object && exit 0
+
+ucidef_set_interface_lan 'eth0'
+[ -d /sys/class/net/eth1 ] && ucidef_set_interface_wan 'eth1'
+
+board_config_flush
+
+exit 0

+ 12 - 0
package/base-files/files/etc/config/system

@@ -0,0 +1,12 @@
+config system
+	option hostname	OpenWrt
+	option timezone	UTC
+	option ttylogin	0
+
+config timeserver ntp
+	list server	0.openwrt.pool.ntp.org
+	list server	1.openwrt.pool.ntp.org
+	list server	2.openwrt.pool.ntp.org
+	list server	3.openwrt.pool.ntp.org
+	option enabled 1
+	option enable_server 0

+ 4 - 0
package/base-files/files/etc/device_info

@@ -0,0 +1,4 @@
+DEVICE_MANUFACTURER='%M'
+DEVICE_MANUFACTURER_URL='%m'
+DEVICE_PRODUCT='%P'
+DEVICE_REVISION='%h'

+ 4 - 0
package/base-files/files/etc/diag.sh

@@ -0,0 +1,4 @@
+#!/bin/sh
+# Copyright (C) 2006-2009 OpenWrt.org
+
+set_state() { :; }

+ 10 - 0
package/base-files/files/etc/group

@@ -0,0 +1,10 @@
+root:x:0:
+daemon:x:1:
+adm:x:4:
+mail:x:8:
+audio:x:29:
+www-data:x:33:
+ftp:x:55:
+users:x:100:
+network:x:101:
+nogroup:x:65534:

+ 5 - 0
package/base-files/files/etc/hosts

@@ -0,0 +1,5 @@
+127.0.0.1 localhost
+
+::1     localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters

+ 9 - 0
package/base-files/files/etc/hotplug.d/net/00-sysctl

@@ -0,0 +1,9 @@
+#!/bin/sh
+
+if [ "$ACTION" = add ]; then
+	for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
+		[ ! -f "$CONF" ] && continue;
+		sed -ne "/^[[:space:]]*net\..*\.$DEVICENAME\./p" "$CONF" | \
+			sysctl -e -p - | logger -t sysctl
+	done
+fi

+ 61 - 0
package/base-files/files/etc/init.d/boot

@@ -0,0 +1,61 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2011 OpenWrt.org
+
+START=10
+STOP=98
+
+uci_apply_defaults() {
+	. /lib/functions/system.sh
+
+	cd /etc/uci-defaults || return 0
+	files="$(ls)"
+	[ -z "$files" ] && return 0
+	mkdir -p /tmp/.uci
+	for file in $files; do
+		( . "./$(basename $file)" ) && rm -f "$file"
+	done
+	uci commit
+}
+
+boot() {
+	[ -f /proc/mounts ] || /sbin/mount_root
+	[ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc
+	[ -f /proc/net/vlan/config ] && vconfig set_name_type DEV_PLUS_VID_NO_PAD
+
+	mkdir -p /var/run
+	mkdir -p /var/log
+	mkdir -p /var/lock
+	mkdir -p /var/state
+	mkdir -p /var/tmp
+	mkdir -p /tmp/.uci
+	chmod 0700 /tmp/.uci
+	touch /var/log/wtmp
+	touch /var/log/lastlog
+	touch /tmp/resolv.conf.auto
+	ln -sf /tmp/resolv.conf.auto /tmp/resolv.conf
+	grep -q debugfs /proc/filesystems && /bin/mount -o noatime -t debugfs debugfs /sys/kernel/debug
+	[ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe
+
+	/sbin/kmodloader
+
+	# allow wifi modules time to settle
+	sleep 1
+
+	/sbin/wifi detect > /tmp/wireless.tmp
+	[ -s /tmp/wireless.tmp ] && {
+		cat /tmp/wireless.tmp >> /etc/config/wireless
+	}
+	rm -f /tmp/wireless.tmp
+
+	/bin/board_detect
+	uci_apply_defaults
+	
+	# temporary hack until configd exists
+	/sbin/reload_config
+
+	# create /dev/root if it doesn't exist
+	[ -e /dev/root -o -h /dev/root ] || {
+		rootdev=$(awk 'BEGIN { RS=" "; FS="="; } $1 == "root" { print $2 }' < /proc/cmdline)
+		[ -n "$rootdev" ] && ln -s "$rootdev" /dev/root
+	}
+}

+ 17 - 0
package/base-files/files/etc/init.d/done

@@ -0,0 +1,17 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=95
+boot() {
+	mount_root done
+	rm -f /sysupgrade.tgz
+
+	# process user commands
+	[ -f /etc/rc.local ] && {
+		sh /etc/rc.local
+	}
+
+	# set leds to normal state
+	. /etc/diag.sh
+	set_state done
+}

+ 42 - 0
package/base-files/files/etc/init.d/gpio_switch

@@ -0,0 +1,42 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2015 OpenWrt.org
+
+START=98
+STOP=10
+USE_PROCD=1
+
+
+load_gpio_switch()
+{
+	local name
+	local gpio_pin
+	local value
+
+	config_get gpio_pin "$1" gpio_pin
+	config_get name "$1" name
+	config_get value "$1" value 0
+
+	local gpio_path="/sys/class/gpio/gpio${gpio_pin}"
+	# export GPIO pin for access
+	[ -d "$gpio_path" ] || {
+		echo "$gpio_pin" >/sys/class/gpio/export
+		# we need to wait a bit until the GPIO appears
+		[ -d "$gpio_path" ] || sleep 1
+		echo out >"$gpio_path/direction"
+	}
+	# write 0 or 1 to the "value" field
+	{ [ "$value" = "0" ] && echo "0" || echo "1"; } >"$gpio_path/value"
+}
+
+service_triggers()
+{
+	procd_add_reload_trigger "system"
+}
+
+start_service()
+{
+	[ -e /sys/class/gpio/ ] && {
+		config_load system
+		config_foreach load_gpio_switch gpio_switch
+	}
+}

+ 109 - 0
package/base-files/files/etc/init.d/led

@@ -0,0 +1,109 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2008 OpenWrt.org
+
+START=96
+
+load_led() {
+	local name
+	local sysfs
+	local trigger
+	local dev
+	local mode
+	local default
+	local delayon
+	local delayoff
+	local interval
+
+	config_get sysfs $1 sysfs
+	config_get name $1 name "$sysfs"
+	config_get trigger $1 trigger "none"
+	config_get dev $1 dev
+	config_get mode $1 mode "link"
+	config_get_bool default $1 default "nil"
+	config_get delayon $1 delayon
+	config_get delayoff $1 delayoff
+	config_get interval $1 interval "50"
+	config_get port_state $1 port_state
+	config_get delay $1 delay "150"
+	config_get message $1 message ""
+	config_get gpio $1 gpio "0"
+	config_get inverted $1 inverted "0"
+
+	if [ "$trigger" = "rssi" ]; then
+		# handled by rssileds userspace process
+		return
+	fi
+
+	[ -e /sys/class/leds/${sysfs}/brightness ] && {
+		echo "setting up led ${name}"
+
+		[ "$default" = 0 ] &&
+			echo 0 >/sys/class/leds/${sysfs}/brightness
+
+		echo $trigger > /sys/class/leds/${sysfs}/trigger 2> /dev/null
+		ret="$?"
+
+		[ $default = 1 ] &&
+			cat /sys/class/leds/${sysfs}/max_brightness > /sys/class/leds/${sysfs}/brightness
+
+		[ $ret = 0 ] || {
+			echo >&2 "Skipping trigger '$trigger' for led '$name' due to missing kernel module"
+			return 1
+		}
+		case "$trigger" in
+		"netdev")
+			[ -n "$dev" ] && {
+				echo $dev > /sys/class/leds/${sysfs}/device_name
+				echo $mode > /sys/class/leds/${sysfs}/mode
+			}
+			;;
+
+		"timer")
+			[ -n "$delayon" ] && \
+				echo $delayon > /sys/class/leds/${sysfs}/delay_on
+			[ -n "$delayoff" ] && \
+				echo $delayoff > /sys/class/leds/${sysfs}/delay_off
+			;;
+
+		"usbdev")
+			[ -n "$dev" ] && {
+				echo $dev > /sys/class/leds/${sysfs}/device_name
+				echo $interval > /sys/class/leds/${sysfs}/activity_interval
+			}
+			;;
+
+		"port_state")
+			[ -n "$port_state" ] && \
+				echo $port_state > /sys/class/leds/${sysfs}/port_state
+			;;
+
+		"morse")
+			echo $message > /sys/class/leds/${sysfs}/message
+			echo $delay > /sys/class/leds/${sysfs}/delay
+			;;
+
+		"gpio")
+			echo $gpio > /sys/class/leds/${sysfs}/gpio
+			echo $inverted > /sys/class/leds/${sysfs}/inverted
+			;;
+
+		switch[0-9]*)
+			local port_mask speed_mask
+
+			config_get port_mask $1 port_mask
+			[ -n "$port_mask" ] && \
+				echo $port_mask > /sys/class/leds/${sysfs}/port_mask
+			config_get speed_mask $1 speed_mask
+			[ -n "$speed_mask" ] && \
+				echo $speed_mask > /sys/class/leds/${sysfs}/speed_mask
+			;;
+		esac
+	}
+}
+
+start() {
+	[ -e /sys/class/leds/ ] && {
+		config_load system
+		config_foreach load_led led
+	}
+}

+ 9 - 0
package/base-files/files/etc/init.d/sysctl

@@ -0,0 +1,9 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=11
+start() {
+	for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
+		[ -f "$CONF" ] && sysctl -p "$CONF" -e >&-
+	done
+}

+ 25 - 0
package/base-files/files/etc/init.d/sysfixtime

@@ -0,0 +1,25 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013-2014 OpenWrt.org
+
+START=00
+STOP=90
+
+RTC_DEV=/dev/rtc0
+HWCLOCK=/sbin/hwclock
+
+boot() {
+	start && exit 0
+
+	local curtime="$(date +%s)"
+	local maxtime="$(find /etc -type f -exec date -r {} +%s \; | sort -nr | head -n1)"
+	[ $curtime -lt $maxtime ] && date -s @$maxtime
+}
+
+start() {
+	[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -s -f $RTC_DEV
+}
+
+stop() {
+	[ -e "$RTC_DEV" ] && [ -e "$HWCLOCK" ] && $HWCLOCK -w -f $RTC_DEV && \
+		logger -t sysfixtime "saved '$(date)' to $RTC_DEV"
+}

Some files were not shown because too many files changed in this diff