+define MkImageTpl/squashfs
+ $(eval output_name=$(IMG_PREFIX)-$(2)-$(1)-$(if $(4),$(4),sysupgrade).bin)
+ $(STAGING_DIR_HOST)/bin/mktplinkfw2 -V "ver. 2.0" -B "$(2)" -j \
+ -o $(KDIR)/$(output_name) \
+ -k $(KDIR)/vmlinux-$(1)$(4).bin.lzma \
+ -r $(KDIR)/root.$(1)
+ $(CP) $(KDIR)/$(output_name) $(BIN_DIR)/$(output_name)
+endef
+
+define MkImageTpl/initramfs
+ $(eval output_name=$(IMG_PREFIX)-$(2)-$(1).bin)
+ $(STAGING_DIR_HOST)/bin/mktplinkfw2 -V "ver. 2.0" -B "$(2)" -c \
+ -o $(KDIR)/$(output_name) \
+ -k $(KDIR)/vmlinux-$(1).bin.lzma
+ $(CP) $(KDIR)/$(output_name) $(BIN_DIR)/$(output_name)
+endef
+
+# $(1), lowercase board name like "mt7620a_v22sg"
+# $(2), DTS filename without .dts extension
+# $(3), optional filename suffix, e.g. "-initramfs"
+define PatchKernelLzmaDtb
+ cp $(KDIR)/vmlinux$(3) $(KDIR)/vmlinux-$(1)$(3)
+ $(LINUX_DIR)/scripts/dtc/dtc -O dtb -o $(KDIR)/$(2).dtb ../dts/$(2).dts
+ $(STAGING_DIR_HOST)/bin/patch-dtb $(KDIR)/vmlinux-$(1)$(3) $(KDIR)/$(2).dtb
+ $(call CompressLzma,$(KDIR)/vmlinux-$(1)$(3),$(KDIR)/vmlinux-$(1)$(3).bin.lzma)
+endef
+
+# $(1), lowercase board name
+# $(2), DTS filename without .dts extension
+# $(3), ih_name field of uImage header
+# $(4), optional filename suffix, e.g. "-initramfs"
+define MkImageLzmaDtb
+ $(call PatchKernelLzmaDtb,$(1),$(2),$(4))
+ $(call MkImage,lzma,$(KDIR)/vmlinux-$(1)$(4).bin.lzma,$(KDIR)/vmlinux-$(1)$(4).uImage,$(3))
+endef
+
+# $(1), Rootfs type, e.g. squashfs
+# $(2), lowercase board name
+# $(3), DTS filename without .dts extension
+# $(4), maximum size of sysupgrade image
+# $(5), uImage header's ih_name field
+define BuildFirmware/OF
+ $(call MkImageLzmaDtb,$(2),$(3),$(5))
+ $(call MkImageSysupgrade/$(1),$(1),$(2),$(4),$(6))
+endef
+
+define BuildFirmware/OF/tplink
+ $(call PatchKernelLzmaDtb,$(1),$(2),$(4))
+ $(call MkImageTpl/$(1),$(1),$(2),$(4),$(5))
+endef
+
+define BuildFirmware/OF/tplink/initramfs
+ $(call PatchKernelLzmaDtb,$(2),$(3),-initramfs)
+ $(call MkImageTpl/$(1),$(1),$(2),$(4),$(5))
+endef
+
+# $(1), squashfs/initramfs
+# $(2), lowercase board name
+# $(3), DTS filename without .dts extension
+# $(4), ih_name field of uImage header
+define BuildFirmware/OF/initramfs
+ $(call MkImageLzmaDtb,$(2),$(3),$(4),-initramfs)
+ $(CP) $(KDIR)/vmlinux-$(2)-initramfs.uImage $(call imgname,$(1),$(2))-uImage.bin
+endef
+
+
+# Build images for default ralink layout for 4MB flash
+# kernel + roots = 0x3b0000
+# $(1) = squashfs/initramfs
+# $(2) = lowercase board name
+# $(3) = dts file
+ralink_default_fw_size_4M=3866624
+BuildFirmware/Default4M/squashfs=$(call BuildFirmware/OF,$(1),$(2),$(3),$(ralink_default_fw_size_4M),$(4))
+BuildFirmware/Default4M/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3),$(4))
+
+# Build images for default ralink layout for 8MB flash
+# kernel + roots = 0x7b0000
+# $(1) = squashfs/initramfs
+# $(2) = lowercase board name
+# $(3) = dts file
+# $(4) = uImage header name field
+ralink_default_fw_size_8M=8060928
+BuildFirmware/Default8M/squashfs=$(call BuildFirmware/OF,$(1),$(2),$(3),$(ralink_default_fw_size_8M),$(4))
+BuildFirmware/Default8M/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3),$(4))
+BuildFirmware/Tplink/squashfs=$(call BuildFirmware/OF/tplink,$(1),$(2),$(3),$(4))
+BuildFirmware/Tplink/initramfs=$(call BuildFirmware/OF/tplink/initramfs,$(1),$(2),$(3),$(4))
+
+ralink_default_fw_size_16M=16121856
+BuildFirmware/Default16M/squashfs=$(call BuildFirmware/OF,$(1),$(2),$(3),$(ralink_default_fw_size_16M),$(4))
+BuildFirmware/Default16M/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3),$(4))
+
+# Build images for a custom sized flash layout
+# $(1) = squashfs/initramfs
+# $(2) = lowercase board name
+# $(3) = dts file
+# $(4) = kernel + rootfs size
+BuildFirmware/CustomFlash/squashfs=$(call BuildFirmware/OF,$(1),$(2),$(3),$(4),$(5),$(6))
+BuildFirmware/CustomFlash/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3))
+
+# wrappers for boards that have 4MB and 8MB versions
+define BuildFirmware/DefaultDualSize/squashfs
+ $(call BuildFirmware/Default4M/$(1),$(1),$(2)-4M,$(3)-4M)
+ $(call BuildFirmware/Default8M/$(1),$(1),$(2)-8M,$(3)-8M)
+endef
+define BuildFirmware/DefaultDualSize/initramfs
+ $(call BuildFirmware/OF/initramfs,$(1),$(2)-4M,$(3)-4M)
+ $(call BuildFirmware/OF/initramfs,$(1),$(2)-8M,$(3)-8M)
+endef
+
+# Some boards need a special header inside the uImage to make them bootable
+define BuildFirmware/CustomFlashFactory/squashfs
+ $(call BuildFirmware/CustomFlash/$(1),$(1),$(2),$(3),$(4))
+ $(call BuildFirmware/CustomFlash/$(1),$(1),$(2),$(3),$(4),$(5),$(6))
+endef
+BuildFirmware/CustomFlashFactory/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3))
+
+# sign an image to make it work with edimax tftp recovery
+define BuildFirmware/Edimax/squashfs
+ $(call BuildFirmware/OF,$(1),$(2),$(3),$(4))
+ if [ -e "$(call sysupname,$(1),$(2))" ]; then \
+ mkedimaximg -i $(call sysupname,$(1),$(2)) \
+ -o $(call imgname,$(1),$(2))-factory.bin \
+ -s $(5) -m $(6) -f $(7) -S $(8); \
+ fi