Browse Source

Rebased from upstream / out of band repository.

RISCi_ATOM 5 years ago
parent
commit
dc0e62a006
100 changed files with 3132 additions and 1309 deletions
  1. 2 0
      Config.in
  2. 17 12
      Makefile
  3. 41 8
      config/Config-build.in
  4. 14 5
      config/Config-devel.in
  5. 26 3
      config/Config-images.in
  6. 87 13
      config/Config-kernel.in
  7. 42 0
      docs/ccs.md
  8. 0 1
      feeds.conf.default
  9. 3 3
      include/autotools.mk
  10. 4 4
      include/cmake.mk
  11. 7 1
      include/depends.mk
  12. 1 1
      include/device_table.txt
  13. 63 25
      include/download.mk
  14. 6 19
      include/feeds.mk
  15. 2 0
      include/hardened-ld-pie.specs
  16. 7 0
      include/hardening.mk
  17. 30 26
      include/host-build.mk
  18. 0 51
      include/host.mk
  19. 171 9
      include/image-commands.mk
  20. 57 20
      include/image.mk
  21. 7 10
      include/kernel-build.mk
  22. 16 36
      include/kernel-defaults.mk
  23. 19 4
      include/kernel-version.mk
  24. 105 64
      include/kernel.mk
  25. 56 15
      include/netfilter.mk
  26. 1 1
      include/nls.mk
  27. 14 4
      include/package-bin.mk
  28. 5 3
      include/package-defaults.mk
  29. 13 44
      include/package-dumpinfo.mk
  30. 22 28
      include/package-ipkg.mk
  31. 53 37
      include/package.mk
  32. 25 24
      include/prereq-build.mk
  33. 2 1
      include/prereq.mk
  34. 37 26
      include/quilt.mk
  35. 15 7
      include/rootfs.mk
  36. 1 1
      include/scan.awk
  37. 9 3
      include/scan.mk
  38. 26 0
      include/site/powerpc64
  39. 23 8
      include/subdir.mk
  40. 26 9
      include/target.mk
  41. 2 2
      include/toolchain-build.mk
  42. 34 16
      include/toplevel.mk
  43. 104 0
      include/u-boot.mk
  44. 19 0
      include/upstream.mk
  45. 11 11
      include/verbose.mk
  46. 41 42
      include/version.mk
  47. 9 7
      package/Makefile
  48. 43 18
      package/base-files/Makefile
  49. 36 24
      package/base-files/files/bin/config_generate
  50. 3 1
      package/base-files/files/etc/banner.failsafe
  51. 48 2
      package/base-files/files/etc/diag.sh
  52. 6 0
      package/base-files/files/etc/ethers
  53. 1 0
      package/base-files/files/etc/group
  54. 1 1
      package/base-files/files/etc/hotplug.d/net/00-sysctl
  55. 10 4
      package/base-files/files/etc/init.d/gpio_switch
  56. 8 2
      package/base-files/files/etc/init.d/led
  57. 30 11
      package/base-files/files/etc/init.d/sysctl
  58. 1 1
      package/base-files/files/etc/init.d/system
  59. 8 0
      package/base-files/files/etc/iproute2/ematch_map
  60. 1 2
      package/base-files/files/etc/openwrt_release
  61. 9 2
      package/base-files/files/etc/profile
  62. 1 1
      package/base-files/files/etc/rc.button/reset
  63. 17 10
      package/base-files/files/etc/rc.common
  64. 4 2
      package/base-files/files/etc/services
  65. 1 30
      package/base-files/files/etc/sysctl.conf
  66. 25 0
      package/base-files/files/etc/sysctl.d/10-default.conf
  67. 0 16
      package/base-files/files/etc/uci-defaults/11_migrate-sysctl
  68. 36 38
      package/base-files/files/lib/functions.sh
  69. 14 0
      package/base-files/files/lib/functions/leds.sh
  70. 14 3
      package/base-files/files/lib/functions/network.sh
  71. 39 13
      package/base-files/files/lib/functions/system.sh
  72. 131 193
      package/base-files/files/lib/functions/uci-defaults.sh
  73. 0 0
      package/base-files/files/lib/preinit/02_sysinfo
  74. 5 7
      package/base-files/files/lib/preinit/10_indicate_preinit
  75. 1 1
      package/base-files/files/lib/preinit/30_failsafe_wait
  76. 5 1
      package/base-files/files/lib/preinit/40_run_failsafe_hook
  77. 1 1
      package/base-files/files/lib/preinit/81_urandom_seed
  78. 7 4
      package/base-files/files/lib/preinit/99_10_failsafe_login
  79. 71 160
      package/base-files/files/lib/upgrade/common.sh
  80. 23 2
      package/base-files/files/lib/upgrade/fwtool.sh
  81. 332 0
      package/base-files/files/lib/upgrade/nand.sh
  82. 151 0
      package/base-files/files/lib/upgrade/stage2
  83. 192 61
      package/base-files/files/sbin/sysupgrade
  84. 1 1
      package/base-files/files/sbin/urandom_seed
  85. 3 2
      package/base-files/files/sbin/wifi
  86. 5 5
      package/base-files/files/usr/lib/os-release
  87. 1 1
      package/base-files/files/usr/libexec/login.sh
  88. 16 33
      package/base-files/image-config.in
  89. 51 0
      package/boot/arm-trusted-firmware-sunxi/Makefile
  90. 45 0
      package/boot/fconfig/Makefile
  91. 7 8
      package/boot/grub2/Makefile
  92. 71 0
      package/boot/grub2/patches/0008-Fix-packed-not-aligned-error-on-GCC-8.patch
  93. 40 0
      package/boot/grub2/patches/300-CVE-2015-8370.patch
  94. 75 0
      package/boot/grub2/patches/400-R_X86_64_PLT32.patch
  95. 1 8
      package/boot/kexec-tools/Config.in
  96. 64 16
      package/boot/kexec-tools/Makefile
  97. 7 0
      package/boot/kexec-tools/files/kdump.config
  98. 11 0
      package/boot/kexec-tools/files/kdump.defaults
  99. 184 0
      package/boot/kexec-tools/files/kdump.init
  100. 0 20
      package/boot/kexec-tools/patches/100-format_string_fix.patch

+ 2 - 0
Config.in

@@ -31,4 +31,6 @@ source "target/sdk/Config.in"
 
 source "target/toolchain/Config.in"
 
+source "target/ccsdisk/Config.in"
+
 source "tmp/.config-package.in"

+ 17 - 12
Makefile

@@ -1,4 +1,4 @@
-# Makefile for OpenWrt
+# Makefile for libreCMC
 #
 # Copyright (C) 2007 OpenWrt.org
 #
@@ -14,19 +14,21 @@ export TOPDIR LC_ALL LANG TZ
 
 empty:=
 space:= $(empty) $(empty)
-$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the LEDE directory must not include any spaces))
+$(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the libreCMC directory must not include any spaces))
 
 world:
 
-include $(TOPDIR)/include/host.mk
+export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
 
-ifneq ($(OPENWRT_BUILD),1)
+ifneq ($(LIBRECMC_BUILD),1)
   _SINGLE=export MAKEFLAGS=$(space);
 
-  override OPENWRT_BUILD=1
-  export OPENWRT_BUILD
+  override LIBRECMC_BUILD=1
+  export LIBRECMC_BUILD
   GREP_OPTIONS=
   export GREP_OPTIONS
+  CDPATH=
+  export CDPATH
   include $(TOPDIR)/include/debug.mk
   include $(TOPDIR)/include/depends.mk
   include $(TOPDIR)/include/toplevel.mk
@@ -39,8 +41,8 @@ else
   include tools/Makefile
   include toolchain/Makefile
 
-$(toolchain/stamp-install): $(tools/stamp-install)
-$(target/stamp-compile): $(toolchain/stamp-install) $(tools/stamp-install) $(BUILD_DIR)/.prepared
+$(toolchain/stamp-compile): $(tools/stamp-compile)
+$(target/stamp-compile): $(toolchain/stamp-compile) $(tools/stamp-compile) $(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)
@@ -55,7 +57,7 @@ clean: FORCE
 	rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages
 
 dirclean: clean
-	rm -rf $(STAGING_DIR_HOST) $(TOOLCHAIN_DIR) $(BUILD_DIR_HOST) $(BUILD_DIR_TOOLCHAIN)
+	rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
 	rm -rf $(TMP_DIR)
 
 ifndef DUMP_TARGET_DB
@@ -85,16 +87,19 @@ prereq: $(target/stamp-prereq) tmp/.prereq_packages
 	fi
 
 checksum: FORCE
-	$(call sha256sums,$(BIN_DIR))
+	$(call sha256sums,$(BIN_DIR),$(CONFIG_BUILDBOT))
+
+ccsdisk: $(target/ccsdisk/install)
 
 diffconfig: FORCE
 	mkdir -p $(BIN_DIR)
 	$(SCRIPT_DIR)/diffconfig.sh > $(BIN_DIR)/config.seed
 
-prepare: .config $(tools/stamp-install) $(toolchain/stamp-install)
+prepare: .config $(tools/stamp-compile) $(toolchain/stamp-compile)
+	$(_SINGLE)$(SUBMAKE) -r diffconfig
+
 world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
 	$(_SINGLE)$(SUBMAKE) -r package/index
-	$(_SINGLE)$(SUBMAKE) -r diffconfig
 	$(_SINGLE)$(SUBMAKE) -r checksum
 
 .PHONY: clean dirclean prereq prepare world package/symlinks package/symlinks-install package/symlinks-clean

+ 41 - 8
config/Config-build.in

@@ -9,15 +9,16 @@ menu "Global build settings"
 
 	config ALL_NONSHARED
 		bool "Select all target specific packages by default"
-		default ALL || BUILDBOT
+		select ALL_KMODS
+		default BUILDBOT
 
 	config ALL_KMODS
 		bool "Select all kernel module packages by default"
-		default ALL
 
 	config ALL
 		bool "Select all userspace packages by default"
-		default n
+		select ALL_KMODS
+		select ALL_NONSHARED
 
 	config BUILDBOT
 		bool "Set build defaults for automatic builds (e.g. via buildbot)"
@@ -40,7 +41,7 @@ menu "Global build settings"
 		default n
 
 	config BUILD_PATENTED
-		default y
+		default n
 		bool "Compile with support for patented functionality"
 		help
 		  When this option is disabled, software which provides patented functionality
@@ -52,7 +53,7 @@ menu "Global build settings"
 		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
+		  iconv and GNU gettext instead of the default libreCMC stubs. If uClibc is
 		  used, it is also built with locale support.
 
 	config SHADOW_PASSWORDS
@@ -67,6 +68,12 @@ menu "Global build settings"
 		  This removes all ipkg/opkg status data files from the target directory
 		  before building the root filesystem.
 
+	config INCLUDE_CONFIG
+		bool "Include build configuration in firmware" if DEVEL
+		default n
+		help
+		  If enabled, config.seed will be stored in /etc/build.config of firmware.
+
 	config COLLECT_KERNEL_DEBUG
 		bool
 		prompt "Collect kernel debug information"
@@ -77,10 +84,12 @@ menu "Global build settings"
 		  Useful for release builds, so that kernel issues can be debugged offline
 		  later.
 
-	comment "Kernel build options"
+	menu "Kernel build options"
 
 	source "config/Config-kernel.in"
 
+	endmenu
+
 	comment "Package build options"
 
 	config DEBUG
@@ -175,6 +184,22 @@ menu "Global build settings"
 		  this per package by adding PKG_CHECK_FORMAT_SECURITY:=0 in the package
 		  Makefile.
 
+	config PKG_ASLR_PIE
+		bool
+		prompt "User space ASLR PIE compilation"
+		select BUSYBOX_DEFAULT_PIE
+		default n
+		help
+		  Add -fPIC to CFLAGS and -specs=hardened-build-ld to LDFLAGS.
+		  This enables package build as Position Independent Executables (PIE)
+		  to protect against "return-to-text" attacks. This belongs to the
+		  feature of Address Space Layout Randomisation (ASLR), which is
+		  implemented by the kernel and the ELF loader by randomising the
+		  location of memory allocations. This makes memory addresses harder
+		  to predict when an attacker is attempting a memory-corruption exploit.
+		  You can disable this per package by adding PKG_ASLR_PIE:=0 in the package
+		  Makefile.
+
 	choice
 		prompt "User space Stack-Smashing Protection"
 		depends on USE_MUSL
@@ -185,11 +210,11 @@ menu "Global build settings"
 			bool "None"
 		config PKG_CC_STACKPROTECTOR_REGULAR
 			bool "Regular"
-			select SSP_SUPPORT if !USE_MUSL
+			select GCC_LIBSSP if !USE_MUSL
 			depends on KERNEL_CC_STACKPROTECTOR_REGULAR
 		config PKG_CC_STACKPROTECTOR_STRONG
 			bool "Strong"
-			select SSP_SUPPORT if !USE_MUSL
+			select GCC_LIBSSP if !USE_MUSL
 			depends on !GCC_VERSION_4_8
 			depends on KERNEL_CC_STACKPROTECTOR_STRONG
 	endchoice
@@ -209,6 +234,14 @@ menu "Global build settings"
 			bool "Strong"
 	endchoice
 
+	config  KERNEL_STACKPROTECTOR
+		bool
+		default KERNEL_CC_STACKPROTECTOR_REGULAR || KERNEL_CC_STACKPROTECTOR_STRONG
+
+	config  KERNEL_STACKPROTECTOR_STRONG
+		bool
+		default KERNEL_CC_STACKPROTECTOR_STRONG
+
 	choice
 		prompt "Enable buffer-overflows detection (FORTIFY_SOURCE)"
 		default PKG_FORTIFY_SOURCE_1

+ 14 - 5
config/Config-devel.in

@@ -27,7 +27,7 @@ menuconfig DEVEL
 		  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.
+		  setting a path outside the libreCMC tree downloads will be saved.
 
 	config LOCALMIRROR
 		string "Local mirror for source packages" if DEVEL
@@ -39,6 +39,14 @@ menuconfig DEVEL
 		help
 		  Automatically rebuild packages when their files change.
 
+	config AUTOREMOVE
+		bool "Automatic removal of build directories" if DEVEL
+		default n
+		help
+		  Automatically delete build directories after make target completed.
+		  This allows you to symlink build_dir into a scratch location, e.g. a ramdisk,
+		  which does not have enough space to keep a complete build_dir.
+
 	config BUILD_SUFFIX
 		string "Build suffix to append to the target BUILD_DIR variable" if DEVEL
 		default ""
@@ -82,13 +90,14 @@ menuconfig DEVEL
 		  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
+	config KERNEL_GIT_REF
+		string "Enter git ref at which to checkout" 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.
+		  Enter the git ref at which to checkout the git repository
+		  after it is cloned, and before making it a tar-ball.
+		  It can be a git hash or a branch name.
 		  If unused, the clone's repository HEAD will be checked-out.
 
 	config BUILD_LOG

+ 26 - 3
config/Config-images.in

@@ -17,6 +17,7 @@ menu "Target Images"
 			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ar71xx
 			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_ramips
 			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_apm821xx
+			default TARGET_INITRAMFS_COMPRESSION_LZMA if TARGET_mpc85xx
 			default TARGET_INITRAMFS_COMPRESSION_NONE
 			depends on TARGET_ROOTFS_INITRAMFS
 			help
@@ -51,6 +52,13 @@ menu "Target Images"
 			help
 			  Kernel uses specified external cpio as INITRAMFS_SOURCE.
 
+		config TARGET_INITRAMFS_FORCE
+                        bool "Force"
+                        depends on TARGET_ROOTFS_INITRAMFS
+                        default n
+                        help
+                          Ignore the initramfs passed by the bootloader.
+
 	comment "Root filesystem archives"
 
 	config TARGET_ROOTFS_CPIOGZ
@@ -141,6 +149,7 @@ menu "Target Images"
 			int "Block size (in KiB)"
 			depends on TARGET_ROOTFS_SQUASHFS
 			default 64 if LOW_MEMORY_FOOTPRINT
+			default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
 			default 256
 
 	menuconfig TARGET_ROOTFS_UBIFS
@@ -203,6 +212,11 @@ menu "Target Images"
 		default 38400 if TARGET_x86_generic
 		default 115200
 
+	config GRUB_FLOWCONTROL
+		bool "Use RTE/CTS on serial console"
+		depends on GRUB_SERIAL != ""
+		default n
+
 	config GRUB_BOOTOPTS
 		string "Extra kernel boot options"
 		depends on GRUB_IMAGES
@@ -217,6 +231,14 @@ menu "Target Images"
 		help
 		  If you don't know, 5 seconds is a reasonable default.
 
+	config GRUB_TITLE
+		string "Title for the menu entry in GRUB"
+		depends on GRUB_IMAGES
+		default "libreCMC"
+		help
+		  This is the title of the GRUB menu entry.
+		  If unspecified, it defaults to libreCMC.
+
 	config VDI_IMAGES
 		bool "Build VirtualBox image files (VDI)"
 		depends on TARGET_x86 || TARGET_x86_64
@@ -237,7 +259,7 @@ menu "Target Images"
 
 	config TARGET_IMAGES_GZIP
 		bool "GZip images"
-		depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS
+		depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS || TARGET_x86
 		default y
 
 	comment "Image Options"
@@ -246,12 +268,13 @@ menu "Target Images"
 
 	config TARGET_KERNEL_PARTSIZE
 		int "Kernel partition size (in MB)"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || USES_BOOT_PART
+		default 8 if TARGET_apm821xx_sata
 		default 16
 
 	config TARGET_ROOTFS_PARTSIZE
 		int "Root filesystem partition size (in MB)"
-		depends on GRUB_IMAGES || TARGET_ROOTFS_EXT4FS || TARGET_rb532 || TARGET_mvebu || TARGET_uml
+		depends on GRUB_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_rb532 || TARGET_sunxi || TARGET_uml
 		default 256
 		help
 		  Select the root filesystem partition size.

+ 87 - 13
config/Config-kernel.in

@@ -31,7 +31,7 @@ config KERNEL_CRASHLOG
 
 config KERNEL_SWAP
 	bool "Support for paging of anonymous memory (swap)"
-	default y
+	default y if !SMALL_FLASH
 
 config KERNEL_DEBUG_FS
 	bool "Compile the kernel with debug filesystem enabled"
@@ -42,15 +42,20 @@ config KERNEL_DEBUG_FS
 	  write to these files. Many common debugging facilities, such as
 	  ftrace, require the existence of debugfs.
 
+config KERNEL_MIPS_FPU_EMULATOR
+	bool "Compile the kernel with MIPS FPU Emulator"
+	default y if TARGET_pistachio
+	depends on (mips || mipsel || mips64 || mips64el)
+
 config KERNEL_ARM_PMU
 	bool
 	default n
-	depends on (arm || arm64)
+	depends on (arm || aarch64)
 
 config KERNEL_PERF_EVENTS
-	bool
+	bool "Compile the kernel with performance events and counters"
 	default n
-	select KERNEL_ARM_PMU if (arm || arm64)
+	select KERNEL_ARM_PMU if (arm || aarch64)
 
 config KERNEL_PROFILING
 	bool "Compile the kernel with profiling enabled"
@@ -60,6 +65,27 @@ config KERNEL_PROFILING
 	  Enable the extended profiling support mechanisms used by profilers such
 	  as OProfile.
 
+config KERNEL_TASKSTATS
+	bool "Compile the kernel with task resource/io statistics and accounting"
+	default n
+	help
+	  Enable the collection and publishing of task/io statistics and
+	  accounting.  Enable this option to enable i/o monitoring in system
+	  monitors.
+
+if KERNEL_TASKSTATS
+
+	config KERNEL_TASK_DELAY_ACCT
+		def_bool y
+
+	config KERNEL_TASK_IO_ACCOUNTING
+		def_bool y
+
+	config KERNEL_TASK_XACCT
+		def_bool y
+
+endif
+
 config KERNEL_KALLSYMS
 	bool "Compile the kernel with symbol table information"
 	default y if !SMALL_FLASH
@@ -107,7 +133,7 @@ config KERNEL_DEBUG_KERNEL
 
 config KERNEL_DEBUG_INFO
 	bool "Compile the kernel with debug information"
-	default y
+	default y if !SMALL_FLASH
 	select KERNEL_DEBUG_KERNEL
 	help
 	  This will compile your kernel and modules with debug information.
@@ -170,10 +196,6 @@ 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
@@ -204,7 +226,7 @@ config KERNEL_COREDUMP
 config KERNEL_ELF_CORE
 	bool "Enable process core dump support"
 	select KERNEL_COREDUMP
-	default y
+	default y if !SMALL_FLASH
 
 config KERNEL_PROVE_LOCKING
 	bool "Enable kernel lock checking"
@@ -235,6 +257,16 @@ config KERNEL_RELAY
 config KERNEL_KEXEC
 	bool "Enable kexec support"
 
+config KERNEL_PROC_VMCORE
+	bool
+
+config KERNEL_CRASH_DUMP
+	depends on i386 || x86_64 || arm || armeb
+	select KERNEL_KEXEC
+	select KERNEL_PROC_VMCORE
+	bool "Enable support for kexec crashdump"
+	default y
+
 config USE_RFKILL
 	bool "Enable rfkill support"
 	default RFKILL_SUPPORT
@@ -248,7 +280,7 @@ config KERNEL_DEVTMPFS
 	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
+	  devices nodes for all registered devices to simplify boot, but leaves more
 	  complex tasks to userspace (e.g. udev).
 
 if KERNEL_DEVTMPFS
@@ -601,6 +633,17 @@ config KERNEL_SECCOMP
 		help
 		  Build kernel with support for seccomp.
 
+#
+# IPv4 configuration
+#
+
+config KERNEL_IP_MROUTE
+	bool "Enable IPv4 multicast routing"
+	default y
+	help
+	  Multicast routing requires a multicast routing daemon in
+	  addition to kernel support.
+
 #
 # IPv6 configuration
 #
@@ -617,7 +660,11 @@ if KERNEL_IPV6
 		def_bool y
 
 	config KERNEL_IPV6_MROUTE
-		def_bool y
+		bool "Enable IPv6 multicast routing"
+		default y
+		help
+		  Multicast routing requires a multicast routing daemon in
+		  addition to kernel support.
 
 	config KERNEL_IPV6_PIMSM_V2
 		def_bool n
@@ -666,7 +713,7 @@ menu "Filesystem ACL and attr support options"
 		  Make using ACLs (e.g. POSIX ACL, NFSv4 ACL) the default
 		  for kernel and packages, except tmpfs, flash filesystems,
 		  and old NFS.  Also enable userspace extended attribute support
-		  by default.  (OpenWrt already has an expection it will be
+		  by default.  (libreCMC already has an expection it will be
 		  present in the kernel).
 
 	config KERNEL_FS_POSIX_ACL
@@ -759,3 +806,30 @@ config KERNEL_DEVKMEM
 	  Say Y here if you want to support the /dev/kmem device. The
 	  /dev/kmem device is rarely used, but can be used for certain
 	  kind of kernel debugging operations.
+
+config KERNEL_SQUASHFS_FRAGMENT_CACHE_SIZE
+	int "Number of squashfs fragments cached"
+	default 2 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT)
+	default 3
+
+#
+# compile optimiziation setting
+#
+choice
+	prompt "Compiler optimization level"
+	default KERNEL_CC_OPTIMIZE_FOR_SIZE if SMALL_FLASH
+
+config KERNEL_CC_OPTIMIZE_FOR_PERFORMANCE
+	bool "Optimize for performance"
+	help
+	  This is the default optimization level for the kernel, building
+	  with the "-O2" compiler flag for best performance and most
+	  helpful compile-time warnings.
+
+config KERNEL_CC_OPTIMIZE_FOR_SIZE
+	bool "Optimize for size"
+	help
+	  Enabling this option will pass "-Os" instead of "-O2" to
+	  your compiler resulting in a smaller kernel.
+
+endchoice

+ 42 - 0
docs/ccs.md

@@ -0,0 +1,42 @@
+# CCS (Complete Corresponding Source) Requirements
+
+As a Free Software project, libreCMC works to go above and beyond its license
+obligations to be a good neighbor and to promote the ideals of Free
+Software. The project was founded on the idea that everyone should have the
+*freedom* to control the hardware they own, which means being able to fully
+control what it does and what runs on it. To ensure that everyone who uses
+libreCMC continues to have this freedom, a mechanism was added to the build
+system [1] to generate a CCS disk which OEMs and others would be able to
+distribute with devices shipping libreCMC. This was done to ease compliance and
+to push the idea that sources should be provided with a device at the time of
+sale. Shipping a CCS disk ensures that second hand sales of the device can be
+compliant if the disk is handed off with the device.
+
+
+## `make ccsdisk`
+
+A new target was created to build a CCS disk based upon the option of using an
+external repository or to use a local checkout. As it stands, this includes
+everything except for u-boot sources for a given target. In the near future, the
+libreCMC project will start including versions of u-boot for all officially
+supported targets and, going forward, make this a requirement for official
+hardware in libreCMC.
+
+
+## How to use
+
+There are two ways to use CCS disk : enable "Build the libreCMC CCS Disk" during
+image configuration or run `make ccsdisk` after all desired firmware images have
+been built. Since u-boot for a given target most likely is missing, it's
+important that the sources for u-boot be packaged and included on the disk. To
+do this, make sure they are included in `target/ccsdisk/files` with proper
+documentation. To make things a little bit easier, enabling the toolchain option
+during image configuration and using the toolchain to build u-boot will make
+things go much easier if it can be done.
+
+
+
+[1] libreCMC is a fork of OpenWrt, which both use a fork of
+[Buildroot](https://buildroot.org). Buildroot is a build system which helps to
+make it easier to create firmware images for "embedded" devices.
+

+ 0 - 1
feeds.conf.default

@@ -1 +0,0 @@
-src-git packages https://gogs.librecmc.org/libreCMC/package-feed.git;v1.4

+ 3 - 3
include/autotools.mk

@@ -75,7 +75,7 @@ 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)))
+    $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR_HOSTPKG)/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS)))
 endef
 
 define patch_libtool_target
@@ -105,14 +105,14 @@ ifneq ($(filter patch-libtool,$(PKG_FIXUP)),)
 endif
 
 ifneq ($(filter libtool,$(PKG_FIXUP)),)
-  PKG_BUILD_DEPENDS += libtool libintl libiconv
+  PKG_BUILD_DEPENDS += libtool gettext 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
+  PKG_BUILD_DEPENDS += libtool gettext libiconv
  ifeq ($(filter no-autoreconf,$(PKG_FIXUP)),)
   Hooks/Configure/Pre += autoreconf_target
  endif

+ 4 - 4
include/cmake.mk

@@ -2,13 +2,13 @@ cmake_bool = $(patsubst %,-D%:BOOL=$(if $($(1)),ON,OFF),$(2))
 
 PKG_INSTALL:=1
 
-ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+ifneq ($(findstring c,$(LIBRECMC_VERBOSE)),)
   MAKE_FLAGS+=VERBOSE=1
 endif
 
 CMAKE_BINARY_DIR = $(PKG_BUILD_DIR)$(if $(CMAKE_BINARY_SUBDIR),/$(CMAKE_BINARY_SUBDIR))
-CMAKE_SOURCE_DIR = $(PKG_BUILD_DIR)
-HOST_CMAKE_SOURCE_DIR = $(HOST_BUILD_DIR)
+CMAKE_SOURCE_DIR = $(PKG_BUILD_DIR)$(if $(CMAKE_SOURCE_SUBDIR),/$(CMAKE_SOURCE_SUBDIR))
+HOST_CMAKE_SOURCE_DIR = $(HOST_BUILD_DIR)$(if $(CMAKE_SOURCE_SUBDIR),/$(CMAKE_SOURCE_SUBDIR))
 MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .)
 
 ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
@@ -34,7 +34,7 @@ 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_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOSTPKG);$(STAGING_DIR_HOST)
 CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
 
 define Build/Configure/Default

+ 7 - 1
include/depends.mk

@@ -11,7 +11,7 @@
 #	3: tempfile for file listings
 #	4: find options
 
-DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp"
+DEP_FINDPARAMS := -x "*/.svn*" -x ".*" -x "*:*" -x "*\!*" -x "* *" -x "*\\\#*" -x "*/.*_check" -x "*/.*.swp" -x "*/.pkgdir*"
 
 find_md5=find $(wildcard $(1)) -type f $(patsubst -x,-and -not -path,$(DEP_FINDPARAMS) $(2)) | mkhash md5
 
@@ -20,6 +20,7 @@ define rdep
   .SILENT: $(2)_check
 
   $(2): $(2)_check
+  check-depends: $(2)_check
 
 ifneq ($(wildcard $(2)),)
   $(2)_check::
@@ -46,3 +47,8 @@ endif
 
 endef
 
+ifeq ($(filter .%,$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),$(MAKECMDGOALS),x))
+  define rdep
+    $(2): $(2)_check
+  endef
+endif

+ 1 - 1
include/device_table.txt

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

+ 63 - 25
include/download.mk

@@ -6,8 +6,9 @@
 # See /LICENSE for more information.
 #
 
-PROJECT_GIT = https://gogs.librecmc.org/OWEALs
-OPENWRT_GIT = $(PROJECT_GIT)
+PROJECT_GIT = https://git.openwrt.org
+
+LIBRECMC_GIT = $(PROJECT_GIT)
 LEDE_GIT = $(PROJECT_GIT)
 
 ifdef PKG_SOURCE_VERSION
@@ -18,17 +19,23 @@ endif
 
 DOWNLOAD_RDEP=$(STAMP_PREPARED) $(HOST_STAMP_PREPARED)
 
+define dl_method_git
+$(if $(filter https://github.com/% git://github.com/%,$(1)),github_archive,git)
+endef
+
 # Try to guess the download method from the URL
 define dl_method
 $(strip \
-  $(if $(2),$(2), \
-    $(if $(filter @APACHE/% @GNOME/% @GNU/% @KERNEL_LIBRE/% @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 \
+  $(if $(filter git,$(2)),$(call dl_method_git,$(1),$(2)),
+    $(if $(2),$(2), \
+      $(if $(filter @APACHE/% @GNOME/% @GNU/% @KERNEL_LIBRE/% @KERNEL/% @SAVANNAH/% ftp://% http://% https://% file://%,$(1)),default, \
+        $(if $(filter git://%,$(1)),$(call dl_method_git,$(1),$(2)), \
+          $(if $(filter svn://%,$(1)),svn, \
+            $(if $(filter cvs://%,$(1)),cvs, \
+              $(if $(filter hg://%,$(1)),hg, \
+                $(if $(filter sftp://%,$(1)),bzr, \
+                  unknown \
+                ) \
               ) \
             ) \
           ) \
@@ -55,6 +62,10 @@ ifdef CHECK
 check_escape=$(subst ','\'',$(1))
 #')
 
+# $(1): suffix of the F_, C_ variables, e.g. hash_deprecated, hash_mismatch, etc.
+# $(2): filename
+# $(3): expected hash value
+# $(4): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 check_warn_nofix = $(info $(shell printf "$(_R)WARNING: %s$(_N)" '$(call check_escape,$(call C_$(1),$(2),$(3),$(4)))'))
 ifndef FIXUP
   check_warn = $(check_warn_nofix)
@@ -70,11 +81,17 @@ F_hash_mismatch = $(F_hash_deprecated)
 F_hash_missing = $(SCRIPT_DIR)/fixup-makefile.pl $(CURDIR)/Makefile add-hash $(3) $(call gen_sha256sum,$(1))
 endif
 
+# $(1): filename
+# $(2): expected hash value
+# $(3): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 C_download_missing = $(1) is missing, please run make download before re-running this check
 C_hash_mismatch = $(3) does not match $(1) hash $(call gen_sha256sum,$(1))
 C_hash_deprecated = $(3) uses deprecated hash, set to $(call gen_sha256sum,$(1))
 C_hash_missing = $(3) is missing, set to $(call gen_sha256sum,$(1))
 
+# $(1): filename
+# $(2): expected hash value
+# $(3): var name of the the form: {PKG_,Download/<name>:}{,MIRROR_}{HASH,MIRROR_HASH}
 check_hash = \
   $(if $(wildcard $(DL_DIR)/$(1)), \
     $(if $(filter-out x,$(2)), \
@@ -104,7 +121,7 @@ hash_var = $(if $(filter-out x,$(1)),MD5SUM,HASH)
 endif
 
 define DownloadMethod/unknown
-	@echo "ERROR: No download method available"; false
+	echo "ERROR: No download method available"; false
 endef
 
 define DownloadMethod/default
@@ -115,6 +132,9 @@ define DownloadMethod/default
 	)
 endef
 
+# $(1): "check"
+# $(2): "PKG_" if <name> as in Download/<name> is "default", otherwise "Download/<name>:"
+# $(3): shell command sequence to do the download
 define wrap_mirror
 $(if $(if $(MIRROR),$(filter-out x,$(MIRROR_HASH))),$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(FILE)" "$(MIRROR_HASH)" "" || ( $(3) ),$(3)) \
 $(if $(filter check,$(1)), \
@@ -158,23 +178,41 @@ endef
 
 define DownloadMethod/git
 	$(call wrap_mirror,$(1),$(2), \
-		echo "Checking out files from the git repository..."; \
-		mkdir -p $(TMP_DIR)/dl && \
-		cd $(TMP_DIR)/dl && \
-		rm -rf $(SUBDIR) && \
-		[ \! -d $(SUBDIR) ] && \
-		git clone $(OPTS) $(URL) $(SUBDIR) && \
-		(cd $(SUBDIR) && git checkout $(VERSION) && \
-		git submodule update --init --recursive) && \
-		echo "Packing checkout..." && \
-		export TAR_TIMESTAMP=`cd $(SUBDIR) && git log -1 --format='@%ct'` && \
-		rm -rf $(SUBDIR)/.git && \
-		$(call dl_tar_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
-		mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
-		rm -rf $(SUBDIR); \
+		$(call DownloadMethod/rawgit) \
+	)
+endef
+
+define DownloadMethod/github_archive
+	$(call wrap_mirror,$(1),$(2), \
+		$(SCRIPT_DIR)/dl_github_archive.py \
+			--dl-dir="$(DL_DIR)" \
+			--url="$(URL)" \
+			--version="$(VERSION)" \
+			--subdir="$(SUBDIR)" \
+			--source="$(FILE)" \
+			--hash="$(MIRROR_HASH)" \
+		|| ( $(call DownloadMethod/rawgit) ); \
 	)
 endef
 
+# Only intends to be called as a submethod from other DownloadMethod
+define DownloadMethod/rawgit
+	echo "Checking out files from the git repository..."; \
+	mkdir -p $(TMP_DIR)/dl && \
+	cd $(TMP_DIR)/dl && \
+	rm -rf $(SUBDIR) && \
+	[ \! -d $(SUBDIR) ] && \
+	git clone $(OPTS) $(URL) $(SUBDIR) && \
+	(cd $(SUBDIR) && git checkout $(VERSION) && \
+	git submodule update --init --recursive) && \
+	echo "Packing checkout..." && \
+	export TAR_TIMESTAMP=`cd $(SUBDIR) && git log -1 --format='@%ct'` && \
+	rm -rf $(SUBDIR)/.git && \
+	$(call dl_tar_pack,$(TMP_DIR)/dl/$(FILE),$(SUBDIR)) && \
+	mv $(TMP_DIR)/dl/$(FILE) $(DL_DIR)/ && \
+	rm -rf $(SUBDIR);
+endef
+
 define DownloadMethod/bzr
 	$(call wrap_mirror,$(1),$(2), \
 		echo "Checking out files from the bzr repository..."; \

+ 6 - 19
include/feeds.mk

@@ -10,31 +10,17 @@
 
 FEEDS_INSTALLED:=$(notdir $(wildcard $(TOPDIR)/package/feeds/*))
 FEEDS_AVAILABLE:=$(sort $(FEEDS_INSTALLED) $(shell $(SCRIPT_DIR)/feeds list -n))
-FEEDS_ENABLED:=$(foreach feed,$(FEEDS_AVAILABLE),$(if $(CONFIG_FEED_$(feed)),$(feed)))
-FEEDS_DISABLED:=$(filter-out $(FEEDS_ENABLED),$(FEEDS_AVAILABLE))
 
 PACKAGE_SUBDIRS=$(PACKAGE_DIR)
 ifneq ($(CONFIG_PER_FEED_REPO),)
   PACKAGE_SUBDIRS += $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/base
-  ifneq ($(CONFIG_PER_FEED_REPO_ADD_DISABLED),)
-    PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_AVAILABLE),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
-  else
-    PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_ENABLED),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
-  endif
+  PACKAGE_SUBDIRS += $(foreach FEED,$(FEEDS_AVAILABLE),$(OUTPUT_DIR)/packages/$(ARCH_PACKAGES)/$(FEED))
 endif
 
-PACKAGE_DIR_ALL := $(TOPDIR)/staging_dir/packages/$(BOARD)
-
 opkg_package_files = $(wildcard \
 	$(foreach dir,$(PACKAGE_SUBDIRS), \
 	  $(foreach pkg,$(1), $(dir)/$(pkg)_*.ipk)))
 
-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), \
@@ -47,10 +33,11 @@ endef
 # 1: destination file
 define FeedSourcesAppend
 ( \
-  echo "src/gz %n_core %U/%S/packages"; \
+  echo 'src/gz %d_core %U/targets/%S/packages'; \
   $(strip $(if $(CONFIG_PER_FEED_REPO), \
-	$(foreach feed,base $(FEEDS_ENABLED),echo "src/gz %n_$(feed) %U/packages/%A/$(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/packages/%A/$(feed)";)))) \
+	echo 'src/gz %d_base %U/packages/%A/base'; \
+	$(foreach feed,$(FEEDS_AVAILABLE), \
+		$(if $(CONFIG_FEED_$(feed)), \
+			echo '$(if $(filter m,$(CONFIG_FEED_$(feed))),# )src/gz %d_$(feed) %U/packages/%A/$(feed)';)))) \
 ) >> $(1)
 endef

+ 2 - 0
include/hardened-ld-pie.specs

@@ -0,0 +1,2 @@
+*self_spec:
++ %{no-pie|static|r|shared:;:-pie}

+ 7 - 0
include/hardening.mk

@@ -6,6 +6,7 @@
 #
 
 PKG_CHECK_FORMAT_SECURITY ?= 1
+PKG_ASLR_PIE ?= 1
 PKG_SSP ?= 1
 PKG_FORTIFY_SOURCE ?= 1
 PKG_RELRO ?= 1
@@ -15,6 +16,12 @@ ifdef CONFIG_PKG_CHECK_FORMAT_SECURITY
     TARGET_CFLAGS += -Wformat -Werror=format-security
   endif
 endif
+ifdef CONFIG_PKG_ASLR_PIE
+  ifeq ($(strip $(PKG_ASLR_PIE)),1)
+    TARGET_CFLAGS += $(FPIC)
+    TARGET_LDFLAGS += $(FPIC) -specs=$(INCLUDE_DIR)/hardened-ld-pie.specs
+  endif
+endif
 ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR
   ifeq ($(strip $(PKG_SSP)),1)
     TARGET_CFLAGS += -fstack-protector

+ 30 - 26
include/host-build.mk

@@ -19,22 +19,23 @@ else
 HOST_JOBS?=$(if $(HOST_BUILD_PARALLEL),$(HOST_MAKE_J),-j1)
 endif
 
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/unpack.mk
 include $(INCLUDE_DIR)/depends.mk
+include $(INCLUDE_DIR)/quilt.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_PREPARED=$(HOST_BUILD_DIR)/.prepared$(if $(HOST_QUILT)$(DUMP),,$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))_$(call confvar,CONFIG_AUTOREMOVE $(HOST_PREPARED_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_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_target:=$(if $(HOST_QUILT),,.)
+
 Host/Patch:=$(Host/Patch/Default)
 ifneq ($(strip $(HOST_UNPACK)),)
   define Host/Prepare/Default
@@ -51,6 +52,7 @@ endef
 HOST_CONFIGURE_VARS = \
 	CC="$(HOSTCC)" \
 	CFLAGS="$(HOST_CFLAGS)" \
+	CXX="$(HOSTCXX)" \
 	CPPFLAGS="$(HOST_CPPFLAGS)" \
 	LDFLAGS="$(HOST_LDFLAGS)" \
 	CONFIG_SHELL="$(SHELL)"
@@ -110,7 +112,7 @@ define Host/Compile
 endef
 
 define Host/Install/Default
-	$(_SINGLE)$(MAKE) -C $(HOST_BUILD_DIR) install
+	$(call Host/Compile/Default,install)
 endef
 
 define Host/Install
@@ -126,11 +128,11 @@ ifneq ($(if $(HOST_QUILT),,$(CONFIG_AUTOREBUILD)),)
 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 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_HOSTPKG)/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 $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR_HOST)/ccache)
   $(if $(HOST_CONFIG_SITE),$(1) : export CONFIG_SITE:=$(HOST_CONFIG_SITE))
   $(if $(IS_PACKAGE_BUILD),$(1) : export PATH=$$(TARGET_PATH_PKG))
 endef
@@ -173,32 +175,34 @@ ifndef DUMP
 		touch $(HOST_STAMP_BUILT)
 		touch $$@
 
+  $(call DefaultTargets,$(patsubst %,host-%,$(DEFAULT_SUBDIR_TARGETS)))
   ifndef STAMP_BUILT
-    prepare: host-prepare
-    compile: host-compile
-    install: host-install
-    clean: host-clean
-    update: host-update
-    refresh: host-refresh
+    $(foreach t,$(DEFAULT_SUBDIR_TARGETS),
+      $(t): host-$(t)
+      .$(t): .host-$(t)
+    )
+    clean-build: host-clean-build
   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
+  $(_host_target)host-prepare: $(HOST_STAMP_PREPARED)
+  $(_host_target)host-configure: $(HOST_STAMP_CONFIGURED)
+  $(_host_target)host-compile: $(HOST_STAMP_BUILT) $(HOST_STAMP_INSTALLED)
+  host-install: host-compile
+
+  host-clean-build: FORCE
+	rm -rf $(HOST_BUILD_DIR) $(HOST_STAMP_BUILT)
+
+  host-clean: host-clean-build
 	$(call Host/Clean)
 	$(call Host/Uninstall)
-	rm -rf $(HOST_BUILD_DIR) $(HOST_STAMP_INSTALLED) $(HOST_STAMP_BUILT)
+	rm -rf $(HOST_STAMP_INSTALLED)
 
+    ifneq ($(CONFIG_AUTOREMOVE),)
+      host-compile:
+		$(FIND) $(HOST_BUILD_DIR) -mindepth 1 -maxdepth 1 -not '(' -type f -and -name '.*' -and -size 0 ')' | \
+			$(XARGS) rm -rf
+    endif
   endef
-
-  download:
-  prepare:
-  compile:
-  install:
-  clean:
-
 endif
 
 define HostBuild

+ 0 - 51
include/host.mk

@@ -1,51 +0,0 @@
-#
-# 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

+ 171 - 9
include/image-commands.mk

@@ -7,8 +7,71 @@ 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 '$(if $(UIMAGE_NAME),$(UIMAGE_NAME),$(call toupper,$(LINUX_KARCH)) libreCMC Linux-$(LINUX_VERSION))' -d $@ $@.new
-	@mv $@.new $@
+		-n '$(if $(UIMAGE_NAME),$(UIMAGE_NAME),$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION))' -d $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-enc
+	$(eval product=$(word 1,$(1)))
+	$(eval version=$(word 2,$(1)))
+	$(eval args=$(wordlist 3,$(words $(1)),$(1)))
+	$(STAGING_DIR_HOST)/bin/buffalo-enc \
+		-p $(product) -v $(version) $(args) \
+		-i $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-enc-tag
+	$(call Build/buffalo-enc,'' '' -S 152 $(1))
+endef
+
+define Build/buffalo-tag-dhp
+	$(eval product=$(word 1,$(1)))
+	$(eval region=$(word 2,$(1)))
+	$(eval language=$(word 3,$(1)))
+	$(STAGING_DIR_HOST)/bin/buffalo-tag \
+		-d 0x01000000 -w 1 \
+		-a $(BUFFALO_TAG_PLATFORM) \
+		-v $(BUFFALO_TAG_VERSION) -m $(BUFFALO_TAG_MINOR) \
+		-b $(product) -p $(product) \
+		-r $(region) -r $(region) -l $(language) \
+		-I $@ -o $@.new
+	mv $@.new $@
+endef
+
+define Build/buffalo-dhp-image
+	$(STAGING_DIR_HOST)/bin/mkdhpimg $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/eva-image
+	$(STAGING_DIR_HOST)/bin/lzma2eva $(KERNEL_LOADADDR) $(KERNEL_LOADADDR) $@ $@.new
+	mv $@.new $@
+endef
+
+define Build/seama
+	$(STAGING_DIR_HOST)/bin/seama -i $@ \
+		-m "dev=/dev/mtdblock/$(SEAMA_MTDBLOCK)" -m "type=firmware"
+	mv $@.seama $@
+endef
+
+define Build/seama-seal
+	$(STAGING_DIR_HOST)/bin/seama -i $@ -s $@.seama \
+		-m "signature=$(SEAMA_SIGNATURE)"
+	mv $@.seama $@
+endef
+
+define Build/zyxel-ras-image
+	let \
+		newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
+		$(STAGING_DIR_HOST)/bin/mkrasimage \
+			-b $(RAS_BOARD) \
+			-v $(RAS_VERSION) \
+			-r $@ \
+			-s $$newsize \
+			-o $@.new \
+			$(if $(findstring separate-kernel,$(word 1,$(1))),-k $(IMAGE_KERNEL)) \
+		&& mv $@.new $@
 endef
 
 define Build/netgear-chk
@@ -16,22 +79,49 @@ define Build/netgear-chk
 		-o $@.new \
 		-k $@ \
 		-b $(NETGEAR_BOARD_ID) \
-		-r $(NETGEAR_REGION)
+		$(if $(NETGEAR_REGION),-r $(NETGEAR_REGION),)
 	mv $@.new $@
 endef
 
 define Build/netgear-dni
 	$(STAGING_DIR_HOST)/bin/mkdniimg \
-		-B $(NETGEAR_BOARD_ID) -v libreCMC.$(REVISION) \
+		-B $(NETGEAR_BOARD_ID) -v $(VERSION_DIST).$(firstword $(subst -, ,$(REVISION))) \
 		$(if $(NETGEAR_HW_ID),-H $(NETGEAR_HW_ID)) \
 		-r "$(1)" \
 		-i $@ -o $@.new
 	mv $@.new $@
 endef
 
+define Build/append-squashfs-fakeroot-be
+	rm -rf $@.fakefs $@.fakesquashfs
+	mkdir $@.fakefs
+	$(STAGING_DIR_HOST)/bin/mksquashfs-lzma \
+		$@.fakefs $@.fakesquashfs \
+		-noappend -root-owned -be -nopad -b 65536 \
+		$(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH))
+	cat $@.fakesquashfs >> $@
+endef
+
+define Build/append-string
+	echo -n $(1) >> $@
+endef
+
+# append a fake/empty uImage header, to fool bootloaders rootfs integrity check
+# for example
+define Build/append-uImage-fakehdr
+	touch $@.fakehdr
+	$(STAGING_DIR_HOST)/bin/mkimage \
+		-A $(LINUX_KARCH) -O linux -T $(1) -C none \
+		-n '$(VERSION_DIST) fake $(1)' \
+		-d $@.fakehdr \
+		-s \
+		$@.fakehdr
+	cat $@.fakehdr >> $@
+endef
+
 define Build/tplink-safeloader
        -$(STAGING_DIR_HOST)/bin/tplink-safeloader \
-		-B $(TPLINK_BOARD_NAME) \
+		-B $(TPLINK_BOARD_ID) \
 		-V $(REVISION) \
 		-k $(IMAGE_KERNEL) \
 		-r $@ \
@@ -42,8 +132,7 @@ define Build/tplink-safeloader
 endef
 
 define Build/append-dtb
-	$(call Image/BuildDTB,$(if $(DEVICE_DTS_DIR),$(DEVICE_DTS_DIR),$(DTS_DIR))/$(DEVICE_DTS).dts,$@.dtb)
-	cat $@.dtb >> $@
+	cat $(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb >> $@
 endef
 
 define Build/install-dtb
@@ -59,6 +148,7 @@ define Build/fit
 		-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)) \
+		-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
 		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
 	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
 	@mv $@.new $@
@@ -74,10 +164,20 @@ define Build/lzma-no-dict
 endef
 
 define Build/gzip
-	gzip -9n -c $@ $(1) > $@.new
+	gzip -f -9n -c $@ $(1) > $@.new
 	@mv $@.new $@
 endef
 
+define Build/zip
+	mkdir $@.tmp
+	mv $@ $@.tmp/$(1)
+
+	zip -j -X \
+		$(if $(SOURCE_DATE_EPOCH),--mtime="$(SOURCE_DATE_EPOCH)") \
+		$@ $@.tmp/$(if $(1),$(1),$@)
+	rm -rf $@.tmp
+endef
+
 define Build/jffs2
 	rm -rf $(KDIR_TMP)/$(DEVICE_NAME)/jffs2 && \
 		mkdir -p $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/$$(dirname $(1)) && \
@@ -125,6 +225,10 @@ define Build/append-ubi
 	rm $@.tmp
 endef
 
+define Build/append-uboot
+	dd if=$(UBOOT_PATH) >> $@
+endef
+
 define Build/pad-to
 	dd if=$@ of=$@.new bs=$(1) conv=sync
 	mv $@.new $@
@@ -150,6 +254,11 @@ define Build/pad-offset
 	mv $@.new $@
 endef
 
+define Build/xor-image
+	$(STAGING_DIR_HOST)/bin/xorimage -i $@ -o $@.xor $(1)
+	mv $@.xor $@
+endef
+
 define Build/check-size
 	@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$(stat -c%s $@)" ] || { \
 		echo "WARNING: Image file $@ is too big" >&2; \
@@ -165,6 +274,24 @@ define Build/combined-image
 	@mv $@.new $@
 endef
 
+define Build/openmesh-image
+	$(TOPDIR)/scripts/om-fwupgradecfg-gen.sh \
+		"$(call param_get_default,ce_type,$(1),$(DEVICE_NAME))" \
+		"$@-fwupgrade.cfg" \
+		"$(call param_get_default,kernel,$(1),$(IMAGE_KERNEL))" \
+		"$(call param_get_default,rootfs,$(1),$@)"
+	$(TOPDIR)/scripts/combined-ext-image.sh \
+		"$(call param_get_default,ce_type,$(1),$(DEVICE_NAME))" "$@" \
+		"$@-fwupgrade.cfg" "fwupgrade.cfg" \
+		"$(call param_get_default,kernel,$(1),$(IMAGE_KERNEL))" "kernel" \
+		"$(call param_get_default,rootfs,$(1),$@)" "rootfs"
+endef
+
+define Build/senao-header
+	$(STAGING_DIR_HOST)/bin/mksenaofw $(1) -e $@ -o $@.new
+	mv $@.new $@
+endef
+
 define Build/sysupgrade-tar
 	sh $(TOPDIR)/scripts/sysupgrade-tar.sh \
 		--board $(if $(BOARD_NAME),$(BOARD_NAME),$(DEVICE_NAME)) \
@@ -173,6 +300,35 @@ define Build/sysupgrade-tar
 		$@
 endef
 
+define Build/tplink-v1-header
+	$(STAGING_DIR_HOST)/bin/mktplinkfw \
+		-c -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -L $(KERNEL_LOADADDR) \
+		-E $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
+		-m $(TPLINK_HEADER_VERSION) -N "$(VERSION_DIST)" -V $(REVISION) \
+		-k $@ -o $@.new $(1)
+	@mv $@.new $@
+endef
+
+define Build/tplink-v2-header
+	$(STAGING_DIR_HOST)/bin/mktplinkfw2 \
+		-c -H $(TPLINK_HWID) -W $(TPLINK_HWREV) -L $(KERNEL_LOADADDR) \
+		-E $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR))  \
+		-w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \
+		-T $(TPLINK_HVERSION) -V "ver. 2.0" \
+		-k $@ -o $@.new $(1)
+	@mv $@.new $@
+endef
+
+define Build/tplink-v2-image
+	$(STAGING_DIR_HOST)/bin/mktplinkfw2 \
+		-H $(TPLINK_HWID) -W $(TPLINK_HWREV) \
+		-w $(TPLINK_HWREVADD) -F "$(TPLINK_FLASHLAYOUT)" \
+		-T $(TPLINK_HVERSION) -V "ver. 2.0" -a 0x4 -j \
+		-k $(IMAGE_KERNEL) -r $(IMAGE_ROOTFS) -o $@.new $(1)
+	cat $@.new >> $@
+	rm -rf $@.new
+endef
+
 json_quote=$(subst ','\'',$(subst ",\",$(1)))
 #")')
 metadata_devices=$(if $(1),$(subst "$(space)","$(comma)",$(strip $(foreach v,$(1),"$(call json_quote,$(v))"))))
@@ -188,7 +344,13 @@ metadata_json = \
 	}'
 
 define Build/append-metadata
-	$(if $(SUPPORTED_DEVICES),echo $(call metadata_json,$(SUPPORTED_DEVICES)) | fwtool -I - $@)
+	$(if $(SUPPORTED_DEVICES),-echo $(call metadata_json,$(SUPPORTED_DEVICES)) | fwtool -I - $@)
+	[ ! -s "$(BUILD_KEY)" -o ! -s "$(BUILD_KEY).ucert" -o ! -s "$@" ] || { \
+		cp "$(BUILD_KEY).ucert" "$@.ucert" ;\
+		usign -S -m "$@" -s "$(BUILD_KEY)" -x "$@.sig" ;\
+		ucert -A -c "$@.ucert" -x "$@.sig" ;\
+		fwtool -S "$@.ucert" "$@" ;\
+	}
 endef
 
 define Build/kernel2minor

+ 57 - 20
include/image.mk

@@ -8,7 +8,6 @@
 override TARGET_BUILD=
 include $(INCLUDE_DIR)/prereq.mk
 include $(INCLUDE_DIR)/kernel.mk
-include $(INCLUDE_DIR)/host.mk
 include $(INCLUDE_DIR)/version.mk
 include $(INCLUDE_DIR)/image-commands.mk
 
@@ -19,10 +18,8 @@ ifndef IB
 endif
 
 include $(INCLUDE_DIR)/image-legacy.mk
-
-ifdef TARGET_PER_DEVICE_ROOTFS
-  include $(INCLUDE_DIR)/rootfs.mk
-endif
+include $(INCLUDE_DIR)/feeds.mk
+include $(INCLUDE_DIR)/rootfs.mk
 
 override MAKE:=$(_SINGLE)$(SUBMAKE)
 override NO_TRACE_MAKE:=$(_SINGLE)$(NO_TRACE_MAKE)
@@ -137,12 +134,13 @@ endef
 
 define Image/BuildKernel/MkuImage
 	mkimage -A $(ARCH) -O linux -T kernel -C $(1) -a $(2) -e $(3) \
-		-n '$(call toupper,$(ARCH)) libreCMC Linux-$(LINUX_VERSION)' -d $(4) $(5)
+		-n '$(call toupper,$(ARCH)) $(VERSION_DIST) 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) \
+		-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
 		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
 	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $(KDIR)/fit-$(1).its $(KDIR)/fit-$(1)$(7).itb
 endef
@@ -162,6 +160,7 @@ define Image/BuildDTB
 	$(TARGET_CROSS)cpp -nostdinc -x assembler-with-cpp \
 		-I$(DTS_DIR) \
 		-I$(DTS_DIR)/include \
+		-I$(LINUX_DIR)/include/ \
 		-undef -D__DTS__ $(3) \
 		-o $(2).tmp $(1)
 	$(LINUX_DIR)/scripts/dtc/dtc -O dtb \
@@ -211,14 +210,15 @@ endef
 # $(1): board name
 # $(2): rootfs type
 # $(3): kernel image
+# $(4): compat string
 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"
+	mkdir -p "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/"
+	echo "BOARD=$(if $(4),$(4),$(1))" > "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/CONTROL"
+	[ -z "$(2)" ] || $(CP) "$(KDIR)/root.$(2)" "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/root"
+	[ -z "$(3)" ] || $(CP) "$(3)" "$(KDIR_TMP)/sysupgrade-$(if $(4),$(4),$(1))/kernel"
 	(cd "$(KDIR_TMP)"; $(TAR) cvf \
-		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-sysupgrade.tar" sysupgrade-$(1) \
+		"$(BIN_DIR)/$(IMG_PREFIX)-$(1)-$(2)-sysupgrade.tar" sysupgrade-$(if $(4),$(4),$(1)) \
 			$(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \
 	)
    endef
@@ -260,10 +260,7 @@ define Image/mkfs/ext4
 endef
 
 define Image/Manifest
-	$(STAGING_DIR_HOST)/bin/opkg \
-		--offline-root $(TARGET_DIR) \
-		--add-arch all:100 \
-		--add-arch $(if $(ARCH_PACKAGES),$(ARCH_PACKAGES),$(BOARD)):200 list-installed > \
+	$(call opkg,$(TARGET_DIR_ORIG)) list-installed > \
 		$(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest
 endef
 
@@ -302,9 +299,9 @@ target-dir-%: FORCE
 		$(opkg_target) update && \
 		$(opkg_target) install \
 			$(call opkg_package_files,$(mkfs_packages_add)))
-	$(call prepare_rootfs,$(mkfs_cur_target_dir))
-	-mv $(mkfs_cur_target_dir).opkg $(mkfs_cur_target_dir)/etc/opkg
-	rm -f $(mkfs_cur_target_dir).conf
+	-$(CP) -T $(mkfs_cur_target_dir).opkg/ $(mkfs_cur_target_dir)/etc/opkg/
+	rm -rf $(mkfs_cur_target_dir).opkg $(mkfs_cur_target_dir).conf
+	$(call prepare_rootfs,$(mkfs_cur_target_dir),$(TOPDIR)/files)
 
 $(KDIR)/root.%: kernel_prepare
 	$(call Image/mkfs/$(word 1,$(target_params)),$(target_params))
@@ -324,6 +321,7 @@ define Device/Init
   CMDLINE:=
 
   IMAGES :=
+  ARTIFACTS :=
   IMAGE_PREFIX := $(IMG_PREFIX)-$(1)
   IMAGE_NAME = $$(IMAGE_PREFIX)-$$(1)-$$(2)
   KERNEL_PREFIX = $$(IMAGE_PREFIX)
@@ -351,6 +349,7 @@ define Device/Init
   FS_OPTIONS/ubifs = $$(MKUBIFS_OPTS)
 
   DEVICE_DTS :=
+  DEVICE_DTS_CONFIG :=
   DEVICE_DTS_DIR :=
 
   BOARD_NAME :=
@@ -363,8 +362,8 @@ endef
 
 DEFAULT_DEVICE_VARS := \
   DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_SIZE KERNEL_INITRAMFS_IMAGE \
-  DEVICE_DTS DEVICE_DTS_DIR BOARD_NAME CMDLINE \
-  UBOOTENV_IN_UBI KERNEL_IN_UBI \
+  KERNEL_LOADADDR DEVICE_DTS DEVICE_DTS_CONFIG DEVICE_DTS_DIR BOARD_NAME \
+  CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI \
   BLOCKSIZE PAGESIZE SUBPAGESIZE VID_HDR_OFFSET \
   UBINIZE_OPTS UIMAGE_NAME UBINIZE_PARTS \
   SUPPORTED_DEVICES IMAGE_METADATA
@@ -395,6 +394,7 @@ endef
 
 define Device/Check/Common
   _PROFILE_SET = $$(strip $$(foreach profile,$$(PROFILES) DEVICE_$(1),$$(call DEVICE_CHECK_PROFILE,$$(profile))))
+  DEVICE_PACKAGES += $$(call extra_packages,$$(DEVICE_PACKAGES))
   ifdef TARGET_PER_DEVICE_ROOTFS
     $$(eval $$(call merge_packages,_PACKAGES,$$(DEVICE_PACKAGES) $$(call DEVICE_EXTRA_PACKAGES,$(1))))
     ROOTFS_ID/$(1) := $$(if $$(_PROFILE_SET),$$(call mkfs_packages_id,$$(_PACKAGES)))
@@ -434,7 +434,27 @@ define Device/Build/compile
 
 endef
 
+ifndef IB
+define Device/Build/dtb
+  ifndef BUILD_DTS_$(1)
+  BUILD_DTS_$(1) := 1
+  $(KDIR)/image-$(1).dtb: FORCE
+	$(call Image/BuildDTB,$(strip $(2))/$(strip $(3)).dts,$$@)
+
+  image_prepare: $(KDIR)/image-$(1).dtb
+  endif
+
+endef
+endif
+
 define Device/Build/kernel
+  $$(eval $$(foreach dts,$$(DEVICE_DTS), \
+	$$(call Device/Build/dtb,$$(notdir $$(dts)), \
+		$$(if $$(DEVICE_DTS_DIR),$$(DEVICE_DTS_DIR),$$(DTS_DIR)), \
+		$$(dts) \
+	) \
+  ))
+
   $(KDIR)/$$(KERNEL_NAME):: image_prepare
   $$(_TARGET): $$(if $$(KERNEL_INSTALL),$(BIN_DIR)/$$(KERNEL_IMAGE))
   $(call Device/Export,$$(KDIR_KERNEL_IMAGE),$(1))
@@ -479,6 +499,19 @@ define Device/Build/image
 
 endef
 
+define Device/Build/artifact
+  $$(_TARGET): $(BIN_DIR)/$(IMAGE_PREFIX)-$(1)
+  $(KDIR)/tmp/$(IMAGE_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE)
+	@rm -f $$@
+	$$(call concat_cmd,$(ARTIFACT/$(1)))
+
+  .IGNORE: $(BIN_DIR)/$(IMAGE_PREFIX)-$(1)
+
+  $(BIN_DIR)/$(IMAGE_PREFIX)-$(1): $(KDIR)/tmp/$(IMAGE_PREFIX)-$(1)
+	cp $$^ $$@
+
+endef
+
 define Device/Build
   $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Device/Build/initramfs,$(1)))
   $(call Device/Build/kernel,$(1))
@@ -489,6 +522,10 @@ define Device/Build
   $$(eval $$(foreach image,$$(IMAGES), \
     $$(foreach fs,$$(filter $(TARGET_FILESYSTEMS),$$(FILESYSTEMS)), \
       $$(call Device/Build/image,$$(fs),$$(image),$(1)))))
+
+  $$(eval $$(foreach artifact,$$(ARTIFACTS), \
+    $$(call Device/Build/artifact,$$(artifact))))
+
 endef
 
 define Device/DumpInfo

+ 7 - 10
include/kernel-build.mk

@@ -4,7 +4,6 @@
 # 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
 include $(INCLUDE_DIR)/depends.mk
 
@@ -12,7 +11,7 @@ ifneq ($(DUMP),1)
   all: compile
 endif
 
-KERNEL_FILE_DEPENDS=$(GENERIC_PATCH_DIR) $(PATCH_DIR) $(GENERIC_FILES_DIR) $(FILES_DIR)
+KERNEL_FILE_DEPENDS=$(GENERIC_BACKPORT_DIR) $(GENERIC_PATCH_DIR) $(GENERIC_HACK_DIR) $(PATCH_DIR) $(GENERIC_FILES_DIR) $(FILES_DIR)
 STAMP_PREPARED=$(LINUX_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,$(KERNEL_FILE_DEPENDS),)))
 STAMP_CONFIGURED:=$(LINUX_DIR)/.configured
 include $(INCLUDE_DIR)/download.mk
@@ -51,14 +50,10 @@ 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
-
 define Download/git-kernel
   URL:=$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI))
   PROTO:=git
-  VERSION:=$(CONFIG_KERNEL_GIT_BRANCH)
+  VERSION:=$(CONFIG_KERNEL_GIT_REF)
   FILE:=$(LINUX_SOURCE)
   SUBDIR:=linux-$(LINUX_VERSION)
   OPTS:=$(KERNEL_GIT_OPTS)
@@ -105,7 +100,7 @@ define BuildKernel
   $(KERNEL_BUILD_DIR)/symtab.h: FORCE
 	rm -f $(KERNEL_BUILD_DIR)/symtab.h
 	touch $(KERNEL_BUILD_DIR)/symtab.h
-	+$(MAKE) $(KERNEL_MAKEOPTS) vmlinux
+	+$(KERNEL_MAKE) vmlinux
 	find $(LINUX_DIR) $(STAGING_DIR_ROOT)/lib/modules -name \*.ko | \
 		xargs $(TARGET_CROSS)nm | \
 		awk '$$$$1 == "U" { print $$$$2 } ' | \
@@ -152,7 +147,7 @@ define BuildKernel
   endef
 
   download: $(if $(LINUX_SITE),$(DL_DIR)/$(LINUX_SOURCE))
-  prepare: $(STAMP_CONFIGURED)
+  prepare: $(STAMP_PREPARED)
   compile: $(LINUX_DIR)/.modules
 	$(MAKE) -C image compile TARGET_BUILD=
 
@@ -160,7 +155,9 @@ define BuildKernel
 	rm -f $(LINUX_DIR)/.config.prev
 	rm -f $(STAMP_CONFIGURED)
 	$(LINUX_RECONF_CMD) > $(LINUX_DIR)/.config
-	$(_SINGLE)$(MAKE) -C $(LINUX_DIR) $(KERNEL_MAKEOPTS) HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib -lncurses" $$@
+	$(_SINGLE)$(KERNEL_MAKE) \
+		$(if $(findstring Darwin,$(HOST_OS)),HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib -lncurses") \
+		$$@
 	$(LINUX_RECONF_DIFF) $(LINUX_DIR)/.config > $(LINUX_RECONFIG_TARGET)
 
   install: $(LINUX_DIR)/.image

+ 16 - 36
include/kernel-defaults.mk

@@ -5,26 +5,6 @@
 # See /LICENSE for more information.
 #
 
-ifneq ($(SOURCE_DATE_EPOCH),)
-  ifndef DUMP
-    KBUILD_BUILD_TIMESTAMP:=$(shell perl -e 'print scalar gmtime($(SOURCE_DATE_EPOCH))')
-  endif
-endif
-
-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))" \
-	KBUILD_BUILD_TIMESTAMP="$(KBUILD_BUILD_TIMESTAMP)" \
-	KBUILD_BUILD_VERSION="0" \
-	HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
-	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"
@@ -36,29 +16,27 @@ ifneq (,$(KERNEL_CC))
   KERNEL_MAKEOPTS += CC="$(KERNEL_CC)"
 endif
 
-ifdef CONFIG_USE_SPARSE
-  KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse
-endif
-
-ifneq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
- KERNEL_MAKEOPTS += LOCALVERSION=
-endif
-
 export HOST_EXTRACFLAGS=-I$(STAGING_DIR_HOST)/include
 
 # defined in quilt.mk
 Kernel/Patch:=$(Kernel/Patch/Default)
 
+ifneq (,$(findstring .xz,$(LINUX_SOURCE)))
+  LINUX_CAT:=xzcat
+else
+  LINUX_CAT:=zcat
+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)
+	$(LINUX_CAT) $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
 	$(Kernel/Patch)
 	$(if $(QUILT),touch $(LINUX_DIR)/.quilt_used)
     endef
   else
     define Kernel/Prepare/Default
-	xzcat $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
+	$(LINUX_CAT) $(DL_DIR)/$(LINUX_SOURCE) | $(TAR) -C $(KERNEL_BUILD_DIR) $(TAR_OPTIONS)
     endef
   endif
 else
@@ -91,6 +69,7 @@ ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
 	$(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_FORCE),CONFIG_INITRAMFS_FORCE=y,# CONFIG_INITRAMFS_FORCE is not set)" >> $(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
@@ -106,6 +85,7 @@ 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
+	echo '# CONFIG_INITRAMFS_FORCE is not set' >> $(LINUX_DIR)/.config.set
 endef
 
 define Kernel/Configure/Default
@@ -124,7 +104,7 @@ define Kernel/Configure/Default
 		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
+	$(_SINGLE) [ -d $(LINUX_DIR)/user_headers ] || $(KERNEL_MAKE) INSTALL_HDR_PATH=$(LINUX_DIR)/user_headers headers_install
 	grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | mkhash md5 > $(LINUX_DIR)/.vermagic
 endef
 
@@ -134,7 +114,7 @@ endef
 
 define Kernel/CompileModules/Default
 	rm -f $(LINUX_DIR)/vmlinux $(LINUX_DIR)/System.map
-	+$(MAKE) $(KERNEL_MAKEOPTS) modules
+	+$(KERNEL_MAKE) modules
 endef
 
 OBJCOPY_STRIP = -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id
@@ -150,7 +130,7 @@ define Kernel/CopyImage
 		$(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))), \
+			$(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out vmlinux dtbs,$(KERNELNAME))), \
 			$(CP) $(LINUX_DIR)/arch/$(LINUX_KARCH)/boot/$(IMAGES_DIR)/$(k) $(KERNEL_BUILD_DIR)/$(k)$(1); \
 		) \
 	}
@@ -158,16 +138,16 @@ endef
 
 define Kernel/CompileImage/Default
 	rm -f $(TARGET_DIR)/init
-	+$(MAKE) $(KERNEL_MAKEOPTS) $(if $(KERNELNAME),$(KERNELNAME),all) modules
+	+$(KERNEL_MAKE) $(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
+	$(CP) $(GENERIC_PLATFORM_DIR)/other-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
+	+$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules
 	$(call Kernel/CopyImage,-initramfs)
 endef
 else

+ 19 - 4
include/kernel-version.mk

@@ -2,15 +2,30 @@
 
 LINUX_RELEASE?=1
 
-LINUX_VERSION-4.4 = .159
-LINUX_VERSION-4.19 =
+LINUX_VERSION-3.18 = .132
+LINUX_VERSION-4.9 = .150
+LINUX_VERSION-4.14 = .93
+LINUX_VERSION-4.19 = .16
 
-LINUX_KERNEL_HASH-4.4.159 = d464fea1f888ada3a55c3aea1c05ba9fd2d4edd7ffb152369faace18a285998b
-LINUX_KERNEL_HASH-4.19 = d06d7a0d59a96ab04e7af63244627d1d5aa2d99db84f81f559f0f8e7e58f94c8
+LINUX_KERNEL_HASH-3.18.132 =
+LINUX_KERNEL_HASH-4.9.150 =
+LINUX_KERNEL_HASH-4.14.93 = 5a61c1b681d74216c0547da1bc3d530152fae8c92af118feff94002c39943114
+LINUX_KERNEL_HASH-4.19.16 = d3bbf6b90e3e47cc2b37f855f6cbd6cceff90a4802ae0d713439ebf91da5eeb6
 
+remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1))))
+sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1)))))))
+
+ifneq ($(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+  LINUX_VERSION:=$(call sanitize_uri,$(call remove_uri_prefix,$(CONFIG_KERNEL_GIT_CLONE_URI)))
+  ifeq ($(call qstrip,$(CONFIG_KERNEL_GIT_REF)),)
+    CONFIG_KERNEL_GIT_REF:=HEAD
+  endif
+  LINUX_VERSION:=$(LINUX_VERSION)-$(call sanitize_uri,$(CONFIG_KERNEL_GIT_REF))
+else
 ifdef KERNEL_PATCHVER
   LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER)))
 endif
+endif
 
 split_version=$(subst ., ,$(1))
 merge_version=$(subst $(space),.,$(1))

+ 105 - 64
include/kernel.mk

@@ -10,6 +10,12 @@ CHECK:=1
 DUMP:=1
 endif
 
+ifneq ($(SOURCE_DATE_EPOCH),)
+  ifndef DUMP
+    KBUILD_BUILD_TIMESTAMP:=$(shell perl -e 'print scalar gmtime($(SOURCE_DATE_EPOCH))')
+  endif
+endif
+
 ifeq ($(__target_inc),)
   ifndef CHECK
     include $(INCLUDE_DIR)/target.mk
@@ -46,22 +52,30 @@ else
   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)
+  LINUX_UNAME_VERSION:=$(KERNEL_BASE)
   ifneq ($(findstring -rc,$(LINUX_VERSION)),)
     LINUX_UNAME_VERSION:=$(LINUX_UNAME_VERSION)-$(strip $(lastword $(subst -, ,$(LINUX_VERSION))))
   endif
 
-  MODULES_SUBDIR:=lib/modules/$(LINUX_UNAME_VERSION)-gnu
-  TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
-
   LINUX_KERNEL:=$(KERNEL_BUILD_DIR)/vmlinux
 
-  LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.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_LIBRE/$(LINUX_VERSION)-gnu$(TESTING)
+  ifneq (,$(findstring -rc,$(LINUX_VERSION)))
+      LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.tar.gz
+  else
+      LINUX_SOURCE:=linux-libre-$(LINUX_VERSION)-gnu.tar.xz
+  endif
+
+  ifneq (,$(findstring -rc,$(LINUX_VERSION)))
+      LINUX_SITE:=https://git.kernel.org/torvalds/t
+  else ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+      LINUX_SITE:=@KERNEL_LIBRE/$(LINUX_VERSION)-gnu$(TESTING)
+  else
+      LINUX_UNAME_VERSION:=$(strip $(shell cat $(LINUX_DIR)/include/config/kernel.release 2>/dev/null))
   endif
 
+  MODULES_SUBDIR:=lib/modules/$(LINUX_UNAME_VERSION)
+  TARGET_MODULES_DIR:=$(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)
+
   ifneq ($(TARGET_BUILD),1)
     PKG_BUILD_DIR ?= $(KERNEL_BUILD_DIR)/$(PKG_NAME)$(if $(PKG_VERSION),-$(PKG_VERSION))
   endif
@@ -77,6 +91,8 @@ else ifneq (,$(findstring $(ARCH) , armeb ))
   LINUX_KARCH := arm
 else ifneq (,$(findstring $(ARCH) , mipsel mips64 mips64el ))
   LINUX_KARCH := mips
+else ifneq (,$(findstring $(ARCH) , powerpc64 ))
+  LINUX_KARCH := powerpc
 else ifneq (,$(findstring $(ARCH) , sh2 sh3 sh4 ))
   LINUX_KARCH := sh
 else ifneq (,$(findstring $(ARCH) , i386 x86_64 ))
@@ -85,61 +101,81 @@ else
   LINUX_KARCH := $(ARCH)
 endif
 
+KERNEL_MAKE = $(MAKE) $(KERNEL_MAKEOPTS)
+
+KERNEL_MAKE_FLAGS = \
+	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))" \
+	KBUILD_BUILD_TIMESTAMP="$(KBUILD_BUILD_TIMESTAMP)" \
+	KBUILD_BUILD_VERSION="0" \
+	HOST_LOADLIBES="-L$(STAGING_DIR_HOST)/lib" \
+	CONFIG_SHELL="$(BASH)" \
+	$(if $(findstring c,$(LIBRECMC_VERBOSE)),V=1,V='') \
+	$(if $(PKG_BUILD_ID),LDFLAGS_MODULE=--build-id=0x$(PKG_BUILD_ID)) \
+	cmd_syscalls=
+
+ifeq ($(call qstrip,$(CONFIG_EXTERNAL_KERNEL_TREE))$(call qstrip,$(CONFIG_KERNEL_GIT_CLONE_URI)),)
+  KERNEL_MAKE_FLAGS += \
+	KERNELRELEASE=$(LINUX_VERSION)
+endif
+
+KERNEL_MAKEOPTS := -C $(LINUX_DIR) $(KERNEL_MAKE_FLAGS)
+
+ifdef CONFIG_USE_SPARSE
+  KERNEL_MAKEOPTS += C=1 CHECK=$(STAGING_DIR_HOST)/bin/sparse
+endif
+
+PKG_EXTMOD_SUBDIRS ?= .
+
+define populate_module_symvers
+	@mkdir -p $(PKG_INFO_DIR)
+	cat /dev/null > $(PKG_INFO_DIR)/$(PKG_NAME).symvers; \
+	for subdir in $(PKG_EXTMOD_SUBDIRS); do \
+		cat $(PKG_INFO_DIR)/*.symvers 2>/dev/null > $(PKG_BUILD_DIR)/$$$$subdir/Module.symvers; \
+	done
+endef
+
+define collect_module_symvers
+	for subdir in $(PKG_EXTMOD_SUBDIRS); do \
+		grep -F $$$$(readlink -f $(PKG_BUILD_DIR)) $(PKG_BUILD_DIR)/$$$$subdir/Module.symvers >> $(PKG_BUILD_DIR)/Module.symvers.tmp; \
+	done; \
+	sort -u $(PKG_BUILD_DIR)/Module.symvers.tmp > $(PKG_BUILD_DIR)/Module.symvers; \
+	mv $(PKG_BUILD_DIR)/Module.symvers $(PKG_INFO_DIR)/$(PKG_NAME).symvers
+endef
+
+define KernelPackage/hooks
+  ifneq ($(PKG_NAME),kernel)
+    Hooks/Compile/Pre += populate_module_symvers
+    Hooks/Compile/Post += collect_module_symvers
+  endif
+  define KernelPackage/hooks
+  endef
+endef
+
 define KernelPackage/Defaults
   FILES:=
   AUTOLOAD:=
+  MODPARAMS:=
   PKGFLAGS+=nonshared
 endef
 
+# 1: name
+# 2: install prefix
+# 3: module priority prefix
+# 4: required for boot
+# 5: module list
 define ModuleAutoLoad
-	$(SH_FUNC) \
-	export modules=; \
-	probe_module() { \
-		local mods="$$$$$$$$1"; \
-		local boot="$$$$$$$$2"; \
-		local mod; \
-		shift 2; \
-		for mod in $$$$$$$$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" -a ! -e $(2)/etc/modules-boot.d/$(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() { \
-		local priority="$$$$$$$$1"; \
-		local mods="$$$$$$$$2"; \
-		local boot="$$$$$$$$3"; \
-		local mod; \
-		shift 3; \
-		for mod in $$$$$$$$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" -a ! -e $(2)/etc/modules-boot.d/$$$$$$$$priority-$(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 \
-		modules="$$$$$$$$(echo "$$$$$$$$modules" | tr ' ' '\n' | sort | uniq | paste -s -d' ' -)"; \
-		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
+  $(if $(5), \
+    mkdir -p $(2)/etc/modules.d; \
+    ($(foreach mod,$(5), \
+      echo "$(mod)$(if $(MODPARAMS.$(mod)), $(MODPARAMS.$(mod)),$(if $(MODPARAMS), $(MODPARAMS)))"; )) > $(2)/etc/modules.d/$(3)$(1); \
+    $(if $(4), \
+      mkdir -p $(2)/etc/modules-boot.d; \
+      ln -sf ../modules.d/$(3)$(1) $(2)/etc/modules-boot.d/;))
 endef
 
 ifeq ($(DUMP)$(TARGET_BUILD),)
@@ -192,10 +228,10 @@ $(call KernelPackage/$(1)/config)
   endif
 
   $(call KernelPackage/depends)
+  $(call KernelPackage/hooks)
 
   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
+    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."; \
@@ -207,10 +243,9 @@ $(call KernelPackage/$(1)/config)
 				exit 1; \
 			fi; \
 		  done;
-		  $(call ModuleAutoLoad,$(1),$$(1),$(AUTOLOAD))
+		  $(call ModuleAutoLoad,$(1),$$(1),$(filter-out 0-,$(word 1,$(AUTOLOAD))-),$(filter-out 0,$(word 2,$(AUTOLOAD))),$(wordlist 3,99,$(AUTOLOAD)))
 		  $(call KernelPackage/$(1)/install,$$(1))
-      endef
-    endif
+    endef
   $(if $(CONFIG_PACKAGE_kmod-$(1)),
     else
       compile: $(1)-disabled
@@ -224,17 +259,23 @@ $(call KernelPackage/$(1)/config)
   endif
   $$(eval $$(call BuildPackage,kmod-$(1)))
 
-  $$(IPKG_kmod-$(1)): $$(wildcard $$(FILES))
+  $$(IPKG_kmod-$(1)): $$(wildcard $$(call version_filter,$$(FILES)))
+
 endef
 
 version_filter=$(if $(findstring @,$(1)),$(shell $(SCRIPT_DIR)/package-metadata.pl version_filter $(KERNEL_PATCHVER) $(1)),$(1))
 
+# 1: priority (optional)
+# 2: module list
+# 3: boot flag
 define AutoLoad
-  add_module "$(1)" "$(call version_filter,$(2))" "$(3)";
+  $(if $(1),$(1),0) $(if $(3),1,0) $(call version_filter,$(2))
 endef
 
+# 1: module list
+# 2: boot flag
 define AutoProbe
-  probe_module "$(call version_filter,$(1))" "$(2)";
+  $(call AutoLoad,,$(1),$(2))
 endef
 
 version_field=$(if $(word $(1),$(2)),$(word $(1),$(2)),0)

+ 56 - 15
include/netfilter.mk

@@ -30,9 +30,10 @@ endef
 # core
 
 # kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_REJECT,CONFIG_NF_REJECT_IPV4, $(P_V4)nf_reject_ipv4),))
+
 $(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,NF_IPT,CONFIG_NF_REJECT_IPV4, $(P_V4)nf_reject_ipv4),))
 
 $(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),))
@@ -79,26 +80,34 @@ $(eval $(call nf_add,IPT_CONNTRACK,CONFIG_NETFILTER_XT_MATCH_CONNTRACK, $(P_XT)x
 
 $(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_CONNCOUNT, $(P_XT)nf_conncount))
 $(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)))
 
+#conntrack-label
+
+$(eval $(call nf_add,IPT_CONNTRACK_LABEL,CONFIG_NETFILTER_XT_MATCH_CONNLABEL, $(P_XT)xt_connlabel))
+
 # 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))
 
+# physdev
+
+$(eval $(call nf_add,IPT_PHYSDEV,CONFIG_NETFILTER_XT_MATCH_PHYSDEV, $(P_XT)xt_physdev))
 
 # filter
 
 $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_string))
+$(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_BPF, $(P_XT)xt_bpf))
 
 
 # ipopt
@@ -106,6 +115,8 @@ $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_STRING, $(P_XT)xt_stri
 $(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_RPFILTER,CONFIG_IP_NF_MATCH_RPFILTER, $(P_V4)ipt_rpfilter))
+$(eval $(call nf_add,IPT_RPFILTER,CONFIG_IP6_NF_MATCH_RPFILTER, $(P_V6)ip6t_rpfilter))
 $(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))
@@ -136,14 +147,18 @@ $(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))
 
+# flow offload support
+$(eval $(call nf_add,IPT_FLOW,CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD, $(P_XT)xt_FLOWOFFLOAD))
 
 # IPv6
 
 # kernel only
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_REJECT6,CONFIG_NF_REJECT_IPV6, $(P_V6)nf_reject_ipv6),))
+
 $(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_IPT6,CONFIG_NF_REJECT_IPV6, $(P_V6)nf_reject_ipv6),))
 
-$(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_CONNTRACK,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6, ge 4.19),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_CONNTRACK6,CONFIG_NF_DEFRAG_IPV6, $(P_V6)nf_defrag_ipv6, lt 4.19),))
 $(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),))
@@ -172,10 +187,10 @@ $(eval $(call nf_add,IPT_IPV6_EXTRA,CONFIG_IP6_NF_MATCH_RT, $(P_V6)ip6t_rt))
 $(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_NAT,CONFIG_NF_NAT_MASQUERADE_IPV4, $(P_V4)nf_nat_masquerade_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT,CONFIG_NF_NAT_MASQUERADE_IPV4, $(P_V4)nf_nat_masquerade_ipv4, lt 4.18),))
 
 $(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,NF_NAT6,CONFIG_NF_NAT_MASQUERADE_IPV6, $(P_V6)nf_nat_masquerade_ipv6),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NF_NAT6,CONFIG_NF_NAT_MASQUERADE_IPV6, $(P_V6)nf_nat_masquerade_ipv6, lt 4.18),))
 
 $(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),))
@@ -245,7 +260,11 @@ $(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_NF_SOCKET_IPV4, $(P_V4)nf_socket_ipv4, ge 4.10))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_SOCKET_IPV6, $(P_V6)nf_socket_ipv6, ge 4.10))
 $(eval $(call nf_add,IPT_TPROXY,CONFIG_NETFILTER_XT_TARGET_TPROXY, $(P_XT)xt_TPROXY))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV4, $(P_V4)nf_tproxy_ipv4, ge 4.18))
+$(eval $(call nf_add,IPT_TPROXY,CONFIG_NF_TPROXY_IPV6, $(P_V6)nf_tproxy_ipv6, ge 4.18))
 
 # led
 $(eval $(call nf_add,IPT_LED,CONFIG_NETFILTER_XT_TARGET_LED, $(P_XT)xt_LED))
@@ -260,6 +279,10 @@ $(eval $(if $(NF_KMOD),$(call nf_add,IPT_TEE,CONFIG_NF_DUP_IPV6, $(P_V6)nf_dup_i
 
 $(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
 
@@ -311,31 +334,48 @@ $(eval $(call nf_add,EBTABLES_WATCHERS,CONFIG_BRIDGE_EBT_NFQUEUE, $(P_EBT)ebt_nf
 
 # 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_NF_TABLES_INET, $(P_XT)nf_tables_inet, lt 4.17),))
 $(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_NUMGEN, $(P_XT)nft_numgen, ge 4.9.0),))
 $(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_SET_RBTREE, $(P_XT)nft_set_rbtree, ge 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_RBTREE, $(P_XT)nft_rbtree, lt 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_SET_HASH, $(P_XT)nft_set_hash, ge 4.9.0),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NFT_HASH, $(P_XT)nft_hash, lt 4.9.0),))
 $(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_TABLES_IPV4, $(P_V4)nf_tables_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_CORE,CONFIG_NF_TABLES_IPV4, $(P_V4)nf_tables_ipv4, lt 4.17),))
 $(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_NF_TABLES_IPV6, $(P_V6)nf_tables_ipv6, lt 4.17),))
 $(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_CORE,CONFIG_NFT_QUOTA, $(P_XT)nft_quota, ge 4.9.0),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_ARP,CONFIG_NF_TABLES_ARP, $(P_V4)nf_tables_arp, lt 4.17),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NF_TABLES_BRIDGE, $(P_EBT)nf_tables_bridge, lt 4.17),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NFT_BRIDGE_META, $(P_EBT)nft_meta_bridge),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_BRIDGE,CONFIG_NFT_BRIDGE_REJECT, $(P_EBT)nft_reject_bridge),))
 
 $(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_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),))
+
+$(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_NAT6,CONFIG_NFT_MASQ_IPV6, $(P_V6)nft_masq_ipv6),))
+
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB, $(P_XT)nft_fib),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_INET, $(P_XT)nft_fib_inet),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_IPV4, $(P_V4)nft_fib_ipv4),))
+$(eval $(if $(NF_KMOD),$(call nf_add,NFT_FIB,CONFIG_NFT_FIB_IPV6, $(P_V6)nft_fib_ipv6),))
+
 
 # userland only
 IPT_BUILTIN += $(NF_IPT-y) $(NF_IPT-m)
@@ -345,7 +385,9 @@ IPT_BUILTIN += $(NF_CONNTRACK6-y)
 IPT_BUILTIN += $(IPT_CONNTRACK-y)
 IPT_BUILTIN += $(IPT_CONNTRACK_EXTRA-y)
 IPT_BUILTIN += $(IPT_EXTRA-y)
+IPT_BUILTIN += $(IPT_PHYSDEV-y)
 IPT_BUILTIN += $(IPT_FILTER-y)
+IPT_BUILTIN += $(IPT_FLOW-y) $(IPT_FLOW-m)
 IPT_BUILTIN += $(IPT_IPOPT-y)
 IPT_BUILTIN += $(IPT_IPRANGE-y)
 IPT_BUILTIN += $(IPT_CLUSTER-y)
@@ -360,7 +402,6 @@ 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)

+ 1 - 1
include/nls.mk

@@ -23,7 +23,7 @@ else
 endif
 
 PKG_CONFIG_DEPENDS += CONFIG_BUILD_NLS
-PKG_BUILD_DEPENDS += !BUILD_NLS:libiconv !BUILD_NLS:libintl
+PKG_BUILD_DEPENDS += !BUILD_NLS:libiconv !BUILD_NLS:gettext
 
 ICONV_DEPENDS:=+BUILD_NLS:libiconv-full
 ICONV_CFLAGS:=-I$(ICONV_PREFIX)/include

+ 14 - 4
include/package-bin.mk

@@ -10,6 +10,7 @@ ifeq ($(DUMP),)
     ifeq ($(if $(VARIANT),$(BUILD_VARIANT)),$(VARIANT))
     ifdef Package/$(1)/install
       ifneq ($(CONFIG_PACKAGE_$(1))$(DEVELOPER),)
+        $(_pkg_target)compile: $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
         compile: install-bin-$(1)
       else
         compile: $(1)-disabled
@@ -19,10 +20,19 @@ ifeq ($(DUMP),)
     endif
     endif
 
-    install-bin-$(1): $(STAMP_BUILT)
-	  rm -rf $(BIN_DIR)/$(1)
-	  $(INSTALL_DIR) $(BIN_DIR)/$(1)
-	  $(call Package/$(1)/install,$(BIN_DIR)/$(1))
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed: $(STAMP_BUILT)
+		rm -rf $(PKG_BUILD_DIR)/.pkgdir/$(1) $$@
+		mkdir -p $(PKG_BUILD_DIR)/.pkgdir/$(1)
+		$(call Package/$(1)/install,$(PKG_BUILD_DIR)/.pkgdir/$(1))
+		touch $$@
+
+    install-bin-$(1): $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+	rm -rf $(BIN_DIR)/$(1)
+	-rmdir $(PKG_BUILD_DIR)/.pkgdir/$(1) >/dev/null 2>/dev/null
+	if [ -d $(PKG_BUILD_DIR)/.pkgdir/$(1) ]; then \
+		$(INSTALL_DIR) $(BIN_DIR)/$(1) && \
+		$(CP) $(PKG_BUILD_DIR)/.pkgdir/$(1)/. $(BIN_DIR)/$(1)/; \
+	fi
 
     clean-$(1):
 	  rm -rf $(BIN_DIR)/$(1)

+ 5 - 3
include/package-defaults.mk

@@ -5,7 +5,7 @@
 # See /LICENSE for more information.
 #
 
-PKG_DEFAULT_DEPENDS = +libc +SSP_SUPPORT:libssp +USE_GLIBC:librt +USE_GLIBC:libpthread
+PKG_DEFAULT_DEPENDS = +libc +GCC_LIBSSP: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)))
@@ -56,13 +56,16 @@ define Package/Default
   VARIANT:=
   DEFAULT_VARIANT:=
   USERID:=
+  ALTERNATIVES:=
+  LICENSE:=$(PKG_LICENSE)
+  LICENSE_FILES:=$(PKG_LICENSE_FILES)
 endef
 
 Build/Patch:=$(Build/Patch/Default)
 ifneq ($(strip $(PKG_UNPACK)),)
   define Build/Prepare/Default
 	$(PKG_UNPACK)
-	[ ! -d ./src/ ] || $(CP) ./src/* $(PKG_BUILD_DIR)
+	[ ! -d ./src/ ] || $(CP) ./src/. $(PKG_BUILD_DIR)
 	$(Build/Patch)
   endef
 endif
@@ -92,7 +95,6 @@ CONFIGURE_ARGS = \
 		--mandir=$(CONFIGURE_PREFIX)/man \
 		--infodir=$(CONFIGURE_PREFIX)/info \
 		$(DISABLE_NLS) \
-		$(DISABLE_LARGEFILE) \
 		$(DISABLE_IPV6)
 
 CONFIGURE_VARS = \

+ 13 - 44
include/package-dumpinfo.mk

@@ -7,23 +7,17 @@
 
 ifneq ($(DUMP),)
 
-dumpinfo: FORCE
-
-define Config/template
-Preconfig: $(1)
-Preconfig-Type: $(2)
-Preconfig-Default: $(3)
-Preconfig-Label: $(4)
 
-endef
+define SOURCE_INFO
+$(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)
+)
 
-define Config
-  Preconfig/$(1) = $$(call Config/template,$(1),$(2),$(3),$(4))
-  preconfig_$$(1) += $(1)
 endef
 
 define Dumpinfo/Package
-$(info Package: $(1)
+$(info $(SOURCE_INFO)Package: $(1)
 $(if $(MENU),Menu: $(MENU)
 )$(if $(SUBMENU),Submenu: $(SUBMENU)
 )$(if $(SUBMENUDEP),Submenu-Depends: $(SUBMENUDEP)
@@ -36,18 +30,15 @@ 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)
+))Section: $(SECTION)
 Category: $(CATEGORY)
 $(if $(filter nonshared,$(PKGFLAGS)),,Repository: $(if $(FEED),$(FEED),base)
 )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)
+$(if $(LICENSE),License: $(LICENSE)
+)$(if $(LICENSE_FILES),LicenseFiles: $(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)
@@ -59,33 +50,11 @@ $(if $(URL),$(URL)
 $(if $(Package/$(1)/config),Config:
 $(Package/$(1)/config)
 @@
-)$(foreach pc,$(preconfig_$(1)),
-$(Preconfig/$(pc))))
+))
+SOURCE_INFO :=
 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
+dumpinfo: FORCE
+	$(if $(SOURCE_INFO),$(info $(SOURCE_INFO)))
 
 endif

+ 22 - 28
include/package-ipkg.mk

@@ -106,25 +106,19 @@ ifeq ($(DUMP),)
     ifdef do_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
+        $(_pkg_target)compile: $$(IPKG_$(1)) $(PKG_INFO_DIR)/$(1).provides $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+        prepare-package-install: $$(IPKG_$(1))
+        compile: $(STAGING_DIR_ROOT)/stamp/.$(1)_installed
       else
         $(if $(CONFIG_PACKAGE_$(1)),$$(info WARNING: skipping $(1) -- package not selected))
       endif
 
       .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
       ifeq ($(CONFIG_PACKAGE_$(1)),y)
-			echo "$(1)" >> $(PKG_INSTALL_STAMP)
+        compile: $(PKG_INSTALL_STAMP).$(1)
       endif
+      $(PKG_INSTALL_STAMP).$(1): prepare-package-install
+		echo "$(1)" >> $(PKG_INSTALL_STAMP)
     endif
     endif
 
@@ -140,19 +134,19 @@ ifeq ($(DUMP),)
     $(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)
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed : export PATH=$$(TARGET_PATH_PKG)
+    $(PKG_BUILD_DIR)/.pkgdir/$(1).installed: $(STAMP_BUILT)
+	rm -rf $$@ $(PKG_BUILD_DIR)/.pkgdir/$(1)
+	mkdir -p $(PKG_BUILD_DIR)/.pkgdir/$(1)
+	$(call Package/$(1)/install,$(PKG_BUILD_DIR)/.pkgdir/$(1))
+	$(call Package/$(1)/install_lib,$(PKG_BUILD_DIR)/.pkgdir/$(1))
 	touch $$@
 
-    $(PKG_INFO_DIR)/$(1).version: $$(IPKG_$(1))
-	echo '$(ABI_VERSION)' | cmp -s - $$@ || \
-		echo '$(ABI_VERSION)' > $$@
+    $(STAGING_DIR_ROOT)/stamp/.$(1)_installed: $(PKG_BUILD_DIR)/.pkgdir/$(1).installed
+	mkdir -p $(STAGING_DIR_ROOT)/stamp
+	$(if $(ABI_VERSION),echo '$(ABI_VERSION)' | cmp -s - $(PKG_INFO_DIR)/$(1).version || echo '$(ABI_VERSION)' > $(PKG_INFO_DIR)/$(1).version)
+	$(call locked,$(CP) $(PKG_BUILD_DIR)/.pkgdir/$(1)/. $(STAGING_DIR_ROOT)/,root-copy)
+	touch $$@
 
     Package/$(1)/DEPENDS := $$(call mergelist,$$(filter-out @%,$$(IDEPEND_$(1))))
     ifneq ($$(EXTRA_DEPENDS),)
@@ -165,9 +159,10 @@ Version: $(VERSION)
 $$(call addfield,Depends,$$(Package/$(1)/DEPENDS)
 )$$(call addfield,Conflicts,$$(call mergelist,$(CONFLICTS))
 )$$(call addfield,Provides,$$(call mergelist,$(PROVIDES))
+)$$(call addfield,Alternatives,$$(call mergelist,$(ALTERNATIVES))
 )$$(call addfield,Source,$(SOURCE)
-)$$(call addfield,License,$$(PKG_LICENSE)
-)$$(call addfield,LicenseFiles,$$(PKG_LICENSE_FILES)
+)$$(call addfield,License,$(LICENSE)
+)$$(call addfield,LicenseFiles,$(LICENSE_FILES)
 )$$(call addfield,Section,$(SECTION)
 )$$(call addfield,Require-User,$(USERID)
 )$(if $(filter hold,$(PKG_FLAGS)),Status: unknown hold not-installed
@@ -177,11 +172,10 @@ $$(call addfield,Depends,$$(Package/$(1)/DEPENDS)
 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
+    $(PKG_INFO_DIR)/$(1).provides $$(IPKG_$(1)): $(STAMP_BUILT) $(INCLUDE_DIR)/package-ipkg.mk
 	@rm -rf $$(IDIR_$(1)) $$(call opkg_package_files,$(1))
 	mkdir -p $(PACKAGE_DIR) $$(IDIR_$(1))/CONTROL $(PKG_INFO_DIR)
 	$(call Package/$(1)/install,$$(IDIR_$(1)))
@@ -196,7 +190,7 @@ $(_endef)
 			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)
+	$(if $(PROVIDES),@for pkg in $(filter-out $(1),$(PROVIDES)); do cp $(PKG_INFO_DIR)/$(1).provides $(PKG_INFO_DIR)/$$$$pkg.provides; done)
 	$(CheckDependencies)
 
 	$(RSTRIP) $$(IDIR_$(1))

+ 53 - 37
include/package.mk

@@ -37,10 +37,22 @@ 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
 
+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
+
+include $(INCLUDE_DIR)/quilt.mk
+
 find_library_dependencies = $(wildcard $(patsubst %,$(STAGING_DIR)/pkginfo/%.version, \
 	$(filter-out $(BUILD_PACKAGES),$(foreach dep, \
 		$(filter-out @%, $(patsubst +%,%,$(1))), \
@@ -57,7 +69,7 @@ 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)))
+  STAMP_PREPARED=$(PKG_BUILD_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))_$(call confvar,CONFIG_AUTOREMOVE $(PKG_PREPARED_DEPENDS)))
 endif
 STAMP_CONFIGURED=$(PKG_BUILD_DIR)/.configured$(if $(DUMP),,_$(call confvar,$(PKG_CONFIG_DEPENDS)))
 STAMP_CONFIGURED_WILDCARD=$(PKG_BUILD_DIR)/.configured_*
@@ -76,26 +88,17 @@ define CleanStaging
 	)
 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
 
+_pkg_target:=$(if $(QUILT),,.)
+
 override MAKEFLAGS=
 CONFIG_SITE:=$(INCLUDE_DIR)/site/$(ARCH)
 CUR_MAKEFILE:=$(filter-out Makefile,$(firstword $(MAKEFILE_LIST)))
@@ -117,7 +120,12 @@ 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 .)
+	( cd $(PKG_BUILD_DIR); \
+		git checkout .; \
+		git submodule update --recursive; \
+		git submodule foreach git config --unset core.worktree; \
+		git submodule foreach git checkout .; \
+	)
   endef
 endif
 ifdef USE_SOURCE_DIR
@@ -130,19 +138,23 @@ ifdef USE_SOURCE_DIR
 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 ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR_HOSTPKG)/share/aclocal $$(STAGING_DIR_HOSTPKG)/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
+  $(if $(CONFIG_CCACHE),$(1) : export CCACHE_DIR:=$(STAGING_DIR)/ccache)
 endef
 Build/Exports=$(Build/Exports/Default)
 
 define Build/CoreTargets
+  STAMP_PREPARED:=$$(STAMP_PREPARED)
+  STAMP_CONFIGURED:=$$(STAMP_CONFIGURED)
+
   $(if $(QUILT),$(Build/Quilt))
   $(call Build/Autoclean)
+  $(call DefaultTargets)
 
   download:
 	$(foreach hook,$(Hooks/Download),
@@ -153,6 +165,7 @@ define Build/CoreTargets
   $(STAMP_PREPARED): $(STAMP_PREPARED_DEPENDS)
 	@-rm -rf $(PKG_BUILD_DIR)
 	@mkdir -p $(PKG_BUILD_DIR)
+	touch $$@_check
 	$(foreach hook,$(Hooks/Prepare/Pre),$(call $(hook))$(sep))
 	$(Build/Prepare)
 	$(foreach hook,$(Hooks/Prepare/Post),$(call $(hook))$(sep))
@@ -160,15 +173,17 @@ define Build/CoreTargets
 
   $(call Build/Exports,$(STAMP_CONFIGURED))
   $(STAMP_CONFIGURED): $(STAMP_PREPARED) $(STAMP_CONFIGURED_DEPENDS)
+	rm -f $(STAMP_CONFIGURED_WILDCARD)
 	$(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) $(STAMP_BUILT_DEPENDS)
+	rm -f $$@
+	touch $$@_check
 	$(foreach hook,$(Hooks/Compile/Pre),$(call $(hook))$(sep))
 	$(Build/Compile)
 	$(foreach hook,$(Hooks/Compile/Post),$(call $(hook))$(sep))
@@ -203,13 +218,20 @@ define Build/CoreTargets
 	touch $$@
 
   ifdef Build/InstallDev
-    compile: $(STAMP_INSTALLED)
+    $(_pkg_target)compile: $(STAMP_INSTALLED)
   endif
 
-  prepare: $(STAMP_PREPARED)
-  configure: $(STAMP_CONFIGURED)
-  dist: $(STAMP_CONFIGURED)
-  distcheck: $(STAMP_CONFIGURED)
+  $(_pkg_target)prepare: $(STAMP_PREPARED)
+  $(_pkg_target)configure: $(STAMP_CONFIGURED)
+  $(_pkg_target)dist: $(STAMP_CONFIGURED)
+  $(_pkg_target)distcheck: $(STAMP_CONFIGURED)
+
+  ifneq ($(CONFIG_AUTOREMOVE),)
+    compile:
+		-touch -r $(PKG_BUILD_DIR)/.built $(PKG_BUILD_DIR)/.autoremove 2>/dev/null >/dev/null
+		$(FIND) $(PKG_BUILD_DIR) -mindepth 1 -maxdepth 1 -not '(' -type f -and -name '.*' -and -size 0 ')' -and -not -name '.pkgdir' | \
+			$(XARGS) rm -rf
+  endif
 endef
 
 define Build/DefaultTargets
@@ -220,14 +242,7 @@ define Build/DefaultTargets
   endef
 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)))
 
@@ -281,25 +296,26 @@ Build/DistCheck=$(call Build/DistCheck/Default,)
 .PHONY: prepare-package-install
 prepare-package-install:
 	@mkdir -p $(PKG_INFO_DIR)
-	@touch $(PKG_INSTALL_STAMP).clean
+	@rm -f $(PKG_INSTALL_STAMP)
 	@echo "$(filter-out essential nonshared,$(PKG_FLAGS))" > $(PKG_INSTALL_STAMP).flags
 
 $(PACKAGE_DIR):
 	mkdir -p $@
 
-dumpinfo:
-download:
-prepare:
-configure:
-compile: prepare-package-install
+compile:
+.install: .compile
 install: compile
 
-clean: FORCE
+force-clean-build: FORCE
+	rm -rf $(PKG_BUILD_DIR)
+
+clean-build: $(if $(wildcard $(PKG_BUILD_DIR)/.autoremove),force-clean-build)
+
+clean: force-clean-build
 	$(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)

+ 25 - 24
include/prereq-build.mk

@@ -7,8 +7,6 @@
 
 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
@@ -29,32 +27,40 @@ $(eval $(call TestHostCommand,proper-umask, \
 	umask | grep -xE 00[012][012]))
 
 $(eval $(call SetupHostCommand,gcc, \
-	Please install the GNU C Compiler (gcc), \
-	$(CC) --version | grep gcc, \
-	gcc --version | grep gcc, \
-	gcc49 --version | grep gcc, \
+	Please install the GNU C Compiler (gcc) 4.8 or later, \
+	$(CC) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
+	gcc -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
 	gcc48 --version | grep gcc, \
-	gcc47 --version | grep gcc, \
-	gcc46 --version | grep gcc, \
+	gcc49 --version | grep gcc, \
+	gcc5 --version | grep gcc, \
+	gcc6 --version | grep gcc, \
+	gcc7 --version | grep gcc, \
+	gcc8 --version | grep gcc, \
+	gcc9 --version | grep gcc, \
 	gcc --version | grep Apple.LLVM ))
 
 $(eval $(call TestHostCommand,working-gcc, \
-	Please reinstall the GNU C Compiler - it appears to be broken, \
+	\nPlease reinstall the GNU C Compiler (4.8 or later) - \
+	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++, \
+	Please install the GNU C++ Compiler (g++) 4.8 or later, \
+	$(CXX) -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
+	g++ -dumpversion | grep -E '^(4\.[8-9]|[5-9]\.?)', \
 	g++48 --version | grep g++, \
-	g++47 --version | grep g++, \
-	g++46 --version | grep g++, \
+	g++49 --version | grep g++, \
+	g++5 --version | grep g++, \
+	g++6 --version | grep g++, \
+	g++7 --version | grep g++, \
+	g++8 --version | grep g++, \
+	g++9 --version | grep g++, \
 	g++ --version | grep Apple.LLVM ))
 
 $(eval $(call TestHostCommand,working-g++, \
-	Please reinstall the GNU C++ Compiler - it appears to be broken, \
+	\nPlease reinstall the GNU C++ Compiler (4.8 or later) - \
+	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))
@@ -70,11 +76,6 @@ 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,perl-thread-queue, \
 	Please install the Perl Thread::Queue module, \
 	perl -MThread::Queue -e 1))
@@ -123,9 +124,9 @@ $(eval $(call SetupHostCommand,getopt, \
 	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))
+	gnustat -c%s $(TOPDIR)/Makefile, \
+	gstat -c%s $(TOPDIR)/Makefile, \
+	stat -c%s $(TOPDIR)/Makefile))
 
 $(eval $(call SetupHostCommand,unzip,Please install 'unzip', \
 	unzip 2>&1 | grep zipfile, \

+ 2 - 1
include/prereq.mk

@@ -90,7 +90,8 @@ define SetupHostCommand
 	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 \
+	           $(call QuoteHostCommand,$(9)) $(call QuoteHostCommand,$(10)) \
+	           $(call QuoteHostCommand,$(11)) $(call QuoteHostCommand,$(12)); do \
 		if [ -n "$$$$$$$$cmd" ]; then \
 			bin="$$$$$$$$(PATH="$(subst $(space),:,$(filter-out $(STAGING_DIR_HOST)/%,$(subst :,$(space),$(PATH))))" \
 				which "$$$$$$$${cmd%% *}")"; \

+ 37 - 26
include/quilt.mk

@@ -4,22 +4,43 @@
 # 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)
+ifneq ($(filter host-refresh refresh,$(MAKECMDGOALS)),)
   override QUILT=1
   override HOST_QUILT=1
 endif
 
+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=
+    override CONFIG_AUTOREMOVE=
+    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=
+    override CONFIG_AUTOREMOVE=
+    host-quilt-check: $(HOST_STAMP_CHECKED)
+  endif
+endif
+
+ifneq ($(if $(DUMP),1,$(__quilt_inc)),1)
+__quilt_inc:=1
+
+PATCH_DIR?=./patches
+FILES_DIR?=./files
+HOST_PATCH_DIR?=$(PATCH_DIR)
+HOST_FILES_DIR?=$(FILES_DIR)
+
 QUILT_CMD:=quilt --quiltrc=-
 
 define filter_series
@@ -59,24 +80,6 @@ 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),)
@@ -94,7 +97,13 @@ define Kernel/Patch/Default
 	$(if $(QUILT),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
+	if [ -d $(GENERIC_PLATFORM_DIR)/patches$(if $(wildcard $(GENERIC_PLATFORM_DIR)/patches-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) ]; then \
+		echo "generic patches directory is present. please move your patches to the pending directory" ; \
+		exit 1; \
+	fi
+	$(call PatchDir,$(PKG_BUILD_DIR),$(GENERIC_BACKPORT_DIR),generic-backport/)
 	$(call PatchDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call PatchDir,$(PKG_BUILD_DIR),$(GENERIC_HACK_DIR),generic-hack/)
 	$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
 endef
 
@@ -121,7 +130,9 @@ define Quilt/Refresh/Kernel
 		echo "All kernel patches must start with either generic/ or platform/"; \
 		false; \
 	}
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_BACKPORT_DIR),generic-backport/)
 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_PATCH_DIR),generic/)
+	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(GENERIC_HACK_DIR),generic-hack/)
 	$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR),platform/)
 endef
 

+ 15 - 7
include/rootfs.mk

@@ -1,5 +1,3 @@
-include $(INCLUDE_DIR)/feeds.mk
-
 ifdef CONFIG_USE_MKLIBS
   define mklibs
 	rm -rf $(TMP_DIR)/mklibs-progs $(TMP_DIR)/mklibs-out
@@ -49,17 +47,25 @@ TARGET_DIR_ORIG := $(TARGET_ROOTFS_DIR)/root.orig-$(BOARD)
 
 ifdef CONFIG_CLEAN_IPKG
   define clean_ipkg
-	-find $(1)/usr/lib/opkg -type f -and -not -name '*.control' | $(XARGS) rm -rf
+	-find $(1)/usr/lib/opkg/info -type f -and -not -name '*.control' | $(XARGS) rm -rf
 	-sed -i -ne '/^Require-User: /p' $(1)/usr/lib/opkg/info/*.control
+	awk ' \
+		BEGIN { conffiles = 0; print "Conffiles:" } \
+		/^Conffiles:/ { conffiles = 1; next } \
+		!/^ / { conffiles = 0; next } \
+		conffiles == 1 { print } \
+	' $(1)/usr/lib/opkg/status >$(1)/usr/lib/opkg/status.new
+	mv $(1)/usr/lib/opkg/status.new $(1)/usr/lib/opkg/status
 	-find $(1)/usr/lib/opkg -empty | $(XARGS) rm -rf
   endef
 endif
 
 define prepare_rootfs
-	@if [ -d $(TOPDIR)/files ]; then \
-		$(call file_copy,$(TOPDIR)/files/.,$(1)); \
-	fi
+	$(if $(2),@if [ -d '$(2)' ]; then \
+		$(call file_copy,$(2)/.,$(1)); \
+	fi)
 	@mkdir -p $(1)/etc/rc.d
+	@mkdir -p $(1)/var/lock
 	@( \
 		cd $(1); \
 		for script in ./usr/lib/opkg/info/*.postinst; do \
@@ -80,9 +86,11 @@ define prepare_rootfs
 	@-find $(1) -name .svn  | $(XARGS) rm -rf
 	@-find $(1) -name .git  | $(XARGS) rm -rf
 	@-find $(1) -name '.#*' | $(XARGS) rm -f
+	rm -rf $(1)/tmp/*
 	rm -f $(1)/usr/lib/opkg/lists/*
 	rm -f $(1)/usr/lib/opkg/info/*.postinst*
-	rm -f $(1)/usr/lib/opkg/info/*.prerm*
+	rm -f $(1)/var/lock/*.lock
+	rm -rf $(1)/boot
 	$(call clean_ipkg,$(1))
 	$(call mklibs,$(1))
 endef

+ 1 - 1
include/scan.awk

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

+ 9 - 3
include/scan.mk

@@ -3,8 +3,6 @@ TMP_DIR:=$(TOPDIR)/tmp
 
 all: $(TMP_DIR)/.$(SCAN_TARGET)
 
-include $(TOPDIR)/include/host.mk
-
 SCAN_TARGET ?= packageinfo
 SCAN_NAME ?= package
 SCAN_DIR ?= package
@@ -12,6 +10,14 @@ 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)
 
+export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)
+
+ifeq ($(SCAN_NAME),target)
+  SCAN_DEPS=image/Makefile profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk image/*.mk
+else
+  SCAN_DEPS=$(TOPDIR)/include/package*.mk
+endif
+
 ifeq ($(IS_TTY),1)
   define progress
 	printf "\033[M\r$(1)" >&2;
@@ -56,7 +62,7 @@ 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 > $@
+	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)
 	( \

+ 26 - 0
include/site/powerpc64

@@ -0,0 +1,26 @@
+#!/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_char=1
+ac_cv_sizeof_char_p=8
+ac_cv_sizeof_double=8
+ac_cv_sizeof_float=4
+ac_cv_sizeof_int=4
+ac_cv_sizeof_long=8
+ac_cv_sizeof_long_double=16
+ac_cv_sizeof_long_int=8
+ac_cv_sizeof_long_long=8
+ac_cv_sizeof_long_long_int=8
+ac_cv_sizeof_short=2
+ac_cv_sizeof_short_int=2
+ac_cv_sizeof_signed_char=1
+ac_cv_sizeof_unsigned_char=1
+ac_cv_sizeof_unsigned_int=4
+ac_cv_sizeof_unsigned_long=8
+ac_cv_sizeof_unsigned_long_int=8
+ac_cv_sizeof_unsigned_long_long_int=8
+ac_cv_sizeof_unsigned_short=2
+ac_cv_sizeof_unsigned_short_int=2
+ac_cv_sizeof_void_p=8

+ 23 - 8
include/subdir.mk

@@ -9,7 +9,7 @@ ifeq ($(MAKECMDGOALS),prereq)
   SUBTARGETS:=prereq
   PREREQ_ONLY:=1
 else
-  SUBTARGETS:=clean download prepare compile install update refresh prereq dist distcheck configure check
+  SUBTARGETS:=$(DEFAULT_SUBDIR_TARGETS)
 endif
 
 subtarget-default = $(filter-out ., \
@@ -29,6 +29,11 @@ endef
 lastdir=$(word $(words $(subst /, ,$(1))),$(subst /, ,$(1)))
 diralias=$(if $(findstring $(1),$(call lastdir,$(1))),,$(call lastdir,$(1)))
 
+subdir_make_opts = \
+	-r -C $(1) \
+		BUILD_SUBDIR="$(1)" \
+		BUILD_VARIANT="$(4)"
+
 # 1: subdir
 # 2: target
 # 3: build type
@@ -38,26 +43,36 @@ log_make = \
 	 $(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)" \
+	$(SCRIPT_DIR)/time.pl "time: $(1)$(if $(4),/$(4))/$(if $(3),$(3)-)$(2)" \
+	$$(SUBMAKE) $(subdir_make_opts) $(if $(3),$(3)-)$(2) \
 		$(if $(BUILD_LOG),SILENT= 2>&1 | tee $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4))/$(if $(3),$(3)-)$(2).txt)
 
+ifdef CONFIG_AUTOREMOVE
+rebuild_check = \
+	@-$$(NO_TRACE_MAKE) $(subdir_make_opts) check-depends >/dev/null 2>/dev/null; \
+		$(if $(BUILD_LOG),mkdir -p $(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4));) \
+		$$(NO_TRACE_MAKE) $(if $(BUILD_LOG),-d) -q $(subdir_make_opts) .$(if $(3),$(3)-)$(2) \
+			> $(if $(BUILD_LOG),$(BUILD_LOG_DIR)/$(1)$(if $(4),/$(4))/check-$(if $(3),$(3)-)$(2).txt,/dev/null) 2>&1 || \
+			$$(SUBMAKE) $(subdir_make_opts) clean-build >/dev/null 2>/dev/null
+
+endif
+
 # 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 target,$(SUBTARGETS) $($(1)/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 warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(NO_DEPS)$(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))))
+      $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(NO_DEPS)$(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)))
+			$(if $($(1)/autoremove),$(call rebuild_check,$(1)/$(bd),$(target),,$(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))).))
         )
@@ -67,7 +82,7 @@ define subdir
 	  )
 	)
   )
-  $(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target)))
+  $(foreach target,$(SUBTARGETS) $($(1)/subtargets),$(call subtarget,$(1),$(target)))
 endef
 
 ifndef DUMP_TARGET_DB

+ 26 - 9
include/target.mk

@@ -13,11 +13,11 @@ __target_inc=1
 DEVICE_TYPE?=router
 
 # Default packages - the really basic set
-DEFAULT_PACKAGES:=base-files ca-bundle libmbedtls libustream-mbedtls libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd
+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 ppp-mod-pppoa firewall odhcpd odhcp6c
+DEFAULT_PACKAGES.router:=dnsmasq iptables ip6tables ppp ppp-mod-pppoe firewall odhcpd-ipv6only odhcp6c kmod-ipt-offload
 DEFAULT_PACKAGES.bootloader:=
 
 ifneq ($(DUMP),)
@@ -51,11 +51,15 @@ else
   endif
 endif
 
+ifneq ($(filter 3.18 4.9,$(KERNEL_PATCHVER)),)
+  DEFAULT_PACKAGES.router:=$(filter-out kmod-ipt-offload,$(DEFAULT_PACKAGES.router))
+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)
+extra_packages = $(if $(filter wpad-mini wpad-basic wpad nas,$(1)),iwinfo)
 
 define ProfileDefault
   NAME:=
@@ -68,6 +72,7 @@ define Profile
   $(eval $(call ProfileDefault))
   $(eval $(call Profile/$(1)))
   dumpinfo : $(call shexport,Profile/$(1)/Description)
+  PACKAGES := $(filter-out -%,$(PACKAGES))
   DUMPINFO += \
 	echo "Target-Profile: $(1)"; \
 	$(if $(PRIORITY), echo "Target-Profile-Priority: $(PRIORITY)"; ) \
@@ -104,7 +109,9 @@ ifneq ($(TARGET_BUILD)$(if $(DUMP),,1),)
 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_BACKPORT_DIR := $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER))
+GENERIC_HACK_DIR := $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(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
@@ -167,7 +174,7 @@ ifeq ($(DUMP),1)
     CPU_CFLAGS_mips64 = -mips64 -mtune=mips64 -mabi=64
     CPU_CFLAGS_24kc = -mips32r2 -mtune=24kc
     CPU_CFLAGS_74kc = -mips32r2 -mtune=74kc
-    CPU_CFLAGS_octeon = -march=octeon -mabi=64
+    CPU_CFLAGS_octeonplus = -march=octeon+ -mabi=64
   endif
   ifeq ($(ARCH),i386)
     CPU_TYPE ?= pentium
@@ -186,6 +193,7 @@ ifeq ($(DUMP),1)
     CPU_CFLAGS_cortex-a9 = -mcpu=cortex-a9
     CPU_CFLAGS_cortex-a15 = -mcpu=cortex-a15
     CPU_CFLAGS_cortex-a53 = -mcpu=cortex-a53
+    CPU_CFLAGS_cortex-a72 = -mcpu=cortex-a72
     CPU_CFLAGS_fa526 = -mcpu=fa526
     CPU_CFLAGS_mpcore = -mcpu=mpcore
     CPU_CFLAGS_xscale = -mcpu=xscale
@@ -203,20 +211,29 @@ ifeq ($(DUMP),1)
     CPU_CFLAGS_440:=-mcpu=440
     CPU_CFLAGS_464fp:=-mcpu=464fp
   endif
+  ifeq ($(ARCH),powerpc64)
+    CPU_TYPE ?= powerpc64
+    CPU_CFLAGS_powerpc64:=-mcpu=powerpc64
+  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
+    CPU_TYPE ?= generic
+    CPU_CFLAGS_generic = -mcpu=generic
     CPU_CFLAGS_cortex-a53 = -mcpu=cortex-a53
   endif
   ifeq ($(ARCH),arc)
     CPU_TYPE ?= arc700
     CPU_CFLAGS += -matomic
-    CPU_CFLAGS_arc700 = -marc700
-    CPU_CFLAGS_archs = -marchs
+    CPU_CFLAGS_arc700 = -mcpu=arc700
+    CPU_CFLAGS_archs = -mcpu=archs
+  endif
+  ifneq ($(CPU_TYPE),)
+    ifndef CPU_CFLAGS_$(CPU_TYPE)
+      $(warning CPU_TYPE "$(CPU_TYPE)" doesn't correspond to a known type)
+    endif
   endif
   DEFAULT_CFLAGS=$(strip $(CPU_CFLAGS) $(CPU_CFLAGS_$(CPU_TYPE)) $(CPU_CFLAGS_$(CPU_SUBTYPE)))
 

+ 2 - 2
include/toolchain-build.mk

@@ -6,9 +6,9 @@
 #
 
 override CONFIG_AUTOREBUILD=
+override CONFIG_AUTOREMOVE=
 
-REAL_STAGING_DIR_HOST:=$(STAGING_DIR_HOST)
-STAGING_DIR_HOST:=$(TOOLCHAIN_DIR)
+HOST_BUILD_PREFIX:=$(TOOLCHAIN_DIR)
 BUILD_DIR_HOST:=$(BUILD_DIR_TOOLCHAIN)
 
 include $(INCLUDE_DIR)/host-build.mk

+ 34 - 16
include/toplevel.mk

@@ -1,4 +1,4 @@
-# Makefile for OpenWrt
+# Makefile for libreCMC
 #
 # Copyright (C) 2007-2012 OpenWrt.org
 #
@@ -6,7 +6,7 @@
 # See /LICENSE for more information.
 #
 
-PREP_MK= OPENWRT_BUILD= QUIET=0
+PREP_MK= LIBRECMC_BUILD= QUIET=0
 
 export IS_TTY=$(shell tty -s && echo 1 || echo 0)
 
@@ -25,6 +25,9 @@ export SOURCE_DATE_EPOCH
 export GIT_CONFIG_PARAMETERS='core.autocrlf=false'
 export GIT_ASKPASS:=/bin/true
 export MAKE_JOBSERVER=$(filter --jobserver%,$(MAKEFLAGS))
+export GNU_HOST_NAME:=$(shell $(TOPDIR)/scripts/config.guess)
+export HOST_OS:=$(shell uname)
+export HOST_ARCH:=$(shell uname -m)
 
 # prevent perforce from messing with the patch utility
 unexport P4PORT P4USER P4CONFIG P4CLIENT
@@ -79,8 +82,8 @@ _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="image/Makefile profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1"
+	$(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" 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_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/$${type}-metadata.pl $(_ignore) config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \
@@ -92,7 +95,7 @@ prepare-tmpinfo: FORCE
 
 .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; \
+		[ -e $(HOME)/.librecmc/defconfig ] && cp $(HOME)/.librecmc/defconfig .config; \
 		$(_SINGLE)$(NO_TRACE_MAKE) menuconfig $(PREP_MK); \
 	fi
 
@@ -101,19 +104,24 @@ scripts/config/mconf:
 
 $(eval $(call rdep,scripts/config,scripts/config/mconf))
 
+scripts/config/qconf:
+	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config qconf CC="$(HOSTCC_WRAPPER)"
+
 scripts/config/conf:
 	@$(_SINGLE)$(SUBMAKE) -s -C scripts/config conf CC="$(HOSTCC_WRAPPER)"
 
 config: scripts/config/conf prepare-tmpinfo FORCE
-	$< Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< Config.in
 
 config-clean: FORCE
 	$(_SINGLE)$(NO_TRACE_MAKE) -C scripts/config clean
 
 defconfig: scripts/config/conf prepare-tmpinfo FORCE
 	touch .config
-	@if [ ! -s .config -a -e $(HOME)/.openwrt/defconfig ]; then cp $(HOME)/.openwrt/defconfig .config; fi
-	$< --defconfig=.config Config.in
+	@if [ ! -s .config -a -e $(HOME)/.librecmc/defconfig ]; then cp $(HOME)/.librecmc/defconfig .config; fi
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< --defconfig=.config Config.in
 
 confdefault-y=allyes
 confdefault-m=allmod
@@ -121,19 +129,27 @@ confdefault-n=allno
 confdefault:=$(confdefault-$(CONFDEFAULT))
 
 oldconfig: scripts/config/conf prepare-tmpinfo FORCE
-	$< --$(if $(confdefault),$(confdefault),old)config Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< --$(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; \
+	if [ \! -e .config -a -e $(HOME)/.librecmc/defconfig ]; then \
+		cp $(HOME)/.librecmc/defconfig .config; \
 	fi
-	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; $< Config.in
+	[ -L .config ] && export KCONFIG_OVERWRITECONFIG=1; \
+		$< Config.in
+
+xconfig: scripts/config/qconf prepare-tmpinfo FORCE
+	if [ \! -e .config -a -e $(HOME)/.librecmc/defconfig ]; then \
+		cp $(HOME)/.librecmc/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
+	@+$(SUBMAKE) -r tools/quilt/compile
 else
   prepare_kernel_conf: ;
 endif
@@ -149,7 +165,6 @@ kernel_nconfig: prepare_kernel_conf
 
 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; \
@@ -183,7 +198,10 @@ prereq:: prepare-tmpinfo .config
 check: .config FORCE
 	@+$(NO_TRACE_MAKE) -r -s $@ QUIET= V=s
 
-WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(OPENWRT_VERBOSE))))
+val.%: FORCE
+	@+$(NO_TRACE_MAKE) -r -s $@ QUIET= V=s
+
+WARN_PARALLEL_ERROR = $(if $(BUILD_LOG),,$(and $(filter -j,$(MAKEFLAGS)),$(findstring s,$(LIBRECMC_VERBOSE))))
 
 ifeq ($(SDK),1)
 
@@ -228,7 +246,7 @@ help:
 	cat README
 
 distclean:
-	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/openwrt-packages staging_dir tmp
+	rm -rf bin build_dir .config* dl feeds key-build* logs package/feeds package/librecmc-packages staging_dir tmp
 	@$(_SINGLE)$(SUBMAKE) -C scripts/config clean
 
 ifeq ($(findstring v,$(DEBUG)),)

+ 104 - 0
include/u-boot.mk

@@ -0,0 +1,104 @@
+PKG_NAME ?= u-boot
+
+ifndef PKG_SOURCE_PROTO
+PKG_SOURCE = $(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL = \
+	http://sources.lede-project.org \
+	ftp://ftp.denx.de/pub/u-boot
+endif
+
+PKG_BUILD_DIR = $(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_TARGETS := bin
+PKG_FLAGS:=nonshared
+
+PKG_LICENSE:=GPL-2.0 GPL-2.0+
+PKG_LICENSE_FILES:=Licenses/README
+
+PKG_BUILD_PARALLEL:=1
+
+export GCC_HONOUR_COPTS=s
+
+define Package/u-boot/install/default
+	$(CP) $(patsubst %,$(PKG_BUILD_DIR)/%,$(UBOOT_IMAGE)) $(1)/
+endef
+
+Package/u-boot/install = $(Package/u-boot/install/default)
+
+define U-Boot/Init
+  BUILD_TARGET:=
+  BUILD_SUBTARGET:=
+  BUILD_DEVICES:=
+  NAME:=
+  DEPENDS:=
+  HIDDEN:=
+  DEFAULT:=
+  VARIANT:=$(1)
+  UBOOT_CONFIG:=$(1)
+  UBOOT_IMAGE:=u-boot.bin
+endef
+
+TARGET_DEP = TARGET_$(BUILD_TARGET)$(if $(BUILD_SUBTARGET),_$(BUILD_SUBTARGET))
+
+UBOOT_MAKE_FLAGS = \
+	HOSTCC="$(HOSTCC)" \
+	HOSTCFLAGS="$(HOST_CFLAGS) $(HOST_CPPFLAGS)" \
+	HOSTLDFLAGS="$(HOST_LDFLAGS)"
+
+define Build/U-Boot/Target
+  $(eval $(call U-Boot/Init,$(1)))
+  $(eval $(call U-Boot/Default,$(1)))
+  $(eval $(call U-Boot/$(1),$(1)))
+
+ define Package/u-boot-$(1)
+    SECTION:=boot
+    CATEGORY:=Boot Loaders
+    TITLE:=U-Boot for $(NAME)
+    VARIANT:=$(VARIANT)
+    DEPENDS:=@!IN_SDK $(DEPENDS)
+    HIDDEN:=$(HIDDEN)
+    ifneq ($(BUILD_TARGET),)
+      DEPENDS += @$(TARGET_DEP)
+      ifneq ($(BUILD_DEVICES),)
+        DEFAULT := y if ($(TARGET_DEP)_Default \
+		$(patsubst %,|| $(TARGET_DEP)_DEVICE_%,$(BUILD_DEVICES)) \
+		$(patsubst %,|| $(patsubst TARGET_%,TARGET_DEVICE_%,$(TARGET_DEP))_DEVICE_%,$(BUILD_DEVICES)))
+      endif
+    endif
+    $(if $(DEFAULT),DEFAULT:=$(DEFAULT))
+    URL:=http://www.denx.de/wiki/U-Boot
+  endef
+
+  define Package/u-boot-$(1)/install
+	$$(Package/u-boot/install)
+  endef
+endef
+
+define Build/Configure/U-Boot
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) $(UBOOT_CONFIGURE_VARS) $(UBOOT_CONFIG)_config
+endef
+
+DTC=$(wildcard $(LINUX_DIR)/scripts/dtc/dtc)
+
+define Build/Compile/U-Boot
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+		CROSS_COMPILE=$(TARGET_CROSS) \
+		$(if $(DTC),DTC="$(DTC)") \
+		$(UBOOT_MAKE_FLAGS)
+endef
+
+define BuildPackage/U-Boot/Defaults
+  Build/Configure/Default = $$$$(Build/Configure/U-Boot)
+  Build/Compile/Default = $$$$(Build/Compile/U-Boot)
+endef
+
+define BuildPackage/U-Boot
+  $(eval $(call BuildPackage/U-Boot/Defaults))
+  $(foreach type,$(if $(DUMP),$(UBOOT_TARGETS),$(BUILD_VARIANT)), \
+    $(eval $(call Build/U-Boot/Target,$(type)))
+  )
+  $(eval $(call Build/DefaultTargets))
+  $(foreach type,$(if $(DUMP),$(UBOOT_TARGETS),$(BUILD_VARIANT)), \
+    $(call BuildPackage,u-boot-$(type))
+  )
+endef

+ 19 - 0
include/upstream.mk

@@ -0,0 +1,19 @@
+#
+# Copyright (c) libreCMC Project <info@librecmc.org>
+# Copyright (c) Robert Call <bob@bobcall.me>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+EXCLUDE_DIRS:=target/linux/ath79/* \
+	target/linux/ar71xx/* \
+	target/linux/x86/* \
+	target/linux/xburst/* \
+	target/linux/Makefile \
+
+
+find ./ $(foreach exclude,$(EXCLUDE_DIRS),! --path"$(exclude)")
+
+
+clean_src:
+	

+ 11 - 11
include/verbose.mk

@@ -5,22 +5,22 @@
 # See /LICENSE for more information.
 #
 
-ifndef OPENWRT_VERBOSE
-  OPENWRT_VERBOSE:=
+ifndef LIBRECMC_VERBOSE
+  LIBRECMC_VERBOSE:=
 endif
 ifeq ("$(origin V)", "command line")
-  OPENWRT_VERBOSE:=$(V)
+  LIBRECMC_VERBOSE:=$(V)
 endif
 
-ifeq ($(OPENWRT_VERBOSE),1)
-  OPENWRT_VERBOSE:=w
+ifeq ($(LIBRECMC_VERBOSE),1)
+  LIBRECMC_VERBOSE:=w
 endif
-ifeq ($(OPENWRT_VERBOSE),99)
-  OPENWRT_VERBOSE:=s
+ifeq ($(LIBRECMC_VERBOSE),99)
+  LIBRECMC_VERBOSE:=s
 endif
 
 ifeq ($(NO_TRACE_MAKE),)
-NO_TRACE_MAKE := $(MAKE) V=s$(OPENWRT_VERBOSE)
+NO_TRACE_MAKE := $(MAKE) V=s$(LIBRECMC_VERBOSE)
 export NO_TRACE_MAKE
 endif
 
@@ -32,7 +32,7 @@ ifeq ($(IS_TTY),1)
   endif
 endif
 
-ifeq ($(findstring s,$(OPENWRT_VERBOSE)),)
+ifeq ($(findstring s,$(LIBRECMC_VERBOSE)),)
   define MESSAGE
 	printf "$(_Y)%s$(_N)\n" "$(1)" >&8
   endef
@@ -52,9 +52,9 @@ ifeq ($(findstring s,$(OPENWRT_VERBOSE)),)
     ))
     SUBMAKE=$(MAKE)
   else
-    SILENT:=>/dev/null $(if $(findstring w,$(OPENWRT_VERBOSE)),,2>&1)
+    SILENT:=>/dev/null $(if $(findstring w,$(LIBRECMC_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
+    SUBMAKE=cmd() { $(SILENT) $(MAKE) -s "$$@" < /dev/null || { echo "make $$*: build failed. Please re-run make with -j1 V=s or V=sc for a higher verbosity level to see what's going on"; false; } } 8>&1 9>&2; cmd
   endif
 
   .SILENT: $(MAKECMDGOALS)

+ 41 - 42
include/version.mk

@@ -10,13 +10,11 @@
 # REVISION:=x
 # SOURCE_DATE_EPOCH:=x
 
-RELEASE:=Dropstart-next
-
 PKG_CONFIG_DEPENDS += \
+	CONFIG_VERSION_HOME_URL \
 	CONFIG_VERSION_BUG_URL \
 	CONFIG_VERSION_NUMBER \
 	CONFIG_VERSION_CODE \
-	CONFIG_VERSION_NICK \
 	CONFIG_VERSION_REPO \
 	CONFIG_VERSION_DIST \
 	CONFIG_VERSION_MANUFACTURER \
@@ -25,43 +23,40 @@ PKG_CONFIG_DEPENDS += \
 	CONFIG_VERSION_SUPPORT_URL \
 	CONFIG_VERSION_HWREV \
 
-qstrip_escape=$(subst ','\'',$(call qstrip,$(1)))
-#'
-
 sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1))))
 
-VERSION_NUMBER:=$(call qstrip_escape,$(CONFIG_VERSION_NUMBER))
+VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER))
 VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),v1.5)
 
-VERSION_CODE:=$(call qstrip_escape,$(CONFIG_VERSION_CODE))
+VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE))
 VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION))
 
-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:=$(call qstrip,$(CONFIG_VERSION_REPO))
 VERSION_REPO:=$(if $(VERSION_REPO),$(VERSION_REPO),https://librecmc.org/librecmc/downloads/snapshots/%v)
 
-VERSION_DIST:=$(call qstrip_escape,$(CONFIG_VERSION_DIST))
+VERSION_DIST:=$(call qstrip,$(CONFIG_VERSION_DIST))
 VERSION_DIST:=$(if $(VERSION_DIST),$(VERSION_DIST),libreCMC)
 VERSION_DIST_SANITIZED:=$(call sanitize,$(VERSION_DIST))
 
-VERSION_MANUFACTURER:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER))
+VERSION_MANUFACTURER:=$(call qstrip,$(CONFIG_VERSION_MANUFACTURER))
 VERSION_MANUFACTURER:=$(if $(VERSION_MANUFACTURER),$(VERSION_MANUFACTURER),libreCMC)
 
-VERSION_MANUFACTURER_URL:=$(call qstrip_escape,$(CONFIG_VERSION_MANUFACTURER_URL))
+VERSION_MANUFACTURER_URL:=$(call qstrip,$(CONFIG_VERSION_MANUFACTURER_URL))
 VERSION_MANUFACTURER_URL:=$(if $(VERSION_MANUFACTURER_URL),$(VERSION_MANUFACTURER_URL),https://librecmc.org)
 
-VERSION_BUG_URL:=$(call qstrip_escape,$(CONFIG_VERSION_BUG_URL))
-VERSION_BUG_URL:=$(if $(VERSION_BUG_URL),$(VERSION_BUG_URL),https://gogs.librecmc.org/libreCMC/libreCMC/issues)
+VERSION_BUG_URL:=$(call qstrip,$(CONFIG_VERSION_BUG_URL))
+VERSION_BUG_URL:=$(if $(VERSION_BUG_URL),$(VERSION_BUG_URL),https://gogs.librecmc.org/librecmc/librecmc/issues)
+
+VERSION_HOME_URL:=$(call qstrip,$(CONFIG_VERSION_HOME_URL))
+VERSION_HOME_URL:=$(if $(VERSION_HOME_URL),$(VERSION_HOME_URL),https://librecmc.org)
 
-VERSION_SUPPORT_URL:=$(call qstrip_escape,$(CONFIG_VERSION_SUPPORT_URL))
+VERSION_SUPPORT_URL:=$(call qstrip,$(CONFIG_VERSION_SUPPORT_URL))
 VERSION_SUPPORT_URL:=$(if $(VERSION_SUPPORT_URL),$(VERSION_SUPPORT_URL))
 
-VERSION_PRODUCT:=$(call qstrip_escape,$(CONFIG_VERSION_PRODUCT))
+VERSION_PRODUCT:=$(call qstrip,$(CONFIG_VERSION_PRODUCT))
 VERSION_PRODUCT:=$(if $(VERSION_PRODUCT),$(VERSION_PRODUCT),Generic)
 
-VERSION_HWREV:=$(call qstrip_escape,$(CONFIG_VERSION_HWREV))
+VERSION_HWREV:=$(call qstrip,$(CONFIG_VERSION_HWREV))
 VERSION_HWREV:=$(if $(VERSION_HWREV),$(VERSION_HWREV),v0)
 
 define taint2sym
@@ -88,25 +83,29 @@ VERSION_TAINTS := $(strip $(foreach taint,$(VERSION_TAINT_SPECS), \
 
 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,%A,$(ARCH_PACKAGES),g' \
-	-e 's,%t,$(VERSION_TAINTS),g' \
-	-e 's,%M,$(VERSION_MANUFACTURER),g' \
-	-e 's,%m,$(VERSION_MANUFACTURER_URL),g' \
-	-e 's,%b,$(VERSION_BUG_URL),g' \
-	-e 's,%s,$(VERSION_SUPPORT_URL),g' \
-	-e 's,%P,$(VERSION_PRODUCT),g' \
-	-e 's,%h,$(VERSION_HWREV),g'
-
-VERSION_SED_SCRIPT:=$(subst '\'','\'\\\\\'\'',$(VERSION_SED))
+# escape commas, backslashes, squotes, and ampersands for sed
+define sed_escape
+$(subst &,\&,$(subst $(comma),\$(comma),$(subst ','\'',$(subst \,\\,$(1)))))
+endef
+#'
+
+VERSION_SED_SCRIPT:=$(SED) 's,%U,$(call sed_escape,$(VERSION_REPO)),g' \
+	-e 's,%V,$(call sed_escape,$(VERSION_NUMBER)),g' \
+	-e 's,%v,\L$(call sed_escape,$(subst $(space),_,$(VERSION_NUMBER))),g' \
+	-e 's,%C,$(call sed_escape,$(VERSION_CODE)),g' \
+	-e 's,%c,\L$(call sed_escape,$(subst $(space),_,$(VERSION_CODE))),g' \
+	-e 's,%D,$(call sed_escape,$(VERSION_DIST)),g' \
+	-e 's,%d,\L$(call sed_escape,$(subst $(space),_,$(VERSION_DIST))),g' \
+	-e 's,%R,$(call sed_escape,$(REVISION)),g' \
+	-e 's,%T,$(call sed_escape,$(BOARD)),g' \
+	-e 's,%S,$(call sed_escape,$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic)),g' \
+	-e 's,%A,$(call sed_escape,$(ARCH_PACKAGES)),g' \
+	-e 's,%t,$(call sed_escape,$(VERSION_TAINTS)),g' \
+	-e 's,%M,$(call sed_escape,$(VERSION_MANUFACTURER)),g' \
+	-e 's,%m,$(call sed_escape,$(VERSION_MANUFACTURER_URL)),g' \
+	-e 's,%b,$(call sed_escape,$(VERSION_BUG_URL)),g' \
+	-e 's,%u,$(call sed_escape,$(VERSION_HOME_URL)),g' \
+	-e 's,%s,$(call sed_escape,$(VERSION_SUPPORT_URL)),g' \
+	-e 's,%P,$(call sed_escape,$(VERSION_PRODUCT)),g' \
+	-e 's,%h,$(call sed_escape,$(VERSION_HWREV)),g'
+

+ 9 - 7
package/Makefile

@@ -7,11 +7,12 @@
 
 curdir:=package
 
+include $(INCLUDE_DIR)/feeds.mk
 include $(INCLUDE_DIR)/rootfs.mk
 
 -include $(TMP_DIR)/.packagedeps
+$(curdir)/autoremove:=1
 $(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))
 ifdef CHECK_ALL
@@ -56,10 +57,14 @@ $(curdir)/merge:
 $(curdir)/merge-index: $(curdir)/merge
 	(cd $(PACKAGE_DIR_ALL) && $(SCRIPT_DIR)/ipkg-make-index.sh . 2>&1 > Packages; )
 
-$(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/compile $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
+ifndef SDK
+  $(curdir)/compile: $(curdir)/system/opkg/host/compile
+endif
+
+$(curdir)/install: $(TMP_DIR)/.build $(curdir)/merge $(if $(CONFIG_TARGET_PER_DEVICE_ROOTFS),$(curdir)/merge-index)
 	- find $(STAGING_DIR_ROOT) -type d | $(XARGS) chmod 0755
 	rm -rf $(TARGET_DIR) $(TARGET_DIR_ORIG)
-	[ -d $(TARGET_DIR)/tmp ] || mkdir -p $(TARGET_DIR)/tmp
+	mkdir -p $(TARGET_DIR)/tmp
 	$(call opkg,$(TARGET_DIR)) install \
 		$(call opkg_package_files,$(shell cat $(PACKAGE_INSTALL_FILES) 2>/dev/null))
 	@for file in $(PACKAGE_INSTALL_FILES); do \
@@ -68,11 +73,10 @@ $(curdir)/install: $(TMP_DIR)/.build $(curdir)/system/opkg/host/compile $(curdir
 			$(call opkg,$(TARGET_DIR)) flag $$flag `cat $$file`; \
 		done; \
 	done || true
-	@-$(MAKE) package/preconfig
 
 	$(CP) $(TARGET_DIR) $(TARGET_DIR_ORIG)
 
-	$(call prepare_rootfs,$(TARGET_DIR))
+	$(call prepare_rootfs,$(TARGET_DIR),$(TOPDIR)/files)
 
 $(curdir)/index: FORCE
 	@echo Generating package index...
@@ -92,8 +96,6 @@ ifdef CONFIG_SIGNED_PACKAGES
 	); done
 endif
 
-$(curdir)/preconfig:
-
 $(curdir)/flags-install:= -j1
 
 $(eval $(call stampfile,$(curdir),package,prereq,.config))

+ 43 - 18
package/base-files/Makefile

@@ -9,17 +9,23 @@
 include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 include $(INCLUDE_DIR)/version.mk
+include $(INCLUDE_DIR)/feeds.mk
 
 PKG_NAME:=base-files
-PKG_RELEASE:=173.1
+PKG_RELEASE:=196
 PKG_FLAGS:=nonshared
 
 PKG_FILE_DEPENDS:=$(PLATFORM_DIR)/ $(GENERIC_PLATFORM_DIR)/base-files/
-PKG_BUILD_DEPENDS:=usign/host
+PKG_BUILD_DEPENDS:=usign/host ucert/host
 PKG_LICENSE:=GPL-2.0
 
 # Extend depends from version.mk
-PKG_CONFIG_DEPENDS += CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE
+PKG_CONFIG_DEPENDS += \
+	CONFIG_SIGNED_PACKAGES CONFIG_TARGET_INIT_PATH CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE \
+	CONFIG_NAND_SUPPORT \
+	CONFIG_CLEAN_IPKG \
+	CONFIG_PER_FEED_REPO \
+	$(foreach feed,$(FEEDS_AVAILABLE),CONFIG_FEED_$(feed))
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -31,39 +37,39 @@ endif
 define Package/base-files
   SECTION:=base
   CATEGORY:=Base system
-  DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:librecmc-keyring +fstools +fwtool
-  TITLE:=Base filesystem for Lede
+  DEPENDS:=+netifd +libc +procd +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:librecmc-keyring +NAND_SUPPORT:ubi-utils +fstools +fwtool
+  TITLE:=Base filesystem for libreCMC
   URL:=http://openwrt.org/
   VERSION:=$(PKG_RELEASE)-$(REVISION)
 endef
 
 define Package/base-files/conffiles
+/etc/config/
 /etc/config/network
 /etc/config/system
+/etc/crontabs/
+/etc/dropbear/
+/etc/ethers
+/etc/group
 /etc/hosts
 /etc/inittab
-/etc/group
+/etc/iproute2/rt_protos
+/etc/iproute2/rt_tables
 /etc/passwd
-/etc/shadow
 /etc/profile
+/etc/profile.d
 /etc/protocols
+/etc/rc.local
 /etc/services
+/etc/shadow
 /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
-/etc/iproute2/rt_protos
 $(call $(TARGET)/conffiles)
 endef
 
 define Package/base-files/description
- This package contains a base filesystem and system scripts for OpenWrt.
+ This package contains a base filesystem and system scripts for libreCMC.
 endef
 
 define ImageConfigOptions
@@ -97,6 +103,9 @@ ifdef CONFIG_SIGNED_PACKAGES
 	[ -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"
 
+	[ -s $(BUILD_KEY).ucert ] || \
+		$(STAGING_DIR_HOST)/bin/ucert -I -c $(BUILD_KEY).ucert -p $(BUILD_KEY).pub -s $(BUILD_KEY)
+
   endef
 
   define Package/base-files/install-key
@@ -106,9 +115,16 @@ ifdef CONFIG_SIGNED_PACKAGES
   endef
 endif
 
+ifeq ($(CONFIG_NAND_SUPPORT),)
+  define Package/base-files/nand-support
+	rm -f $(1)/lib/upgrade/nand.sh
+  endef
+endif
+
 define Package/base-files/install
 	$(CP) ./files/* $(1)/
 	$(Package/base-files/install-key)
+	$(Package/base-files/nand-support)
 	if [ -d $(GENERIC_PLATFORM_DIR)/base-files/. ]; then \
 		$(CP) $(GENERIC_PLATFORM_DIR)/base-files/* $(1)/; \
 	fi
@@ -121,7 +137,7 @@ define Package/base-files/install
 		fi; \
 	)
 
-	$(VERSION_SED) \
+	$(VERSION_SED_SCRIPT) \
 		$(1)/etc/banner \
 		$(1)/etc/openwrt_version \
 		$(1)/usr/lib/os-release
@@ -155,7 +171,7 @@ define Package/base-files/install
 	mkdir -p $(1)/root
 	$(LN) /proc/mounts $(1)/etc/mtab
 	rm -f $(1)/var
-	$(LN) /tmp $(1)/var
+	$(LN) tmp $(1)/var
 	mkdir -p $(1)/etc
 	$(LN) /tmp/resolv.conf /tmp/TZ /tmp/localtime $(1)/etc/
 
@@ -170,6 +186,15 @@ define Package/base-files/install
 				echo "$$$${conffile##$(1)}" >> $(1)/CONTROL/conffiles; \
 		fi \
 	done
+
+	$(if $(CONFIG_INCLUDE_CONFIG), \
+		echo -e "# Build configuration for board $(BOARD)/$(SUBTARGET)/$(PROFILE)\n" >$(1)/etc/build.config; \
+		cat $(BIN_DIR)/config.seed >>$(1)/etc/build.config)
+
+	$(if $(CONFIG_CLEAN_IPKG),, \
+		mkdir -p $(1)/etc/opkg; \
+		$(call FeedSourcesAppend,$(1)/etc/opkg/distfeeds.conf); \
+		$(VERSION_SED_SCRIPT) $(1)/etc/opkg/distfeeds.conf)
 endef
 
 ifneq ($(DUMP),1)

+ 36 - 24
package/base-files/files/bin/config_generate

@@ -15,17 +15,21 @@ generate_static_network() {
 		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
+		[ -e /proc/sys/net/ipv6 ] && {
+			uci -q batch <<-EOF
+				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
+					local vpi vci encaps payload nameprefix
+					json_get_vars vpi vci encaps payload nameprefix
 					uci -q batch <<-EOF
 						delete network.atm
 						set network.atm='atm-bridge'
@@ -33,6 +37,7 @@ generate_static_network() {
 						set network.atm.vci='$vci'
 						set network.atm.encaps='$encaps'
 						set network.atm.payload='$payload'
+						set network.atm.nameprefix='$nameprefix'
 					EOF
 				json_select ..
 			fi
@@ -101,21 +106,23 @@ generate_network() {
 				set network.$1.proto='static'
 				set network.$1.ipaddr='$ipad'
 				set network.$1.netmask='$netm'
-				set network.$1.ip6assign='60'
 			EOF
+			[ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60'
 		;;
 
 		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
+			uci set network.$1.proto='dhcp'
+			[ -e /proc/sys/net/ipv6 ] && {
+				uci -q batch <<-EOF
+					delete network.${1}6
+					set network.${1}6='interface'
+					set network.${1}6.ifname='$ifname'
+					set network.${1}6.proto='dhcpv6'
+				EOF
+			}
 		;;
 
 		pppoe)
@@ -123,12 +130,16 @@ generate_network() {
 				set network.$1.proto='pppoe'
 				set network.$1.username='username'
 				set network.$1.password='password'
-				set network.$1.ipv6='1'
-				delete network.${1}6
-				set network.${1}6='interface'
-				set network.${1}6.ifname='@${1}'
-				set network.${1}6.proto='dhcpv6'
 			EOF
+			[ -e /proc/sys/net/ipv6 ] && {
+				uci -q batch <<-EOF
+					set network.$1.ipv6='1'
+					delete network.${1}6
+					set network.${1}6='interface'
+					set network.${1}6.ifname='@${1}'
+					set network.${1}6.proto='dhcpv6'
+				EOF
+			}
 		;;
 	esac
 }
@@ -233,10 +244,10 @@ generate_static_system() {
 		set system.ntp='timeserver'
 		set system.ntp.enabled='1'
 		set system.ntp.enable_server='0'
-		add_list system.ntp.server='0.lede.pool.ntp.org'
-		add_list system.ntp.server='1.lede.pool.ntp.org'
-		add_list system.ntp.server='2.lede.pool.ntp.org'
-		add_list system.ntp.server='3.lede.pool.ntp.org'
+		add_list system.ntp.server='0.openwrt.pool.ntp.org'
+		add_list system.ntp.server='1.openwrt.pool.ntp.org'
+		add_list system.ntp.server='2.openwrt.pool.ntp.org'
+		add_list system.ntp.server='3.openwrt.pool.ntp.org'
 	EOF
 
 	if json_is_a system object; then
@@ -355,11 +366,12 @@ generate_led() {
 		;;
 
 		switch)
-			local port_mask speed_mask
-			json_get_vars port_mask speed_mask
+			local port_mask speed_mask mode
+			json_get_vars port_mask speed_mask mode
 			uci -q batch <<-EOF
 				set system.$cfg.port_mask='$port_mask'
 				set system.$cfg.speed_mask='$speed_mask'
+				set system.$cfg.mode='$mode'
 			EOF
 		;;
 

+ 3 - 1
package/base-files/files/etc/banner.failsafe

@@ -8,6 +8,8 @@ after mount_root:
 * /etc/config		    directory with config files
 
 for more help see:
-http://wiki.openwrt.org/doc/howto/generic.failsafe
+https://openwrt.org/docs/guide-user/troubleshooting/
+- failsafe_and_factory_reset
+- root_password_reset
 =======================================================
 

+ 48 - 2
package/base-files/files/etc/diag.sh

@@ -1,4 +1,50 @@
 #!/bin/sh
-# Copyright (C) 2006-2009 OpenWrt.org
+# Copyright (C) 2006-2019 OpenWrt.org
 
-set_state() { :; }
+. /lib/functions/leds.sh
+
+boot="$(get_dt_led boot)"
+failsafe="$(get_dt_led failsafe)"
+running="$(get_dt_led running)"
+upgrade="$(get_dt_led upgrade)"
+
+set_led_state() {
+	status_led="$boot"
+
+	case "$1" in
+	preinit)
+		status_led_blink_preinit
+		;;
+	failsafe)
+		status_led_off
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_off
+		}
+		status_led="$failsafe"
+		status_led_blink_failsafe
+		;;
+	preinit_regular)
+		status_led_blink_preinit_regular
+		;;
+	upgrade)
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_off
+		}
+		status_led="$upgrade"
+		status_led_blink_preinit_regular
+		;;
+	done)
+		status_led_off
+		[ -n "$running" ] && {
+			status_led="$running"
+			status_led_on
+		}
+		;;
+	esac
+}
+
+set_state() {
+	[ -n "$boot" -o -n "$failsafe" -o -n "$running" -o -n "$upgrade" ] && set_led_state "$1"
+}

+ 6 - 0
package/base-files/files/etc/ethers

@@ -0,0 +1,6 @@
+#
+#  Lookup man 5 ethers for syntax documentation
+#
+#  Examples :
+#	02:00:11:22:33:44	libreCMC.lan
+#	02:00:11:22:33:44	192.168.10.1

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

@@ -1,6 +1,7 @@
 root:x:0:
 daemon:x:1:
 adm:x:4:
+tty:x:5:
 mail:x:8:
 audio:x:29:
 www-data:x:33:

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

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

+ 10 - 4
package/base-files/files/etc/init.d/gpio_switch

@@ -1,7 +1,7 @@
 #!/bin/sh /etc/rc.common
 # Copyright (C) 2015 OpenWrt.org
 
-START=98
+START=94
 STOP=10
 USE_PROCD=1
 
@@ -22,10 +22,16 @@ load_gpio_switch()
 		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"
+
+	# direction attribute only exists if the kernel supports changing the
+	# direction of a GPIO
+	if [ -e "${gpio_path}/direction" ]; then
+		# set the pin to output with high or low pin value
+		{ [ "$value" = "0" ] && echo "low" || echo "high"; } >"$gpio_path/direction"
+	else
+		{ [ "$value" = "0" ] && echo "0" || echo "1"; } >"$gpio_path/value"
+	fi
 }
 
 service_triggers()

+ 8 - 2
package/base-files/files/etc/init.d/led

@@ -20,7 +20,7 @@ load_led() {
 	config_get trigger $1 trigger "none"
 	config_get dev $1 dev
 	config_get ports $1 port
-	config_get mode $1 mode "link"
+	config_get mode $1 mode
 	config_get_bool default $1 default "nil"
 	config_get delayon $1 delayon
 	config_get delayoff $1 delayoff
@@ -71,7 +71,11 @@ load_led() {
 		"netdev")
 			[ -n "$dev" ] && {
 				echo $dev > /sys/class/leds/${sysfs}/device_name
-				echo $mode > /sys/class/leds/${sysfs}/mode
+				for m in $mode; do
+					[ -e "/sys/class/leds/${sysfs}/$m" ] && \
+						echo 1 > /sys/class/leds/${sysfs}/$m
+				done
+				echo $interval > /sys/class/leds/${sysfs}/interval
 			}
 			;;
 
@@ -109,6 +113,8 @@ load_led() {
 			config_get speed_mask $1 speed_mask
 			[ -n "$speed_mask" ] && \
 				echo $speed_mask > /sys/class/leds/${sysfs}/speed_mask
+			[ -n "$mode" ] && \
+				echo "$mode" > /sys/class/leds/${sysfs}/mode
 			;;
 		esac
 	}

+ 30 - 11
package/base-files/files/etc/init.d/sysctl

@@ -3,23 +3,42 @@
 
 START=11
 
-set_vm_min_free() {
-	mem="$(grep MemTotal /proc/meminfo  | awk '{print $2}')"
+apply_defaults() {
+	local mem="$(awk '/^MemTotal:/ {print $2}' /proc/meminfo)"
+	local min_free frag_low_thresh frag_high_thresh
+
 	if [ "$mem" -gt 65536 ]; then # 128M
-		val=16384
+		min_free=16384
 	elif [ "$mem" -gt 32768 ]; then # 64M
-		val=8192
-	elif [ "$mem" -gt 16384 ]; then # 32M
-		val=1024
+		min_free=8192
 	else
-		return
+		min_free=1024
+		frag_low_thresh=393216
+		frag_high_thresh=524288
+	fi
+
+	sysctl -qw vm.min_free_kbytes="$min_free"
+
+	[ "$frag_low_thresh" ] && sysctl -qw \
+		net.ipv4.ipfrag_low_thresh="$frag_low_thresh" \
+		net.ipv4.ipfrag_high_thresh="$frag_high_thresh" \
+		net.ipv6.ip6frag_low_thresh="$frag_low_thresh" \
+		net.ipv6.ip6frag_high_thresh="$frag_high_thresh" \
+		net.netfilter.nf_conntrack_frag6_low_thresh="$frag_low_thresh" \
+		net.netfilter.nf_conntrack_frag6_high_thresh="$frag_high_thresh"
+
+	# first set default, then all interfaces to avoid races with appearing interfaces
+	if [ -d /proc/sys/net/ipv6/conf ]; then
+		echo 0 > /proc/sys/net/ipv6/conf/default/accept_ra
+		for iface in /proc/sys/net/ipv6/conf/*/accept_ra; do
+			echo 0 > "$iface"
+		done
 	fi
-	sysctl -qw vm.min_free_kbytes="$val"
 }
 
 start() {
-	set_vm_min_free
-	for CONF in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
-		[ -f "$CONF" ] && sysctl -p "$CONF" -e >&-
+	apply_defaults
+	for CONF in /etc/sysctl.d/*.conf /etc/sysctl.conf; do
+		[ -f "$CONF" ] && sysctl -e -p "$CONF" >&-
 	done
 }

+ 1 - 1
package/base-files/files/etc/init.d/system

@@ -7,7 +7,7 @@ USE_PROCD=1
 validate_system_section()
 {
 	uci_validate_section system system "${1}" \
-		'hostname:string:librecmc' \
+		'hostname:string:libreCMC' \
 		'conloglevel:uinteger' \
 		'buffersize:uinteger' \
 		'timezone:string:UTC' \

+ 8 - 0
package/base-files/files/etc/iproute2/ematch_map

@@ -0,0 +1,8 @@
+# lookup table for ematch kinds
+1	cmp
+2	nbyte
+3	u32
+4	meta
+7	canid
+8	ipset
+9	ipt

+ 1 - 2
package/base-files/files/etc/openwrt_release

@@ -1,8 +1,7 @@
 DISTRIB_ID='%D'
 DISTRIB_RELEASE='%V'
 DISTRIB_REVISION='%R'
-DISTRIB_CODENAME='%n'
 DISTRIB_TARGET='%S'
 DISTRIB_ARCH='%A'
-DISTRIB_DESCRIPTION='%D %N %V %C'
+DISTRIB_DESCRIPTION='%D %V %C'
 DISTRIB_TAINTS='%t'

+ 9 - 2
package/base-files/files/etc/profile

@@ -1,6 +1,9 @@
 #!/bin/sh
+[ -e /tmp/.failsafe ] && export FAILSAFE=1
+
 [ -f /etc/banner ] && cat /etc/banner
-[ -e /tmp/.failsafe ] && cat /etc/banner.failsafe
+[ -n "$FAILSAFE" ] && cat /etc/banner.failsafe
+
 fgrep -sq '/ overlay ro,' /proc/mounts && {
 	echo 'Your JFFS2-partition seems full and overlayfs is mounted read-only.'
 	echo 'Please try to remove files from /overlay/upper/... and reboot!'
@@ -11,7 +14,11 @@ export HOME=$(grep -e "^${USER:-root}:" /etc/passwd | cut -d ":" -f 6)
 export HOME=${HOME:-/root}
 export PS1='\u@\h:\w\$ '
 
-[ "$TERM" = "xterm" ] && export PS1='\[\e]0;\u@\h: \w\a\]'$PS1
+case "$TERM" in
+	xterm*|rxvt*)
+		export PS1='\[\e]0;\u@\h: \w\a\]'$PS1
+		;;
+esac
 
 [ -x /bin/more ] || alias more=less
 [ -x /usr/bin/vim ] && alias vi=vim || alias vim=vi

+ 1 - 1
package/base-files/files/etc/rc.button/reset

@@ -20,7 +20,7 @@ released)
 		echo "REBOOT" > /dev/console
 		sync
 		reboot
-	elif [ "$SEEN" -gt 5 -a -n "$OVERLAY" ]
+	elif [ "$SEEN" -ge 5 -a -n "$OVERLAY" ]
 	then
 		echo "FACTORY RESET" > /dev/console
 		jffs2reset -y && reboot &

+ 17 - 10
package/base-files/files/etc/rc.common

@@ -17,12 +17,13 @@ stop() {
 }
 
 reload() {
-	return 1
+	restart
 }
 
 restart() {
 	trap '' TERM
 	stop "$@"
+	trap - TERM
 	start "$@"
 }
 
@@ -41,14 +42,15 @@ disable() {
 }
 
 enable() {
+	err=1
 	name="$(basename "${initscript}")"
-	disable
-	[ -n "$START" -o -n "$STOP" ] || {
-		echo "/etc/init.d/$name does not have a START or STOP value"
-		return 1
-	}
-	[ "$START" ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}"
-	[ "$STOP"  ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}"
+	[ "$START" ] && \
+		ln -sf "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}" && \
+		err=0
+	[ "$STOP" ] && \
+		ln -sf "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}" && \
+		err=0
+	return $err
 }
 
 enabled() {
@@ -68,7 +70,7 @@ Available commands:
 	start	Start the service
 	stop	Stop the service
 	restart	Restart the service
-	reload	Reload configuration files (or restart if that fails)
+	reload	Reload configuration files (or restart if service does not implement reload)
 	enable	Enable service autostart
 	disable	Disable service autostart
 $EXTRA_HELP
@@ -88,6 +90,10 @@ service_triggers() {
 	return 0
 }
 
+service_data() {
+	return 0
+}
+
 service_running() {
 	return 0
 }
@@ -122,12 +128,14 @@ ${INIT_TRACE:+set -x}
 	}
 
 	stop() {
+		procd_lock
 		stop_service "$@"
 		procd_kill "$(basename ${basescript:-$initscript})" "$1"
 	}
 
 	reload() {
 		if eval "type reload_service" 2>/dev/null >/dev/null; then
+			procd_lock
 			reload_service "$@"
 		else
 			start
@@ -141,5 +149,4 @@ ${INIT_TRACE:+set -x}
 
 ALL_COMMANDS="start stop reload restart boot shutdown enable disable enabled depends ${EXTRA_COMMANDS}"
 list_contains ALL_COMMANDS "$action" || action=help
-[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@" && :'
 $action "$@"

+ 4 - 2
package/base-files/files/etc/services

@@ -29,8 +29,8 @@ kerberos	88/tcp		kerberos5 krb5 kerberos-sec
 kerberos	88/udp		kerberos5 krb5 kerberos-sec
 pop3		110/tcp
 pop3		110/udp
-sunrpc		111/tcp
-sunrpc		111/udp
+sunrpc		111/tcp		rpcbind
+sunrpc		111/udp		rpcbind
 auth		113/tcp		ident
 sftp		115/tcp
 nntp		119/tcp
@@ -76,6 +76,8 @@ afpovertcp	548/tcp
 afpovertcp	548/udp
 nntps		563/tcp		snntp
 nntps		563/udp		snntp
+submission	587/tcp
+submission	587/udp
 ldaps		636/tcp
 ldaps		636/udp
 tinc		655/tcp

+ 1 - 30
package/base-files/files/etc/sysctl.conf

@@ -1,30 +1 @@
-kernel.panic=3
-kernel.core_pattern=/tmp/%e.%t.%p.%s.core
-
-net.ipv4.conf.default.arp_ignore=1
-net.ipv4.conf.all.arp_ignore=1
-net.ipv4.ip_forward=1
-net.ipv4.icmp_echo_ignore_broadcasts=1
-net.ipv4.icmp_ignore_bogus_error_responses=1
-net.ipv4.igmp_max_memberships=100
-net.ipv4.tcp_fin_timeout=30
-net.ipv4.tcp_keepalive_time=120
-net.ipv4.tcp_syncookies=1
-net.ipv4.tcp_timestamps=1
-net.ipv4.tcp_sack=1
-net.ipv4.tcp_dsack=1
-
-net.ipv6.conf.default.forwarding=1
-net.ipv6.conf.all.forwarding=1
-
-net.netfilter.nf_conntrack_acct=1
-net.netfilter.nf_conntrack_checksum=0
-net.netfilter.nf_conntrack_max=16384
-net.netfilter.nf_conntrack_tcp_timeout_established=7440
-net.netfilter.nf_conntrack_udp_timeout=60
-net.netfilter.nf_conntrack_udp_timeout_stream=180
-
-# disable bridge firewalling by default
-net.bridge.bridge-nf-call-arptables=0
-net.bridge.bridge-nf-call-ip6tables=0
-net.bridge.bridge-nf-call-iptables=0
+# Defaults are configured in /etc/sysctl.d/* and can be customized in this file

+ 25 - 0
package/base-files/files/etc/sysctl.d/10-default.conf

@@ -0,0 +1,25 @@
+# Do not edit, changes to this file will be lost on upgrades
+# /etc/sysctl.conf can be used to customize sysctl settings
+
+kernel.panic=3
+kernel.core_pattern=/tmp/%e.%t.%p.%s.core
+fs.suid_dumpable=2
+
+fs.protected_hardlinks=1
+fs.protected_symlinks=1
+
+net.ipv4.conf.default.arp_ignore=1
+net.ipv4.conf.all.arp_ignore=1
+net.ipv4.ip_forward=1
+net.ipv4.icmp_echo_ignore_broadcasts=1
+net.ipv4.icmp_ignore_bogus_error_responses=1
+net.ipv4.igmp_max_memberships=100
+net.ipv4.tcp_fin_timeout=30
+net.ipv4.tcp_keepalive_time=120
+net.ipv4.tcp_syncookies=1
+net.ipv4.tcp_timestamps=1
+net.ipv4.tcp_sack=1
+net.ipv4.tcp_dsack=1
+
+net.ipv6.conf.default.forwarding=1
+net.ipv6.conf.all.forwarding=1

+ 0 - 16
package/base-files/files/etc/uci-defaults/11_migrate-sysctl

@@ -1,16 +0,0 @@
-#!/bin/sh
-
-if [ ! -f "/rom/etc/sysctl.conf" ] || cmp -s "/rom/etc/sysctl.conf" "/etc/sysctl.conf"; then
-	exit 0
-fi
-
-fingerprint="$(md5sum /etc/sysctl.conf)"
-fingerprint="${fingerprint%% *}"
-
-if [ "$fingerprint" = "1b05ebb41f72cb84e5510573cd4aca26" ] || \
-   [ "$fingerprint" = "62deb895be1a7f496040187b7c930e4e" ]; then
-	logger -t migrate-sysctl "Updating sysctl.conf to use current defaults"
-	cp "/rom/etc/sysctl.conf" "/etc/sysctl.conf"
-fi
-
-exit 0

+ 36 - 38
package/base-files/files/lib/functions.sh

@@ -57,16 +57,16 @@ config () {
 	export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$(($CONFIG_NUM_SECTIONS + 1))
 	name="${name:-cfg$CONFIG_NUM_SECTIONS}"
 	append CONFIG_SECTIONS "$name"
-	[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
 	export ${NO_EXPORT:+-n} CONFIG_SECTION="$name"
-	export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype"
+	config_set "$CONFIG_SECTION" "TYPE" "${cfgtype}"
+	[ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name"
 }
 
 option () {
 	local varname="$1"; shift
 	local value="$*"
 
-	export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_${varname}=$value"
+	config_set "$CONFIG_SECTION" "${varname}" "${value}"
 	[ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*"
 }
 
@@ -81,7 +81,7 @@ list() {
 	config_set "$CONFIG_SECTION" "${varname}_ITEM$len" "$value"
 	config_set "$CONFIG_SECTION" "${varname}_LENGTH" "$len"
 	append "CONFIG_${CONFIG_SECTION}_${varname}" "$value" "$LIST_SEP"
-	list_cb "$varname" "$*"
+	[ -n "$NO_CALLBACK" ] || list_cb "$varname" "$*"
 }
 
 config_unset() {
@@ -113,11 +113,8 @@ config_set() {
 	local section="$1"
 	local option="$2"
 	local value="$3"
-	local old_section="$CONFIG_SECTION"
 
-	CONFIG_SECTION="$section"
-	option "$option" "$value"
-	CONFIG_SECTION="$old_section"
+	export ${NO_EXPORT:+-n} "CONFIG_${section}_${option}=${value}"
 }
 
 config_foreach() {
@@ -153,34 +150,29 @@ config_list_foreach() {
 	done
 }
 
-insert_modules() {
-	for m in $*; do
-		if [ -f /etc/modules.d/$m ]; then
-			sed 's/^[^#]/insmod &/' /etc/modules.d/$m | ash 2>&- || :
-		else
-			modprobe $m
-		fi
-	done
-}
-
 default_prerm() {
 	local root="${IPKG_INSTROOT}"
-	local name
+	local pkgname="$(basename ${1%.*})"
+	local ret=0
 
-	name=$(basename ${1%.*})
-	[ -f "$root/usr/lib/opkg/info/${name}.prerm-pkg" ] && . "$root/usr/lib/opkg/info/${name}.prerm-pkg"
+	if [ -f "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" ]; then
+		( . "$root/usr/lib/opkg/info/${pkgname}.prerm-pkg" )
+		ret=$?
+	fi
 
 	local shell="$(which bash)"
-	for i in `cat "$root/usr/lib/opkg/info/${name}.list" | grep "^/etc/init.d/"`; do
+	for i in $(grep -s "^/etc/init.d/" "$root/usr/lib/opkg/info/${pkgname}.list"); do
 		if [ -n "$root" ]; then
 			${shell:-/bin/sh} "$root/etc/rc.common" "$root$i" disable
 		else
 			if [ "$PKG_UPGRADE" != "1" ]; then
 				"$i" disable
 			fi
-			"$i" stop || /bin/true
+			"$i" stop
 		fi
 	done
+
+	return $ret
 }
 
 add_group_and_user() {
@@ -202,7 +194,7 @@ add_group_and_user() {
 			if [ -n "$gname" ] && [ -n "$gid" ]; then
 				group_exists "$gname" || group_add "$gname" "$gid"
 			elif [ -n "$gname" ]; then
-				group_add_next "$gname"; gid=$?
+				gid="$(group_add_next "$gname")"
 			fi
 
 			if [ -n "$uname" ]; then
@@ -235,13 +227,16 @@ default_postinst() {
 		rm -fR $root/rootfs-overlay/
 	fi
 
+	if [ -z "$root" ] && grep -q -s "^/etc/modules.d/" "/usr/lib/opkg/info/${pkgname}.list"; then
+		kmodloader
+	fi
+
 	if [ -z "$root" ] && grep -q -s "^/etc/uci-defaults/" "/usr/lib/opkg/info/${pkgname}.list"; then
 		. /lib/functions/system.sh
 		[ -d /tmp/.uci ] || mkdir -p /tmp/.uci
-		for i in $(sed -ne 's!^/etc/uci-defaults/!!p' "/usr/lib/opkg/info/${pkgname}.list"); do (
-			cd /etc/uci-defaults
-			[ -f "$i" ] && . ./"$i" && rm -f "$i"
-		) done
+		for i in $(grep -s "^/etc/uci-defaults/" "/usr/lib/opkg/info/${pkgname}.list"); do
+			( [ -f "$i" ] && cd "$(dirname $i)" && . "$i" ) && rm -f "$i"
+		done
 		uci commit
 	fi
 
@@ -292,9 +287,7 @@ group_add() {
 	[ -f "${IPKG_INSTROOT}/etc/group" ] || return 1
 	[ -n "$IPKG_INSTROOT" ] || lock /var/lock/group
 	echo "${name}:x:${gid}:" >> ${IPKG_INSTROOT}/etc/group
-	rc=$?
 	[ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/group
-	return $rc
 }
 
 group_exists() {
@@ -304,14 +297,17 @@ group_exists() {
 group_add_next() {
 	local gid gids
 	gid=$(grep -s "^${1}:" ${IPKG_INSTROOT}/etc/group | cut -d: -f3)
-	[ -n "$gid" ] && return $gid
+	if [ -n "$gid" ]; then
+		echo $gid
+		return
+	fi
 	gids=$(cat ${IPKG_INSTROOT}/etc/group | cut -d: -f3)
-	gid=100
-	while [ -n "$(echo $gids | grep $gid)" ] ; do
+	gid=65536
+	while [ -n "$(echo "$gids" | grep "^$gid$")" ] ; do
 	        gid=$((gid + 1))
 	done
 	group_add $1 $gid
-	return $gid
+	echo $gid
 }
 
 group_add_user() {
@@ -334,8 +330,8 @@ user_add() {
 	local rc
 	[ -z "$uid" ] && {
 		uids=$(cat ${IPKG_INSTROOT}/etc/passwd | cut -d: -f3)
-		uid=100
-		while [ -n "$(echo $uids | grep $uid)" ] ; do
+		uid=65536
+		while [ -n "$(echo "$uids" | grep "^$uid$")" ] ; do
 		        uid=$((uid + 1))
 		done
 	}
@@ -344,13 +340,15 @@ user_add() {
 	[ -n "$IPKG_INSTROOT" ] || lock /var/lock/passwd
 	echo "${name}:x:${uid}:${gid}:${desc}:${home}:${shell}" >> ${IPKG_INSTROOT}/etc/passwd
 	echo "${name}:x:0:0:99999:7:::" >> ${IPKG_INSTROOT}/etc/shadow
-	rc=$?
 	[ -n "$IPKG_INSTROOT" ] || lock -u /var/lock/passwd
-	return $rc
 }
 
 user_exists() {
 	grep -qs "^${1}:" ${IPKG_INSTROOT}/etc/passwd
 }
 
+board_name() {
+	[ -e /tmp/sysinfo/board_name ] && cat /tmp/sysinfo/board_name || echo "generic"
+}
+
 [ -z "$IPKG_INSTROOT" -a -f /lib/config/uci.sh ] && . /lib/config/uci.sh

+ 14 - 0
package/base-files/files/lib/functions/leds.sh

@@ -1,6 +1,20 @@
 #!/bin/sh
 # Copyright (C) 2013 OpenWrt.org
 
+get_dt_led() {
+	local label
+	local ledpath
+	local basepath="/proc/device-tree"
+	local nodepath="$basepath/aliases/led-$1"
+
+	[ -f "$nodepath" ] && ledpath=$(cat "$nodepath")
+	[ -n "$ledpath" ] && \
+		label=$(cat "$basepath$ledpath/label" 2>/dev/null) || \
+		label=$(cat "$basepath$ledpath/chan-name" 2>/dev/null)
+
+	echo "$label"
+}
+
 led_set_attr() {
 	[ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2"
 }

+ 14 - 3
package/base-files/files/lib/functions/network.sh

@@ -6,10 +6,16 @@
 __network_ifstatus() {
 	local __tmp
 
-	[ -z "$__NETWORK_CACHE" ] && \
-		export __NETWORK_CACHE="$(ubus call network.interface dump)"
+	[ -z "$__NETWORK_CACHE" ] && {
+		__tmp="$(ubus call network.interface dump 2>&1)"
+		case "$?" in
+			4) : ;;
+			0) export __NETWORK_CACHE="$__tmp" ;;
+			*) echo "$__tmp" >&2 ;;
+		esac
+	}
 
-	__tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "$__NETWORK_CACHE" -e "$1=@.interface${2:+[@.interface='$2']}$3")"
+	__tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "${__NETWORK_CACHE:-{}}" -e "$1=@.interface${2:+[@.interface='$2']}$3")"
 
 	[ -z "$__tmp" ] && \
 		unset "$1" && \
@@ -265,6 +271,11 @@ network_is_up()
 # 2: interface
 network_get_protocol() { __network_ifstatus "$1" "$2" ".proto"; }
 
+# determine the metric of the given logical interface
+# 1: destination variable
+# 2: interface
+network_get_metric() { __network_ifstatus "$1" "$2" ".metric"; }
+
 # determine the layer 3 linux network device of the given logical interface
 # 1: destination variable
 # 2: interface

+ 39 - 13
package/base-files/files/lib/functions/system.sh

@@ -1,5 +1,17 @@
 # Copyright (C) 2006-2013 OpenWrt.org
 
+get_mac_binary() {
+	local path="$1"
+	local offset="$2"
+
+	if [ -z "$path" ]; then
+		echo "get_mac_binary: file $path not found!" >&2
+		return
+	fi
+
+	hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $path 2>/dev/null
+}
+
 find_mtd_chardev() {
 	local INDEX=$(find_mtd_index "$1")
 	local PREFIX=/dev/mtd
@@ -8,8 +20,7 @@ find_mtd_chardev() {
 	echo "${INDEX:+$PREFIX$INDEX}"
 }
 
-mtd_get_mac_ascii()
-{
+mtd_get_mac_ascii() {
 	local mtdname="$1"
 	local key="$2"
 	local part
@@ -27,18 +38,36 @@ mtd_get_mac_ascii()
 	[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
 }
 
-mtd_get_mac_binary() {
-	local mtdname="$1"
-	local offset="$2"
+mtd_get_mac_text() {
+	local mtdname=$1
+	local offset=$2
 	local part
+	local mac_dirty
 
 	part=$(find_mtd_part "$mtdname")
 	if [ -z "$part" ]; then
-		echo "mtd_get_mac_binary: partition $mtdname not found!" >&2
+		echo "mtd_get_mac_text: partition $mtdname not found!" >&2
 		return
 	fi
 
-	hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $part 2>/dev/null
+	if [ -z "$offset" ]; then
+		echo "mtd_get_mac_text: offset missing!" >&2
+		return
+	fi
+
+	mac_dirty=$(dd if="$part" bs=1 skip="$offset" count=17 2>/dev/null)
+
+	# "canonicalize" mac
+	[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+}
+
+mtd_get_mac_binary() {
+	local mtdname="$1"
+	local offset="$2"
+	local part
+
+	part=$(find_mtd_part "$mtdname")
+	get_mac_binary "$part" "$offset"
 }
 
 mtd_get_mac_binary_ubi() {
@@ -80,22 +109,19 @@ macaddr_add() {
 	echo $oui:$nic
 }
 
-macaddr_setbit_la()
-{
+macaddr_setbit_la() {
 	local mac=$1
 
 	printf "%02x:%s" $((0x${mac%%:*} | 0x02)) ${mac#*:}
 }
 
-macaddr_2bin()
-{
+macaddr_2bin() {
 	local mac=$1
 
 	echo -ne \\x${mac//:/\\x}
 }
 
-macaddr_canonicalize()
-{
+macaddr_canonicalize() {
 	local mac="$1"
 	local canon=""
 

+ 131 - 193
package/base-files/files/lib/functions/uci-defaults.sh

@@ -27,30 +27,33 @@ json_select_object() {
 	json_select "$1"
 }
 
-_ucidef_set_interface() {
-	local name="$1"
-	local iface="$2"
-	local proto="$3"
+ucidef_set_interface() {
+	local network=$1; shift
 
-	json_select_object "$name"
-	json_add_string ifname "$iface"
-
-	if ! json_is_a protocol string || [ -n "$proto" ]; then
-		case "$proto" in
-			static|dhcp|none|pppoe) : ;;
-			*)
-				case "$name" in
-					lan) proto="static" ;;
-					wan) proto="dhcp" ;;
-					*) proto="none" ;;
-				esac
-			;;
-		esac
+	[ -z "$network" ] && return
+
+	json_select_object network
+	json_select_object "$network"
+
+	while [ -n "$1" ]; do
+		local opt=$1; shift
+		local val=$1; shift
+
+		[ -n "$opt" -a -n "$val" ] || break
 
-		json_add_string protocol "$proto"
+		json_add_string "$opt" "$val"
+	done
+
+	if ! json_is_a protocol string; then
+		case "$network" in
+			lan) json_add_string protocol static ;;
+			wan) json_add_string protocol dhcp ;;
+			*) json_add_string protocol none ;;
+		esac
 	fi
 
 	json_select ..
+	json_select ..
 }
 
 ucidef_set_board_id() {
@@ -66,31 +69,19 @@ ucidef_set_model_name() {
 }
 
 ucidef_set_interface_lan() {
-	json_select_object network
-	_ucidef_set_interface lan "$@"
-	json_select ..
+	ucidef_set_interface "lan" ifname "$1" protocol "${2:-static}"
 }
 
 ucidef_set_interface_wan() {
-	json_select_object network
-	_ucidef_set_interface wan "$@"
-	json_select ..
+	ucidef_set_interface "wan" ifname "$1" protocol "${2:-dhcp}"
 }
 
 ucidef_set_interfaces_lan_wan() {
 	local lan_if="$1"
 	local wan_if="$2"
 
-	json_select_object network
-	_ucidef_set_interface lan "$lan_if"
-	_ucidef_set_interface wan "$wan_if"
-	json_select ..
-}
-
-ucidef_set_interface_raw() {
-	json_select_object network
-	_ucidef_set_interface "$@"
-	json_select ..
+	ucidef_set_interface_lan "$lan_if"
+	ucidef_set_interface_wan "$wan_if"
 }
 
 _ucidef_add_switch_port() {
@@ -160,7 +151,7 @@ _ucidef_finish_switch_roles() {
 					json_select ..
 				json_select ..
 
-				if [ $n_vlan -gt $n_cpu -o ${need_tag:-0} -eq 1 ]; then
+				if [ ${need_tag:-0} -eq 1 -o ${want_untag:-0} -ne 1 ]; then
 					num="${num}t"
 					device="${device}.${index}"
 				fi
@@ -185,9 +176,9 @@ _ucidef_finish_switch_roles() {
 					devices="${devices:+$devices }$device"
 				fi
 			json_select ..
-
-			_ucidef_set_interface "$role" "$devices"
 		json_select ..
+
+		ucidef_set_interface "$role" ifname "$devices"
 	done
 }
 
@@ -300,18 +291,7 @@ ucidef_set_interface_macaddr() {
 	local network="$1"
 	local macaddr="$2"
 
-	json_select_object network
-
-	json_select "$network"
-	[ $? -eq 0 ] || {
-		json_select ..
-		return
-	}
-
-	json_add_string macaddr "$macaddr"
-	json_select ..
-
-	json_select ..
+	ucidef_set_interface "$network" macaddr "$macaddr"
 }
 
 ucidef_add_atm_bridge() {
@@ -319,6 +299,7 @@ ucidef_add_atm_bridge() {
 	local vci="$2"
 	local encaps="$3"
 	local payload="$4"
+	local nameprefix="$5"
 
 	json_select_object dsl
 		json_select_object atmbridge
@@ -326,6 +307,7 @@ ucidef_add_atm_bridge() {
 			json_add_int vci "$vci"
 			json_add_string encaps "$encaps"
 			json_add_string payload "$payload"
+			json_add_string nameprefix "$nameprefix"
 		json_select ..
 	json_select ..
 }
@@ -358,236 +340,193 @@ ucidef_add_vdsl_modem() {
 	json_select ..
 }
 
-ucidef_set_led_netdev() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local dev="$4"
-	local mode="${5:-link tx rx}"
-
-	json_select_object led
-
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type netdev
-	json_add_string sysfs "$sysfs"
-	json_add_string device "$dev"
-	json_add_string mode "$mode"
-	json_select ..
-
-	json_select ..
+ucidef_set_led_ataport() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" ata"$4"
 }
 
-ucidef_set_led_usbdev() {
+_ucidef_set_led_common() {
 	local cfg="led_$1"
 	local name="$2"
 	local sysfs="$3"
-	local dev="$4"
 
 	json_select_object led
 
 	json_select_object "$1"
 	json_add_string name "$name"
-	json_add_string type usb
 	json_add_string sysfs "$sysfs"
-	json_add_string device "$dev"
-	json_select ..
-
-	json_select ..
 }
 
-ucidef_set_led_usbport() {
-	local obj="$1"
-	local name="$2"
-	local sysfs="$3"
-	shift
-	shift
-	shift
+ucidef_set_led_default() {
+	local default="$4"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$obj"
-	json_add_string name "$name"
-	json_add_string type usbport
-	json_add_string sysfs "$sysfs"
-	json_select_array ports
-		for port in "$@"; do
-			json_add_string port "$port"
-		done
-	json_select ..
+	json_add_string default "$default"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_wlan() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
+ucidef_set_led_gpio() {
+	local gpio="$4"
+	local inverted="$5"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type trigger
-	json_add_string sysfs "$sysfs"
 	json_add_string trigger "$trigger"
+	json_add_string type gpio
+	json_add_int gpio "$gpio"
+	json_add_boolean inverted "$inverted"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_switch() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
-	local port_mask="$5"
-	local speed_mask="$6"
+ucidef_set_led_ide() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" ide-disk
+}
 
-	json_select_object led
+ucidef_set_led_netdev() {
+	local dev="$4"
+	local mode="${5:-link tx rx}"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type switch
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger "$trigger"
-	json_add_string port_mask "$port_mask"
-	json_add_string speed_mask "$speed_mask"
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string type netdev
+	json_add_string device "$dev"
+	json_add_string mode "$mode"
 	json_select ..
 
 	json_select ..
 }
 
+ucidef_set_led_oneshot() {
+	_ucidef_set_led_timer $1 $2 $3 "oneshot" $4 $5
+}
+
 ucidef_set_led_portstate() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
 	local port_state="$4"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string type portstate
-	json_add_string sysfs "$sysfs"
 	json_add_string trigger port_state
+	json_add_string type portstate
 	json_add_string port_state "$port_state"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_default() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local default="$4"
+ucidef_set_led_rssi() {
+	local iface="$4"
+	local minq="$5"
+	local maxq="$6"
+	local offset="${7:-0}"
+	local factor="${8:-1}"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
+	json_add_string type rssi
 	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string default "$default"
+	json_add_string iface "$iface"
+	json_add_string minq "$minq"
+	json_add_string maxq "$maxq"
+	json_add_string offset "$offset"
+	json_add_string factor "$factor"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_gpio() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local gpio="$4"
-	local inverted="$5"
+ucidef_set_led_switch() {
+	local trigger_name="$4"
+	local port_mask="$5"
+	local speed_mask="$6"
+	local mode="$7"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string type gpio
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger "$trigger"
-	json_add_int gpio "$gpio"
-	json_add_boolean inverted "$inverted"
+	json_add_string trigger "$trigger_name"
+	json_add_string type switch
+	json_add_string mode "$mode"
+	json_add_string port_mask "$port_mask"
+	json_add_string speed_mask "$speed_mask"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_ide() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
+_ucidef_set_led_timer() {
+	local trigger_name="$4"
+	local delayon="$5"
+	local delayoff="$6"
 
-	json_select_object led
+	_ucidef_set_led_common "$1" "$2" "$3"
 
-	json_select_object "$1"
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_string trigger ide-disk
+	json_add_string trigger "$trigger_name"
+	json_add_int delayon "$delayon"
+	json_add_int delayoff "$delayoff"
 	json_select ..
 
 	json_select ..
 }
 
-__ucidef_set_led_timer() {
-	local cfg="led_$1"
-	local name="$2"
-	local sysfs="$3"
-	local trigger="$4"
-	local delayon="$5"
-	local delayoff="$6"
+ucidef_set_led_timer() {
+	_ucidef_set_led_timer $1 $2 $3 "timer" $4 $5
+}
 
-	json_select_object led
+_ucidef_set_led_trigger() {
+	local trigger_name="$4"
 
-	json_select_object "$1"
-	json_add_string type "$trigger"
-	json_add_string name "$name"
-	json_add_string sysfs "$sysfs"
-	json_add_int delayon "$delayon"
-	json_add_int delayoff "$delayoff"
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string trigger "$trigger_name"
 	json_select ..
 
 	json_select ..
 }
 
-ucidef_set_led_oneshot() {
-	__ucidef_set_led_timer $1 $2 $3 "oneshot" $4 $5
+ucidef_set_led_usbdev() {
+	local dev="$4"
+
+	_ucidef_set_led_common "$1" "$2" "$3"
+
+	json_add_string type usb
+	json_add_string device "$dev"
+	json_select ..
+
+	json_select ..
 }
 
-ucidef_set_led_timer() {
-	__ucidef_set_led_timer $1 $2 $3 "timer" $4 $5
+ucidef_set_led_usbhost() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" usb-host
 }
 
-ucidef_set_led_rssi() {
-	local cfg="led_$1"
+ucidef_set_led_usbport() {
+	local obj="$1"
 	local name="$2"
 	local sysfs="$3"
-	local iface="$4"
-	local minq="$5"
-	local maxq="$6"
-	local offset="$7"
-	local factor="$8"
+	shift
+	shift
+	shift
 
-	json_select_object led
+	_ucidef_set_led_common "$obj" "$name" "$sysfs"
 
-	json_select_object "$1"
-	json_add_string type rssi
-	json_add_string name "$name"
-	json_add_string iface "$iface"
-	json_add_string sysfs "$sysfs"
-	json_add_string minq "$minq"
-	json_add_string maxq "$maxq"
-	json_add_string offset "$offset"
-	json_add_string factor "$factor"
+	json_add_string type usbport
+	json_select_array ports
+		for port in "$@"; do
+			json_add_string port "$port"
+		done
+	json_select ..
 	json_select ..
 
 	json_select ..
 }
 
+ucidef_set_led_wlan() {
+	_ucidef_set_led_trigger "$1" "$2" "$3" "$4"
+}
+
 ucidef_set_rssimon() {
 	local dev="$1"
 	local refresh="$2"
@@ -601,7 +540,6 @@ ucidef_set_rssimon() {
 	json_select ..
 
 	json_select ..
-
 }
 
 ucidef_add_gpio_switch() {

+ 0 - 0
package/base-files/files/lib/preinit/10_sysinfo → package/base-files/files/lib/preinit/02_sysinfo


+ 5 - 7
package/base-files/files/lib/preinit/10_indicate_preinit

@@ -43,7 +43,10 @@ preinit_config_switch() {
 			json_select ..
 
 			if [ "$device" = "$lan_if" ]; then
-				swconfig dev $name set reset $reset
+				if [ "$reset" -eq "1" ]; then
+					swconfig dev $name set reset
+				fi
+
 				swconfig dev $name set enable_vlan $enable
 				swconfig dev $name vlan $role set ports "$ports"
 				swconfig dev $name set apply
@@ -110,7 +113,7 @@ preinit_ip() {
 		preinit_config_board
 	fi
 
-	preinit_net_echo "Doing Lede Preinit\n"
+	preinit_net_echo "Doing libreCMC Preinit\n"
 }
 
 preinit_ip_deconfig() {
@@ -144,11 +147,6 @@ preinit_net_echo() {
 	}
 }
 
-preinit_echo() {
-	preinit_net_echo $1
-	echo $1
-}
-
 pi_indicate_preinit() {
 	set_state preinit
 }

+ 1 - 1
package/base-files/files/lib/preinit/30_failsafe_wait

@@ -82,7 +82,7 @@ fs_wait_for_key () {
 
 failsafe_wait() {
 	FAILSAFE=
-	[ "$pi_preinit_no_failsafe" == "y" ] && {
+	[ "$pi_preinit_no_failsafe" = "y" ] && {
 		fs_wait_for_key "" "" $fs_failsafe_wait_timeout
 		return
 	}

+ 5 - 1
package/base-files/files/lib/preinit/40_run_failsafe_hook

@@ -5,8 +5,12 @@
 run_failsafe_hook() {
     [ "$pi_preinit_no_failsafe" = "y" ] && return
     if [ "$FAILSAFE" = "true" ]; then
+	lock /tmp/.failsafe
 	boot_run_hook failsafe
-	lock -w /tmp/.failsafe
+	while [ ! -e /tmp/sysupgrade ]; do
+	    lock -w /tmp/.failsafe
+	done
+	exit
     fi
 }
 

+ 1 - 1
package/base-files/files/lib/preinit/81_urandom_seed

@@ -18,7 +18,7 @@ do_urandom_seed() {
     _do_urandom_seed "/etc/urandom.seed"
 
     SEED="$(uci -q get system.@system[0].urandom_seed)"
-    [ "${SEED:0:1}" == "/" -a "$SEED" != "/etc/urandom.seed" ] && _do_urandom_seed "$SEED"
+    [ "${SEED:0:1}" = "/" -a "$SEED" != "/etc/urandom.seed" ] && _do_urandom_seed "$SEED"
 }
 
 boot_hook_add preinit_main do_urandom_seed

+ 7 - 4
package/base-files/files/lib/preinit/99_10_failsafe_login

@@ -8,10 +8,13 @@ failsafe_netlogin () {
 }
 
 failsafe_shell() {
-	lock /tmp/.failsafe
-	ash --login
-	echo "Please reboot system when done with failsafe network logins"
-	while true; do sleep 1; done
+	local console="$(sed -e 's/ /\n/g' /proc/cmdline | grep '^console=' | head -1 | sed -e 's/^console=//' -e 's/,.*//')"
+	[ -n "$console" ] || console=console
+	[ -c "/dev/$console" ] || return 0
+	while true; do
+		ash --login <"/dev/$console" >"/dev/$console" 2>"/dev/$console"
+		sleep 1
+	done &
 }
 
 boot_hook_add failsafe failsafe_netlogin

+ 71 - 160
package/base-files/files/lib/upgrade/common.sh

@@ -6,143 +6,33 @@ RAM_ROOT=/tmp/root
 libs() { ldd $* 2>/dev/null | sed -r 's/(.* => )?(.*) .*/\2/'; }
 
 install_file() { # <file> [ <file> ... ]
+	local target dest dir
 	for file in "$@"; do
+		if [ -L "$file" ]; then
+			target="$(readlink -f "$file")"
+			dest="$RAM_ROOT/$file"
+			[ ! -f "$dest" ] && {
+				dir="$(dirname "$dest")"
+				mkdir -p "$dir"
+				ln -s "$target" "$dest"
+			}
+			file="$target"
+		fi
 		dest="$RAM_ROOT/$file"
-		[ -f $file -a ! -f $dest ] && {
-			dir="$(dirname $dest)"
+		[ -f "$file" -a ! -f "$dest" ] && {
+			dir="$(dirname "$dest")"
 			mkdir -p "$dir"
-			cp $file $dest
+			cp "$file" "$dest"
 		}
 	done
 }
 
-install_bin() { # <file> [ <symlink> ... ]
+install_bin() {
+	local src files
 	src=$1
 	files=$1
 	[ -x "$src" ] && files="$src $(libs $src)"
 	install_file $files
-	shift
-	for link in "$@"; do {
-		dest="$RAM_ROOT/$link"
-		dir="$(dirname $dest)"
-		mkdir -p "$dir"
-		[ -f "$dest" ] || ln -s $src $dest
-	}; done
-}
-
-supivot() { # <new_root> <old_root>
-	/bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
-	mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
-	/bin/mount -o noatime,move /proc $1/proc && \
-	pivot_root $1 $1$2 || {
-		/bin/umount -l $1 $1
-		return 1
-	}
-
-	/bin/mount -o noatime,move $2/sys /sys
-	/bin/mount -o noatime,move $2/dev /dev
-	/bin/mount -o noatime,move $2/tmp /tmp
-	/bin/mount -o noatime,move $2/overlay /overlay 2>&-
-	return 0
-}
-
-run_ramfs() { # <command> [...]
-	install_bin /bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount	\
-		/sbin/pivot_root /sbin/reboot /bin/sync /bin/dd	/bin/grep       \
-		/bin/cp /bin/mv /bin/tar /usr/bin/md5sum "/usr/bin/[" /bin/dd	\
-		/bin/vi /bin/ls /bin/cat /usr/bin/awk /usr/bin/hexdump		\
-		/bin/sleep /bin/zcat /usr/bin/bzcat /usr/bin/printf /usr/bin/wc \
-		/bin/cut /usr/bin/printf /bin/sync /bin/mkdir /bin/rmdir	\
-		/bin/rm /usr/bin/basename /bin/kill /bin/chmod /usr/bin/find \
-		/bin/mknod
-
-	install_bin /bin/uclient-fetch /bin/wget
-	install_bin /sbin/mtd
-	install_bin /sbin/mount_root
-	install_bin /sbin/snapshot
-	install_bin /sbin/snapshot_tool
-	install_bin /usr/sbin/ubiupdatevol
-	install_bin /usr/sbin/ubiattach
-	install_bin /usr/sbin/ubiblock
-	install_bin /usr/sbin/ubiformat
-	install_bin /usr/sbin/ubidetach
-	install_bin /usr/sbin/ubirsvol
-	install_bin /usr/sbin/ubirmvol
-	install_bin /usr/sbin/ubimkvol
-	install_bin /usr/sbin/partx
-	install_bin /usr/sbin/losetup
-	install_bin /usr/sbin/mkfs.ext4
-	for file in $RAMFS_COPY_BIN; do
-		install_bin ${file//:/ }
-	done
-	install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
-
-	[ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
-
-	supivot $RAM_ROOT /mnt || {
-		echo "Failed to switch over to ramfs. Please reboot."
-		exit 1
-	}
-
-	/bin/mount -o remount,ro /mnt
-	/bin/umount -l /mnt
-
-	grep /overlay /proc/mounts > /dev/null && {
-		/bin/mount -o noatime,remount,ro /overlay
-		/bin/umount -l /overlay
-	}
-
-	# spawn a new shell from ramdisk to reduce the probability of cache issues
-	exec /bin/busybox ash -c "$*"
-}
-
-kill_remaining() { # [ <signal> ]
-	local sig="${1:-TERM}"
-	echo -n "Sending $sig to remaining processes ... "
-
-	local my_pid=$$
-	local my_ppid=$(cut -d' ' -f4  /proc/$my_pid/stat)
-	local my_ppisupgraded=
-	grep -q upgraded /proc/$my_ppid/cmdline >/dev/null && {
-		local my_ppisupgraded=1
-	}
-	
-	local stat
-	for stat in /proc/[0-9]*/stat; do
-		[ -f "$stat" ] || continue
-
-		local pid name state ppid rest
-		read pid name state ppid rest < $stat
-		name="${name#(}"; name="${name%)}"
-
-		local cmdline
-		read cmdline < /proc/$pid/cmdline
-
-		# Skip kernel threads
-		[ -n "$cmdline" ] || continue
-
-		if [ $$ -eq 1 ] || [ $my_ppid -eq 1 ] && [ -n "$my_ppisupgraded" ]; then
-			# Running as init process, kill everything except me
-			if [ $pid -ne $$ ] && [ $pid -ne $my_ppid ]; then
-				echo -n "$name "
-				kill -$sig $pid 2>/dev/null
-			fi
-		else 
-			case "$name" in
-				# Skip essential services
-				*procd*|*ash*|*init*|*watchdog*|*ssh*|*dropbear*|*telnet*|*login*|*hostapd*|*wpa_supplicant*|*nas*|*relayd*) : ;;
-
-				# Killable process
-				*)
-					if [ $pid -ne $$ ] && [ $ppid -ne $$ ]; then
-						echo -n "$name "
-						kill -$sig $pid 2>/dev/null
-					fi
-				;;
-			esac
-		fi
-	done
-	echo ""
 }
 
 run_hooks() {
@@ -175,28 +65,31 @@ v() {
 	[ "$VERBOSE" -ge 1 ] && echo "$@"
 }
 
+json_string() {
+	local v="$1"
+	v="${v//\\/\\\\}"
+	v="${v//\"/\\\"}"
+	echo "\"$v\""
+}
+
 rootfs_type() {
 	/bin/mount | awk '($3 ~ /^\/$/) && ($5 !~ /rootfs/) { print $5 }'
 }
 
 get_image() { # <source> [ <command> ]
 	local from="$1"
-	local conc="$2"
-	local cmd
-
-	case "$from" in
-		http://*|ftp://*) cmd="wget -O- -q";;
-		*) cmd="cat";;
-	esac
-	if [ -z "$conc" ]; then
-		local magic="$(eval $cmd \"$from\" 2>/dev/null | dd bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
+	local cmd="$2"
+
+	if [ -z "$cmd" ]; then
+		local magic="$(dd if="$from" bs=2 count=1 2>/dev/null | hexdump -n 2 -e '1/1 "%02x"')"
 		case "$magic" in
-			1f8b) conc="zcat";;
-			425a) conc="bzcat";;
+			1f8b) cmd="zcat";;
+			425a) cmd="bzcat";;
+			*) cmd="cat";;
 		esac
 	fi
 
-	eval "$cmd \"$from\" 2>/dev/null ${conc:+| $conc}"
+	cat "$from" 2>/dev/null | $cmd
 }
 
 get_magic_word() {
@@ -208,7 +101,7 @@ get_magic_long() {
 }
 
 export_bootdevice() {
-	local cmdline uuid disk uevent
+	local cmdline uuid disk uevent line
 	local MAJOR MINOR DEVNAME DEVTYPE
 
 	if read cmdline < /proc/cmdline; then
@@ -241,8 +134,9 @@ export_bootdevice() {
 		esac
 
 		if [ -e "$uevent" ]; then
-			. "$uevent"
-
+			while read line; do
+				export -n "$line"
+			done < "$uevent"
 			export BOOTDEV_MAJOR=$MAJOR
 			export BOOTDEV_MINOR=$MINOR
 			return 0
@@ -254,10 +148,12 @@ export_bootdevice() {
 
 export_partdevice() {
 	local var="$1" offset="$2"
-	local uevent MAJOR MINOR DEVNAME DEVTYPE
+	local uevent line MAJOR MINOR DEVNAME DEVTYPE
 
 	for uevent in /sys/class/block/*/uevent; do
-		. "$uevent"
+		while read line; do
+			export -n "$line"
+		done < "$uevent"
 		if [ $BOOTDEV_MAJOR = $MAJOR -a $(($BOOTDEV_MINOR + $offset)) = $MINOR -a -b "/dev/$DEVNAME" ]; then
 			export "$var=$DEVNAME"
 			return 0
@@ -267,6 +163,14 @@ export_partdevice() {
 	return 1
 }
 
+hex_le32_to_cpu() {
+	[ "$(echo 01 | hexdump -v -n 2 -e '/2 "%x"')" = "3031" ] && {
+		echo "${1:0:2}${1:8:2}${1:6:2}${1:4:2}${1:2:2}"
+		return
+	}
+	echo "$@"
+}
+
 get_partitions() { # <device> <filename>
 	local disk="$1"
 	local filename="$2"
@@ -274,8 +178,8 @@ get_partitions() { # <device> <filename>
 	if [ -b "$disk" -o -f "$disk" ]; then
 		v "Reading partition table from $filename..."
 
-		local magic="$(hexdump -v -n 2 -s 0x1FE -e '1/2 "0x%04X"' "$disk")"
-		if [ "$magic" != 0xAA55 ]; then
+		local magic=$(dd if="$disk" bs=2 count=1 skip=255 2>/dev/null)
+		if [ "$magic" != $'\x55\xAA' ]; then
 			v "Invalid partition table on $disk"
 			exit
 		fi
@@ -286,9 +190,9 @@ get_partitions() { # <device> <filename>
 		for part in 1 2 3 4; do
 			set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
 
-			local type="$(($1 % 256))"
-			local lba="$(($2))"
-			local num="$(($3))"
+			local type="$(( $(hex_le32_to_cpu $1) % 256))"
+			local lba="$(( $(hex_le32_to_cpu $2) ))"
+			local num="$(( $(hex_le32_to_cpu $3) ))"
 
 			[ $type -gt 0 ] || continue
 
@@ -307,6 +211,11 @@ jffs2_copy_config() {
 	fi
 }
 
+indicate_upgrade() {
+	. /etc/diag.sh
+	set_state upgrade
+}
+
 # Flash firmware to MTD partition
 #
 # $(1): path to image
@@ -318,14 +227,17 @@ default_do_upgrade() {
 	else
 		get_image "$1" "$2" | mtd write - "${PART_NAME:-image}"
 	fi
+	[ $? -ne 0 ] && exit 1
 }
 
-do_upgrade() {
+do_upgrade_stage2() {
 	v "Performing system upgrade..."
-	if type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
-		platform_do_upgrade "$ARGV"
+	if [ -n "$do_upgrade" ]; then
+		eval "$do_upgrade"
+	elif type 'platform_do_upgrade' >/dev/null 2>/dev/null; then
+		platform_do_upgrade "$IMAGE"
 	else
-		default_do_upgrade "$ARGV"
+		default_do_upgrade "$IMAGE"
 	fi
 
 	if [ "$SAVE_CONFIG" -eq 1 ] && type 'platform_copy_config' >/dev/null 2>/dev/null; then
@@ -333,12 +245,11 @@ do_upgrade() {
 	fi
 
 	v "Upgrade completed"
-	[ -n "$DELAY" ] && sleep "$DELAY"
-	ask_bool 1 "Reboot" && {
-		v "Rebooting system..."
-		umount -a
-		reboot -f
-		sleep 5
-		echo b 2>/dev/null >/proc/sysrq-trigger
-	}
+	sleep 1
+
+	v "Rebooting system..."
+	umount -a
+	reboot -f
+	sleep 5
+	echo b 2>/dev/null >/proc/sysrq-trigger
 }

+ 23 - 2
package/base-files/files/lib/upgrade/fwtool.sh

@@ -1,5 +1,26 @@
-fwtool_pre_upgrade() {
-	fwtool -q -i /dev/null "$1"
+fwtool_check_signature() {
+	[ $# -gt 1 ] && return 1
+
+	[ ! -x /usr/bin/ucert ] && {
+		if [ "$REQUIRE_IMAGE_SIGNATURE" = 1 ]; then
+			return 1
+		else
+			return 0
+		fi
+	}
+
+	if ! fwtool -q -t -s /tmp/sysupgrade.ucert "$1"; then
+		echo "Image signature not found"
+		[ "$REQUIRE_IMAGE_SIGNATURE" = 1 -a "$FORCE" != 1 ] && {
+			echo "Use sysupgrade -F to override this check when downgrading or flashing to vendor firmware"
+		}
+		[ "$REQUIRE_IMAGE_SIGNATURE" = 1 ] && return 1
+		return 0
+	fi
+
+	ucert -V -m "$1" -c "/tmp/sysupgrade.ucert" -P /etc/opkg/keys
+
+	return $?
 }
 
 fwtool_check_image() {

+ 332 - 0
package/base-files/files/lib/upgrade/nand.sh

@@ -0,0 +1,332 @@
+#!/bin/sh
+# Copyright (C) 2014 OpenWrt.org
+#
+
+. /lib/functions.sh
+
+# 'kernel' partition on NAND contains the kernel
+CI_KERNPART="${CI_KERNPART:-kernel}"
+
+# 'ubi' partition on NAND contains UBI
+CI_UBIPART="${CI_UBIPART:-ubi}"
+
+# 'rootfs' partition on NAND contains the rootfs
+CI_ROOTPART="${CI_ROOTPART:-rootfs}"
+
+ubi_mknod() {
+	local dir="$1"
+	local dev="/dev/$(basename $dir)"
+
+	[ -e "$dev" ] && return 0
+
+	local devid="$(cat $dir/dev)"
+	local major="${devid%%:*}"
+	local minor="${devid##*:}"
+	mknod "$dev" c $major $minor
+}
+
+nand_find_volume() {
+	local ubidevdir ubivoldir
+	ubidevdir="/sys/devices/virtual/ubi/$1"
+	[ ! -d "$ubidevdir" ] && return 1
+	for ubivoldir in $ubidevdir/${1}_*; do
+		[ ! -d "$ubivoldir" ] && continue
+		if [ "$( cat $ubivoldir/name )" = "$2" ]; then
+			basename $ubivoldir
+			ubi_mknod "$ubivoldir"
+			return 0
+		fi
+	done
+}
+
+nand_find_ubi() {
+	local ubidevdir ubidev mtdnum
+	mtdnum="$( find_mtd_index $1 )"
+	[ ! "$mtdnum" ] && return 1
+	for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
+		[ ! -d "$ubidevdir" ] && continue
+		cmtdnum="$( cat $ubidevdir/mtd_num )"
+		[ ! "$mtdnum" ] && continue
+		if [ "$mtdnum" = "$cmtdnum" ]; then
+			ubidev=$( basename $ubidevdir )
+			ubi_mknod "$ubidevdir"
+			echo $ubidev
+			return 0
+		fi
+	done
+}
+
+nand_get_magic_long() {
+	dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
+}
+
+get_magic_long_tar() {
+	( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
+}
+
+identify_magic() {
+	local magic=$1
+	case "$magic" in
+		"55424923")
+			echo "ubi"
+			;;
+		"31181006")
+			echo "ubifs"
+			;;
+		"68737173")
+			echo "squashfs"
+			;;
+		"d00dfeed")
+			echo "fit"
+			;;
+		"4349"*)
+			echo "combined"
+			;;
+		*)
+			echo "unknown $magic"
+			;;
+	esac
+}
+
+
+identify() {
+	identify_magic $(nand_get_magic_long "$1" "${2:-0}")
+}
+
+identify_tar() {
+	identify_magic $(get_magic_long_tar "$1" "$2")
+}
+
+nand_restore_config() {
+	sync
+	local ubidev=$( nand_find_ubi $CI_UBIPART )
+	local ubivol="$( nand_find_volume $ubidev rootfs_data )"
+	[ ! "$ubivol" ] &&
+		ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
+	mkdir /tmp/new_root
+	if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
+		echo "mounting ubifs $ubivol failed"
+		rmdir /tmp/new_root
+		return 1
+	fi
+	mv "$1" "/tmp/new_root/sysupgrade.tgz"
+	umount /tmp/new_root
+	sync
+	rmdir /tmp/new_root
+}
+
+nand_upgrade_prepare_ubi() {
+	local rootfs_length="$1"
+	local rootfs_type="$2"
+	local has_kernel="${3:-0}"
+	local has_env="${4:-0}"
+
+	local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+	if [ ! "$mtdnum" ]; then
+		echo "cannot find ubi mtd partition $CI_UBIPART"
+		return 1
+	fi
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	if [ ! "$ubidev" ]; then
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	fi
+
+	if [ ! "$ubidev" ]; then
+		ubiformat /dev/mtd$mtdnum -y
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+		[ "$has_env" -gt 0 ] && {
+			ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
+			ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
+		}
+	fi
+
+	local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
+	local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
+	local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
+
+	# remove ubiblock device of rootfs
+	local root_ubiblk="ubiblock${root_ubivol:3}"
+	if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then
+		echo "removing $root_ubiblk"
+		if ! ubiblock -r /dev/$root_ubivol; then
+			echo "cannot remove $root_ubiblk"
+			return 1;
+		fi
+	fi
+
+	# kill volumes
+	[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
+	[ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
+	[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
+
+	# update kernel
+	if [ "$has_kernel" = "1" ]; then
+		if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
+			echo "cannot create kernel volume"
+			return 1;
+		fi
+	fi
+
+	# update rootfs
+	local root_size_param
+	if [ "$rootfs_type" = "ubifs" ]; then
+		root_size_param="-m"
+	else
+		root_size_param="-s $rootfs_length"
+	fi
+	if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $root_size_param; then
+		echo "cannot create rootfs volume"
+		return 1;
+	fi
+
+	# create rootfs_data for non-ubifs rootfs
+	if [ "$rootfs_type" != "ubifs" ]; then
+		if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then
+			echo "cannot initialize rootfs_data volume"
+			return 1
+		fi
+	fi
+	sync
+	return 0
+}
+
+nand_do_upgrade_success() {
+	local conf_tar="/tmp/sysupgrade.tgz"
+
+	sync
+	[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
+	echo "sysupgrade successful"
+	umount -a
+	reboot -f
+}
+
+# Flash the UBI image to MTD partition
+nand_upgrade_ubinized() {
+	local ubi_file="$1"
+	local mtdnum="$(find_mtd_index "$CI_UBIPART")"
+
+	[ ! "$mtdnum" ] && {
+		CI_UBIPART="rootfs"
+		mtdnum="$(find_mtd_index "$CI_UBIPART")"
+	}
+
+	if [ ! "$mtdnum" ]; then
+		echo "cannot find mtd device $CI_UBIPART"
+		umount -a
+		reboot -f
+	fi
+
+	local mtddev="/dev/mtd${mtdnum}"
+	ubidetach -p "${mtddev}" || true
+	sync
+	ubiformat "${mtddev}" -y -f "${ubi_file}"
+	ubiattach -p "${mtddev}"
+	nand_do_upgrade_success
+}
+
+# Write the UBIFS image to UBI volume
+nand_upgrade_ubifs() {
+	local rootfs_length=`(cat $1 | wc -c) 2> /dev/null`
+
+	nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
+	ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
+
+	nand_do_upgrade_success
+}
+
+nand_upgrade_tar() {
+	local tar_file="$1"
+	local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
+
+	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
+	board_dir=${board_dir%/}
+
+	local kernel_length=`(tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null`
+	local rootfs_length=`(tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null`
+
+	local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
+
+	local has_kernel=1
+	local has_env=0
+
+	[ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
+		tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART
+	}
+	[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
+
+	nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
+
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	[ "$has_kernel" = "1" ] && {
+		local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)"
+		tar xf $tar_file ${board_dir}/kernel -O | \
+			ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
+	}
+
+	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
+	tar xf $tar_file ${board_dir}/root -O | \
+		ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
+
+	nand_do_upgrade_success
+}
+
+# Recognize type of passed file and start the upgrade process
+nand_do_upgrade() {
+	if [ -n "$IS_PRE_UPGRADE" ]; then
+		# Previously, nand_do_upgrade was called from the platform_pre_upgrade
+		# hook; this piece of code handles scripts that haven't been
+		# updated. All scripts should gradually move to call nand_do_upgrade
+		# from platform_do_upgrade instead.
+		export do_upgrade="nand_do_upgrade '$1'"
+		return
+	fi
+
+	local file_type=$(identify $1)
+
+	if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
+		platform_nand_pre_upgrade "$1"
+	fi
+
+	[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
+
+	case "$file_type" in
+		"ubi")		nand_upgrade_ubinized $1;;
+		"ubifs")	nand_upgrade_ubifs $1;;
+		*)		nand_upgrade_tar $1;;
+	esac
+}
+
+# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
+# 3 types of files:
+# 1) UBI - should contain an ubinized image, header is checked for the proper
+#    MAGIC
+# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
+#    header is checked for the proper MAGIC
+# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
+#    "CONTROL" file (at this point its content isn't verified)
+#
+# You usually want to call this function in platform_check_image.
+#
+# $(1): board name, used in case of passing TAR file
+# $(2): file to be checked
+nand_do_platform_check() {
+	local board_name="$1"
+	local tar_file="$2"
+	local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null`
+	local file_type="$(identify $2)"
+
+	[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
+		echo "Invalid sysupgrade file."
+		return 1
+	}
+
+	return 0
+}

+ 151 - 0
package/base-files/files/lib/upgrade/stage2

@@ -0,0 +1,151 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /lib/functions/system.sh
+
+export IMAGE="$1"
+COMMAND="$2"
+
+export ARGV="$IMAGE"
+export ARGC=1
+
+export SAVE_CONFIG=1
+export SAVE_PARTITIONS=1
+
+export INTERACTIVE=0
+export VERBOSE=1
+export CONFFILES=/tmp/sysupgrade.conffiles
+export CONF_TAR=/tmp/sysupgrade.tgz
+
+RAMFS_COPY_BIN=		# extra programs for temporary ramfs root
+RAMFS_COPY_DATA=	# extra data files
+
+
+[ -f "$CONF_TAR" ] || export SAVE_CONFIG=0
+[ -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap ] && export SAVE_PARTITIONS=0
+
+include /lib/upgrade
+
+
+supivot() { # <new_root> <old_root>
+	/bin/mount | grep "on $1 type" 2>&- 1>&- || /bin/mount -o bind $1 $1
+	mkdir -p $1$2 $1/proc $1/sys $1/dev $1/tmp $1/overlay && \
+	/bin/mount -o noatime,move /proc $1/proc && \
+	pivot_root $1 $1$2 || {
+		/bin/umount -l $1 $1
+		return 1
+	}
+
+	/bin/mount -o noatime,move $2/sys /sys
+	/bin/mount -o noatime,move $2/dev /dev
+	/bin/mount -o noatime,move $2/tmp /tmp
+	/bin/mount -o noatime,move $2/overlay /overlay 2>&-
+	return 0
+}
+
+switch_to_ramfs() {
+	for binary in \
+		/bin/busybox /bin/ash /bin/sh /bin/mount /bin/umount	\
+		pivot_root mount_root reboot sync kill sleep		\
+		md5sum hexdump cat zcat bzcat dd tar			\
+		ls basename find cp mv rm mkdir rmdir mknod touch chmod \
+		'[' printf wc grep awk sed cut				\
+		mtd partx losetup mkfs.ext4				\
+		ubiupdatevol ubiattach ubiblock ubiformat		\
+		ubidetach ubirsvol ubirmvol ubimkvol			\
+		snapshot snapshot_tool					\
+		$RAMFS_COPY_BIN
+	do
+		local file="$(which "$binary" 2>/dev/null)"
+		[ -n "$file" ] && install_bin "$file"
+	done
+	install_file /etc/resolv.conf /lib/*.sh /lib/functions/*.sh /lib/upgrade/*.sh $RAMFS_COPY_DATA
+
+	[ -L "/lib64" ] && ln -s /lib $RAM_ROOT/lib64
+
+	supivot $RAM_ROOT /mnt || {
+		echo "Failed to switch over to ramfs. Please reboot."
+		exit 1
+	}
+
+	/bin/mount -o remount,ro /mnt
+	/bin/umount -l /mnt
+
+	grep /overlay /proc/mounts > /dev/null && {
+		/bin/mount -o noatime,remount,ro /overlay
+		/bin/umount -l /overlay
+	}
+}
+
+kill_remaining() { # [ <signal> [ <loop> ] ]
+	local loop_limit=10
+
+	local sig="${1:-TERM}"
+	local loop="${2:-0}"
+	local run=true
+	local stat
+	local proc_ppid=$(cut -d' ' -f4  /proc/$$/stat)
+
+	echo -n "Sending $sig to remaining processes ... "
+
+	while $run; do
+		run=false
+		for stat in /proc/[0-9]*/stat; do
+			[ -f "$stat" ] || continue
+
+			local pid name state ppid rest
+			read pid name state ppid rest < $stat
+			name="${name#(}"; name="${name%)}"
+
+			# Skip PID1, our parent, ourself and our children
+			[ $pid -ne 1 -a $pid -ne $proc_ppid -a $pid -ne $$ -a $ppid -ne $$ ] || continue
+
+			local cmdline
+			read cmdline < /proc/$pid/cmdline
+
+			# Skip kernel threads
+			[ -n "$cmdline" ] || continue
+
+			echo -n "$name "
+			kill -$sig $pid 2>/dev/null
+
+			[ $loop -eq 1 ] && run=true
+		done
+
+		let loop_limit--
+		[ $loop_limit -eq 0 ] && {
+			echo
+			echo "Failed to kill all processes."
+			exit 1
+		}
+	done
+	echo
+}
+
+indicate_upgrade
+
+killall -9 telnetd
+killall -9 dropbear
+killall -9 ash
+
+kill_remaining TERM
+sleep 3
+kill_remaining KILL 1
+
+sleep 1
+
+
+if [ -n "$IMAGE" ] && type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
+	IS_PRE_UPGRADE=1 platform_pre_upgrade "$IMAGE"
+
+	# Needs to be unset again because of busybox weirdness ...
+	IS_PRE_UPGRADE=
+fi
+
+if [ -n "$(rootfs_type)" ]; then
+	echo "Switching to ramdisk..."
+	switch_to_ramfs
+fi
+
+# Exec new shell from ramfs
+exec /bin/busybox ash -c "$COMMAND"

+ 192 - 61
package/base-files/files/sbin/sysupgrade

@@ -1,17 +1,18 @@
 #!/bin/sh
+
 . /lib/functions.sh
 . /lib/functions/system.sh
 
 # initialize defaults
-RAMFS_COPY_BIN=""	# extra programs for temporary ramfs root
-RAMFS_COPY_DATA=""	# extra data files
 export MTD_CONFIG_ARGS=""
 export INTERACTIVE=0
 export VERBOSE=1
 export SAVE_CONFIG=1
 export SAVE_OVERLAY=0
+export SAVE_OVERLAY_PATH=
 export SAVE_PARTITIONS=1
-export DELAY=
+export SAVE_INSTALLED_PKGS=0
+export SKIP_UNCHANGED=0
 export CONF_IMAGE=
 export CONF_BACKUP_LIST=0
 export CONF_BACKUP=
@@ -20,26 +21,29 @@ export NEED_IMAGE=
 export HELP=0
 export FORCE=0
 export TEST=0
+export UMOUNT_ETCBACKUP_DIR=0
 
 # parse options
 while [ -n "$1" ]; do
 	case "$1" in
 		-i) export INTERACTIVE=1;;
-		-d) export DELAY="$2"; shift;;
 		-v) export VERBOSE="$(($VERBOSE + 1))";;
 		-q) export VERBOSE="$(($VERBOSE - 1))";;
 		-n) export SAVE_CONFIG=0;;
-		-c) export SAVE_OVERLAY=1;;
+		-c) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/etc;;
+		-o) export SAVE_OVERLAY=1 SAVE_OVERLAY_PATH=/;;
 		-p) export SAVE_PARTITIONS=0;;
+		-k) export SAVE_INSTALLED_PKGS=1;;
+		-u) export SKIP_UNCHANGED=1;;
 		-b|--create-backup) export CONF_BACKUP="$2" NEED_IMAGE=1; shift;;
 		-r|--restore-backup) export CONF_RESTORE="$2" NEED_IMAGE=1; shift;;
-		-l|--list-backup) export CONF_BACKUP_LIST=1; break;;
+		-l|--list-backup) export CONF_BACKUP_LIST=1;;
 		-f) export CONF_IMAGE="$2"; shift;;
 		-F|--force) export FORCE=1;;
 		-T|--test) export TEST=1;;
 		-h|--help) export HELP=1; break;;
 		-*)
-			echo "Invalid option: $1"
+			echo "Invalid option: $1" >&2
 			exit 1
 		;;
 		*) break;;
@@ -49,22 +53,27 @@ done
 
 export CONFFILES=/tmp/sysupgrade.conffiles
 export CONF_TAR=/tmp/sysupgrade.tgz
+export ETCBACKUP_DIR=/etc/backup
+export INSTALLED_PACKAGES=${ETCBACKUP_DIR}/installed_packages.txt
 
-export ARGV="$*"
-export ARGC="$#"
+IMAGE="$1"
 
-[ -z "$ARGV" -a -z "$NEED_IMAGE" -o $HELP -gt 0 ] && {
+[ -z "$IMAGE" -a -z "$NEED_IMAGE" -a $CONF_BACKUP_LIST -eq 0 -o $HELP -gt 0 ] && {
 	cat <<EOF
 Usage: $0 [<upgrade-option>...] <image file or URL>
-       $0 [-q] [-i] <backup-command> <file>
+       $0 [-q] [-i] [-c] [-u] [-o] [-k] <backup-command> <file>
 
 upgrade-option:
-	-d <delay>   add a delay before rebooting
 	-f <config>  restore configuration from .tar.gz (file or url)
 	-i           interactive mode
 	-c           attempt to preserve all changed files in /etc/
+	-o           attempt to preserve all changed files in /, except those
+	             from packages but including changed confs.
+	-u           skip from backup files that are equal to those in /rom
 	-n           do not save configuration over reflash
 	-p           do not attempt to restore the partition table after flash.
+	-k           include in backup a list of current installed packages at
+	             $INSTALLED_PACKAGES
 	-T | --test
 	             Verify image and config .tar.gz but do not actually flash.
 	-F | --force
@@ -90,7 +99,7 @@ EOF
 	exit 1
 }
 
-[ -n "$ARGV" -a -n "$NEED_IMAGE" ] && {
+[ -n "$IMAGE" -a -n "$NEED_IMAGE" ] && {
 	cat <<-EOF
 		-b|--create-backup and -r|--restore-backup do not perform a firmware upgrade.
 		Do not specify both -b|-r and a firmware image.
@@ -101,63 +110,162 @@ EOF
 # prevent messages from clobbering the tarball when using stdout
 [ "$CONF_BACKUP" = "-" ] && export VERBOSE=0
 
-add_uci_conffiles() {
+
+list_conffiles() {
+	awk '
+		BEGIN { conffiles = 0 }
+		/^Conffiles:/ { conffiles = 1; next }
+		!/^ / { conffiles = 0; next }
+		conffiles == 1 { print }
+	' /usr/lib/opkg/status
+}
+
+list_changed_conffiles() {
+	# Cannot handle spaces in filenames - but opkg cannot either...
+	list_conffiles | while read file csum; do
+		[ -r "$file" ] || continue
+
+		echo "${csum}  ${file}" | sha256sum -sc - || echo "$file"
+	done
+}
+
+add_conffiles() {
 	local file="$1"
 	( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
 		/etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
-		-type f -o -type l 2>/dev/null;
-	  opkg list-changed-conffiles ) | sort -u > "$file"
+		\( -type f -o -type l \) $find_filter 2>/dev/null;
+	  list_changed_conffiles ) | sort -u > "$file"
 	return 0
 }
 
 add_overlayfiles() {
 	local file="$1"
-	if [ -d /overlay/upper ]; then
-		local overlaydir="/overlay/upper"
-	else
-		local overlaydir="/overlay"
+
+	local packagesfiles=$1.packagesfiles
+	touch "$packagesfiles"
+
+	if [ "$SAVE_OVERLAY_PATH" = / ]; then
+		local conffiles=$1.conffiles
+		local keepfiles=$1.keepfiles
+
+		list_conffiles | cut -f2 -d ' ' | sort -u > "$conffiles"
+
+		# backup files from /etc/sysupgrade.conf and /lib/upgrade/keep.d, but
+		# ignore those aready controlled by opkg conffiles
+		find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' \
+			/etc/sysupgrade.conf /lib/upgrade/keep.d/* 2>/dev/null) \
+			\( -type f -o -type l \) 2>/dev/null | sort -u |
+			grep -h -v -x -F -f $conffiles > "$keepfiles"
+
+		# backup conffiles, but only those changed if '-u'
+		[ $SKIP_UNCHANGED = 1 ] &&
+			list_changed_conffiles | sort -u > "$conffiles"
+
+		# do not backup files from packages, except those listed
+		# in conffiles and keep.d
+		{
+			find /usr/lib/opkg/info -type f -name "*.list" -exec cat {} \;
+			find /usr/lib/opkg/info -type f -name "*.control" -exec sed \
+				-ne '/^Alternatives/{s/^Alternatives: //;s/, /\n/g;p}' {} \; |
+				cut -f2 -d:
+		} |  grep -v -x -F -f $conffiles |
+		     grep -v -x -F -f $keepfiles | sort -u > "$packagesfiles"
+		rm -f "$keepfiles" "$conffiles"
 	fi
-	find $overlaydir/etc/ -type f -o -type l | sed \
-		-e 's,^/overlay\/upper/,/,' \
-		-e 's,^/overlay/,/,' \
-		-e '\,/META_[a-zA-Z0-9]*$,d' \
-		-e '\,/functions.sh$,d' \
+
+	# busybox grep bug when file is empty
+	[ -s "$packagesfiles" ] || echo > $packagesfiles
+
+	( cd /overlay/upper/; find .$SAVE_OVERLAY_PATH \( -type f -o -type l \) $find_filter | sed \
+		-e 's,^\.,,' \
+		-e '\,^/etc/board.json$,d' \
 		-e '\,/[^/]*-opkg$,d' \
-	> "$file"
+		-e '\,^/etc/urandom.seed$,d' \
+		-e "\,^$INSTALLED_PACKAGES$,d" \
+		-e '\,^/usr/lib/opkg/.*,d' \
+	) | grep -v -x -F -f $packagesfiles > "$file"
+
+	rm -f "$packagesfiles"
+
 	return 0
 }
 
 # hooks
-sysupgrade_image_check="fwtool_check_image platform_check_image"
-sysupgrade_pre_upgrade="fwtool_pre_upgrade"
-[ $SAVE_OVERLAY = 0 -o ! -d /overlay/etc ] && \
-	sysupgrade_init_conffiles="add_uci_conffiles" || \
+sysupgrade_image_check="fwtool_check_signature fwtool_check_image platform_check_image"
+
+if [ $SAVE_OVERLAY = 1 ]; then
+	[ ! -d /overlay/upper/etc ] && {
+		echo "Cannot find '/overlay/upper/etc', required for '-c'" >&2
+		exit 1
+	}
 	sysupgrade_init_conffiles="add_overlayfiles"
+else
+	sysupgrade_init_conffiles="add_conffiles"
+fi
 
-include /lib/upgrade
+find_filter=""
+if [ $SKIP_UNCHANGED = 1 ]; then
+	[ ! -d /rom/ ] && {
+		echo "'/rom/' is required by '-u'"
+		exit 1
+	}
+	find_filter='( ( -exec test -e /rom/{} ; -exec cmp -s /{} /rom/{} ; ) -o -print )'
+fi
 
-[ "$1" = "nand" ] && nand_upgrade_stage2 $@
+include /lib/upgrade
 
 do_save_conffiles() {
-	local conf_tar="${1:-$CONF_TAR}"
+	local conf_tar="$1"
 
 	[ -z "$(rootfs_type)" ] && {
-		echo "Cannot save config while running from ramdisk."
+		echo "Cannot save config while running from ramdisk." >&2
 		ask_bool 0 "Abort" && exit
+		rm -f "$conf_tar"
 		return 0
 	}
 	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
 	ask_bool 0 "Edit config file list" && vi "$CONFFILES"
 
+	if [ "$SAVE_INSTALLED_PKGS" -eq 1 ]; then
+		echo "${INSTALLED_PACKAGES}" >> "$CONFFILES"
+		mkdir -p "$ETCBACKUP_DIR"
+		# Avoid touching filesystem on each backup
+		RAMFS="$(mktemp -d -t sysupgrade.XXXXXX)"
+		mkdir -p "$RAMFS/upper" "$RAMFS/work"
+		mount -t overlay overlay -o lowerdir=$ETCBACKUP_DIR,upperdir=$RAMFS/upper,workdir=$RAMFS/work $ETCBACKUP_DIR &&
+			UMOUNT_ETCBACKUP_DIR=1 || {
+				echo "Cannot mount '$ETCBACKUP_DIR' as tmpfs to avoid touching disk while saving the list of installed packages." >&2
+				ask_bool 0 "Abort" && exit
+			}
+
+		# Format: pkg-name<TAB>{rom,overlay,unkown}
+		# rom is used for pkgs in /rom, even if updated later
+		find /usr/lib/opkg/info -name "*.control" \( \
+			\( -exec test -f /rom/{} \; -exec echo {} rom \; \) -o \
+			\( -exec test -f /overlay/upper/{} \; -exec echo {} overlay \; \) -o \
+			\( -exec echo {} unknown \; \) \
+			\) | sed -e 's,.*/,,;s/\.control /\t/' > ${INSTALLED_PACKAGES}
+	fi
+
 	v "Saving config files..."
 	[ "$VERBOSE" -gt 1 ] && TAR_V="v" || TAR_V=""
 	tar c${TAR_V}zf "$conf_tar" -T "$CONFFILES" 2>/dev/null
+	if [ "$?" -ne 0 ]; then
+		echo "Failed to create the configuration backup."
+		rm -f "$conf_tar"
+		exit 1
+	fi
 
+	[ "$UMOUNT_ETCBACKUP_DIR" -eq 1 ] && {
+		umount "$ETCBACKUP_DIR"
+		rm -rf "$RAMFS"
+	}
 	rm -f "$CONFFILES"
 }
 
 if [ $CONF_BACKUP_LIST -eq 1 ]; then
-	add_uci_conffiles "$CONFFILES"
+	run_hooks "$CONFFILES" $sysupgrade_init_conffiles
+	[ "$SAVE_INSTALLED_PKGS" -eq 1 ] && echo ${INSTALLED_PACKAGES} >> "$CONFFILES"
 	cat "$CONFFILES"
 	rm -f "$CONFFILES"
 	exit 0
@@ -170,7 +278,7 @@ fi
 
 if [ -n "$CONF_RESTORE" ]; then
 	if [ "$CONF_RESTORE" != "-" ] && [ ! -f "$CONF_RESTORE" ]; then
-		echo "Backup archive '$CONF_RESTORE' not found."
+		echo "Backup archive '$CONF_RESTORE' not found." >&2
 		exit 1
 	fi
 
@@ -180,17 +288,43 @@ if [ -n "$CONF_RESTORE" ]; then
 fi
 
 type platform_check_image >/dev/null 2>/dev/null || {
-	echo "Firmware upgrade is not implemented for this platform."
+	echo "Firmware upgrade is not implemented for this platform." >&2
 	exit 1
 }
 
+case "$IMAGE" in
+	http://*|\
+	https://*)
+		wget -O/tmp/sysupgrade.img "$IMAGE"
+		IMAGE=/tmp/sysupgrade.img
+		;;
+esac
+
+IMAGE="$(readlink -f "$IMAGE")"
+
+case "$IMAGE" in
+	'')
+		echo "Image file not found." >&2
+		exit 1
+		;;
+	/tmp/*)	;;
+	*)
+		v "Image not in /tmp, copying..."
+		cp -f "$IMAGE" /tmp/sysupgrade.img
+		IMAGE=/tmp/sysupgrade.img
+		;;
+esac
+
+export ARGV="$IMAGE"
+export ARGC=1
+
 for check in $sysupgrade_image_check; do
-	( eval "$check \"\$ARGV\"" ) || {
+	( $check "$IMAGE" ) || {
 		if [ $FORCE -eq 1 ]; then
-			echo "Image check '$check' failed but --force given - will update anyway!"
+			echo "Image check '$check' failed but --force given - will update anyway!" >&2
 			break
 		else
-			echo "Image check '$check' failed."
+			echo "Image check '$check' failed." >&2
 			exit 1
 		fi
 	}
@@ -201,16 +335,17 @@ if [ -n "$CONF_IMAGE" ]; then
 		# .gz files
 		1f8b) ;;
 		*)
-			echo "Invalid config file. Please use only .tar.gz files"
+			echo "Invalid config file. Please use only .tar.gz files" >&2
 			exit 1
 		;;
 	esac
 	get_image "$CONF_IMAGE" "cat" > "$CONF_TAR"
 	export SAVE_CONFIG=1
 elif ask_bool $SAVE_CONFIG "Keep config files over reflash"; then
-	[ $TEST -eq 1 ] || do_save_conffiles
+	[ $TEST -eq 1 ] || do_save_conffiles "$CONF_TAR"
 	export SAVE_CONFIG=1
 else
+	[ $TEST -eq 1 ] || rm -f "$CONF_TAR"
 	export SAVE_CONFIG=0
 fi
 
@@ -218,28 +353,24 @@ if [ $TEST -eq 1 ]; then
 	exit 0
 fi
 
-run_hooks "" $sysupgrade_pre_upgrade
-
-# Some platforms/devices may want different sysupgrade process, e.g. without
-# killing processes yet or calling ubus system upgrade method.
-# This is needed e.g. on NAND devices where we just want to trigger stage1 at
-# this point.
-if type 'platform_pre_upgrade' >/dev/null 2>/dev/null; then
-	platform_pre_upgrade "$ARGV"
+if [ $SAVE_PARTITIONS -eq 0 ]; then
+	touch /tmp/sysupgrade.always.overwrite.bootdisk.partmap
+else
+	rm -f /tmp/sysupgrade.always.overwrite.bootdisk.partmap
 fi
 
-ubus call system upgrade
-touch /tmp/sysupgrade
+install_bin /sbin/upgraded
+v "Commencing upgrade. Closing all shell sessions."
 
-if [ ! -f /tmp/failsafe ] ; then
-	kill_remaining TERM
-	sleep 3
-	kill_remaining KILL
-fi
+COMMAND='. /lib/functions.sh; include /lib/upgrade; do_upgrade_stage2'
 
-if [ -n "$(rootfs_type)" ]; then
-	v "Switching to ramdisk..."
-	run_ramfs '. /lib/functions.sh; include /lib/upgrade; do_upgrade'
+if [ -n "$FAILSAFE" ]; then
+	printf '%s\x00%s\x00%s' "$RAM_ROOT" "$IMAGE" "$COMMAND" >/tmp/sysupgrade
+	lock -u /tmp/.failsafe
 else
-	do_upgrade
+	ubus call system sysupgrade "{
+		\"prefix\": $(json_string "$RAM_ROOT"),
+		\"path\": $(json_string "$IMAGE"),
+		\"command\": $(json_string "$COMMAND")
+	}"
 fi

+ 1 - 1
package/base-files/files/sbin/urandom_seed

@@ -13,7 +13,7 @@ save() {
 }
 
 SEED="$(uci -q get system.@system[0].urandom_seed || true)"
-[ "${SEED:0:1}" == "/" ] && save "$SEED"
+[ "${SEED:0:1}" = "/" ] && save "$SEED"
 
 SEED=/etc/urandom.seed
 [ ! -f $SEED ] && save "$SEED"

+ 3 - 2
package/base-files/files/sbin/wifi

@@ -6,7 +6,7 @@
 
 usage() {
 	cat <<EOF
-Usage: $0 [config|down|reload|status]
+Usage: $0 [config|up|down|reload|status]
 enables (default), disables or configures devices not yet configured.
 EOF
 	exit 1
@@ -241,5 +241,6 @@ case "$1" in
 	reload) wifi_reload "$2";;
 	reload_legacy) wifi_reload_legacy "$2";;
 	--help|help) usage;;
-	*) ubus call network reload; wifi_updown "enable" "$2";;
+	''|up) ubus call network reload; wifi_updown "enable" "$2";;
+	*) usage; exit 1;;
 esac

+ 5 - 5
package/base-files/files/usr/lib/os-release

@@ -1,10 +1,10 @@
 NAME="%D"
-VERSION="%V, %N"
+VERSION="%V"
 ID="%d"
-ID_LIKE="librecmc openwrt"
-PRETTY_NAME="%D %N %V"
+ID_LIKE="lede librecmc"
+PRETTY_NAME="%D %V"
 VERSION_ID="%v"
-HOME_URL="%m"
+HOME_URL="%u"
 BUG_URL="%b"
 SUPPORT_URL="%s"
 BUILD_ID="%R"
@@ -15,4 +15,4 @@ LEDE_DEVICE_MANUFACTURER="%M"
 LEDE_DEVICE_MANUFACTURER_URL="%m"
 LEDE_DEVICE_PRODUCT="%P"
 LEDE_DEVICE_REVISION="%h"
-LEDE_RELEASE="%D %N %V %C"
+LEDE_RELEASE="%D %V %C"

+ 1 - 1
package/base-files/files/usr/libexec/login.sh

@@ -1,5 +1,5 @@
 #!/bin/sh
 
-[ "$(uci get system.@system[0].ttylogin)" == 1 ] || exec /bin/ash --login
+[ "$(uci -q get system.@system[0].ttylogin)" = 1 ] || exec /bin/ash --login
 
 exec /bin/login

+ 16 - 33
package/base-files/image-config.in

@@ -18,11 +18,11 @@ config TARGET_PREINIT_SUPPRESS_STDERR
 	default y
 	help
 		Sends stderr to null during preinit.  This is the default behaviour
-		in previous versions of OpenWrt.  This also prevents init process
+		in previous versions of libreCMC.  This also prevents init process
 		itself from displaying stderr, however processes launched by init
 		in multiuser through inittab will use the current terminal (e.g.
 		the ash shell launched by inittab will display stderr).  That's
-		the same behaviour as seen in previous version of OpenWrt.
+		the same behaviour as seen in previous version of libreCMC.
 
 config TARGET_PREINIT_DISABLE_FAILSAFE
 	bool
@@ -139,7 +139,7 @@ menuconfig INITOPT
 		help
 			Prevents showing stderr messages for init command if not already
 			suppressed during preinit.  This is the default behaviour in
-			previous versions of OpenWrt.  Removing this does nothing if
+			previous versions of libreCMC.  Removing this does nothing if
 			stderr is suppressed during preinit (which is the default).
 
 
@@ -150,7 +150,7 @@ menuconfig VERSIONOPT
 		These options allow to override the version information embedded in
 		the /etc/openwrt_version, /etc/openwrt_release, /etc/banner,
 		/etc/opkg.conf, and /etc/os-release files. Usually there is no need
-		to set these, but they're useful for release builds or custom OpenWrt
+		to set these, but they're useful for release builds or custom libreCMC
 		redistributions that should carry custom version tags.
 
 if VERSIONOPT
@@ -161,14 +161,7 @@ if VERSIONOPT
 		default "libreCMC"
 		help
 			This is the name of the release distribution.
-			If unspecified, it defaults to OpenWrt.
-
-	config VERSION_NICK
-		string
-		prompt "Release version nickname"
-		help
-			This is the release codename embedded in the image.
-			If unspecified, it defaults to the name of source branch.
+			If unspecified, it defaults to libreCMC.
 
 	config VERSION_NUMBER
 		string
@@ -190,7 +183,7 @@ if VERSIONOPT
 	config VERSION_REPO
 		string
 		prompt "Release repository"
-		default "https://librecmc.org/librecmc/downloads/snapshots/%v"
+		default "http://downloads.lede-project.org/snapshots"
 		help
 			This is the repository address embedded in the image, it defaults
 			to the trunk snapshot repo; the url may contain the following placeholders:
@@ -199,8 +192,6 @@ if VERSIONOPT
 			 %v .. Configured release version number or "snapshot", lowercase
 			 %C .. Configured release revision code or value of %R, uppercase
 			 %c .. Configured release revision code or value of %R, lowercase
-			 %N .. Release name, uppercase
-			 %n .. Release name, lowercase
 			 %D .. Distribution name or "libreCMC", uppercase
 			 %d .. Distribution name or "librecmc", lowercase
 			 %T .. Target name
@@ -211,19 +202,25 @@ if VERSIONOPT
 			 %P .. Product name or "Generic"
 			 %h .. Hardware revision or "v0"
 
+	config VERSION_HOME_URL
+		string
+		prompt "Release Homepage"
+		help
+			This is the release version homepage
+
 	config VERSION_MANUFACTURER
 		string
 		prompt "Manufacturer name"
 		help
 			This is the manufacturer name embedded in /etc/device_info
-			Useful for OEMs building OpenWrt based firmware
+			Useful for OEMs building libreCMC based firmware
 
 	config VERSION_MANUFACTURER_URL
 		string
 		prompt "Manufacturer URL"
 		help
 			This is an URL to the manufacturer's website embedded in /etc/device_info
-			Useful for OEMs building OpenWrt based firmware
+			Useful for OEMs building libreCMC based firmware
 
 	config VERSION_BUG_URL
 		string
@@ -242,14 +239,14 @@ if VERSIONOPT
 		prompt "Product name"
 		help
 			This is the product name embedded in /etc/device_info
-			Useful for OEMs building OpenWrt based firmware
+			Useful for OEMs building libreCMC based firmware
 
 	config VERSION_HWREV
 		string
 		prompt "Hardware revision"
 		help
 			This is the hardware revision string embedded in /etc/device_info
-			Useful for OEMs building OpenWrt based firmware
+			Useful for OEMs building libreCMC based firmware
 
 	config VERSION_FILENAMES
 		bool
@@ -277,18 +274,4 @@ menuconfig PER_FEED_REPO
 		If set, a separate repository is generated within bin/*/packages/
 		for the core packages and each enabled feed.
 
-	config PER_FEED_REPO_ADD_DISABLED
-		bool "Add available but not enabled feeds to opkg.conf"
-		default y
-		depends on PER_FEED_REPO
-		help
-		  Add not installed or disabled feeds from feeds.conf to opkg.conf.
-
-	config PER_FEED_REPO_ADD_COMMENTED
-		bool "Comment out not enabled feeds"
-		default !BUILDBOT
-		depends on PER_FEED_REPO && PER_FEED_REPO_ADD_DISABLED
-		help
-		  Add not enabled feeds as commented out source lines to opkg.conf.
-
 source "tmp/.config-feeds.in"

+ 51 - 0
package/boot/arm-trusted-firmware-sunxi/Makefile

@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2017 Hauke Mehrtens
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=arm-trusted-firmware-sunxi
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=https://github.com/ARM-software/arm-trusted-firmware
+PKG_SOURCE_DATE:=2018-10-02
+PKG_SOURCE_VERSION:=dbc8d9496ead9ecdd7c2a276b542a4fbbbf64027
+PKG_MIRROR_HASH:=c81521a27b86f606e927b4e346286540b862828c8d49292eae1f5c6adfc24001
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=license.md
+
+PKG_MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de>
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/arm-trusted-firmware-sunxi
+    SECTION:=boot
+    CATEGORY:=Boot Loaders
+    TITLE:=ARM Trusted Firmware for Allwinner
+    DEPENDS:=@TARGET_sunxi_cortexa53
+endef
+
+export GCC_HONOUR_COPTS=s
+
+MAKE_VARS = \
+	CROSS_COMPILE="$(TARGET_CROSS)"
+
+MAKE_FLAGS += \
+	PLAT=sun50i_a64 \
+	bl31
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(STAGING_DIR_IMAGE)
+	$(CP) $(PKG_BUILD_DIR)/build/sun50i_a64/release/bl31.bin $(STAGING_DIR_IMAGE)/bl31.bin
+endef
+
+define Package/arm-trusted-firmware-sunxi/install
+endef
+
+$(eval $(call BuildPackage,arm-trusted-firmware-sunxi))

+ 45 - 0
package/boot/fconfig/Makefile

@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2006-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fconfig
+PKG_VERSION:=20080329
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://downloads.openwrt.org/sources
+PKG_HASH:=4ff0e8f07e35e46b705c0dbe9d9544ede01ea092a69e3f7db03e55a3f2bb8eb7
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fconfig
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Boot Loaders
+  TITLE:=RedBoot configuration editor
+endef
+
+define Package/fconfig/description
+	displays and (if writable) also edits the RedBoot configuration.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+	$(call Build/Compile/Default)
+endef
+
+define Package/fconfig/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/fconfig $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,fconfig))

+ 7 - 8
package/boot/grub2/Makefile

@@ -9,15 +9,13 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=grub
-PKG_VERSION:=2.02~rc1
-PKG_RELEASE:=1
+PKG_CPE_ID:=cpe:/a:gnu:grub2
+PKG_VERSION:=2.02
+PKG_RELEASE:=3
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=http://alpha.gnu.org/gnu/grub \
-	http://gnualpha.uib.no/grub/ \
-	http://mirrors.fe.up.pt/pub/gnu-alpha/grub/ \
-	http://www.nic.funet.fi/pub/gnu/alpha/gnu/grub/
-PKG_HASH:=445239e9b96d1143c194c1d37851cf4196b83701c60172e49665e9d453d80278
+PKG_SOURCE_URL:=@GNU/grub
+PKG_HASH:=810b3798d316394f94096ec2797909dbf23c858e48f7b3830826b8daa06b7b0f
 
 PKG_FIXUP:=autoreconf
 HOST_BUILD_PARALLEL:=1
@@ -62,7 +60,8 @@ CONFIGURE_ARGS += \
 	--disable-nls \
 	--disable-device-mapper \
 	--disable-libzfs \
-	--disable-grub-mkfont
+	--disable-grub-mkfont \
+	--with-platform=none
 
 HOST_CONFIGURE_VARS += \
 	grub_build_mkfont_excuse="don't want fonts"

+ 71 - 0
package/boot/grub2/patches/0008-Fix-packed-not-aligned-error-on-GCC-8.patch

@@ -0,0 +1,71 @@
+From 563b1da6e6ae7af46cc8354cadb5dab416989f0a Mon Sep 17 00:00:00 2001
+From: Michael Chang <mchang@suse.com>
+Date: Mon, 26 Mar 2018 16:52:34 +0800
+Subject: Fix packed-not-aligned error on GCC 8
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When building with GCC 8, there are several errors regarding packed-not-aligned.
+
+./include/grub/gpt_partition.h:79:1: error: alignment 1 of ‘struct grub_gpt_partentry’ is less than 8 [-Werror=packed-not-aligned]
+
+This patch fixes the build error by cleaning up the ambiguity of placing
+aligned structure in a packed one. In "struct grub_btrfs_time" and "struct
+grub_gpt_part_type", the aligned attribute seems to be superfluous, and also
+has to be packed, to ensure the structure is bit-to-bit mapped to the format
+laid on disk. I think we could blame to copy and paste error here for the
+mistake. In "struct efi_variable", we have to use grub_efi_packed_guid_t, as
+the name suggests. :)
+
+Signed-off-by: Michael Chang <mchang@suse.com>
+Tested-by: Michael Chang <mchang@suse.com>
+Tested-by: Paul Menzel <paulepanter@users.sourceforge.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+---
+ grub-core/fs/btrfs.c          | 2 +-
+ include/grub/efiemu/runtime.h | 2 +-
+ include/grub/gpt_partition.h  | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
+index 4849c1ceb..be195448d 100644
+--- a/grub-core/fs/btrfs.c
++++ b/grub-core/fs/btrfs.c
+@@ -175,7 +175,7 @@ struct grub_btrfs_time
+ {
+   grub_int64_t sec;
+   grub_uint32_t nanosec;
+-} __attribute__ ((aligned (4)));
++} GRUB_PACKED;
+ 
+ struct grub_btrfs_inode
+ {
+diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h
+index 9b6b729f4..36d2dedf4 100644
+--- a/include/grub/efiemu/runtime.h
++++ b/include/grub/efiemu/runtime.h
+@@ -29,7 +29,7 @@ struct grub_efiemu_ptv_rel
+ 
+ struct efi_variable
+ {
+-  grub_efi_guid_t guid;
++  grub_efi_packed_guid_t guid;
+   grub_uint32_t namelen;
+   grub_uint32_t size;
+   grub_efi_uint32_t attributes;
+diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
+index 1b32f6725..9668a68c3 100644
+--- a/include/grub/gpt_partition.h
++++ b/include/grub/gpt_partition.h
+@@ -28,7 +28,7 @@ struct grub_gpt_part_type
+   grub_uint16_t data2;
+   grub_uint16_t data3;
+   grub_uint8_t data4[8];
+-} __attribute__ ((aligned(8)));
++} GRUB_PACKED;
+ typedef struct grub_gpt_part_type grub_gpt_part_type_t;
+ 
+ #define GRUB_GPT_PARTITION_TYPE_EMPTY \
+-- 
+cgit v1.1-33-g03f6

+ 40 - 0
package/boot/grub2/patches/300-CVE-2015-8370.patch

@@ -0,0 +1,40 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Hector Marco-Gisbert <hecmargi@upv.es>
+Date: Fri, 13 Nov 2015 16:21:09 +0100
+Subject: [PATCH] Fix security issue when reading username and password
+
+  This patch fixes two integer underflows at:
+    * grub-core/lib/crypto.c
+    * grub-core/normal/auth.c
+
+Resolves: CVE-2015-8370
+
+Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
+Signed-off-by: Ismael Ripoll-Ripoll <iripoll@disca.upv.es>
+---
+ grub-core/lib/crypto.c  | 2 +-
+ grub-core/normal/auth.c | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/grub-core/lib/crypto.c
++++ b/grub-core/lib/crypto.c
+@@ -468,7 +468,7 @@ grub_password_get (char buf[], unsigned
+ 	  break;
+ 	}
+ 
+-      if (key == '\b')
++      if (key == '\b' && cur_len)
+ 	{
+ 	  if (cur_len)
+ 	    cur_len--;
+--- a/grub-core/normal/auth.c
++++ b/grub-core/normal/auth.c
+@@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned
+ 	  break;
+ 	}
+ 
+-      if (key == '\b')
++      if (key == '\b' && cur_len)
+ 	{
+ 	  if (cur_len)
+ 	    {

+ 75 - 0
package/boot/grub2/patches/400-R_X86_64_PLT32.patch

@@ -0,0 +1,75 @@
+From 02702bdfe14d8a04643a45b03715f734ae34dbac Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+Date: Sat, 17 Feb 2018 06:47:28 -0800
+Subject: x86-64: Treat R_X86_64_PLT32 as R_X86_64_PC32
+
+Starting from binutils commit bd7ab16b4537788ad53521c45469a1bdae84ad4a:
+
+https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=bd7ab16b4537788ad53521c45469a1bdae84ad4a
+
+x86-64 assembler generates R_X86_64_PLT32, instead of R_X86_64_PC32, for
+32-bit PC-relative branches.  Grub2 should treat R_X86_64_PLT32 as
+R_X86_64_PC32.
+
+Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+
+Origin: upstream, https://git.savannah.gnu.org/cgit/grub.git/commit/?id=842c390469e2c2e10b5aa36700324cd3bde25875
+Last-Update: 2018-07-30
+
+Patch-Name: R_X86_64_PLT32.patch
+---
+ grub-core/efiemu/i386/loadcore64.c | 1 +
+ grub-core/kern/x86_64/dl.c         | 1 +
+ util/grub-mkimagexx.c              | 1 +
+ util/grub-module-verifier.c        | 1 +
+ 4 files changed, 4 insertions(+)
+
+diff --git a/grub-core/efiemu/i386/loadcore64.c b/grub-core/efiemu/i386/loadcore64.c
+index e49d0b6ff..18facf47f 100644
+--- a/grub-core/efiemu/i386/loadcore64.c
++++ b/grub-core/efiemu/i386/loadcore64.c
+@@ -98,6 +98,7 @@ grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+ 		    break;
+ 
+ 		  case R_X86_64_PC32:
++		  case R_X86_64_PLT32:
+ 		    err = grub_efiemu_write_value (addr,
+ 						   *addr32 + rel->r_addend
+ 						   + sym.off
+diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c
+index 440690673..3a73e6e6c 100644
+--- a/grub-core/kern/x86_64/dl.c
++++ b/grub-core/kern/x86_64/dl.c
+@@ -70,6 +70,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ 	  break;
+ 
+ 	case R_X86_64_PC32:
++	case R_X86_64_PLT32:
+ 	  {
+ 	    grub_int64_t value;
+ 	    value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
+diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
+index e63f148e4..f20255a28 100644
+--- a/util/grub-mkimagexx.c
++++ b/util/grub-mkimagexx.c
+@@ -832,6 +832,7 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections,
+ 		  break;
+ 
+ 		case R_X86_64_PC32:
++		case R_X86_64_PLT32:
+ 		  {
+ 		    grub_uint32_t *t32 = (grub_uint32_t *) target;
+ 		    *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32)
+diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
+index 9179285a5..a79271f66 100644
+--- a/util/grub-module-verifier.c
++++ b/util/grub-module-verifier.c
+@@ -19,6 +19,7 @@ struct grub_module_verifier_arch archs[] = {
+       -1
+     }, (int[]){
+       R_X86_64_PC32,
++      R_X86_64_PLT32,
+       -1
+     }
+   },

+ 1 - 8
package/boot/kexec-tools/Config.in

@@ -1,12 +1,5 @@
 menu "Configuration"
-	depends on PACKAGE_kexec-tools
-
-config KEXEC_TOOLS_kdump
-	bool
-	prompt "kdump support"
-	default n
-	help
-	  Include the kdump utility.
+	depends on PACKAGE_kexec
 
 config KEXEC_ZLIB
 	bool

+ 64 - 16
package/boot/kexec-tools/Makefile

@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=kexec-tools
-PKG_VERSION:=2.0.14-rc1
+PKG_VERSION:=2.0.16
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@KERNEL/linux/utils/kernel/kexec
-PKG_HASH:=3fc505ff8d8a2d24c68aac5e6b4783997d5a086966ff3de8b05a0ceb27e5e23b
+PKG_HASH:=5b103351ad752c9badd1d65b00eb6de4bce579f944f4df4e3ef3a755ba567010
 
 PKG_FIXUP:=autoreconf
 
@@ -21,22 +21,49 @@ PKG_CONFIG_DEPENDS := CONFIG_KEXEC_ZLIB CONFIG_KEXEC_LZMA
 
 include $(INCLUDE_DIR)/package.mk
 
-define Package/kexec-tools
+define Package/kexec-tools/Default
   SECTION:=utils
   CATEGORY:=Utilities
-  DEPENDS:=@armeb||@arm||@i386||@x86_64||@powerpc64||@mipsel||@mips +KEXEC_ZLIB:zlib +KEXEC_LZMA:liblzma
-  TITLE:=Kernel boots kernel
   URL:=http://kernel.org/pub/linux/kernel/people/horms/kexec-tools/
   MAINTAINER:=Florian Fainelli <florian@openwrt.org>
-  MENU:=1
+endef
+
+define Package/kexec-tools
+  $(call Package/kexec-tools/Default)
+  TITLE:=kexec-tools transition meta package
+  DEPENDS:=+kexec
 endef
 
 define Package/kexec-tools/description
- kexec is a set of systems call that allows you to load
+ kexec is a set of system calls that allows you to load
  another kernel from the currently executing Linux kernel.
+ The kexec utility allows to load and boot another kernel.
 endef
 
-define Package/kexec-tools/config
+define Package/kexec
+  $(call Package/kexec-tools/Default)
+  TITLE:=Kernel boots kernel
+  DEPENDS:=\
+	@armeb||@arm||@i386||@x86_64||@powerpc64||@mipsel||@mips \
+	+KEXEC_ZLIB:zlib +KEXEC_LZMA:liblzma @KERNEL_KEXEC
+endef
+
+define Package/kexec/description
+ The kexec utility allows to load and boot another kernel.
+endef
+
+define Package/kdump
+  $(call Package/kexec-tools/Default)
+  TITLE:=Kernel crash analysis
+  DEPENDS:=+kexec @i386||@x86_64||@arm @KERNEL_CRASH_DUMP
+endef
+
+define Package/kdump/description
+ The kdump package allows to automatically boot into a
+ special kernel for analyzing kernel crashes using kdump.
+endef
+
+define Package/kexec/config
 	source "$(SOURCE)/Config.in"
 endef
 
@@ -65,24 +92,45 @@ CONFIGURE_VARS += \
 	BUILD_CC="$(HOSTCC)" \
 	TARGET_CC="$(TARGET_CC)"
 
-kexec-extra-sbin-$(CONFIG_KEXEC_TOOLS_kdump) += kdump
-
 define Build/Compile
 	$(MAKE) -C $(PKG_BUILD_DIR) DESTDIR="$(PKG_INSTALL_DIR)" all install
 endef
 
 define Package/kexec-tools/install
+	:
+endef
+
+define Package/kexec/install
 	$(INSTALL_DIR) $(1)/usr/sbin
-	$(INSTALL_BIN) \
-		$(addprefix $(PKG_INSTALL_DIR)/usr/sbin/, \
-			$(kexec-extra-sbin-y)) \
-		$(kexec-extra-bin-y) \
-		$(PKG_INSTALL_DIR)/usr/sbin/kexec \
-		$(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/kexec $(1)/usr/sbin
 
 # make a link for compatability with other distros
 	$(INSTALL_DIR) $(1)/sbin
 	$(LN) ../usr/sbin/kexec $(1)/sbin/kexec
 endef
 
+define Package/kdump/install
+	$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config $(1)/etc/uci-defaults
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/kdump $(PKG_INSTALL_DIR)/usr/sbin/vmcore-dmesg $(1)/usr/sbin
+	$(INSTALL_BIN) ./files/kdump.init $(1)/etc/init.d/kdump
+	$(INSTALL_BIN) ./files/kdump.defaults $(1)/etc/uci-defaults/kdump
+	$(INSTALL_CONF) ./files/kdump.config $(1)/etc/config/kdump
+endef
+
+define Package/kdump/prerm
+#!/bin/sh
+
+case $$(uname -m) in
+	i?86|x86_64)
+		if grep -q " crashkernel=" /boot/grub/grub.cfg; then
+			mount /boot -o remount,rw
+			sed -i 's/ crashkernel=[^ ]*//' /boot/grub/grub.cfg
+			mount /boot -o remount,ro
+		fi
+		;;
+esac
+endef
+
 $(eval $(call BuildPackage,kexec-tools))
+$(eval $(call BuildPackage,kexec))
+$(eval $(call BuildPackage,kdump))

+ 7 - 0
package/boot/kexec-tools/files/kdump.config

@@ -0,0 +1,7 @@
+
+config kdump
+	option enabled '1'
+	option save_dmesg '1'
+	option save_vmcore '0'
+# using an external partition to store vmcore is highly recommended!
+#	option path '/mnt/crashdump'

+ 11 - 0
package/boot/kexec-tools/files/kdump.defaults

@@ -0,0 +1,11 @@
+#!/bin/sh
+
+case $(uname -m) in
+	i?86|x86_64)
+		if ! grep -q crashkernel /boot/grub/grub.cfg; then
+			mount /boot -o remount,rw
+			sed -i 's/linux.*/& crashkernel=32M@32M/' /boot/grub/grub.cfg
+			mount /boot -o remount,ro
+		fi
+		;;
+esac

+ 184 - 0
package/boot/kexec-tools/files/kdump.init

@@ -0,0 +1,184 @@
+#!/bin/sh /etc/rc.common
+
+START=41
+STOP=98
+
+EXTRA_COMMANDS="status"
+EXTRA_HELP="        status  Print crashkernel status"
+
+verify_kdump() {
+	local cfg="$1"
+	local enabled
+	local path
+	local save_vmcore
+	local save_dmesg
+
+	config_get_bool enabled "$cfg" enabled 1
+	config_get_bool save_dmesg "$cfg" save_dmesg 1
+	config_get_bool save_vmcore "$cfg" save_vmcore 0
+
+	[ "$enabled" -gt 0 ] || return 2
+
+	[ "$save_dmesg" -gt 0 ] || [ "$save_vmcore" -gt 0 ] || return 2
+
+	config_get path "$cfg" path "/"
+
+	[ -d "$path" ] || mkdir -p "$path" 2>/dev/null || return 1
+}
+
+run_kdump() {
+	local cfg="$1"
+	local enabled
+	local path
+	local save_vmcore
+	local save_dmesg
+
+	config_get_bool enabled "$cfg" enabled 1
+	[ "$enabled" -gt 0 ] || return
+
+	config_get_bool save_dmesg "$cfg" save_dmesg 1
+	config_get_bool save_vmcore "$cfg" save_vmcore 0
+	config_get path "$cfg" path "/"
+
+	timestamp=$(date "+%Y%m%dT%H%M%S")
+
+	if [ "$save_vmcore" -eq 1 ]; then
+		echo -n "Saving vmcore (this may take a while)..."
+		# would like 'sparse' but busybox doesn't support it
+		dd if=/proc/vmcore of="$path/vmcore-$timestamp" conv=fsync bs=1M
+		echo " done"
+	fi
+
+	if [ "$save_dmesg" -eq 1 ]; then
+		vmcore-dmesg /proc/vmcore > "$path/dmesg-$timestamp"
+	fi
+
+	sync
+	reboot -f
+}
+
+find_kernel() {
+	. /lib/functions.sh
+	local kernel
+
+	kernel="$BOOT_IMAGE"
+	if [ -r "$kernel" ]; then
+		echo $kernel
+		return 0
+	fi
+
+	kernel="$(find_mtd_part kernel)"
+	if [ -r "$kernel" ]; then
+		echo $kernel
+		return 0
+	fi
+
+	for voldir in /sys/class/ubi/ubi*_*; do
+		[ ! -e "$voldir" ] && continue
+		if [ "$(cat "${voldir}/name")" = "kernel" ]; then
+			kernel="/dev/$(basename "$voldir")"
+			echo $kernel
+			return 0
+		fi
+	done
+
+	return 1
+}
+
+load_crashkernel() {
+	local append_cmdline
+	local kernel
+
+	kernel="$(find_kernel)"
+	[ $? -gt 0 ] && return 1
+
+	case "$(uname -m)" in
+		i?86|x86_64)
+			grep -q "crashkernel=" /proc/cmdline || return 1
+			append_cmdline="1 irqpoll reset_devices maxcpus=1"
+			;;
+		arm*)
+			append_cmdline="1 maxcpus=1 reset_devices"
+			;;
+	esac
+	kexec -p "$kernel" --reuse-cmdline --append="$append_cmdline"
+	return $?
+}
+
+start() {
+	local retval
+
+	if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
+		return 1
+	fi
+
+	if [ -e /proc/vmcore ]; then
+		config_load kdump
+		config_foreach run_kdump kdump
+	else
+		config_load kdump
+		config_foreach verify_kdump kdump
+		retval=$?
+		[ $retval = 1 ] && return 1
+		[ $retval = 0 ] && load_crashkernel
+		return $?
+	fi
+}
+
+stop() {
+	[ "$(cat /sys/kernel/kexec_crash_loaded)" = "1" ] || return
+
+	if [ -e "$BOOT_IMAGE" ]; then
+		kexec -p -u "$BOOT_IMAGE"
+	fi
+}
+
+status() {
+	local retval kernel
+
+	if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
+		echo "crashdump not supported by kernel"
+		return
+	fi
+
+	if [ $(cat /sys/kernel/kexec_crash_size) -eq 0 ]; then
+		echo "memory for crashdump kernel not reserved!"
+		echo "check crashkernel= kernel cmdline parameter"
+		echo "(a reboot is required after installing kdump)"
+		return
+	fi
+
+	kernel="$(find_kernel)"
+	if [ $? -gt 0 ]; then
+		echo "cannot find kernel image"
+		return
+	else
+		echo "using kernel image $kernel"
+	fi
+
+	echo -n "kdump configuration is "
+	config_load kdump
+	retval=$?
+	if [ $retval = 0 ]; then
+		if [ "$(config_foreach echo kdump)" ]; then
+			config_foreach verify_kdump kdump
+			retval=$?
+		else
+			retval=1
+		fi
+	fi
+
+	if [ $retval = 0 ]; then
+		echo "valid"
+	elif [ $retval = 2 ]; then
+		echo "disabled"
+	else
+		echo "BROKEN"
+	fi
+
+	echo -n "kexec crash kernel "
+	if [ "$(cat /sys/kernel/kexec_crash_loaded)" = "0" ]; then
+		echo -n "not "
+	fi
+	echo "loaded"
+}

+ 0 - 20
package/boot/kexec-tools/patches/100-format_string_fix.patch

@@ -1,20 +0,0 @@
---- a/kexec/arch/i386/kexec-elf-x86.c
-+++ b/kexec/arch/i386/kexec-elf-x86.c
-@@ -296,6 +296,6 @@ out:
- 	free(command_line);
- 	free(modified_cmdline);
- 	if (error_msg)
--		die(error_msg);
-+		die("%s", error_msg);
- 	return result;
- }
---- a/kexec/arch/x86_64/kexec-elf-x86_64.c
-+++ b/kexec/arch/x86_64/kexec-elf-x86_64.c
-@@ -276,6 +276,6 @@ out:
- 	free(command_line);
- 	free(modified_cmdline);
- 	if (error_msg)
--		die(error_msg);
-+		die("%s", error_msg);
- 	return result;
- }

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