diff mbox

[OpenWrt-Devel] ramips: HooToo HT-TM02 factory image generation.

Message ID owrt-patches-20141227-1@vittgam.net
State RFC
Delegated to: John Crispin
Headers show

Commit Message

Vittorio Gambaletta Dec. 28, 2014, 12:34 p.m. UTC
The mkhootoofw.sh is a shell script, because official factory images are shell scripts by themselves, and it made more sense to me to just use a shell script on the build host to put the pieces for the factory image file together, rather than reimplement the wheel in C.

The hootoo_mtd_writer is a stripped-down and modified version of mtd that includes support for flashing at an offset in the MTD. This is needed for the HooToo, because the only usable partition for factory flashing is the one labeled "ALL", and we don't want to flash the u-boot, u-boot-env and factory partitions too...

The hootoo_mtd_writer binary has been compiled using the toolchain contained in the GPL tarball provided by HooToo. (It seems to me from some tests that this is the only way to get executables running on the stock kernel...)

In order to update the firmware from the web interface you need to put a FAT-formatted pendrive in the router USB port, since the original firmware needs this as temporary storage, because the RAM is quite bloated. Then you upload the OpenWrt factory image generated by mkhootoofw.sh, and the script kills unneeded services and partitions to free up RAM, backs up the original firmware on the pendrive, extracts the hootoo_mtd_writer and the sysupgrade image, flashes the sysupgrade image and then reboots.

I've tested the resulting image on the factory firmware, and it successfully installed OpenWrt on my HT-TM02.

Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net>

Comments

Vittorio Gambaletta Jan. 9, 2015, 8:16 a.m. UTC | #1
Hi,

What is the reason has this been rejected? Do I need to change 
something?

Thanks,
Vittorio

Il 28.12.2014 13:34 Vittorio G (VittGam) ha scritto:
> The mkhootoofw.sh is a shell script, because official factory images
> are shell scripts by themselves, and it made more sense to me to just
> use a shell script on the build host to put the pieces for the 
> factory
> image file together, rather than reimplement the wheel in C.
>
> The hootoo_mtd_writer is a stripped-down and modified version of mtd
> that includes support for flashing at an offset in the MTD. This is
> needed for the HooToo, because the only usable partition for factory
> flashing is the one labeled "ALL", and we don't want to flash the
> u-boot, u-boot-env and factory partitions too...
>
> The hootoo_mtd_writer binary has been compiled using the toolchain
> contained in the GPL tarball provided by HooToo. (It seems to me from
> some tests that this is the only way to get executables running on 
> the
> stock kernel...)
>
> In order to update the firmware from the web interface you need to
> put a FAT-formatted pendrive in the router USB port, since the
> original firmware needs this as temporary storage, because the RAM is
> quite bloated. Then you upload the OpenWrt factory image generated by
> mkhootoofw.sh, and the script kills unneeded services and partitions
> to free up RAM, backs up the original firmware on the pendrive,
> extracts the hootoo_mtd_writer and the sysupgrade image, flashes the
> sysupgrade image and then reboots.
>
> I've tested the resulting image on the factory firmware, and it
> successfully installed OpenWrt on my HT-TM02.
>
> Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net>
>
> --- a/target/linux/ramips/image/Makefile
> +++ b/target/linux/ramips/image/Makefile
> @@ -317,6 +317,15 @@
>  	fi
>  endef
>
> +# Build HooToo factory images
> +define BuildFirmware/HooToo8M/squashfs
> +	$(call BuildFirmware/Default8M/$(1),$(1),$(2),$(3))
> +	[ -e "$(call sysupname,$(1),$(2))" ] && \
> +	$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "hootoo_mtd_writer"
> "3d72349cbb1d8e96086a084a6940304d"
> "https://github.com/VittGam/hootoo_mtd_writer/releases/download/1.0/"
> && \
> +	mkhootoofw.sh "$(DL_DIR)/hootoo_mtd_writer" "$(call
> sysupname,$(1),$(2))" "$(call imgname,$(1),$(2))-factory.bin"
> +endef
> +BuildFirmware/HooToo8M/initramfs=$(call
> BuildFirmware/OF/initramfs,$(1),$(2),$(3))
> +
>  #
>  # RT288X Profiles
>  #
> @@ -480,7 +489,7 @@
>  endef
>  Image/Build/Profile/HLKRM04=$(call
> BuildFirmware/HLKRM04/$(1),$(1),hlk-rm04,HLKRM04,HLK-RM02)
>
> -Image/Build/Profile/HT-TM02=$(call
> BuildFirmware/Default8M/$(1),$(1),ht-tm02,HT-TM02)
> +Image/Build/Profile/HT-TM02=$(call
> BuildFirmware/HooToo8M/$(1),$(1),ht-tm02,HT-TM02)
>
>  Image/Build/Profile/M3=$(call BuildFirmware/Poray4M/$(1),$(1),m3,M3)
>
> --- a/tools/firmware-utils/Makefile
> +++ b/tools/firmware-utils/Makefile
> @@ -76,6 +76,7 @@
>
>  define Host/Install
>  	$(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/* $(STAGING_DIR_HOST)/bin/
> +	$(INSTALL_BIN) src/mkhootoofw.sh $(STAGING_DIR_HOST)/bin/
>  endef
>
>  $(eval $(call HostBuild))
> --- /dev/null
> +++ b/tools/firmware-utils/src/mkhootoofw.sh
> @@ -0,0 +1,88 @@
> +#!/bin/sh
> +#
> +# HooToo Factory Firmware Generator for OpenWrt
> +# Copyright (C) 2014 Vittorio Gambaletta <openwrt@vittgam.net>
> +#
> +# This is free software, licensed under the GNU General Public 
> License v2.
> +# See /LICENSE for more information.
> +#
> +# Sources for the hootoo_mtd_writer utility, which must be compiled
> with the GPL
> +# toolchain provided by HooToo for it to work on the factory kernel, 
> can be
> +# found at: https://github.com/VittGam/hootoo_mtd_writer
> +#
> +# Usage: mkhootoofw.sh path-to-hootoo_mtd_writer
> path-to-openwrt-sysupgrade.bin path-to-openwrt-factory.bin
> +#
> +
> +# Write the shellscript stub
> +cat > "${3}.tmp" <<'EOF'
> +SKIP=57
> +
> +echo "Checking firmware checksum..."
> +[ "$CRCSUM" != "`sed '1,3d' "$0" | cksum | sed -e 's/ /Z/' -e 's/
> /Z/' | cut -dZ -f1`" ] && {
> +	echo "Firmware checksum error!"
> +	exit 1
> +}
> +echo "Firmware checksum OK"
> +
> +echo "Killing unneeded services..."
> +killall -9 fileserv ioos upnpd led_control owndns ownhttp vstddns
> udhcpc udhcpd udevd minidlna smbd nmbd
> +sleep 1
> +
> +echo "Unmounting unneeded mounts..."
> +umount /etc
> +umount /boot/tmp
> +umount /usr/local/samba/var
> +umount /opt
> +umount /var
> +
> +echo "Backing up original firmware..."
> +BKPDIRBASE="/data/UsbDisk1/Volume1/OpenWrt-HooToo-Backup-`sed
> 's/:/-/g' < /sys/class/net/ra0/address`-"
> +BKPDIRNUM=1
> +BKPDIR="${BKPDIRBASE}${BKPDIRNUM}"
> +while [ -e "$BKPDIR" ]; do
> +	BKPDIRNUM=$((${BKPDIRNUM}+1))
> +	BKPDIR="${BKPDIRBASE}${BKPDIRNUM}"
> +done
> +echo "Backup directory: ${BKPDIR}"
> +
> +mkdir "$BKPDIR"
> +cp /dev/mtdblock* "${BKPDIR}/" || {
> +	echo "Backup failed!"
> +	exit 1
> +}
> +sync && echo 3 > /proc/sys/vm/drop_caches
> +echo "Backup OK"
> +
> +echo "Extracting OpenWrt firmware..."
> +tail -n +$SKIP "$0" | tar xv -C /tmp/ || {
> +	echo "Extraction of firmware failed!"
> +	exit 1
> +}
> +chmod +x /tmp/hootoo_mtd_writer
> +sync && echo 3 > /proc/sys/vm/drop_caches
> +
> +echo "Writing OpenWrt firmware..."
> +cd /tmp/
> +/tmp/hootoo_mtd_writer /tmp/openwrt.bin ALL 327680 1
> +
> +echo "Upgrade not successful (reboot by hootoo_mtd_writer not 
> happened)..."
> +exit 1
> +END_OF_STUB
> +EOF
> +
> +# Create and append tar archive containing hootoo_mtd_writer and
> sysupgrade image to the factory image file
> +mkdir "${3}-tmpdir"
> +cp "$1" "${3}-tmpdir/hootoo_mtd_writer"
> +cp "$2" "${3}-tmpdir/openwrt.bin"
> +tar cv -C "${3}-tmpdir/" hootoo_mtd_writer openwrt.bin >> "${3}.tmp"
> +rm -rf "${3}-tmpdir"
> +
> +# Generate the final factory image file along with the checksum
> +echo '#!/bin/sh' > "$3"
> +echo '# OpenWrt factory installation for HooToo HT-TM02' >> "$3"
> +echo -n 'CRCSUM=' >> "$3"
> +cksum < "${3}.tmp" | sed -e 's/ /Z/' -e 's/   /Z/' | cut -dZ -f1 >> 
> "$3"
> +cat "${3}.tmp" >> "$3"
> +rm "${3}.tmp"
> +
> +exit 0
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
John Crispin Jan. 9, 2015, 9:48 a.m. UTC | #2
On 09/01/2015 09:16, Vittorio G (VittGam) wrote:
> Hi,
> 
> What is the reason has this been rejected? Do I need to change
> something?
> 
> Thanks, Vittorio
> 
> Il 28.12.2014 13:34 Vittorio G (VittGam) ha scritto:
>> The mkhootoofw.sh is a shell script, because official factory
>> images are shell scripts by themselves, and it made more sense to
>> me to just use a shell script on the build host to put the pieces
>> for the factory image file together, rather than reimplement the
>> wheel in C.
>> 
>> The hootoo_mtd_writer is a stripped-down and modified version of
>> mtd that includes support for flashing at an offset in the MTD.
>> This is needed for the HooToo, because the only usable partition
>> for factory flashing is the one labeled "ALL", and we don't want
>> to flash the u-boot, u-boot-env and factory partitions too...
>> 
>> The hootoo_mtd_writer binary has been compiled using the
>> toolchain contained in the GPL tarball provided by HooToo. (It
>> seems to me from some tests that this is the only way to get
>> executables running on the stock kernel...)
>> 
>> In order to update the firmware from the web interface you need
>> to put a FAT-formatted pendrive in the router USB port, since
>> the original firmware needs this as temporary storage, because
>> the RAM is quite bloated. Then you upload the OpenWrt factory
>> image generated by mkhootoofw.sh, and the script kills unneeded
>> services and partitions to free up RAM, backs up the original
>> firmware on the pendrive, extracts the hootoo_mtd_writer and the
>> sysupgrade image, flashes the sysupgrade image and then reboots.
>> 
>> I've tested the resulting image on the factory firmware, and it 
>> successfully installed OpenWrt on my HT-TM02.
>> 
>> Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net>
>> 
>> --- a/target/linux/ramips/image/Makefile +++
>> b/target/linux/ramips/image/Makefile @@ -317,6 +317,15 @@ fi 
>> endef
>> 
>> +# Build HooToo factory images +define
>> BuildFirmware/HooToo8M/squashfs +    $(call
>> BuildFirmware/Default8M/$(1),$(1),$(2),$(3)) +    [ -e "$(call
>> sysupname,$(1),$(2))" ] && \ +    $(SCRIPT_DIR)/download.pl
>> "$(DL_DIR)" "hootoo_mtd_writer" 
>> "3d72349cbb1d8e96086a084a6940304d" 
>> "https://github.com/VittGam/hootoo_mtd_writer/releases/download/1.0/"
>>
>> 
&& \
>> +    mkhootoofw.sh "$(DL_DIR)/hootoo_mtd_writer" "$(call 
>> sysupname,$(1),$(2))" "$(call imgname,$(1),$(2))-factory.bin" 
>> +endef +BuildFirmware/HooToo8M/initramfs=$(call 
>> BuildFirmware/OF/initramfs,$(1),$(2),$(3)) +


this bit is really bad. you cannot install a binary from a random
source and use that to flash the unit. the tool needs to be compiled
during the build process


>> # # RT288X Profiles # @@ -480,7 +489,7 @@ endef 
>> Image/Build/Profile/HLKRM04=$(call 
>> BuildFirmware/HLKRM04/$(1),$(1),hlk-rm04,HLKRM04,HLK-RM02)
>> 
>> -Image/Build/Profile/HT-TM02=$(call 
>> BuildFirmware/Default8M/$(1),$(1),ht-tm02,HT-TM02) 
>> +Image/Build/Profile/HT-TM02=$(call 
>> BuildFirmware/HooToo8M/$(1),$(1),ht-tm02,HT-TM02)
>> 
>> Image/Build/Profile/M3=$(call
>> BuildFirmware/Poray4M/$(1),$(1),m3,M3)
>> 
>> --- a/tools/firmware-utils/Makefile +++
>> b/tools/firmware-utils/Makefile @@ -76,6 +76,7 @@
>> 
>> define Host/Install $(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/*
>> $(STAGING_DIR_HOST)/bin/ +    $(INSTALL_BIN) src/mkhootoofw.sh
>> $(STAGING_DIR_HOST)/bin/ endef
>> 
>> $(eval $(call HostBuild)) --- /dev/null +++
>> b/tools/firmware-utils/src/mkhootoofw.sh @@ -0,0 +1,88 @@ 
>> +#!/bin/sh +# +# HooToo Factory Firmware Generator for OpenWrt +#
>> Copyright (C) 2014 Vittorio Gambaletta <openwrt@vittgam.net> +# 
>> +# This is free software, licensed under the GNU General Public 
>> License v2. +# See /LICENSE for more information. +# +# Sources
>> for the hootoo_mtd_writer utility, which must be compiled with
>> the GPL +# toolchain provided by HooToo for it to work on the
>> factory kernel, can be +# found at:
>> https://github.com/VittGam/hootoo_mtd_writer +# +# Usage:
>> mkhootoofw.sh path-to-hootoo_mtd_writer 
>> path-to-openwrt-sysupgrade.bin path-to-openwrt-factory.bin +# + 
>> +# Write the shellscript stub +cat > "${3}.tmp" <<'EOF' +SKIP=57 
>> + +echo "Checking firmware checksum..." +[ "$CRCSUM" != "`sed
>> '1,3d' "$0" | cksum | sed -e 's/ /Z/' -e 's/ /Z/' | cut -dZ -f1`"
>> ] && { +    echo "Firmware checksum error!" +    exit 1 +} +echo
>> "Firmware checksum OK" + +echo "Killing unneeded services..." 
>> +killall -9 fileserv ioos upnpd led_control owndns ownhttp
>> vstddns udhcpc udhcpd udevd minidlna smbd nmbd +sleep 1 + +echo
>> "Unmounting unneeded mounts..." +umount /etc +umount /boot/tmp 
>> +umount /usr/local/samba/var +umount /opt +umount /var + +echo
>> "Backing up original firmware..." 
>> +BKPDIRBASE="/data/UsbDisk1/Volume1/OpenWrt-HooToo-Backup-`sed 
>> 's/:/-/g' < /sys/class/net/ra0/address`-" +BKPDIRNUM=1 
>> +BKPDIR="${BKPDIRBASE}${BKPDIRNUM}" +while [ -e "$BKPDIR" ]; do +
>> BKPDIRNUM=$((${BKPDIRNUM}+1)) +
>> BKPDIR="${BKPDIRBASE}${BKPDIRNUM}" +done +echo "Backup directory:
>> ${BKPDIR}" + +mkdir "$BKPDIR" +cp /dev/mtdblock* "${BKPDIR}/" ||
>> { +    echo "Backup failed!" +    exit 1 +} +sync && echo 3 >
>> /proc/sys/vm/drop_caches +echo "Backup OK" + +echo "Extracting
>> OpenWrt firmware..." +tail -n +$SKIP "$0" | tar xv -C /tmp/ || { 
>> +    echo "Extraction of firmware failed!" +    exit 1 +} +chmod
>> +x /tmp/hootoo_mtd_writer +sync && echo 3 >
>> /proc/sys/vm/drop_caches + +echo "Writing OpenWrt firmware..." 
>> +cd /tmp/ +/tmp/hootoo_mtd_writer /tmp/openwrt.bin ALL 327680 1 
>> + +echo "Upgrade not successful (reboot by hootoo_mtd_writer not 
>> happened)..." +exit 1 +END_OF_STUB +EOF + +# Create and append
>> tar archive containing hootoo_mtd_writer and sysupgrade image to
>> the factory image file +mkdir "${3}-tmpdir" +cp "$1"
>> "${3}-tmpdir/hootoo_mtd_writer" +cp "$2"
>> "${3}-tmpdir/openwrt.bin" +tar cv -C "${3}-tmpdir/"
>> hootoo_mtd_writer openwrt.bin >> "${3}.tmp" +rm -rf
>> "${3}-tmpdir" + +# Generate the final factory image file along
>> with the checksum +echo '#!/bin/sh' > "$3" +echo '# OpenWrt
>> factory installation for HooToo HT-TM02' >> "$3" +echo -n
>> 'CRCSUM=' >> "$3" +cksum < "${3}.tmp" | sed -e 's/ /Z/' -e 's/
>> /Z/' | cut -dZ -f1 >> "$3" +cat "${3}.tmp" >> "$3" +rm
>> "${3}.tmp" + +exit 0 
>> _______________________________________________ openwrt-devel
>> mailing list openwrt-devel@lists.openwrt.org 
>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
> _______________________________________________ openwrt-devel
> mailing list openwrt-devel@lists.openwrt.org 
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
>
Vittorio Gambaletta Jan. 9, 2015, 3:09 p.m. UTC | #3
Il 09.01.2015 10:48 John Crispin ha scritto:
>>> +    mkhootoofw.sh "$(DL_DIR)/hootoo_mtd_writer" "$(call
>>> sysupname,$(1),$(2))" "$(call imgname,$(1),$(2))-factory.bin"
>>> +endef +BuildFirmware/HooToo8M/initramfs=$(call
>>> BuildFirmware/OF/initramfs,$(1),$(2),$(3)) +
>
>
> this bit is really bad. you cannot install a binary from a random
> source and use that to flash the unit. the tool needs to be compiled
> during the build process

Unfortunately the factory image uses an ancient version of uclibc, so 
binaries compiled with the newer version bundled with OpenWrt do not 
work on it... Anyway I've compiled that binary using the toolchain 
provided by HooToo, and the build is reproducible, so you or anybody 
else can easily verify that I'm not lying. :)

Please let me know if you have a better solution, because in fact this 
is not quite clean.

Cheers,
Vittorio
Florian Fainelli Jan. 9, 2015, 3:17 p.m. UTC | #4
Le 9 janv. 2015 07:09, "Vittorio G (VittGam)" <openwrt@vittgam.net> a écrit
:
>
> Il 09.01.2015 10:48 John Crispin ha scritto:
>
>>>> +    mkhootoofw.sh "$(DL_DIR)/hootoo_mtd_writer" "$(call
>>>> sysupname,$(1),$(2))" "$(call imgname,$(1),$(2))-factory.bin"
>>>> +endef +BuildFirmware/HooToo8M/initramfs=$(call
>>>> BuildFirmware/OF/initramfs,$(1),$(2),$(3)) +
>>
>>
>>
>> this bit is really bad. you cannot install a binary from a random
>> source and use that to flash the unit. the tool needs to be compiled
>> during the build process
>
>
> Unfortunately the factory image uses an ancient version of uclibc, so
binaries compiled with the newer version bundled with OpenWrt do not work
on it... Anyway I've compiled that binary using the toolchain provided by
HooToo, and the build is reproducible, so you or anybody else can easily
verify that I'm not lying. :)
>
> Please let me know if you have a better solution, because in fact this is
not quite clean.

What about a statically linked binary at least?

>
> Cheers,
> Vittorio
>
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Vittorio Gambaletta Jan. 9, 2015, 11:56 p.m. UTC | #5
Il 09.01.2015 16:17 Florian Fainelli ha scritto:

> What about a statically linked binary at least?

Of course I've missed the obvious thing here. :) Thanks for the 
suggestion! I'm going to try this as soon as I've some spare time (in a 
week or so). Otherwise the code is on my github if you want to try to do 
it in the meantime (and you have the hardware...).

Cheers,
Vittorio G
diff mbox

Patch

--- a/target/linux/ramips/image/Makefile
+++ b/target/linux/ramips/image/Makefile
@@ -317,6 +317,15 @@ 
 	fi
 endef
 
+# Build HooToo factory images
+define BuildFirmware/HooToo8M/squashfs
+	$(call BuildFirmware/Default8M/$(1),$(1),$(2),$(3))
+	[ -e "$(call sysupname,$(1),$(2))" ] && \
+	$(SCRIPT_DIR)/download.pl "$(DL_DIR)" "hootoo_mtd_writer" "3d72349cbb1d8e96086a084a6940304d" "https://github.com/VittGam/hootoo_mtd_writer/releases/download/1.0/" && \
+	mkhootoofw.sh "$(DL_DIR)/hootoo_mtd_writer" "$(call sysupname,$(1),$(2))" "$(call imgname,$(1),$(2))-factory.bin"
+endef
+BuildFirmware/HooToo8M/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3))
+
 #
 # RT288X Profiles
 #
@@ -480,7 +489,7 @@ 
 endef
 Image/Build/Profile/HLKRM04=$(call BuildFirmware/HLKRM04/$(1),$(1),hlk-rm04,HLKRM04,HLK-RM02)
 
-Image/Build/Profile/HT-TM02=$(call BuildFirmware/Default8M/$(1),$(1),ht-tm02,HT-TM02)
+Image/Build/Profile/HT-TM02=$(call BuildFirmware/HooToo8M/$(1),$(1),ht-tm02,HT-TM02)
 
 Image/Build/Profile/M3=$(call BuildFirmware/Poray4M/$(1),$(1),m3,M3)
 
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -76,6 +76,7 @@ 
 
 define Host/Install
 	$(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/* $(STAGING_DIR_HOST)/bin/
+	$(INSTALL_BIN) src/mkhootoofw.sh $(STAGING_DIR_HOST)/bin/
 endef
 
 $(eval $(call HostBuild))
--- /dev/null
+++ b/tools/firmware-utils/src/mkhootoofw.sh
@@ -0,0 +1,88 @@ 
+#!/bin/sh
+#
+# HooToo Factory Firmware Generator for OpenWrt
+# Copyright (C) 2014 Vittorio Gambaletta <openwrt@vittgam.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# Sources for the hootoo_mtd_writer utility, which must be compiled with the GPL
+# toolchain provided by HooToo for it to work on the factory kernel, can be
+# found at: https://github.com/VittGam/hootoo_mtd_writer
+#
+# Usage: mkhootoofw.sh path-to-hootoo_mtd_writer path-to-openwrt-sysupgrade.bin path-to-openwrt-factory.bin
+#
+
+# Write the shellscript stub
+cat > "${3}.tmp" <<'EOF'
+SKIP=57
+
+echo "Checking firmware checksum..."
+[ "$CRCSUM" != "`sed '1,3d' "$0" | cksum | sed -e 's/ /Z/' -e 's/   /Z/' | cut -dZ -f1`" ] && {
+	echo "Firmware checksum error!"
+	exit 1
+}
+echo "Firmware checksum OK"
+
+echo "Killing unneeded services..."
+killall -9 fileserv ioos upnpd led_control owndns ownhttp vstddns udhcpc udhcpd udevd minidlna smbd nmbd
+sleep 1
+
+echo "Unmounting unneeded mounts..."
+umount /etc
+umount /boot/tmp
+umount /usr/local/samba/var
+umount /opt
+umount /var
+
+echo "Backing up original firmware..."
+BKPDIRBASE="/data/UsbDisk1/Volume1/OpenWrt-HooToo-Backup-`sed 's/:/-/g' < /sys/class/net/ra0/address`-"
+BKPDIRNUM=1
+BKPDIR="${BKPDIRBASE}${BKPDIRNUM}"
+while [ -e "$BKPDIR" ]; do
+	BKPDIRNUM=$((${BKPDIRNUM}+1))
+	BKPDIR="${BKPDIRBASE}${BKPDIRNUM}"
+done
+echo "Backup directory: ${BKPDIR}"
+
+mkdir "$BKPDIR"
+cp /dev/mtdblock* "${BKPDIR}/" || {
+	echo "Backup failed!"
+	exit 1
+}
+sync && echo 3 > /proc/sys/vm/drop_caches
+echo "Backup OK"
+
+echo "Extracting OpenWrt firmware..."
+tail -n +$SKIP "$0" | tar xv -C /tmp/ || {
+	echo "Extraction of firmware failed!"
+	exit 1
+}
+chmod +x /tmp/hootoo_mtd_writer
+sync && echo 3 > /proc/sys/vm/drop_caches
+
+echo "Writing OpenWrt firmware..."
+cd /tmp/
+/tmp/hootoo_mtd_writer /tmp/openwrt.bin ALL 327680 1
+
+echo "Upgrade not successful (reboot by hootoo_mtd_writer not happened)..."
+exit 1
+END_OF_STUB
+EOF
+
+# Create and append tar archive containing hootoo_mtd_writer and sysupgrade image to the factory image file
+mkdir "${3}-tmpdir"
+cp "$1" "${3}-tmpdir/hootoo_mtd_writer"
+cp "$2" "${3}-tmpdir/openwrt.bin"
+tar cv -C "${3}-tmpdir/" hootoo_mtd_writer openwrt.bin >> "${3}.tmp"
+rm -rf "${3}-tmpdir"
+
+# Generate the final factory image file along with the checksum
+echo '#!/bin/sh' > "$3"
+echo '# OpenWrt factory installation for HooToo HT-TM02' >> "$3"
+echo -n 'CRCSUM=' >> "$3"
+cksum < "${3}.tmp" | sed -e 's/ /Z/' -e 's/   /Z/' | cut -dZ -f1 >> "$3"
+cat "${3}.tmp" >> "$3"
+rm "${3}.tmp"
+
+exit 0