loboris пре 9 година
родитељ
комит
ebf0da8c1b

+ 0 - 1
.gitignore

@@ -1 +0,0 @@
-images/**

+ 149 - 194
C2/initramfs/ramfs/init

@@ -66,7 +66,11 @@ export fastboot=n
 export forcefsck=n
 export fsckfix=
 export recovery=
-
+export BOOT_CARDTYPE="unknown"
+export OTHER_CARDTYPE="unknown"
+export BOOT_CARDDEV="9"
+export OTHER_CARDDEV="9"
+export CARD_TYPE="SD"
 
 # mdadm needs hostname to be set. This has to be done before the udev rules are called!
 if [ -f "/etc/hostname" ]; then
@@ -88,6 +92,15 @@ DEFAULTBOOT="1"
 # Parse command line options
 for x in $(cat /proc/cmdline); do
     case $x in
+    boot_card_type=*)
+        BOOT_CARDTYPE=${x#boot_card_type=}
+        ;;
+    boot_card_dev=*)
+        BOOT_CARDDEV=${x#boot_card_dev=}
+        ;;
+    cardtype=*)
+        CARD_TYPE=${x#cardtype=}
+        ;;
 	boot_delay=*)
 		BOOTDELAY="${x#boot_delay=}"
 		case ${BOOTDELAY} in
@@ -183,53 +196,18 @@ chown 0:0 /sbin/*
 echo "1 1 1 1" > /proc/sys/kernel/printk
 sleep 1
 
-# ============================
-# === BOOT & TOOLS SELECT  ===
-# ============================
-
-# ========================================================================================
-# During the u-boot (boot.ini):
-# ========================================================================================
-# C2: boots from SDcard if inserted and it is mmc0
-# XU: the BOOT SWITCH SELECTED DRIVE IS ALWAYS mmc0 !!
-# ========================================================================================
-
-# ========================================================================================
-# In initramfs:
-# ========================================================================================
-# When the system has SINGLE CARD inserted, it is always on /dev/mmcblk0
-# ========================================================================================
-# When two cards are inserted (EMMC & SD):
-# ----------------------------------------------------------------------------------------
-# C2: the system ALWAYS BOOTS FROM SDCARD and it is /dev/mmcblk0, EMMC is /dev/mmcblk1
-# ----------------------------------------------------------------------------------------
-# XU: the system boots from EMMC or SDcard depending on BOOT SWITCH, BUT:
-#     EMMC is /dev/mmcblk0 and SDCard is /dev/mmc1 REGARDLESSS OF THE BOOT SWITCH
-# ========================================================================================
-
-# ========================================================================================
-# Mounts:
-# ========================================================================================
-# Single card: on /mnt1
-# ----------------------------------------------------------------------------------------
-# Dual card:
-#   C2: SDCard on /mnt1, EMMC on /mnt2
-#   XU: BOOT CARD on /mnt1, other card on /mnt2
-# ========================================================================================
-
-
 # === Variables ===
 
 [ ! $BOOTDELAY -gt 4 ] &&  BOOTDELAY=5
-export SCRIPT_VERSION="v2.1"
+
+export SCRIPT_VERSION="v2.2"
 export O_BOARD="OD"
 export ODROID_DTB="odroid.dtb"
 export ODROID_FSTAB="fstab.odroid"
 export ODROID_IMAGE="Kernel"
 export ODROID_ASYSTEMIMAGE="androsystem.img"
 export BKP_PREFIX="OD"
-export BOOT_FROM="/dev/mmcblk0"
-export BOOT_CARDTYPE="SD"
+export NUMCARDS="1"
 
 _desc=""
 _ini_prefix="multiboot"
@@ -262,13 +240,13 @@ _mncrd_6="1"
 _mncrd_7="1"
 _mncrd_8="1"
 _boot_delay=2
-_numcards="1"
 _defboot="none"
 _defdescr="none"
 _defcard="1"
 boot_fail="yes"
 
-# === Set come variables depending on used Odroid board ===
+# =========================================================
+# === Set the variables depending on used Odroid board  ===
 if [ -f /ODROID_C2 ]; then
 	O_BOARD="C2"
 	ODROID_DTB="meson64_odroidc2.dtb"
@@ -276,6 +254,13 @@ if [ -f /ODROID_C2 ]; then
 	ODROID_IMAGE="Image"
 	ODROID_ASYSTEMIMAGE="rootsystem.img"
 	BKP_PREFIX="C2"
+	BOOT_CARDTYPE="SD"
+	BOOT_CARDDEV="0"
+	if [ -b /dev/mmcblk1p1 ]; then
+		NUMCARDS="2"
+		OTHER_CARDDEV="1"
+		OTHER_CARDTYPE="EMMC"
+	fi
 elif [ -f /ODROID_XU ]; then
 	O_BOARD="XU"
 	ODROID_DTB="exynos5422-odroidxu3.dtb"
@@ -283,8 +268,33 @@ elif [ -f /ODROID_XU ]; then
 	ODROID_IMAGE="zImage"
 	ODROID_ASYSTEMIMAGE="system.img"
 	BKP_PREFIX="XU"
-fi
 
+	if [ "${BOOT_CARDTYPE}" = "none" ]; then
+		BOOT_CARDTYPE="SD"
+		if [ -b /dev/mmcblk1p1 ]; then
+			NUMCARDS="2"
+			BOOT_CARDDEV="1"
+			OTHER_CARDDEV="0"
+			OTHER_CARDTYPE="EMMC"
+		else
+			BOOT_CARDDEV="0"
+		fi
+	else
+		[ "${BOOT_CARDTYPE}" = "eMMC" ] && BOOT_CARDTYPE="EMMC"
+		if [ "${BOOT_CARDDEV}" = 1 ]; then
+			NUMCARDS="2"
+			if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+				OTHER_CARDDEV="0"
+				OTHER_CARDTYPE="EMMC"
+			else
+				OTHER_CARDDEV="1"
+				OTHER_CARDTYPE="SD"
+				BOOT_CARDDEV="0"
+			fi
+		fi
+	fi
+fi
+# =========================================================
 
 # === Functions ===
 
@@ -304,6 +314,52 @@ get_descr() {
 #-----------------------------------------------------
 
 
+#-----------------------------------------------------------------------------------------------------------------------
+change_afstab() {
+	# === Configure Android fstab to mount the right partitions ===
+	if [ -f /mnt_a/${ODROID_FSTAB}${1} ]; then
+		if [ "${2}" = "yes" ]; then
+			# Two cards, boot to Android on NON Boot card
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+			else
+				if [ "${OTHER_CARDTYPE}" = "SD" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+				else
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				fi
+			fi
+		else
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+			else
+				if [ "${NUMCARDS}" = "1" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				else
+					# Two cards, boot to Android on Boot card
+					if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+					else
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+					fi
+				fi
+			fi
+		fi
+		cp _fstab_ /mnt_a/${ODROID_FSTAB}${1} > /dev/null 2>&1
+		rm _fstab_ > /dev/null 2>&1
+	elif [ "${1}" = "" ]; then
+		printf "\033[31m\033[1m %s not found\033[22m\033[37m" "${ODROID_FSTAB}${1}"
+		cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+		[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+		sleep 3
+		umount /mnt_a > /dev/null 2>&1
+		return 1
+	fi
+	return 0
+}
+#-----------------------------------------------------------------------------------------------------------------------
+
+
 #----------------------------------------------------------------------------------------------------------------------
 # =======================================================================
 # On C2 boot drive is always mmcblk0 and is mounted on /mnt1
@@ -314,26 +370,17 @@ do_boot() {
 
 	local change_drive="no"
 	local _oncard=""
-
 	_actmount="mnt1"
 	if [ "${3}" = "2" ]; then
 		_actmount="mnt2"
 		change_drive="yes"
 	fi
 
-	if [ "${_numcards}" = "2" ]; then
-		if [ "${O_BOARD}" = "C2" ]; then
-			if [ "${_actmount}" = "mnt1" ]; then
-				_oncard=" on EMMC"
-			else
-				_oncard=" on SDcard"
-			fi
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
 		else
-			if [ "${_actmount}" = "mnt1" ] && [ "${BOOT_FROM}" = "/dev/mmcblk1" ]; then
-				_oncard=" on SDcard"
-			else
-				_oncard=" on EMMC"
-			fi
+			_oncard=" on ${OTHER_CARDTYPE}"
 		fi
 	fi
 
@@ -342,7 +389,7 @@ do_boot() {
 		printf "\r\033[2K"
 		printf "    Booting to \033[32m%s\033[37m\033[36m%s\033[37m" "${2}" "${_oncard}"
 
-		# === Copy selected boot.ini fo BOOT partition
+		# === Copy selected boot.ini to BOOT partition
 		cp /${_actmount}/${_ini_prefix}/${1} /mnt1/boot.ini > /dev/null 2>&1
 		if [ ! $? -eq 0 ]; then
 			cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
@@ -354,32 +401,31 @@ do_boot() {
 		sleep 1
 
 		if [ "${change_drive}" = "yes" ]; then
-			# === boot.ini from SDcard, prepare for boot from mmc 1:1 ===
-			# for kernel/initrd/dtb loading
-			cat /mnt1/boot.ini | sed "s/0:1/1:1/g" > _bini_
-			cp _bini_ /mnt1/boot.ini
-			rm _bini_
-			# for boot.ini loading from /multiboot (it was changed with previous sed operation!)
-			cat /mnt1/boot.ini | sed "s/1:1 0x60000000/0:1 0x60000000/g" > _bini_
-			cp _bini_ /mnt1/boot.ini
-			rm _bini_
+			# === boot.ini from NON-BOOT card, prepare for boot from BOOT card ===
+			if [ "${O_BOARD}" = "C2" ]; then
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/fatload mmc 0:1/fatload mmc 1:1/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+				# for boot.ini loading from /multiboot (it was changed with previous sed operation!)
+				cat /mnt1/boot.ini | sed "s/1:1 0x60000000/0:1 0x60000000/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			else
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/setenv change_osdev no/setenv change_osdev yes/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			fi
 		fi
 
 		if [ "${1}" = "boot.ini.android" ]; then
 			# === mount android system partition to prepare android fstab ===
 			mkdir /mnt_a > /dev/null 2>&1
 			if [ "${change_drive}" = "yes" ]; then
-				if [ "${BOOT_FROM}" = "/dev/mmcblk0" ]; then
-					mount -t ext4 /dev/mmcblk1p2 /mnt_a > /dev/null 2>&1
-				else
-					mount -t ext4 /dev/mmcblk0p2 /mnt_a > /dev/null 2>&1
-				fi
+				mount -t ext4 /dev/mmcblk${OTHER_CARDDEV}p2 /mnt_a > /dev/null 2>&1
 			else
-				if [ "${BOOT_FROM}" = "/dev/mmcblk0" ]; then
-					mount -t ext4 /dev/mmcblk0p2 /mnt_a > /dev/null 2>&1
-				else
-					mount -t ext4 /dev/mmcblk1p2 /mnt_a > /dev/null 2>&1
-				fi
+				mount -t ext4 /dev/mmcblk${BOOT_CARDDEV}p2 /mnt_a > /dev/null 2>&1
 			fi
 			if [ $? -ne 0 ]; then
 				printf "\033[31m\033[1m Mount Android system partition ERROR\033[22m\033[37m"
@@ -391,51 +437,23 @@ do_boot() {
 			fi
 
 			# === Configure Android fstab to mount the right partitions ===
-			if [ -f /mnt_a/${ODROID_FSTAB} ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}
-				rm _fstab_
-			else
-				printf "\033[31m\033[1m %s not found\033[22m\033[37m" "${ODROID_FSTAB}"
-				cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
-				[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
-				sleep 3
-				umount /mnt_a > /dev/null 2>&1
-				return 1
-			fi
-			if [ -f /mnt_a/${ODROID_FSTAB}.sdcard ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB}.sdcard | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB}.sdcard | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}.sdcard
-				rm _fstab_
-			fi
-			if [ -f /mnt_a/${ODROID_FSTAB}.sdboot ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB}.sdboot | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB}.sdboot | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}.sdboot
-				rm _fstab_
-			fi
+			change_afstab "" "${change_drive}"
+			[ $? -ne 0 ] && return 1
+			change_afstab ".sdcard" "${change_drive}"
+			change_afstab ".sdboot" "${change_drive}"
+			umount /mnt_a > /dev/null 2>&1
+			# =============================================================
 
-			if [ "${change_drive}" = "yes" ]; then
-				# prepare boot.ini for boot from sdcard
+			if [ "${O_BOARD}" = "C2" ] && [ "${change_drive}" = "yes" ]; then
+				# on C2 prepare boot.ini for boot from sdcard, not needed on XU
 				cat /mnt1/boot.ini | sed "s/root=\/dev\/mmcblk0p2/root=\/dev\/mmcblk1p2/g" > _bini_
 				cp _bini_ /mnt1/boot.ini
 				rm _bini_
 			fi
-			umount /mnt_a > /dev/null 2>&1
 		fi
 
 		if [ "${O_BOARD}" = "XU" ]; then
+			# Convert boot.ini to boot.scr
 			mkimage -C none -A arm -T script -d /mnt1/boot.ini /mnt1/boot.scr > /dev/null 2>&1
 			if [ $? -ne 0 ]; then
 				printf "\033[31m\033[1m mkimage (boot.scr) ERROR\033[22m\033[37m"
@@ -501,19 +519,11 @@ set_menu_key() {
 # shellcheck disable=SC2059
 get_menu_items() {
 	local _oncard=""
-	if [ "${_numcards}" = "2" ]; then
-		if [ "${O_BOARD}" = "C2" ]; then
-			if [ "${_actmount}" = "mnt1" ]; then
-				_oncard=" on EMMC"
-			else
-				_oncard=" on SDcard"
-			fi
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
 		else
-			if [ "${_actmount}" = "mnt1" ] && [ "${BOOT_FROM}" = "/dev/mmcblk1" ]; then
-				_oncard=" on SDcard"
-			else
-				_oncard=" on EMMC"
-			fi
+			_oncard=" on ${OTHER_CARDTYPE}"
 		fi
 	fi
 	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.android ]; then
@@ -595,7 +605,6 @@ os_detect() {
 	_mncrd_7="1"
 	_mncrd_8="1"
 	_boot_delay=2
-	_numcards="1"
 	_defboot="none"
 	_defdescr="none"
 	_defcard="1"
@@ -608,84 +617,25 @@ os_detect() {
 	umount /mnt > /dev/null 2>&1
 
 	clear
+	# Detect new partitions after install
 	blkid  > /dev/null 2>&1
 
-	printf "\n\n    Detecting cards...\n"
-
-	# === Detect mmc cards ===
-	_numcards="0"
-	BOOT_FROM="none"
 	# ================================
-	# Find boot card, mount both cards
+	# Mount available cards
 	# ================================
-	mount -t vfat /dev/mmcblk0p1 /mnt1 > /dev/null 2>&1
+	mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt1 > /dev/null 2>&1
 	if [ $? -eq 0 ]; then
-		_numcards="1"
-		if [ -f /mnt1/_BOOT_FROM_ ]; then
-			# BOOT DRIVE IS mmcblk0
-			BOOT_FROM="/dev/mmcblk0"
-			rm -f /mnt1/_BOOT_FROM_ > /dev/null 2>&1
-		fi
-		# === Check if the 2nd card is present ===
-		if [ -b /dev/mmcblk1p1 ]; then
-			mount -t vfat /dev/mmcblk1p1 /mnt2 > /dev/null 2>&1
-			if [ $? -eq 0 ]; then
-				_numcards="2"
-				if [ "${O_BOARD}" = "XU" ]; then
-					# On XU3/XU4 the boot card can be SDcard or EMMC
-					if [ -f /mnt2/_BOOT_FROM_ ]; then
-						# === BOOT FROM SDcard ===
-						rm -f /mnt2/_BOOT_FROM_ > /dev/null 2>&1
-						if [ "${BOOT_FROM}" = "none" ]; then
-							# === remount boot drive to /mnt1 ===
-							umount /mnt1 > /dev/null 2>&1
-							umount /mnt2 > /dev/null 2>&1
-							sleep 1
-							mount -t vfat /dev/mmcblk1p1 /mnt1 > /dev/null 2>&1
-							mount -t vfat /dev/mmcblk0p1 /mnt2 > /dev/null 2>&1
-							BOOT_FROM="/dev/mmcblk1"
-						fi
-					fi
-				else
-					rm -f /mnt2/_BOOT_FROM_ > /dev/null 2>&1
-					BOOT_FROM="/dev/mmcblk0"
-				fi
+		if [ "${NUMCARDS}" = "2" ]; then
+			mount -t vfat /dev/mmcblk${OTHER_CARDDEV}p1 /mnt2 > /dev/null 2>&1
+			if [ $? -ne 0 ]; then
+				OTHER_CARDDEV="9"
 			fi
-		else
-			BOOT_FROM="/dev/mmcblk0"
 		fi
 	else
 		# === SOMETHING IS VERY WRONG ===
 		do_halt "BOOT CARD NOT MOUNTABLE"
 	fi
 
-	if [ "${O_BOARD}" = "XU" ]; then
-		[ -b /dev/mmcblk0boot0 ] && BOOT_CARDTYPE="EMMC"
-	fi
-
-	if [ "${BOOT_FROM}" = "none" ]; then
-		printf "\033[31m\033[1m    WARNING:\033[36m\n"
-		printf "    ==========================================================\n"
-		printf "    = Two cards detected, the boot card cannot be determined =\n"
-		printf "    = You have probably booted from original Odroid card     =\n"
-		printf "    ==========================================================\n\n"
-		printf "    Have you booted from SD Card ? (y/N) "
-		BOOT_FROM="/dev/mmcblk0"
-		B="X"
-		_delay=60
-		while [ $_reboot_delay -gt 0 ]; do
-			if read -n 1 -t 1 -s B; then
-				_delay=60
-				if [ "${B}" = "y" ] || [ "${B}" = "Y" ]; then
-					BOOT_FROM="/dev/mmcblk1"
-					break
-				fi
-			else
-				let _delay=_delay-1
-			fi
-		done
-	fi
-
 	clear
 	printf "\n"
 	printf "\033[36m\033[1m\n"
@@ -698,7 +648,12 @@ os_detect() {
 		printf "    = ODROID XU3/XU4 BOOT MENU %s =\n" "${SCRIPT_VERSION}"
 		printf "    =================================\n"
 	fi
-	printf "\033[22m\033[37m\n"
+	if [ "${NUMCARDS}" = "2" ]; then
+		printf "\033[22m    Two cards detected, booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	else
+		printf "\033[22m    Booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	fi
+
 
 	#===================================================
 	# === Detect available OS's and print menu items ===
@@ -708,7 +663,7 @@ os_detect() {
 	_actmount="mnt1"
 	if [ -b /dev/disk/by-label/sduserdata ] || [ -b /dev/disk/by-label/emuserdata ]; then
 		get_menu_items
-		if [ "${_numcards}" = "2" ]; then
+		if [ "${NUMCARDS}" = "2" ]; then
 			_actmount="mnt2"
 			[ ! ${_numos} -eq 0 ] && printf "\n"
 			get_menu_items
@@ -915,7 +870,7 @@ while true; do
 		elif [ "${A}" = "s" ]; then
 			# SCREENSHOT ===
 			fbcat > /mb_menu.ppm
-		elif [ ! "${BOOT_FROM}" = "none" ]; then
+		elif [ $_numos -gt 0 ]; then
 			# === BOOT to selected OS
 			boot_fail="no"
 			[ "${A}" = "1" ] && [ ! "${_menuitem_1}" = "none" ] && do_boot "${_menuitem_1}" "${_mndscr_1}" "${_mncrd_1}"

+ 71 - 133
C2/initramfs/ramfs/install.script

@@ -30,80 +30,46 @@ print_header() {
 
 print_header
 
-# ** wait for sd/emmc card
-while [ ! -b /dev/mmcblk0 ] && [ ! -b /dev/mmcblk1 ]
-do
-  printf "    Waiting for sd/mmc card...\r"
-  sleep 1
-done
-sleep 1
-
-export CARD1=""
-export CARD2=""
-export CARD1_EMMC=""
-export CARD2_EMMC=""
-export DEST_CARD=""
-export DEST_EMMC=""
-export SINGLE_CARD="yes"
-export SOURCE_CARD=""
-export INST_ANDROID=""
-export INST_OELEC=""
-export INST_LINUX=""
-export INST_LINUX2=""
-export A_FROMDIR=""
-export L_FROMDIR=""
-export L2_FROMDIR=""
-export O_FROMDIR=""
-export INST_DELAY=60
-export SYSTEM_SIZE=1024
-export SYSTEM_MINSIZE=768
-export DATA_SIZE=1024
-export DATA_MINSIZE=1024
-export CACHE_SIZE=256
-export CACHE_MINSIZE=128
-export USERDATA_SIZE=1024
-export USERDATA_MINSIZE=512
-export LINUX_SIZE=2048
-export LINUX_MINSIZE=2048
-export LINUX2_SIZE=2048
-export LINUX2_MINSIZE=2048
-export OELEC_SIZE=512
-export OELEC_MINSIZE=512
-export LINUX_FSTYPE="ext4"
+# Set variables
+CARD1=""
+CARD2=""
+CARD1_EMMC=""
+CARD2_EMMC=""
+DEST_CARD=""
+DEST_EMMC=""
+INST_ANDROID=""
+INST_OELEC=""
+INST_LINUX=""
+INST_LINUX2=""
+A_FROMDIR=""
+L_FROMDIR=""
+L2_FROMDIR=""
+O_FROMDIR=""
+INST_DELAY=60
+SYSTEM_SIZE=1024
+SYSTEM_MINSIZE=768
+DATA_SIZE=1024
+DATA_MINSIZE=1024
+CACHE_SIZE=256
+CACHE_MINSIZE=128
+USERDATA_SIZE=1024
+USERDATA_MINSIZE=512
+LINUX_SIZE=2048
+LINUX_MINSIZE=2048
+LINUX2_SIZE=2048
+LINUX2_MINSIZE=2048
+OELEC_SIZE=512
+OELEC_MINSIZE=512
+LINUX_FSTYPE="ext4"
 
 #-----------------------------------------------------
 # Check card type
 #----------------
-if [ "${O_BOARD}" = "C2" ]; then
-	# === On C2 the boot card is always /dev/mmcblk0 ===
-	CARD1="/dev/mmcblk0"
-	CARD1_EMMC="SD"
-	if [ -b /dev/mmcblk1 ]; then
-		SINGLE_CARD="no"
-		CARD2="/dev/mmcblk1"
-		CARD1_EMMC="EMMC"
-		CARD2_EMMC="SD"
-	fi
-else
-	# === On XU3/XU4 if the EMMC is present, it is /dev/mmcblk0 !! ===
-	# === boot card can be /dev/mmcblk0 or /dev/mmcblk1 ===
-	if [ -b /dev/mmcblk0 ]; then
-		CARD1="/dev/mmcblk0"
-		if [ -b /dev/mmcblk0boot0 ]; then
-			CARD1_EMMC="EMMC"
-		else
-			CARD1_EMMC="SD"
-		fi
-	fi
-	if [ -b /dev/mmcblk1 ]; then
-		SINGLE_CARD="no"
-		CARD2="/dev/mmcblk1"
-		if [ -b /dev/mmcblk1boot0 ]; then
-			CARD2_EMMC="EMMC"
-		else
-			CARD2_EMMC="SD"
-		fi
-	fi
+CARD1="/dev/mmcblk${BOOT_CARDDEV}"
+CARD1_EMMC="${BOOT_CARDTYPE}"
+if [ "${NUMCARDS}" = "2" ]; then
+	CARD2="/dev/mmcblk${OTHER_CARDDEV}"
+	CARD2_EMMC="${OTHER_CARDTYPE}"
 fi
 #-----------------------------------------------------
 
@@ -116,7 +82,6 @@ check_source() {
     if [ -b ${1} ]; then
 		/bin/mountx ${1} /mnt > /dev/null 2>&1
 		[ $? -ne 0 ] && return 1
-		SOURCE_CARD="${1}"
 	else
 		return 1
     fi
@@ -132,7 +97,7 @@ check_source() {
 			A_FROMDIR="yes"
 		fi
     else
-		if [ -f /mnt/update.tar.gz ]; then
+		if [ -f /mnt/update.tar.gz ] || [ -f /mnt/update.zip ]; then
 			INST_ANDROID="yes"
 			_instfound="yes"
 			if [ "${1}" = "/dev/mmcblk0p1" ] || [ "${1}" = "/dev/mmcblk1p1" ]; then
@@ -214,8 +179,8 @@ exit_script() {
 
 print_header
 
-# === Copy multiboot files ===
-mount -t vfat ${BOOT_FROM}p1 /mnt > /dev/null 2>&1
+# === Copy multiboot files from boot drive to RAMfs directory ===
+mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt > /dev/null 2>&1
 if [ $? -ne 0 ]; then
 	printf "    ERROR mounting boot card"
 	exit_script
@@ -240,11 +205,9 @@ printf "    Searching for installation drive ... "
 # === Set default dest card to sdcard if exists ===
 DEST_CARD=${CARD1}
 DEST_EMMC=${CARD1_EMMC}
-if [ "${SINGLE_CARD}" = "no" ]; then
-	if [ ! "${CARD2}" = "${BOOT_FROM}" ]; then
-		DEST_CARD=${CARD2}
-		DEST_EMMC=${CARD2_EMMC}
-	fi
+if [ "${NUMCARDS}" = "2" ]; then
+	DEST_CARD=${CARD2}
+	DEST_EMMC=${CARD2_EMMC}
 fi
 
 check_source "/dev/sda1"
@@ -255,15 +218,9 @@ if [ $? -ne 0 ]; then
 		if [ $? -ne 0 ]; then
 			check_source "/dev/sda4"
 			if [ $? -ne 0 ]; then
-				check_source "/dev/mmcblk0p1"
-				if [ $? -ne 0 ]; then
-					check_source "/dev/mmcblk1p1"
-					if [ $? -ne 0 ]; then
-						printf "    \033[33m\033[1mNOT FOUND\033[22m\033[37m\n"
-						printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n\n"
-						exit_script
-					fi
-				fi
+				printf "    \033[33m\033[1mNOT FOUND\033[22m\033[37m\n"
+				printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n\n"
+				exit_script
 			fi
 		fi
 	fi
@@ -498,27 +455,7 @@ set_dest() {
 		if read -n 1 -t 1 -s A; then
 			_wait_delay=30
 			if [ "${A}" = "+" ]; then
-				if [ "${O_BOARD}" = "C2" ]; then
-					if [ "${SINGLE_CARD}" = "yes" ]; then
-						if [ "${DEST_EMMC}" = "SD" ]; then
-							DEST_EMMC="EMMC"
-						else
-							DEST_EMMC="SD"
-						fi
-					else
-						if [ "${DEST_CARD}" = "${CARD1}" ]; then
-							if [ ! "${CARD2}" = "" ]; then
-								DEST_CARD=${CARD2}
-								DEST_EMMC=${CARD2_EMMC}
-							fi
-						elif [ "${DEST_CARD}" = "${CARD2}" ]; then
-							if [ ! "${CARD1}" = "" ]; then
-								DEST_CARD=${CARD1}
-								DEST_EMMC=${CARD1_EMMC}
-							fi
-						fi
-					fi
-				else
+				if [ "${NUMCARDS}" = "2" ]; then
 					if [ "${DEST_CARD}" = "${CARD1}" ]; then
 						if [ ! "${CARD2}" = "" ]; then
 							DEST_CARD=${CARD2}
@@ -530,6 +467,12 @@ set_dest() {
 							DEST_EMMC=${CARD1_EMMC}
 						fi
 					fi
+				elif [ "${O_BOARD}" = "C2" ]; then
+					if [ "${DEST_EMMC}" = "SD" ]; then
+						DEST_EMMC="EMMC"
+					else
+						DEST_EMMC="SD"
+					fi
 				fi
 			elif [ "${A}" = "9" ]; then
 				set_cardsize
@@ -1205,7 +1148,7 @@ set_android_sizes() {
 	done
 	CACHE_SIZE=${CACHE_MINSIZE}
 
-	_img_size=$(/bin/lsx -ls ${andro_dest}/userdata.raw.img | awk '{print $1}')
+	_img_size=$(/bin/lsx -ls ${andro_dest}/data.raw.img | awk '{print $1}')
 	_img_size_=$(( $_img_size / 1024 / $PARTSIZE_INC * $PARTSIZE_INC ))
 	while [ $DATA_MINSIZE -lt $_img_size_ ]
 	do
@@ -1294,7 +1237,6 @@ unpack_android() {
 				return 1
 			fi
 			sync
-			echo "OK."
 			andro_source="${source_mount}/android"
 		else
 			echo "ERROR: archive file not found."
@@ -1354,7 +1296,7 @@ unpack_android() {
 			return 1
 		fi
     fi
-
+	
     # All needed images and files are present, get sizes
 	_ramfs_free=$(df | grep tmpfs | awk '{print $4}')
 	_ramfs_free=$(( $_ramfs_free / 1024 - 100 ))
@@ -1398,7 +1340,7 @@ unpack_android() {
 	rm ${andro_source}/cache.img
 
 	printf "data... "
-	simg2img ${andro_source}/userdata.img ${andro_dest}/userdata.raw.img >> ${log_file} 2>&1
+	simg2img ${andro_source}/userdata.img ${andro_dest}/data.raw.img >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
 		echo "ERROR."
 		return 1
@@ -1502,14 +1444,14 @@ install_android() {
     # mount source
 	mount -t ext4 -o ro,loop ${andro_dest}/data.raw.img /mnt1 >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
-		echo "ERROR mounting userdata image."
+		echo "ERROR mounting data image."
 		return 1
 	fi
 	# mount destination
 	mount -t ext4 ${DEST_CARD}p5 /mnt2 >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
 		umount /mnt1 >> ${log_file} 2>&1
-		echo "ERROR mounting userdata partition."
+		echo "ERROR mounting data partition."
 		return 1
 	fi
 	sleep 1
@@ -1559,19 +1501,24 @@ install_android() {
 
     # Install kernel
     printf "\033[36mkernel\033[37m ... "
-	dd if=${andro_dest}/${ODROID_DTB} of=${DEST_CARD} seek=1504 >> ${log_file} 2>&1
-    if [ $? -ne 0 ]; then
-        echo "ERROR installing Android kernel."
-        return 1
-    else
-		dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1632 >> ${log_file} 2>&1
+    if [ "${O_BOARD}" = "xC2" ]; then
+		dd if=${andro_dest}/${ODROID_DTB} of=${DEST_CARD} seek=1504 >> ${log_file} 2>&1
 		if [ $? -ne 0 ]; then
-			echo "ERROR installing Android kernel."
+			echo "ERROR installing Android kernel (DTB)."
 			return 1
 		else
-			echo "OK"
+			dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1632 >> ${log_file} 2>&1
 		fi
-    fi
+    elif [ "${O_BOARD}" = "xXU" ]; then
+		dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1263 >> ${log_file} 2>&1
+	else
+		printf "not needed "
+	fi
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing Android kernel."
+		return 1
+	fi
+	echo "OK"
     sync
     sleep 1
 
@@ -2121,15 +2068,6 @@ else
     label_pref="sd"
 fi
 
-# --- Check source ---------------------------------------------------------------------------------------------------
-if [ "${SOURCE_CARD}" = "${BOOT_FROM}" ]; then
-	if [ "${ONLY_ANDROID}" != "yes" ]; then
-		printf "    \033[33m\033[1mONLY SINGLE ANDROID INSTALLATION\n    IS POSSIBLE FROM BOOT Card !\033[22m\033[37m\n"
-		umount ${source_mount} > /dev/null 2>&1
-		exit_script
-	fi
-fi
-
 if [ "${INST_ANDROID}" != "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
     printf "    \033[33m\033[1mNothing to install!\033[22m\033[37m\n"
     printf "    \033[33m\033[1mAndroid or Linux must be installed!\033[22m\033[37m\n"

+ 3 - 17
C2/multiboot/boot.ini.multi

@@ -13,18 +13,13 @@ setenv DEFAULT_OS "1"
 #
 # ===============================================================
 
-# ===============================================================
-# Time (sec) to automatic install if no key is pressed          =
-# ------------------------------------------------------------- =
-setenv INST_DELAY "10000"
-# ===============================================================
 
 # ===============================================================
-# Card type on which is this file, must be SDCARD or EMMCARD    =
+# Card type on which is this file, must be SD or EMMC           =
 # !! DO NOT CHANGE !!                                           =                                        
 # (will be changed automaticaly when installed on EMMC)         =
 # ------------------------------------------------------------- =
-setenv CARD_TYPE "SDCARD"
+setenv CARD_TYPE "SD"
 # ===============================================================
 
 
@@ -155,21 +150,12 @@ setenv maxcpus "4"
 # setenv max_freq "1656"  # 1.656GHz
 setenv max_freq "1536"  # 1.536GHz
 
-
-# =================================================
-# = NEEDED FOR BOOT SELECT SCRIPT, DO NOT CHANGE  =
-# =================================================
-mw.b 0x60000000 0x41 0x10
-fatwrite mmc 0:1 0x60000000 _BOOT_FROM_ 10
-sleep 1
-# =================================================
-
 ###########################################
 
 # Boot Arguments
 if test "${m}" = "custombuilt"; then setenv cmode "modeline=${modeline}"; fi
 
-setenv bootargs "console=tty0 quiet cardtype=${CARD_TYPE} instdelay=${INST_DELAY} boot_delay=${BOOT_DELAY} default_os=${DEFAULT_OS} no_console_suspend loglevel=0 hdmimode=${m} ${comde} m_bpp=${m_bpp} vout=${vout} fsck.repair=yes net.ifnames=0 elevator=noop disablehpd=${hpd} max_freq=${max_freq} maxcpus=${maxcpus} monitor_onoff=${monitor_onoff}"
+setenv bootargs "console=tty0 quiet cardtype=${CARD_TYPE} boot_delay=${BOOT_DELAY} default_os=${DEFAULT_OS} no_console_suspend loglevel=0 hdmimode=${m} ${comde} m_bpp=${m_bpp} vout=${vout} fsck.repair=yes net.ifnames=0 elevator=noop disablehpd=${hpd} max_freq=${max_freq} maxcpus=${maxcpus} monitor_onoff=${monitor_onoff}"
 
 # Booting
 

BIN
C2/multiboot/uInitrd.multi


+ 149 - 194
XU4/initramfs/ramfs/init

@@ -66,7 +66,11 @@ export fastboot=n
 export forcefsck=n
 export fsckfix=
 export recovery=
-
+export BOOT_CARDTYPE="unknown"
+export OTHER_CARDTYPE="unknown"
+export BOOT_CARDDEV="9"
+export OTHER_CARDDEV="9"
+export CARD_TYPE="SD"
 
 # mdadm needs hostname to be set. This has to be done before the udev rules are called!
 if [ -f "/etc/hostname" ]; then
@@ -88,6 +92,15 @@ DEFAULTBOOT="1"
 # Parse command line options
 for x in $(cat /proc/cmdline); do
     case $x in
+    boot_card_type=*)
+        BOOT_CARDTYPE=${x#boot_card_type=}
+        ;;
+    boot_card_dev=*)
+        BOOT_CARDDEV=${x#boot_card_dev=}
+        ;;
+    cardtype=*)
+        CARD_TYPE=${x#cardtype=}
+        ;;
 	boot_delay=*)
 		BOOTDELAY="${x#boot_delay=}"
 		case ${BOOTDELAY} in
@@ -183,53 +196,18 @@ chown 0:0 /sbin/*
 echo "1 1 1 1" > /proc/sys/kernel/printk
 sleep 1
 
-# ============================
-# === BOOT & TOOLS SELECT  ===
-# ============================
-
-# ========================================================================================
-# During the u-boot (boot.ini):
-# ========================================================================================
-# C2: boots from SDcard if inserted and it is mmc0
-# XU: the BOOT SWITCH SELECTED DRIVE IS ALWAYS mmc0 !!
-# ========================================================================================
-
-# ========================================================================================
-# In initramfs:
-# ========================================================================================
-# When the system has SINGLE CARD inserted, it is always on /dev/mmcblk0
-# ========================================================================================
-# When two cards are inserted (EMMC & SD):
-# ----------------------------------------------------------------------------------------
-# C2: the system ALWAYS BOOTS FROM SDCARD and it is /dev/mmcblk0, EMMC is /dev/mmcblk1
-# ----------------------------------------------------------------------------------------
-# XU: the system boots from EMMC or SDcard depending on BOOT SWITCH, BUT:
-#     EMMC is /dev/mmcblk0 and SDCard is /dev/mmc1 REGARDLESSS OF THE BOOT SWITCH
-# ========================================================================================
-
-# ========================================================================================
-# Mounts:
-# ========================================================================================
-# Single card: on /mnt1
-# ----------------------------------------------------------------------------------------
-# Dual card:
-#   C2: SDCard on /mnt1, EMMC on /mnt2
-#   XU: BOOT CARD on /mnt1, other card on /mnt2
-# ========================================================================================
-
-
 # === Variables ===
 
 [ ! $BOOTDELAY -gt 4 ] &&  BOOTDELAY=5
-export SCRIPT_VERSION="v2.1"
+
+export SCRIPT_VERSION="v2.2"
 export O_BOARD="OD"
 export ODROID_DTB="odroid.dtb"
 export ODROID_FSTAB="fstab.odroid"
 export ODROID_IMAGE="Kernel"
 export ODROID_ASYSTEMIMAGE="androsystem.img"
 export BKP_PREFIX="OD"
-export BOOT_FROM="/dev/mmcblk0"
-export BOOT_CARDTYPE="SD"
+export NUMCARDS="1"
 
 _desc=""
 _ini_prefix="multiboot"
@@ -262,13 +240,13 @@ _mncrd_6="1"
 _mncrd_7="1"
 _mncrd_8="1"
 _boot_delay=2
-_numcards="1"
 _defboot="none"
 _defdescr="none"
 _defcard="1"
 boot_fail="yes"
 
-# === Set come variables depending on used Odroid board ===
+# =========================================================
+# === Set the variables depending on used Odroid board  ===
 if [ -f /ODROID_C2 ]; then
 	O_BOARD="C2"
 	ODROID_DTB="meson64_odroidc2.dtb"
@@ -276,6 +254,13 @@ if [ -f /ODROID_C2 ]; then
 	ODROID_IMAGE="Image"
 	ODROID_ASYSTEMIMAGE="rootsystem.img"
 	BKP_PREFIX="C2"
+	BOOT_CARDTYPE="SD"
+	BOOT_CARDDEV="0"
+	if [ -b /dev/mmcblk1p1 ]; then
+		NUMCARDS="2"
+		OTHER_CARDDEV="1"
+		OTHER_CARDTYPE="EMMC"
+	fi
 elif [ -f /ODROID_XU ]; then
 	O_BOARD="XU"
 	ODROID_DTB="exynos5422-odroidxu3.dtb"
@@ -283,8 +268,33 @@ elif [ -f /ODROID_XU ]; then
 	ODROID_IMAGE="zImage"
 	ODROID_ASYSTEMIMAGE="system.img"
 	BKP_PREFIX="XU"
-fi
 
+	if [ "${BOOT_CARDTYPE}" = "none" ]; then
+		BOOT_CARDTYPE="SD"
+		if [ -b /dev/mmcblk1p1 ]; then
+			NUMCARDS="2"
+			BOOT_CARDDEV="1"
+			OTHER_CARDDEV="0"
+			OTHER_CARDTYPE="EMMC"
+		else
+			BOOT_CARDDEV="0"
+		fi
+	else
+		[ "${BOOT_CARDTYPE}" = "eMMC" ] && BOOT_CARDTYPE="EMMC"
+		if [ "${BOOT_CARDDEV}" = 1 ]; then
+			NUMCARDS="2"
+			if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+				OTHER_CARDDEV="0"
+				OTHER_CARDTYPE="EMMC"
+			else
+				OTHER_CARDDEV="1"
+				OTHER_CARDTYPE="SD"
+				BOOT_CARDDEV="0"
+			fi
+		fi
+	fi
+fi
+# =========================================================
 
 # === Functions ===
 
@@ -304,6 +314,52 @@ get_descr() {
 #-----------------------------------------------------
 
 
+#-----------------------------------------------------------------------------------------------------------------------
+change_afstab() {
+	# === Configure Android fstab to mount the right partitions ===
+	if [ -f /mnt_a/${ODROID_FSTAB}${1} ]; then
+		if [ "${2}" = "yes" ]; then
+			# Two cards, boot to Android on NON Boot card
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+			else
+				if [ "${OTHER_CARDTYPE}" = "SD" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+				else
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				fi
+			fi
+		else
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+			else
+				if [ "${NUMCARDS}" = "1" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				else
+					# Two cards, boot to Android on Boot card
+					if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+					else
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+					fi
+				fi
+			fi
+		fi
+		cp _fstab_ /mnt_a/${ODROID_FSTAB}${1} > /dev/null 2>&1
+		rm _fstab_ > /dev/null 2>&1
+	elif [ "${1}" = "" ]; then
+		printf "\033[31m\033[1m %s not found\033[22m\033[37m" "${ODROID_FSTAB}${1}"
+		cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+		[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+		sleep 3
+		umount /mnt_a > /dev/null 2>&1
+		return 1
+	fi
+	return 0
+}
+#-----------------------------------------------------------------------------------------------------------------------
+
+
 #----------------------------------------------------------------------------------------------------------------------
 # =======================================================================
 # On C2 boot drive is always mmcblk0 and is mounted on /mnt1
@@ -314,26 +370,17 @@ do_boot() {
 
 	local change_drive="no"
 	local _oncard=""
-
 	_actmount="mnt1"
 	if [ "${3}" = "2" ]; then
 		_actmount="mnt2"
 		change_drive="yes"
 	fi
 
-	if [ "${_numcards}" = "2" ]; then
-		if [ "${O_BOARD}" = "C2" ]; then
-			if [ "${_actmount}" = "mnt1" ]; then
-				_oncard=" on EMMC"
-			else
-				_oncard=" on SDcard"
-			fi
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
 		else
-			if [ "${_actmount}" = "mnt1" ] && [ "${BOOT_FROM}" = "/dev/mmcblk1" ]; then
-				_oncard=" on SDcard"
-			else
-				_oncard=" on EMMC"
-			fi
+			_oncard=" on ${OTHER_CARDTYPE}"
 		fi
 	fi
 
@@ -342,7 +389,7 @@ do_boot() {
 		printf "\r\033[2K"
 		printf "    Booting to \033[32m%s\033[37m\033[36m%s\033[37m" "${2}" "${_oncard}"
 
-		# === Copy selected boot.ini fo BOOT partition
+		# === Copy selected boot.ini to BOOT partition
 		cp /${_actmount}/${_ini_prefix}/${1} /mnt1/boot.ini > /dev/null 2>&1
 		if [ ! $? -eq 0 ]; then
 			cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
@@ -354,32 +401,31 @@ do_boot() {
 		sleep 1
 
 		if [ "${change_drive}" = "yes" ]; then
-			# === boot.ini from SDcard, prepare for boot from mmc 1:1 ===
-			# for kernel/initrd/dtb loading
-			cat /mnt1/boot.ini | sed "s/0:1/1:1/g" > _bini_
-			cp _bini_ /mnt1/boot.ini
-			rm _bini_
-			# for boot.ini loading from /multiboot (it was changed with previous sed operation!)
-			cat /mnt1/boot.ini | sed "s/1:1 0x60000000/0:1 0x60000000/g" > _bini_
-			cp _bini_ /mnt1/boot.ini
-			rm _bini_
+			# === boot.ini from NON-BOOT card, prepare for boot from BOOT card ===
+			if [ "${O_BOARD}" = "C2" ]; then
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/fatload mmc 0:1/fatload mmc 1:1/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+				# for boot.ini loading from /multiboot (it was changed with previous sed operation!)
+				cat /mnt1/boot.ini | sed "s/1:1 0x60000000/0:1 0x60000000/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			else
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/setenv change_osdev no/setenv change_osdev yes/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			fi
 		fi
 
 		if [ "${1}" = "boot.ini.android" ]; then
 			# === mount android system partition to prepare android fstab ===
 			mkdir /mnt_a > /dev/null 2>&1
 			if [ "${change_drive}" = "yes" ]; then
-				if [ "${BOOT_FROM}" = "/dev/mmcblk0" ]; then
-					mount -t ext4 /dev/mmcblk1p2 /mnt_a > /dev/null 2>&1
-				else
-					mount -t ext4 /dev/mmcblk0p2 /mnt_a > /dev/null 2>&1
-				fi
+				mount -t ext4 /dev/mmcblk${OTHER_CARDDEV}p2 /mnt_a > /dev/null 2>&1
 			else
-				if [ "${BOOT_FROM}" = "/dev/mmcblk0" ]; then
-					mount -t ext4 /dev/mmcblk0p2 /mnt_a > /dev/null 2>&1
-				else
-					mount -t ext4 /dev/mmcblk1p2 /mnt_a > /dev/null 2>&1
-				fi
+				mount -t ext4 /dev/mmcblk${BOOT_CARDDEV}p2 /mnt_a > /dev/null 2>&1
 			fi
 			if [ $? -ne 0 ]; then
 				printf "\033[31m\033[1m Mount Android system partition ERROR\033[22m\033[37m"
@@ -391,51 +437,23 @@ do_boot() {
 			fi
 
 			# === Configure Android fstab to mount the right partitions ===
-			if [ -f /mnt_a/${ODROID_FSTAB} ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}
-				rm _fstab_
-			else
-				printf "\033[31m\033[1m %s not found\033[22m\033[37m" "${ODROID_FSTAB}"
-				cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
-				[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
-				sleep 3
-				umount /mnt_a > /dev/null 2>&1
-				return 1
-			fi
-			if [ -f /mnt_a/${ODROID_FSTAB}.sdcard ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB}.sdcard | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB}.sdcard | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}.sdcard
-				rm _fstab_
-			fi
-			if [ -f /mnt_a/${ODROID_FSTAB}.sdboot ]; then
-				if [ "${change_drive}" = "yes" ]; then
-					cat /mnt_a/${ODROID_FSTAB}.sdboot | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
-				else
-					cat /mnt_a/${ODROID_FSTAB}.sdboot | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
-				fi
-				cp _fstab_ /mnt_a/${ODROID_FSTAB}.sdboot
-				rm _fstab_
-			fi
+			change_afstab "" "${change_drive}"
+			[ $? -ne 0 ] && return 1
+			change_afstab ".sdcard" "${change_drive}"
+			change_afstab ".sdboot" "${change_drive}"
+			umount /mnt_a > /dev/null 2>&1
+			# =============================================================
 
-			if [ "${change_drive}" = "yes" ]; then
-				# prepare boot.ini for boot from sdcard
+			if [ "${O_BOARD}" = "C2" ] && [ "${change_drive}" = "yes" ]; then
+				# on C2 prepare boot.ini for boot from sdcard, not needed on XU
 				cat /mnt1/boot.ini | sed "s/root=\/dev\/mmcblk0p2/root=\/dev\/mmcblk1p2/g" > _bini_
 				cp _bini_ /mnt1/boot.ini
 				rm _bini_
 			fi
-			umount /mnt_a > /dev/null 2>&1
 		fi
 
 		if [ "${O_BOARD}" = "XU" ]; then
+			# Convert boot.ini to boot.scr
 			mkimage -C none -A arm -T script -d /mnt1/boot.ini /mnt1/boot.scr > /dev/null 2>&1
 			if [ $? -ne 0 ]; then
 				printf "\033[31m\033[1m mkimage (boot.scr) ERROR\033[22m\033[37m"
@@ -501,19 +519,11 @@ set_menu_key() {
 # shellcheck disable=SC2059
 get_menu_items() {
 	local _oncard=""
-	if [ "${_numcards}" = "2" ]; then
-		if [ "${O_BOARD}" = "C2" ]; then
-			if [ "${_actmount}" = "mnt1" ]; then
-				_oncard=" on EMMC"
-			else
-				_oncard=" on SDcard"
-			fi
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
 		else
-			if [ "${_actmount}" = "mnt1" ] && [ "${BOOT_FROM}" = "/dev/mmcblk1" ]; then
-				_oncard=" on SDcard"
-			else
-				_oncard=" on EMMC"
-			fi
+			_oncard=" on ${OTHER_CARDTYPE}"
 		fi
 	fi
 	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.android ]; then
@@ -595,7 +605,6 @@ os_detect() {
 	_mncrd_7="1"
 	_mncrd_8="1"
 	_boot_delay=2
-	_numcards="1"
 	_defboot="none"
 	_defdescr="none"
 	_defcard="1"
@@ -608,84 +617,25 @@ os_detect() {
 	umount /mnt > /dev/null 2>&1
 
 	clear
+	# Detect new partitions after install
 	blkid  > /dev/null 2>&1
 
-	printf "\n\n    Detecting cards...\n"
-
-	# === Detect mmc cards ===
-	_numcards="0"
-	BOOT_FROM="none"
 	# ================================
-	# Find boot card, mount both cards
+	# Mount available cards
 	# ================================
-	mount -t vfat /dev/mmcblk0p1 /mnt1 > /dev/null 2>&1
+	mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt1 > /dev/null 2>&1
 	if [ $? -eq 0 ]; then
-		_numcards="1"
-		if [ -f /mnt1/_BOOT_FROM_ ]; then
-			# BOOT DRIVE IS mmcblk0
-			BOOT_FROM="/dev/mmcblk0"
-			rm -f /mnt1/_BOOT_FROM_ > /dev/null 2>&1
-		fi
-		# === Check if the 2nd card is present ===
-		if [ -b /dev/mmcblk1p1 ]; then
-			mount -t vfat /dev/mmcblk1p1 /mnt2 > /dev/null 2>&1
-			if [ $? -eq 0 ]; then
-				_numcards="2"
-				if [ "${O_BOARD}" = "XU" ]; then
-					# On XU3/XU4 the boot card can be SDcard or EMMC
-					if [ -f /mnt2/_BOOT_FROM_ ]; then
-						# === BOOT FROM SDcard ===
-						rm -f /mnt2/_BOOT_FROM_ > /dev/null 2>&1
-						if [ "${BOOT_FROM}" = "none" ]; then
-							# === remount boot drive to /mnt1 ===
-							umount /mnt1 > /dev/null 2>&1
-							umount /mnt2 > /dev/null 2>&1
-							sleep 1
-							mount -t vfat /dev/mmcblk1p1 /mnt1 > /dev/null 2>&1
-							mount -t vfat /dev/mmcblk0p1 /mnt2 > /dev/null 2>&1
-							BOOT_FROM="/dev/mmcblk1"
-						fi
-					fi
-				else
-					rm -f /mnt2/_BOOT_FROM_ > /dev/null 2>&1
-					BOOT_FROM="/dev/mmcblk0"
-				fi
+		if [ "${NUMCARDS}" = "2" ]; then
+			mount -t vfat /dev/mmcblk${OTHER_CARDDEV}p1 /mnt2 > /dev/null 2>&1
+			if [ $? -ne 0 ]; then
+				OTHER_CARDDEV="9"
 			fi
-		else
-			BOOT_FROM="/dev/mmcblk0"
 		fi
 	else
 		# === SOMETHING IS VERY WRONG ===
 		do_halt "BOOT CARD NOT MOUNTABLE"
 	fi
 
-	if [ "${O_BOARD}" = "XU" ]; then
-		[ -b /dev/mmcblk0boot0 ] && BOOT_CARDTYPE="EMMC"
-	fi
-
-	if [ "${BOOT_FROM}" = "none" ]; then
-		printf "\033[31m\033[1m    WARNING:\033[36m\n"
-		printf "    ==========================================================\n"
-		printf "    = Two cards detected, the boot card cannot be determined =\n"
-		printf "    = You have probably booted from original Odroid card     =\n"
-		printf "    ==========================================================\n\n"
-		printf "    Have you booted from SD Card ? (y/N) "
-		BOOT_FROM="/dev/mmcblk0"
-		B="X"
-		_delay=60
-		while [ $_reboot_delay -gt 0 ]; do
-			if read -n 1 -t 1 -s B; then
-				_delay=60
-				if [ "${B}" = "y" ] || [ "${B}" = "Y" ]; then
-					BOOT_FROM="/dev/mmcblk1"
-					break
-				fi
-			else
-				let _delay=_delay-1
-			fi
-		done
-	fi
-
 	clear
 	printf "\n"
 	printf "\033[36m\033[1m\n"
@@ -698,7 +648,12 @@ os_detect() {
 		printf "    = ODROID XU3/XU4 BOOT MENU %s =\n" "${SCRIPT_VERSION}"
 		printf "    =================================\n"
 	fi
-	printf "\033[22m\033[37m\n"
+	if [ "${NUMCARDS}" = "2" ]; then
+		printf "\033[22m    Two cards detected, booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	else
+		printf "\033[22m    Booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	fi
+
 
 	#===================================================
 	# === Detect available OS's and print menu items ===
@@ -708,7 +663,7 @@ os_detect() {
 	_actmount="mnt1"
 	if [ -b /dev/disk/by-label/sduserdata ] || [ -b /dev/disk/by-label/emuserdata ]; then
 		get_menu_items
-		if [ "${_numcards}" = "2" ]; then
+		if [ "${NUMCARDS}" = "2" ]; then
 			_actmount="mnt2"
 			[ ! ${_numos} -eq 0 ] && printf "\n"
 			get_menu_items
@@ -915,7 +870,7 @@ while true; do
 		elif [ "${A}" = "s" ]; then
 			# SCREENSHOT ===
 			fbcat > /mb_menu.ppm
-		elif [ ! "${BOOT_FROM}" = "none" ]; then
+		elif [ $_numos -gt 0 ]; then
 			# === BOOT to selected OS
 			boot_fail="no"
 			[ "${A}" = "1" ] && [ ! "${_menuitem_1}" = "none" ] && do_boot "${_menuitem_1}" "${_mndscr_1}" "${_mncrd_1}"

+ 71 - 133
XU4/initramfs/ramfs/install.script

@@ -30,80 +30,46 @@ print_header() {
 
 print_header
 
-# ** wait for sd/emmc card
-while [ ! -b /dev/mmcblk0 ] && [ ! -b /dev/mmcblk1 ]
-do
-  printf "    Waiting for sd/mmc card...\r"
-  sleep 1
-done
-sleep 1
-
-export CARD1=""
-export CARD2=""
-export CARD1_EMMC=""
-export CARD2_EMMC=""
-export DEST_CARD=""
-export DEST_EMMC=""
-export SINGLE_CARD="yes"
-export SOURCE_CARD=""
-export INST_ANDROID=""
-export INST_OELEC=""
-export INST_LINUX=""
-export INST_LINUX2=""
-export A_FROMDIR=""
-export L_FROMDIR=""
-export L2_FROMDIR=""
-export O_FROMDIR=""
-export INST_DELAY=60
-export SYSTEM_SIZE=1024
-export SYSTEM_MINSIZE=768
-export DATA_SIZE=1024
-export DATA_MINSIZE=1024
-export CACHE_SIZE=256
-export CACHE_MINSIZE=128
-export USERDATA_SIZE=1024
-export USERDATA_MINSIZE=512
-export LINUX_SIZE=2048
-export LINUX_MINSIZE=2048
-export LINUX2_SIZE=2048
-export LINUX2_MINSIZE=2048
-export OELEC_SIZE=512
-export OELEC_MINSIZE=512
-export LINUX_FSTYPE="ext4"
+# Set variables
+CARD1=""
+CARD2=""
+CARD1_EMMC=""
+CARD2_EMMC=""
+DEST_CARD=""
+DEST_EMMC=""
+INST_ANDROID=""
+INST_OELEC=""
+INST_LINUX=""
+INST_LINUX2=""
+A_FROMDIR=""
+L_FROMDIR=""
+L2_FROMDIR=""
+O_FROMDIR=""
+INST_DELAY=60
+SYSTEM_SIZE=1024
+SYSTEM_MINSIZE=768
+DATA_SIZE=1024
+DATA_MINSIZE=1024
+CACHE_SIZE=256
+CACHE_MINSIZE=128
+USERDATA_SIZE=1024
+USERDATA_MINSIZE=512
+LINUX_SIZE=2048
+LINUX_MINSIZE=2048
+LINUX2_SIZE=2048
+LINUX2_MINSIZE=2048
+OELEC_SIZE=512
+OELEC_MINSIZE=512
+LINUX_FSTYPE="ext4"
 
 #-----------------------------------------------------
 # Check card type
 #----------------
-if [ "${O_BOARD}" = "C2" ]; then
-	# === On C2 the boot card is always /dev/mmcblk0 ===
-	CARD1="/dev/mmcblk0"
-	CARD1_EMMC="SD"
-	if [ -b /dev/mmcblk1 ]; then
-		SINGLE_CARD="no"
-		CARD2="/dev/mmcblk1"
-		CARD1_EMMC="EMMC"
-		CARD2_EMMC="SD"
-	fi
-else
-	# === On XU3/XU4 if the EMMC is present, it is /dev/mmcblk0 !! ===
-	# === boot card can be /dev/mmcblk0 or /dev/mmcblk1 ===
-	if [ -b /dev/mmcblk0 ]; then
-		CARD1="/dev/mmcblk0"
-		if [ -b /dev/mmcblk0boot0 ]; then
-			CARD1_EMMC="EMMC"
-		else
-			CARD1_EMMC="SD"
-		fi
-	fi
-	if [ -b /dev/mmcblk1 ]; then
-		SINGLE_CARD="no"
-		CARD2="/dev/mmcblk1"
-		if [ -b /dev/mmcblk1boot0 ]; then
-			CARD2_EMMC="EMMC"
-		else
-			CARD2_EMMC="SD"
-		fi
-	fi
+CARD1="/dev/mmcblk${BOOT_CARDDEV}"
+CARD1_EMMC="${BOOT_CARDTYPE}"
+if [ "${NUMCARDS}" = "2" ]; then
+	CARD2="/dev/mmcblk${OTHER_CARDDEV}"
+	CARD2_EMMC="${OTHER_CARDTYPE}"
 fi
 #-----------------------------------------------------
 
@@ -116,7 +82,6 @@ check_source() {
     if [ -b ${1} ]; then
 		/bin/mountx ${1} /mnt > /dev/null 2>&1
 		[ $? -ne 0 ] && return 1
-		SOURCE_CARD="${1}"
 	else
 		return 1
     fi
@@ -132,7 +97,7 @@ check_source() {
 			A_FROMDIR="yes"
 		fi
     else
-		if [ -f /mnt/update.tar.gz ]; then
+		if [ -f /mnt/update.tar.gz ] || [ -f /mnt/update.zip ]; then
 			INST_ANDROID="yes"
 			_instfound="yes"
 			if [ "${1}" = "/dev/mmcblk0p1" ] || [ "${1}" = "/dev/mmcblk1p1" ]; then
@@ -214,8 +179,8 @@ exit_script() {
 
 print_header
 
-# === Copy multiboot files ===
-mount -t vfat ${BOOT_FROM}p1 /mnt > /dev/null 2>&1
+# === Copy multiboot files from boot drive to RAMfs directory ===
+mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt > /dev/null 2>&1
 if [ $? -ne 0 ]; then
 	printf "    ERROR mounting boot card"
 	exit_script
@@ -240,11 +205,9 @@ printf "    Searching for installation drive ... "
 # === Set default dest card to sdcard if exists ===
 DEST_CARD=${CARD1}
 DEST_EMMC=${CARD1_EMMC}
-if [ "${SINGLE_CARD}" = "no" ]; then
-	if [ ! "${CARD2}" = "${BOOT_FROM}" ]; then
-		DEST_CARD=${CARD2}
-		DEST_EMMC=${CARD2_EMMC}
-	fi
+if [ "${NUMCARDS}" = "2" ]; then
+	DEST_CARD=${CARD2}
+	DEST_EMMC=${CARD2_EMMC}
 fi
 
 check_source "/dev/sda1"
@@ -255,15 +218,9 @@ if [ $? -ne 0 ]; then
 		if [ $? -ne 0 ]; then
 			check_source "/dev/sda4"
 			if [ $? -ne 0 ]; then
-				check_source "/dev/mmcblk0p1"
-				if [ $? -ne 0 ]; then
-					check_source "/dev/mmcblk1p1"
-					if [ $? -ne 0 ]; then
-						printf "    \033[33m\033[1mNOT FOUND\033[22m\033[37m\n"
-						printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n\n"
-						exit_script
-					fi
-				fi
+				printf "    \033[33m\033[1mNOT FOUND\033[22m\033[37m\n"
+				printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n\n"
+				exit_script
 			fi
 		fi
 	fi
@@ -498,27 +455,7 @@ set_dest() {
 		if read -n 1 -t 1 -s A; then
 			_wait_delay=30
 			if [ "${A}" = "+" ]; then
-				if [ "${O_BOARD}" = "C2" ]; then
-					if [ "${SINGLE_CARD}" = "yes" ]; then
-						if [ "${DEST_EMMC}" = "SD" ]; then
-							DEST_EMMC="EMMC"
-						else
-							DEST_EMMC="SD"
-						fi
-					else
-						if [ "${DEST_CARD}" = "${CARD1}" ]; then
-							if [ ! "${CARD2}" = "" ]; then
-								DEST_CARD=${CARD2}
-								DEST_EMMC=${CARD2_EMMC}
-							fi
-						elif [ "${DEST_CARD}" = "${CARD2}" ]; then
-							if [ ! "${CARD1}" = "" ]; then
-								DEST_CARD=${CARD1}
-								DEST_EMMC=${CARD1_EMMC}
-							fi
-						fi
-					fi
-				else
+				if [ "${NUMCARDS}" = "2" ]; then
 					if [ "${DEST_CARD}" = "${CARD1}" ]; then
 						if [ ! "${CARD2}" = "" ]; then
 							DEST_CARD=${CARD2}
@@ -530,6 +467,12 @@ set_dest() {
 							DEST_EMMC=${CARD1_EMMC}
 						fi
 					fi
+				elif [ "${O_BOARD}" = "C2" ]; then
+					if [ "${DEST_EMMC}" = "SD" ]; then
+						DEST_EMMC="EMMC"
+					else
+						DEST_EMMC="SD"
+					fi
 				fi
 			elif [ "${A}" = "9" ]; then
 				set_cardsize
@@ -1205,7 +1148,7 @@ set_android_sizes() {
 	done
 	CACHE_SIZE=${CACHE_MINSIZE}
 
-	_img_size=$(/bin/lsx -ls ${andro_dest}/userdata.raw.img | awk '{print $1}')
+	_img_size=$(/bin/lsx -ls ${andro_dest}/data.raw.img | awk '{print $1}')
 	_img_size_=$(( $_img_size / 1024 / $PARTSIZE_INC * $PARTSIZE_INC ))
 	while [ $DATA_MINSIZE -lt $_img_size_ ]
 	do
@@ -1294,7 +1237,6 @@ unpack_android() {
 				return 1
 			fi
 			sync
-			echo "OK."
 			andro_source="${source_mount}/android"
 		else
 			echo "ERROR: archive file not found."
@@ -1354,7 +1296,7 @@ unpack_android() {
 			return 1
 		fi
     fi
-
+	
     # All needed images and files are present, get sizes
 	_ramfs_free=$(df | grep tmpfs | awk '{print $4}')
 	_ramfs_free=$(( $_ramfs_free / 1024 - 100 ))
@@ -1398,7 +1340,7 @@ unpack_android() {
 	rm ${andro_source}/cache.img
 
 	printf "data... "
-	simg2img ${andro_source}/userdata.img ${andro_dest}/userdata.raw.img >> ${log_file} 2>&1
+	simg2img ${andro_source}/userdata.img ${andro_dest}/data.raw.img >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
 		echo "ERROR."
 		return 1
@@ -1502,14 +1444,14 @@ install_android() {
     # mount source
 	mount -t ext4 -o ro,loop ${andro_dest}/data.raw.img /mnt1 >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
-		echo "ERROR mounting userdata image."
+		echo "ERROR mounting data image."
 		return 1
 	fi
 	# mount destination
 	mount -t ext4 ${DEST_CARD}p5 /mnt2 >> ${log_file} 2>&1
 	if [ $? -ne 0 ]; then
 		umount /mnt1 >> ${log_file} 2>&1
-		echo "ERROR mounting userdata partition."
+		echo "ERROR mounting data partition."
 		return 1
 	fi
 	sleep 1
@@ -1559,19 +1501,24 @@ install_android() {
 
     # Install kernel
     printf "\033[36mkernel\033[37m ... "
-	dd if=${andro_dest}/${ODROID_DTB} of=${DEST_CARD} seek=1504 >> ${log_file} 2>&1
-    if [ $? -ne 0 ]; then
-        echo "ERROR installing Android kernel."
-        return 1
-    else
-		dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1632 >> ${log_file} 2>&1
+    if [ "${O_BOARD}" = "xC2" ]; then
+		dd if=${andro_dest}/${ODROID_DTB} of=${DEST_CARD} seek=1504 >> ${log_file} 2>&1
 		if [ $? -ne 0 ]; then
-			echo "ERROR installing Android kernel."
+			echo "ERROR installing Android kernel (DTB)."
 			return 1
 		else
-			echo "OK"
+			dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1632 >> ${log_file} 2>&1
 		fi
-    fi
+    elif [ "${O_BOARD}" = "xXU" ]; then
+		dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1263 >> ${log_file} 2>&1
+	else
+		printf "not needed "
+	fi
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing Android kernel."
+		return 1
+	fi
+	echo "OK"
     sync
     sleep 1
 
@@ -2121,15 +2068,6 @@ else
     label_pref="sd"
 fi
 
-# --- Check source ---------------------------------------------------------------------------------------------------
-if [ "${SOURCE_CARD}" = "${BOOT_FROM}" ]; then
-	if [ "${ONLY_ANDROID}" != "yes" ]; then
-		printf "    \033[33m\033[1mONLY SINGLE ANDROID INSTALLATION\n    IS POSSIBLE FROM BOOT Card !\033[22m\033[37m\n"
-		umount ${source_mount} > /dev/null 2>&1
-		exit_script
-	fi
-fi
-
 if [ "${INST_ANDROID}" != "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
     printf "    \033[33m\033[1mNothing to install!\033[22m\033[37m\n"
     printf "    \033[33m\033[1mAndroid or Linux must be installed!\033[22m\033[37m\n"

+ 32 - 13
XU4/initramfs/ramfs/multi/boot.ini.android

@@ -1,4 +1,3 @@
-ODROIDXU-UBOOT-CONFIG
 #DESCRIPTION "Odroid Android"
  
 # setenv fb_x_res "640"
@@ -87,19 +86,39 @@ setenv hpd "1"
  
 setenv led_blink        "1"
  
-# =================================================
-# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE =
-# =================================================
-fatload mmc 0:1 0x60000000 multiboot/boot.scr.multi
-fatwrite mmc 0:1 0x60000000 boot.scr ${filesize}
-sleep 1
-# =================================================
+setenv bootargs     "fb_x_res=${fb_x_res} fb_y_res=${fb_y_res} hdmi_phy_res=${hdmi_phy_res} edid=${edid} hpd=${hpd} led_blink=${led_blink}"
 
-#setenv bootcmd      "movi read kernel 0 40008000;bootz 40008000"
+# ========================================================
+# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE        =
+# ========================================================
+mmc list
+mmc dev
 
-setenv bootargs     "fb_x_res=${fb_x_res} fb_y_res=${fb_y_res} hdmi_phy_res=${hdmi_phy_res} edid=${edid} hpd=${hpd} led_blink=${led_blink}"
+setenv change_osdev no;
+
+setenv bootdev "0:1";
+if test "${mmc_boot_device}" = "0"; then
+  setenv bootdev "0:1";
+elif test "${mmc_boot_device}" = "1"; then
+  setenv bootdev "1:1";
+fi
+
+setenv os_dev "${bootdev}";
+if test "${change_osdev}" = "yes"; then
+  if test "${bootdev}" = "0:1"; then
+    setenv os_dev "1:1";
+  else
+    setenv os_dev "0:1";
+  fi
+fi
+# ========================================================
+
+fatload mmc ${os_dev} 40008000 /multiboot/zImage.android
 
-setenv kernel  "fatload mmc 0:1 40008000 mutiboot/zImage.android"
-setenv bootcmd "${kernel}; bootz 40008000"
+# === RESTORE MULTIBOOT SCRIPT ===========================
+fatload mmc ${bootdev} 0x60000000 /multiboot/boot.scr.multi
+fatwrite mmc ${bootdev} 0x60000000 boot.scr ${filesize}
+#=========================================================
 
-boot
+# Boot the board
+bootz 40008000"

+ 34 - 12
XU4/initramfs/ramfs/multi/boot.ini.linux

@@ -1,4 +1,4 @@
-ODROIDXU-UBOOT-CONFIG
+#DESCRIPTION Odroid Linux
 
 # U-Boot Parameters
 setenv initrd_high "0xffffffff"
@@ -10,7 +10,7 @@ setenv macaddr "00:1e:06:61:7a:39"
 #------------------------------------------------------------------------------------------------------
 # Basic Ubuntu Setup. Don't touch unless you know what you are doing.
 # --------------------------------
-setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=LABEL=XXlinux rootwait ro fsck.repair=yes net.ifnames=0"
+setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=LABEL=XXlinux rootwait ro  loglevel=3 fsck.repair=yes net.ifnames=0"
 
 # --- Screen Configuration for HDMI --- # 
 # ---------------------------------------
@@ -198,18 +198,35 @@ setenv hdmi_tx_res      "0"
 
 setenv hdmi_phy_control "hdmi_tx_amp_lvl=${hdmi_tx_amp_lvl} hdmi_tx_lvl_ch0=${hdmi_tx_lvl_ch0} hdmi_tx_lvl_ch1=${hdmi_tx_lvl_ch1} hdmi_tx_lvl_ch2=${hdmi_tx_lvl_ch2} hdmi_tx_emp_lvl=${hdmi_tx_emp_lvl} hdmi_clk_amp_lvl=${hdmi_clk_amp_lvl} hdmi_tx_res=${hdmi_tx_res} HPD=${HPD} vout=${vout}"
 
-# =================================================
-# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE =
-# =================================================
-fatload mmc 0:1 0x60000000 multiboot/boot.scr.multi
-fatwrite mmc 0:1 0x60000000 boot.scr ${filesize}
-sleep 1
-# =================================================
+# ========================================================
+# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE        =
+# ========================================================
+mmc list
+mmc dev
+
+setenv change_osdev no;
+
+setenv bootdev "0:1";
+if test "${mmc_boot_device}" = "0"; then
+  setenv bootdev "0:1";
+elif test "${mmc_boot_device}" = "1"; then
+  setenv bootdev "1:1";
+fi
+
+setenv os_dev "${bootdev}";
+if test "${change_osdev}" = "yes"; then
+  if test "${bootdev}" = "0:1"; then
+    setenv os_dev "1:1";
+  else
+    setenv os_dev "0:1";
+  fi
+fi
+# ========================================================
 
 # Load kernel, initrd and dtb in that sequence
-fatload mmc 0:1 0x40008000 multiboot/zImage.linux
-fatload mmc 0:1 0x42000000 multiboot/uInitrd.linux
-fatload mmc 0:1 0x44000000 multiboot/exynos5422-odroidxu3.dtb.linux
+fatload mmc ${os_dev} 0x40008000 multiboot/zImage.linux
+fatload mmc ${os_dev} 0x42000000 multiboot/uInitrd.linux
+fatload mmc ${os_dev} 0x44000000 multiboot/exynos5422-odroidxu3.dtb.linux
 
 # set FDT address
 fdt addr 0x44000000
@@ -220,5 +237,10 @@ if test "${cecenable}" = "false"; then fdt rm /cec@101B0000; fi
 # final boot args
 setenv bootargs "${bootrootfs} ${videoconfig} smsc95xx.macaddr=${macaddr} governor=${governor} ${hdmi_phy_control}"
 
+# === RESTORE MULTIBOOT SCRIPT ===========================
+fatload mmc ${bootdev} 0x60000000 multiboot/boot.scr.multi
+fatwrite mmc ${bootdev} 0x60000000 boot.scr ${filesize}
+#=========================================================
+
 # Boot the board
 bootz 0x40008000 0x42000000 0x44000000

+ 34 - 12
XU4/initramfs/ramfs/multi/boot.ini.linux2

@@ -1,4 +1,4 @@
-ODROIDXU-UBOOT-CONFIG
+#DESCRIPTION 2nd Odroid Linux
 
 # U-Boot Parameters
 setenv initrd_high "0xffffffff"
@@ -10,7 +10,7 @@ setenv macaddr "00:1e:06:61:7a:39"
 #------------------------------------------------------------------------------------------------------
 # Basic Ubuntu Setup. Don't touch unless you know what you are doing.
 # --------------------------------
-setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=LABEL=XXlinux rootwait ro fsck.repair=yes net.ifnames=0"
+setenv bootrootfs "console=tty1 console=ttySAC2,115200n8 root=LABEL=XXlinux rootwait ro loglevel=3 fsck.repair=yes net.ifnames=0"
 
 # --- Screen Configuration for HDMI --- # 
 # ---------------------------------------
@@ -198,18 +198,35 @@ setenv hdmi_tx_res      "0"
 
 setenv hdmi_phy_control "hdmi_tx_amp_lvl=${hdmi_tx_amp_lvl} hdmi_tx_lvl_ch0=${hdmi_tx_lvl_ch0} hdmi_tx_lvl_ch1=${hdmi_tx_lvl_ch1} hdmi_tx_lvl_ch2=${hdmi_tx_lvl_ch2} hdmi_tx_emp_lvl=${hdmi_tx_emp_lvl} hdmi_clk_amp_lvl=${hdmi_clk_amp_lvl} hdmi_tx_res=${hdmi_tx_res} HPD=${HPD} vout=${vout}"
 
-# =================================================
-# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE =
-# =================================================
-fatload mmc 0:1 0x60000000 multiboot/boot.scr.multi
-fatwrite mmc 0:1 0x60000000 boot.scr ${filesize}
-sleep 1
-# =================================================
+# ========================================================
+# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE        =
+# ========================================================
+mmc list
+mmc dev
+
+setenv change_osdev no;
+
+setenv bootdev "0:1";
+if test "${mmc_boot_device}" = "0"; then
+  setenv bootdev "0:1";
+elif test "${mmc_boot_device}" = "1"; then
+  setenv bootdev "1:1";
+fi
+
+setenv os_dev "${bootdev}";
+if test "${change_osdev}" = "yes"; then
+  if test "${bootdev}" = "0:1"; then
+    setenv os_dev "1:1";
+  else
+    setenv os_dev "0:1";
+  fi
+fi
+# ========================================================
 
 # Load kernel, initrd and dtb in that sequence
-fatload mmc 0:1 0x40008000 multiboot/zImage.linux2
-fatload mmc 0:1 0x42000000 multiboot/uInitrd.linux2
-fatload mmc 0:1 0x44000000 multiboot/exynos5422-odroidxu3.dtb.linux2
+fatload mmc ${os_dev} 0x40008000 multiboot/zImage.linux2
+fatload mmc ${os_dev} 0x42000000 multiboot/uInitrd.linux2
+fatload mmc ${os_dev} 0x44000000 multiboot/exynos5422-odroidxu3.dtb.linux2
 
 # set FDT address
 fdt addr 0x44000000
@@ -220,5 +237,10 @@ if test "${cecenable}" = "false"; then fdt rm /cec@101B0000; fi
 # final boot args
 setenv bootargs "${bootrootfs} ${videoconfig} smsc95xx.macaddr=${macaddr} governor=${governor} ${hdmi_phy_control}"
 
+# === RESTORE MULTIBOOT SCRIPT ===========================
+fatload mmc ${bootdev} 0x60000000 multiboot/boot.scr.multi
+fatwrite mmc ${bootdev} 0x60000000 boot.scr ${filesize}
+#=========================================================
+
 # Boot the board
 bootz 0x40008000 0x42000000 0x44000000

+ 35 - 24
XU4/initramfs/ramfs/multi/boot.ini.oelec

@@ -1,9 +1,4 @@
-#------------------------------------------------------------------------------------------------------
-#
-# boot.ini identification
-#
-#------------------------------------------------------------------------------------------------------
-ODROIDXU-UBOOT-CONFIG
+#DESCRIPTION Odroid OpenElec
 
 # U-Boot Parameters
 setenv initrd_high "0xffffffff"
@@ -54,16 +49,6 @@ setenv openelec "quiet ssh"
 #------------------------------------------------------------------------------------------------------
 setenv macaddr "00:1e:06:61:7a:39"
 
-#------------------------------------------------------------------------------------------------------
-#
-# U-Boot bootcmd command
-#  
-#------------------------------------------------------------------------------------------------------
-setenv kernel  "fatload mmc 0:1 40008000 multiboot/KERNEL"
-setenv initrd  "fatload mmc 0:1 42000000 multiboot/INITRD"
-setenv dtb     "fatload mmc 0:1 44000000 multiboot/exynos5422-odroidxu3.dtb.oelec"
-setenv bootcmd "${kernel}; ${initrd}; ${dtb}; bootz 40008000 42000000 44000000"
-
 #------------------------------------------------------------------------------------------------------
 #
 # Kernel boot
@@ -71,13 +56,39 @@ setenv bootcmd "${kernel}; ${initrd}; ${dtb}; bootz 40008000 42000000 44000000"
 #------------------------------------------------------------------------------------------------------
 setenv bootargs "${console} ${bootrootfs} ${openelec} smsc95xx.macaddr=${macaddr}"
 
-# =================================================
-# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE =
-# =================================================
-fatload mmc 0:1 0x60000000 multiboot/boot.scr.multi
-fatwrite mmc 0:1 0x60000000 boot.scr ${filesize}
-sleep 1
-# =================================================
+# ========================================================
+# = RESTORE boot.scr FOR MULTIBOOT, DO NOT CHANGE        =
+# ========================================================
+mmc list
+mmc dev
+
+setenv change_osdev no;
+
+setenv bootdev "0:1";
+if test "${mmc_boot_device}" = "0"; then
+  setenv bootdev "0:1";
+elif test "${mmc_boot_device}" = "1"; then
+  setenv bootdev "1:1";
+fi
+
+setenv os_dev "${bootdev}";
+if test "${change_osdev}" = "yes"; then
+  if test "${bootdev}" = "0:1"; then
+    setenv os_dev "1:1";
+  else
+    setenv os_dev "0:1";
+  fi
+fi
+# ========================================================
+
+fatload mmc ${os_dev} 40008000 multiboot/KERNEL
+fatload mmc ${os_dev} 42000000 multiboot/INITRD
+fatload mmc ${os_dev} 44000000 multiboot/exynos5422-odroidxu3.dtb.oelec
+
+# === RESTORE MULTIBOOT SCRIPT ===========================
+fatload mmc ${bootdev} 0x60000000 multiboot/boot.scr.multi
+fatwrite mmc ${bootdev} 0x60000000 boot.scr ${filesize}
+#=========================================================
 
 # Boot the board
-boot
+bootz 40008000 42000000 44000000

BIN
XU4/initramfs/ramfs/multi/u-boot.bin


+ 49 - 21
XU4/multiboot/boot.ini.multi

@@ -1,11 +1,11 @@
-ODROIDXU-UBOOT-CONFIG
+#ODROIDXU-UBOOT-CONFIG
 
 # ===============================================================
 # =              Multi boot & install parameters                =
 # ===============================================================
 # Time (sec) to automatic boot if no key is pressed (min 5)     =
 # ------------------------------------------------------------- =
-setenv BOOT_DELAY "10"
+setenv BOOT_DELAY "600"
 # ===============================================================
 # Menu item to boot if no key is pressed ("1" ~ "8")            =
 # ------------------------------------------------------------- =
@@ -13,12 +13,6 @@ setenv DEFAULT_OS "1"
 #
 # ===============================================================
 
-# ===============================================================
-# Time (sec) to automatic install if no key is pressed          =
-# ------------------------------------------------------------- =
-setenv INST_DELAY "10000"
-# ===============================================================
-
 
 # U-Boot Parameters
 setenv initrd_high "0xffffffff"
@@ -27,13 +21,55 @@ setenv fdt_high "0xffffffff"
 # Mac address configuration
 setenv macaddr "00:1e:06:61:7a:39"
 
-#-------------------------------------------------------------------------------------------------------------------
-# Basic Ubuntu Setup. Don't touch unless you know what you are doing.
-#-------------------------------------------------------------------------------------------------------------------
-setenv bootrootfs "console=tty0 quiet instdelay=${INST_DELAY} no_console_suspend loglevel=0}"
+setenv bootdev "0:1";
+setenv boot_mmc_type "unknown";
+setenv mmc_boot_device 9
+
+# ===================================================================================
+# ==== Get some info about boot device                                           ====
+# ==== Only when booting from multiboot prepared card the values wil be returned ====
+# ===================================================================================
+mmc list
+mmc dev
+
+# ==========================================================================================================================
+# |   Inserted    | ------------------------------------------------------------------------------------------------------ |
+# | emmc | sdcard | switch | boot_mmc0_dev | boot_mmc0_type | boot_mmc1_dev | boot_mmc1_type | mmc_boot_device | boot_from |
+# ==========================================================================================================================
+# | yes  | no     |   SD   |       -       |      ----      |        -      |      ----      |         -       |    ----   |
+# --------------------------------------------------------------------------------------------------------------------------
+# | yes  | no     |  EMMC  |       0       |      eMMC      |        1      |      none      |         0       |    emmc   |
+# --------------------------------------------------------------------------------------------------------------------------
+# | no   | yes    |   SD   |       0       |       SD       |        1      |      none      |         0       |   sdcard  |
+# --------------------------------------------------------------------------------------------------------------------------
+# | no   | yes    |  EMMC  |       -       |      ----      |        -      |      ----      |         -       |    ----   |
+# --------------------------------------------------------------------------------------------------------------------------
+# | yes  | yes    |   SD   |       0       |       SD       |        1      |      eMMC      |         1       |    emmc   |!!
+# --------------------------------------------------------------------------------------------------------------------------
+# | yes  | yes    |  EMMC  |       0       |      eMMC      |        1      |       SD       |         1       |   sdcard  |!!
+# ==========================================================================================================================
+
+
+# =========================================================
+# When mmc_boot_device=1 we have to load from 1:1 device !!
+# =========================================================
+if test "${mmc_boot_device}" = "0"; then
+  setenv bootdev "0:1";
+  setenv boot_mmc_type "${boot_mmc0_type}";
+elif test "${mmc_boot_device}" = "1"; then
+  setenv bootdev "1:1";
+  setenv boot_mmc_type "${boot_mmc1_type}";
+fi
+# =========================================================
+echo "BOOT FROM: ${mmc_boot_device}:${boot_mmc_type}"
+
+#----------------------------------------
+# Set boot variables for kernel/initramfs
+#----------------------------------------
+setenv bootrootfs "console=tty0 quiet boot_card_type=${boot_mmc_type} boot_card_dev=${mmc_boot_device} instdelay=${INST_DELAY} default_boot=${DEFAULT_OS} no_console_suspend loglevel=0}"
 
 # boot commands
-setenv bootcmd "fatload mmc 0:1 0x40008000 multiboot/zImage.multi; fatload mmc 0:1 0x42000000 multiboot/uInitrd.multi; fatload mmc 0:1 0x44000000 multiboot/exynos5422-odroidxu3.dtb.multi; bootz 0x40008000 0x42000000 0x44000000"
+setenv bootcmd "fatload mmc ${bootdev} 0x40008000 multiboot/zImage.multi; fatload mmc ${bootdev} 0x42000000 multiboot/uInitrd.multi; fatload mmc ${bootdev} 0x44000000 multiboot/exynos5422-odroidxu3.dtb.multi; bootz 0x40008000 0x42000000 0x44000000"
 
 # --- Screen Configuration for HDMI --- # 
 # ---------------------------------------
@@ -105,14 +141,6 @@ setenv governor "performance"
 # - Powersave (Keeps the CPU's to the lowest possible temps)
 # setenv governor "powersave"
 
-# =================================================
-# = NEEDED FOR BOOT SELECT SCRIPT, DO NOT CHANGE  =
-# =================================================
-mw.b 0x60000000 0x41 0x10
-fatwrite mmc 0:1 0x60000000 _BOOT_FROM_ 10
-sleep 1
-# =================================================
-
 # final boot args
 setenv bootargs "${bootrootfs} ${videoconfig} smsc95xx.macaddr=${macaddr} governor=${governor}"
 # drm.debug=0xff

BIN
XU4/multiboot/boot.scr.multi


BIN
XU4/multiboot/uInitrd.multi


+ 15 - 0
build_initrd

@@ -0,0 +1,15 @@
+#!/bin/bash
+
+
+cp -f scripts/* C2/initramfs/ramfs
+cp -f scripts/* XU4/initramfs/ramfs
+
+cd C2/initramfs
+./pack
+
+cd ../../
+
+cd XU4/initramfs
+./pack
+
+cd ../../

+ 578 - 0
scripts/backup.script

@@ -0,0 +1,578 @@
+#!/bin/bash
+
+sd_multi="no"
+card_no="0"
+
+#--------------------------------------------------
+disp_header() {
+	clear
+	printf "\n"
+	printf "\n"
+	printf "\033[36m\033[1m\n"
+	if [ "${O_BOARD}" = "C2" ]; then
+		printf "    =================================\n"
+		printf "    = Odroid C2 Backup utility %s =\n" "${SCRIPT_VERSION}"
+		printf "    =================================\n"
+	else
+		printf "    ======================================\n"
+		printf "    = Odroid XU3/XU4 Backup utility %s =\n" "${SCRIPT_VERSION}"
+		printf "    ======================================\n"
+	fi
+	printf "\033[22m\033[37m\n\n"
+	sleep 1
+}
+#--------------------------------------------------
+
+#------------------------------------------------------------------------------------------------------------
+make_image() {
+	# source partition is mounted on /mnt1
+	mkdir /imgmnt >> ${log_file} 2>&1
+
+	printf "    Backup: \033[32m%s\033[37m ... preparing image... " "${2}"
+	# Get size
+	_size_=$(du -s /mnt1 | awk '{print $1}')
+	_size=$(( ($_size_  / 1024) + 128 ))
+	# add 5% ext4 fs overhead
+	_ovhd=$(( ($_size * 6) / 100 ))
+	_size=$(( $_size + $_ovhd ))
+
+    rm -f ${1} >> ${log_file} 2>&1
+	printf " (%sM)... " "${_size}"
+	# create sparse image file
+	dd if=/dev/zero of=${1} bs=1 count=0 seek=${_size}M >> ${log_file} 2>&1
+	#dd if=/dev/zero of=${1} bs=1M count=${_size} >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR\n"
+		return 1
+	fi
+	sync
+
+	printf "mkfs... "
+	mkfs.ext4 ${1} >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR\n"
+		return 1
+	fi
+	sync
+
+	printf "mount... "
+	mountx ${1} /imgmnt >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR\n"
+		return 1
+	fi
+
+	# Copy partition to image
+	printf "copy... "
+	if [ "${3}" = "andro" ]; then
+		rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s -A -X --no-specials /mnt1/ /imgmnt/ >> ${log_file} 2>&1
+	else
+		rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s --stats /mnt1/ /imgmnt/ >> ${log_file} 2>&1
+	fi
+	if [ $? -ne 0 ]; then
+		umount /imgmnt >> ${log_file} 2>&1
+		printf "ERROR\n"
+		return 1
+    fi
+	sync
+
+	umount /imgmnt >> ${log_file} 2>&1
+
+	printf "OK\n"
+	return 0
+}
+#------------------------------------------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------------------------------------
+backup_android() {
+	printf "\n    Backup: \033[32m\033[1mAndroid\033[22m\033[37m\n"
+
+	# backup system partition, allready mounted on /mnt1
+	mkdir /mnt2/${BKP_PREFIX}_backup >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/android >> ${log_file} 2>&1
+	rm -rf /mnt2/${BKP_PREFIX}_backup/android/* >> ${log_file} 2>&1
+
+	make_image "/mnt2/${BKP_PREFIX}_backup/android/system.raw.img" "Android system" "andro"
+	if [ $? -eq 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+
+		# backup data partition
+		if [ "${sd_multi}" = "yes" ]; then
+			/bin/mountx /dev/mmcblk${card_no}p5 /mnt1 >> ${log_file} 2>&1
+		else
+			/bin/mountx /dev/mmcblk${card_no}p4 /mnt1 >> ${log_file} 2>&1
+		fi
+		if [ $? -ne 0 ]; then
+			umount /mnt1 >> ${log_file} 2>&1
+			printf "    ERROR mounting data partition\n"
+			return 1
+		fi
+
+		make_image "/mnt2/${BKP_PREFIX}_backup/android/data.raw.img" "Android data" "andro"
+		if [ $? -eq 0 ]; then
+			umount /mnt1 >> ${log_file} 2>&1
+
+			# backup cache partition
+			/bin/mountx /dev/mmcblk${card_no}p3 /mnt1 >> ${log_file} 2>&1
+			if [ $? -ne 0 ]; then
+				umount /mnt1 >> ${log_file} 2>&1
+				printf "    ERROR mounting cache partition\n"
+				return 1
+			fi
+
+			make_image "/mnt2/${BKP_PREFIX}_backup/android/cache.raw.img" "Android cache" "andro"
+			if [ $? -ne 0 ]; then
+				umount /mnt1 >> ${log_file} 2>&1
+				return 1
+			fi
+		else
+			umount /mnt1 >> ${log_file} 2>&1
+			return 1
+		fi
+	else
+		umount /mnt1 >> ${log_file} 2>&1
+		return 1
+	fi
+
+	umount /mnt1 >> ${log_file} 2>&1
+
+	# Mount boot card and copy android boot files
+	printf "    Backup: \033[32mCopy boot files\033[37m ... "
+	mount -t vfat /dev/mmcblk${card_no}p1 /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR mounting boot card\n"
+		return 1
+	fi
+
+	cp -rf /mnt1/* /mnt2/${BKP_PREFIX}_backup/android >> ${log_file} 2>&1
+	rm -f /mnt2/${BKP_PREFIX}_backup/android/${ODROID_IMAGE} >> ${log_file} 2>&1
+	rm -f /mnt2/${BKP_PREFIX}_backup/android/${ODROID_DTB} >> ${log_file} 2>&1
+	rm -rf /mnt2/${BKP_PREFIX}_backup/android/multiboot/* >> ${log_file} 2>&1
+	rmdir /mnt2/${BKP_PREFIX}_backup/android/multiboot >> ${log_file} 2>&1
+
+	if [ "${sd_multi}" = "yes" ]; then
+		cp /mnt1/multiboot/${ODROID_IMAGE}.android /mnt2/${BKP_PREFIX}_backup/android/${ODROID_IMAGE} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: Image\n"
+			return 1
+		fi
+		cp /mnt1/multiboot/${ODROID_DTB}.android /mnt2/${BKP_PREFIX}_backup/android/${ODROID_DTB} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: dtb\n"
+			return 1
+		fi
+	else
+		cp /mnt1/${ODROID_IMAGE} /mnt2/${BKP_PREFIX}_backup/android >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: Image\n"
+			return 1
+		fi
+		cp /mnt1/${ODROID_DTB} /mnt2/${BKP_PREFIX}_backup/android >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: dtb\n"
+			return 1
+		fi
+	fi
+	umount /mnt1 >> ${log_file} 2>&1
+	sync
+	sleep 1
+	printf "OK\n"
+
+	return 0
+}
+#--------------------------------------------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------------------------------------------
+backup_linux() {
+	printf "\n    Backup: \033[32m\033[1mLinux%s\033[22m\033[37m\n" "${1}"
+
+	# backup Linux partition, allready mounted on /mnt1
+	mkdir /mnt2/${BKP_PREFIX}_backup >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
+	rm -rf /mnt2/${BKP_PREFIX}_backup/linux${1}/* >> ${log_file} 2>&1
+
+	make_image "/mnt2/${BKP_PREFIX}_backup/linux${1}/linux.img" "Linux root" "linux"
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		return 1
+	fi
+
+	umount /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR unmounting Linux partition\n"
+		return 1
+	fi
+
+	# Mount boot card and copy Linux boot files
+	printf "    Backup: \033[32mCopy boot files\033[37m ... "
+	mount -t vfat /dev/mmcblk${card_no}p1 /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR mounting boot partition\n"
+		return 1
+	fi
+
+	if [ "${sd_multi}" = "yes" ]; then
+		cp /mnt1/multiboot/${ODROID_IMAGE}.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/${ODROID_IMAGE} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: Image\n"
+			return 1
+		fi
+		cp /mnt1/multiboot/${ODROID_DTB}.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/${ODROID_DTB} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: dtb\n"
+			return 1
+		fi
+		cp /mnt1/multiboot/uInitrd.linux /mnt2/${BKP_PREFIX}_backup/linux${1}/uInitrd >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: uInitrd\n"
+			return 1
+		fi
+	else
+		cp /mnt1/${ODROID_IMAGE} /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: Image "
+		fi
+		cp /mnt1/${ODROID_DTB} /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: dtb "
+		fi
+		cp /mnt1/uInitrd /mnt2/${BKP_PREFIX}_backup/linux${1} >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: uInitrd "
+		fi
+	fi
+	sync
+	sleep 1
+	umount /mnt1 >> ${log_file} 2>&1
+	printf "OK\n"
+
+	return 0
+}
+#----------------------------------------------------------------------------------------------------------------
+
+backup_oelec() {
+	printf "\n    Backup: \033[32m\033[1mOpenElec\033[22m\033[37m\n"
+
+	# backup oelec partition, allready mounted on /mnt1
+	mkdir /mnt2/${BKP_PREFIX}_backup >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/oelec >> ${log_file} 2>&1
+	rm -rf /mnt2/${BKP_PREFIX}_backup/oelec/* >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/oelec/target >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/oelec/3rdparty >> ${log_file} 2>&1
+	mkdir /mnt2/${BKP_PREFIX}_backup/oelec/3rdparty/bootloader >> ${log_file} 2>&1
+
+	make_image "/mnt2/${BKP_PREFIX}_backup/oelec/oelec.img" "OpenElec" "linux"
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		return 1
+	fi
+
+	umount /mnt1 >> ${log_file} 2>&1
+
+	# Mount boot card and copy OpenElec boot files
+	printf "    Backup: \033[32mCopy OpenElec files\033[37m ... "
+	mount -t vfat /dev/mmcblk${card_no}p1 /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR mounting boot card\n"
+		return 1
+	fi
+
+	cp /mnt1/SYSTEM /mnt2/${BKP_PREFIX}_backup/oelec/target >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR: SYSTEM\n"
+		return 1
+	fi
+	cp /mnt1/multiboot/KERNEL /mnt2/${BKP_PREFIX}_backup/oelec/target >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR: KERNEL\n"
+		return 1
+	fi
+	cp /mnt1/multiboot/${ODROID_DTB}.oelec /mnt2/${BKP_PREFIX}_backup/oelec/3rdparty/bootloader/${ODROID_DTB} >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		printf "ERROR: dtb\n"
+		return 1
+	fi
+	if [ ! "${O_BOARD}" = "C2" ]; then
+		cp /mnt1/multiboot/INITRD /mnt2/${BKP_PREFIX}_backup/oelec/target >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "ERROR: INITRD\n"
+			return 1
+		fi
+	fi
+	umount /mnt1 >> ${log_file} 2>&1
+	printf "OK\n"
+
+	return 0
+}
+
+#----------------------------------------------------------------------------------------------------
+exit_script() {
+	local _delay=30
+	local B="X"
+	echo ""
+	while [ $_delay -gt 0 ]; do
+		printf "    \033[33mPress \033[1mE\033[22m to exit to main menu (%s)  \033[37m\r" "${_delay}"
+		if read -n 1 -t 1 -s B; then
+			_delay=30
+			if [ "${B}" = "E" ] || [ "${B}" = "e" ]; then
+				break
+			elif [ "${B}" = "s" ]; then
+				# SCREENSHOT ===
+				fbcat > /backup_exit.ppm
+			fi
+		else
+			let _delay=_delay-1
+		fi
+	done
+
+	printf "\r\033[2K"
+	umount /mnt1 > /dev/null 2>&1
+	umount /mnt2 > /dev/null 2>&1
+	exit 0
+}
+#----------------------------------------------------------------------------------------------------
+
+
+#=====================================================================================
+
+mkdir /mnt1 > /dev/null 2>&1
+mkdir /mnt2 > /dev/null 2>&1
+mkdir /multiboot > /dev/null 2>&1
+umount /mnt1 > /dev/null 2>&1
+umount /mnt2 > /dev/null 2>&1
+
+disp_header
+
+
+# ===============
+# Check USB drive
+# ===============
+
+if [ ! -b /dev/sda ]; then
+	printf "    ERROR: USB drive not found\n"
+	exit_script
+fi
+
+usb_part="0"
+max_usbpart=0
+
+#------------------------------------------------------------------------------------
+check_usbpart() {
+	local usbpart_free=0
+	if [ -b /dev/sda${1} ]; then
+		let max_usbpart=max_usbpart+1
+		printf "    \033[32m\033[1m%s\033[22m partition #%s \033[37m (" "${1}" "${1}"
+		/bin/mountx /dev/sda${1} /mnt2 > /dev/null 2>&1
+		if [ $? -ne 0 ]; then
+			printf "NOT MOUNTABLE)\n"
+		else
+			[ "${usb_part}" = "0" ] && usb_part="1"
+			usbpart_free=$(df | grep /dev/sda${1} | awk '{print $4}')
+			usbpart_free=$(( $usbpart_free / 1024 ))
+			printf "%sM free)\n" "${usbpart_free}"
+		fi
+		umount /mnt2 > /dev/null 2>&1
+	fi
+}
+#------------------------------------------------------------------------------------
+
+
+printf "    \033[33mMore than one partition on USB drive detected, select which one to use for backup\033[37m\n\n"
+check_usbpart "1"
+check_usbpart "2"
+check_usbpart "3"
+check_usbpart "4"
+check_usbpart "5"
+check_usbpart "6"
+printf "\n"
+
+if [ $max_usbpart -eq 0 ] || [ "${usb_part}" = "0" ]; then
+	printf "    ERROR: no usable USB partition found!\n"
+	exit_script
+fi
+
+
+_delay=30
+usb_part="1"
+while [ $_delay -gt 0 ]; do
+	printf "    \033[33mSelect the backup partition, default is \033[1m#1\033[22m %s\033[37m  \r" "${_delay}"
+	B="X"
+	if read -n 1 -t 1 -s B; then
+		_delay=30
+		if [ "${B}" = "1" ] && [ $max_usbpart -ge 1 ]; then
+			usb_part="1"
+			break
+		elif [ "${B}" = "2" ] && [ $max_usbpart -ge 2 ]; then
+			usb_part="2"
+			break
+		elif [ "${B}" = "3" ] && [ $max_usbpart -ge 3 ]; then
+			usb_part="3"
+			break
+		elif [ "${B}" = "4" ] && [ $max_usbpart -ge 4 ]; then
+			usb_part="4"
+			break
+		elif [ "${B}" = "5" ] && [ $max_usbpart -ge 5 ]; then
+			usb_part="5"
+			break
+		elif [ "${B}" = "6" ] && [ $max_usbpart -ge 6 ]; then
+			usb_part="6"
+			break
+		fi
+	else
+		let _delay=_delay-1
+	fi
+done
+disp_header
+
+# Mount backup partition
+/bin/mountx /dev/sda${usb_part} /mnt2 > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+	printf "    ERROR mounting USB partition #%s\n" "${usb_part}"
+	exit_script
+fi
+
+#==========================================================================================
+rm /mnt2/backup.log > /dev/null 2>&1
+log_file="/mnt2/backup.log"
+#log_file="ls/dev/null"
+
+# Check source drive
+if [ -b /dev/mmcblk1 ]; then
+	printf "    \033[33mTwo cards detected, select which one to use for backup\033[37m\n\n"
+	printf "    \033[32m\033[1m0\033[22m EMMC Card\033[37m\n"
+	printf "    \033[32m\033[1m1\033[22m SD Card\033[37m\n\n"
+
+	_delay=30
+	while [ $_delay -gt 0 ]; do
+		printf "    \033[33mSelect the card, default is \033[1mEMMC\033[22m %s\033[37m  \r" "${_delay}"
+		B="X"
+		if read -n 1 -t 1 -s B; then
+			_delay=30
+			if [ "${B}" = "0" ]; then
+				break
+			elif [ "${B}" = "1" ]; then
+				card_no="1"
+				break
+			fi
+		else
+			let _delay=_delay-1
+		fi
+	done
+	disp_header
+fi
+
+# Display backup info
+printf "    \033[32mBackup from "
+
+card_type="SD"
+if [ -b /dev/disk/by-label/sduserdata ] || [ -b /dev/disk/by-label/emuserdata ]; then
+	sd_multi="yes"
+	# shellcheck disable=SC2010
+	tmp_crdtype=`ls -l /dev/disk/by-label | grep mmcblk${card_no}p1 | awk '{print $4}'`
+	[ "${tmp_crdtype}" = "emuserdata" ] && card_type="EMMC"
+	printf "\033[1mMultiBoot\033[22m %s card " "${card_type}"
+else
+	if [ -b /dev/mmcblk1 ] && [ "${card_no}" = "0" ]; then
+		card_type="EMMC"
+	elif [ -b /dev/mmcblk1 ] && [ "${card_no}" = "1" ]; then
+		card_type="SD"
+	else
+		card_type="SD/EMMC"
+	fi
+	printf "\033[1mOriginal Odroid\033[22m %s card " "${card_type}"
+fi
+
+printf " to \033[1mUSB partition #%s\033[22m\033[37m\n\n" "${usb_part}"
+
+
+# Mount partition 2 (Android system or Linux)
+/bin/mountx /dev/mmcblk${card_no}p2 /mnt1 >> ${log_file} 2>&1
+if [ $? -ne 0 ]; then
+	umount /mnt2 > /dev/null 2>&1
+	printf "    ERROR mounting source card\n"
+	exit_script
+fi
+
+# Wait for confirmation
+_delay=30
+while [ $_delay -gt 0 ]; do
+	printf "    \033[33mReady for backup, press \033[1mY\033[22m to continue, \033[1mE\033[22m to exit (%s)  \033[37m\r" "${_delay}"
+	B="X"
+	if read -n 1 -t 1 -s B; then
+		_delay=30
+		if [ "${B}" = "Y" ]; then
+			printf "\r\033[2K"
+			break
+		elif [ "${B}" = "E" ] || [ "${B}" = "e" ]; then
+			_delay=0
+			break
+		elif [ "${B}" = "s" ]; then
+			# SCREENSHOT ===
+			fbcat > /backup.ppm
+		fi
+	else
+		let _delay=_delay-1
+	fi
+done
+if [ $_delay -eq 0 ]; then
+	printf "\r\033[2K"
+	exit_script
+fi
+
+# Ckeck if it is Android partition
+if [ -f /mnt1/${ODROID_FSTAB} ]; then
+	backup_android
+else
+	if [ ! "${sd_multi}" = "yes" ]; then
+		# backup single linux card
+		if [ -f /mnt1/etc/fstab ]; then
+			backup_linux ""
+		fi
+	fi
+fi
+
+umount /mnt1 >> ${log_file} 2>&1
+if [ "${sd_multi}" = "yes" ]; then
+	if [ -b /dev/disk/by-label/sdlinux ] || [ -b /dev/disk/by-label/emlinux ]; then
+		printf "\n"
+		# Backup multiboot Linux
+		/bin/mountx /dev/mmcblk${card_no}p7 /mnt1 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "    ERROR mounting Linux partition\n"
+			exit_script
+		fi
+		if [ -f /mnt1/etc/fstab ]; then
+			backup_linux ""
+		fi
+	fi
+	umount /mnt1 >> ${log_file} 2>&1
+
+	if [ -b /dev/disk/by-label/sdlinux2 ] || [ -b /dev/disk/by-label/emlinux2 ]; then
+		printf "\n"
+		# Backup multiboot Linux2
+		/bin/mountx /dev/mmcblk${card_no}p8 /mnt1 >> ${log_file} 2>&1
+		if [ $? -eq 0 ]; then
+			if [ -f /mnt1/etc/fstab ]; then
+				backup_linux "2"
+			fi
+		fi
+	fi
+
+	if [ -b /dev/disk/by-label/sdaux ] || [ -b /dev/disk/by-label/emaux ]; then
+		printf "\n"
+		# Backup multiboot OpenElec
+		/bin/mountx /dev/mmcblk${card_no}p6 /mnt1 >> ${log_file} 2>&1
+		if [ $? -eq 0 ]; then
+			backup_oelec
+		fi
+	fi
+fi
+
+umount /mnt1 >> ${log_file} 2>&1
+umount /mnt2 > /dev/null 2>&1
+
+printf "\n    FINISHED.\n"
+exit_script
+
+#=====================================================================================

+ 915 - 0
scripts/init

@@ -0,0 +1,915 @@
+#!/bin/bash
+
+# ============================================================
+# This is the standard Ubuntu initramfs initialization process
+# ============================================================
+
+# Default PATH differs between shells, and is not automatically exported
+# by klibc dash.  Make it consistent.
+export PATH=/sbin:/usr/sbin:/bin:/usr/bin
+
+[ -d /dev ] || mkdir -m 0755 /dev
+[ -d /root ] || mkdir -m 0700 /root
+[ -d /sys ] || mkdir /sys
+[ -d /proc ] || mkdir /proc
+[ -d /tmp ] || mkdir /tmp
+mkdir -p /var/lock
+mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
+mount -t proc -o nodev,noexec,nosuid proc /proc
+# Some things don't work properly without /etc/mtab.
+ln -sf /proc/mounts /etc/mtab
+
+echo "1 1 1 1" > /proc/sys/kernel/printk
+grep -q '\<quiet\>' /proc/cmdline || echo "Loading, please wait..."
+
+# Note that this only becomes /dev on the real filesystem if udev's scripts
+# are used; which they will be, but it's worth pointing out
+if ! mount -t devtmpfs -o nosuid,mode=0755 udev /dev; then
+	echo "W: devtmpfs not available, falling back to tmpfs for /dev"
+	mount -t tmpfs -o nosuid,mode=0755 udev /dev
+	[ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
+	[ -e /dev/null ] || mknod /dev/null c 1 3
+fi
+mkdir /dev/pts
+mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
+mount -t tmpfs -o "noexec,nosuid,size=80%,mode=0755" tmpfs /run
+mkdir -m 0755 /run/initramfs
+
+# Export the dpkg architecture
+export DPKG_ARCH=
+. /conf/arch.conf
+
+# Set modprobe env
+export MODPROBE_OPTIONS="-qb"
+
+# Export relevant variables
+export ROOT=
+export ROOTDELAY=
+export ROOTFLAGS=
+export ROOTFSTYPE=
+export IP=
+export BOOT=
+export BOOTIF=
+export UBIMTD=
+export break=
+export init=/sbin/init
+export quiet=y
+export readonly=y
+export rootmnt=/root
+export debug=
+export panic=
+export blacklist=
+export resume=
+export resume_offset=
+export drop_caps=
+export fastboot=n
+export forcefsck=n
+export fsckfix=
+export recovery=
+export BOOT_CARDTYPE="unknown"
+export OTHER_CARDTYPE="unknown"
+export BOOT_CARDDEV="9"
+export OTHER_CARDDEV="9"
+export CARD_TYPE="SD"
+
+# mdadm needs hostname to be set. This has to be done before the udev rules are called!
+if [ -f "/etc/hostname" ]; then
+        /bin/hostname -F /etc/hostname >/dev/null 2>&1
+fi
+
+# Bring in the main config
+. /conf/initramfs.conf
+for conf in conf/conf.d/*; do
+	[ -f ${conf} ] && . ${conf}
+done
+. /scripts/functions
+echo "1 1 1 1" > /proc/sys/kernel/printk
+
+
+BOOTDELAY=60
+DEFAULTBOOT="1"
+
+# Parse command line options
+for x in $(cat /proc/cmdline); do
+    case $x in
+    boot_card_type=*)
+        BOOT_CARDTYPE=${x#boot_card_type=}
+        ;;
+    boot_card_dev=*)
+        BOOT_CARDDEV=${x#boot_card_dev=}
+        ;;
+    cardtype=*)
+        CARD_TYPE=${x#cardtype=}
+        ;;
+	boot_delay=*)
+		BOOTDELAY="${x#boot_delay=}"
+		case ${BOOTDELAY} in
+		*[![:digit:].]*)
+			BOOTDELAY=60
+			;;
+		esac
+		;;
+	default_boot=*)
+		DEFAULTBOOT="${x#default_boot=}"
+		;;
+    quiet)
+        quiet=y
+        ;;
+    ro)
+        readonly=y
+        ;;
+    rw)
+        readonly=n
+        ;;
+    break=*)
+        break=${x#break=}
+        ;;
+    break)
+        break=premount
+        ;;
+    esac
+done
+
+# Default to BOOT=local if no boot script defined.
+if [ -z "${BOOT}" ]; then
+	BOOT=local
+fi
+
+if [ -n "${noresume}" ]; then
+	export noresume
+	unset resume
+else
+	resume=${RESUME:-}
+fi
+
+maybe_break top
+
+# export BOOT variable value for compcache,
+# so we know if we run from casper
+export BOOT
+
+# Don't do log messages here to avoid confusing graphical boots
+run_scripts /scripts/init-top
+
+#maybe_break modules
+#[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}"
+load_modules
+
+maybe_break premount
+run_scripts /scripts/init-premount
+
+maybe_break mount
+# Always load local and nfs (since these might be needed for /etc or
+# /usr, irrespective of the boot script used to mount the rootfs).
+. /scripts/local
+. /scripts/nfs
+. /scripts/${BOOT}
+parse_numeric ${ROOT}
+maybe_break mountroot
+mount_top
+mount_premount
+#mountroot
+
+if read_fstab_entry /usr; then
+	mountfs /usr
+fi
+
+# Mount cleanup
+mount_bottom
+nfs_bottom
+local_bottom
+
+#maybe_break bottom
+# We expect udev's init-bottom script to move /dev to ${rootmnt}/dev
+#run_scripts /scripts/init-bottom
+
+# Move /run to the root
+#mount -n -o move /run ${rootmnt}/run
+
+#validate_init() {
+#	run-init -n "${rootmnt}" "${1}"
+#}
+
+
+chown 0:0 /bin/*
+chown 0:0 /sbin/*
+echo "1 1 1 1" > /proc/sys/kernel/printk
+sleep 1
+
+# === Variables ===
+
+[ ! $BOOTDELAY -gt 4 ] &&  BOOTDELAY=5
+
+export SCRIPT_VERSION="v2.2"
+export O_BOARD="OD"
+export ODROID_DTB="odroid.dtb"
+export ODROID_FSTAB="fstab.odroid"
+export ODROID_IMAGE="Kernel"
+export ODROID_ASYSTEMIMAGE="androsystem.img"
+export BKP_PREFIX="OD"
+export NUMCARDS="1"
+
+_desc=""
+_ini_prefix="multiboot"
+_actmount="mnt1"
+_numos=0
+_menu_no=49
+_menu_key="1"
+_menuitem_1=""
+_menuitem_2=""
+_menuitem_3=""
+_menuitem_4=""
+_menuitem_5=""
+_menuitem_6=""
+_menuitem_7=""
+_menuitem_8=""
+_mndscr_1=""
+_mndscr_2=""
+_mndscr_3=""
+_mndscr_4=""
+_mndscr_5=""
+_mndscr_6=""
+_mndscr_7=""
+_mndscr_8=""
+_mncrd_1="1"
+_mncrd_2="1"
+_mncrd_3="1"
+_mncrd_4="1"
+_mncrd_5="1"
+_mncrd_6="1"
+_mncrd_7="1"
+_mncrd_8="1"
+_boot_delay=2
+_defboot="none"
+_defdescr="none"
+_defcard="1"
+boot_fail="yes"
+
+# =========================================================
+# === Set the variables depending on used Odroid board  ===
+if [ -f /ODROID_C2 ]; then
+	O_BOARD="C2"
+	ODROID_DTB="meson64_odroidc2.dtb"
+	ODROID_FSTAB="fstab.odroidc2"
+	ODROID_IMAGE="Image"
+	ODROID_ASYSTEMIMAGE="rootsystem.img"
+	BKP_PREFIX="C2"
+	BOOT_CARDTYPE="SD"
+	BOOT_CARDDEV="0"
+	if [ -b /dev/mmcblk1p1 ]; then
+		NUMCARDS="2"
+		OTHER_CARDDEV="1"
+		OTHER_CARDTYPE="EMMC"
+	fi
+elif [ -f /ODROID_XU ]; then
+	O_BOARD="XU"
+	ODROID_DTB="exynos5422-odroidxu3.dtb"
+	ODROID_FSTAB="fstab.odroidxu3"
+	ODROID_IMAGE="zImage"
+	ODROID_ASYSTEMIMAGE="system.img"
+	BKP_PREFIX="XU"
+
+	if [ "${BOOT_CARDTYPE}" = "none" ]; then
+		BOOT_CARDTYPE="SD"
+		if [ -b /dev/mmcblk1p1 ]; then
+			NUMCARDS="2"
+			BOOT_CARDDEV="1"
+			OTHER_CARDDEV="0"
+			OTHER_CARDTYPE="EMMC"
+		else
+			BOOT_CARDDEV="0"
+		fi
+	else
+		[ "${BOOT_CARDTYPE}" = "eMMC" ] && BOOT_CARDTYPE="EMMC"
+		if [ "${BOOT_CARDDEV}" = 1 ]; then
+			NUMCARDS="2"
+			if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+				OTHER_CARDDEV="0"
+				OTHER_CARDTYPE="EMMC"
+			else
+				OTHER_CARDDEV="1"
+				OTHER_CARDTYPE="SD"
+				BOOT_CARDDEV="0"
+			fi
+		fi
+	fi
+fi
+# =========================================================
+
+# === Functions ===
+
+# Get OS description from boot.ini
+#-----------------------------------------------------
+get_descr() {
+	_desc=""
+	local _descx=
+	_descx=`cat /${_actmount}/${_ini_prefix}/$1 | grep \#DESCRIPTION`
+    if [ ! "${_descx}" = "" ]; then
+		_desc=$(echo ${_descx} | sed -r 's/^.{13}//')
+    fi
+	if [ "${_desc}" = "" ]; then
+		_desc="${2}"
+	fi
+}
+#-----------------------------------------------------
+
+
+#-----------------------------------------------------------------------------------------------------------------------
+change_afstab() {
+	# === Configure Android fstab to mount the right partitions ===
+	if [ -f /mnt_a/${ODROID_FSTAB}${1} ]; then
+		if [ "${2}" = "yes" ]; then
+			# Two cards, boot to Android on NON Boot card
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+			else
+				if [ "${OTHER_CARDTYPE}" = "SD" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+				else
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				fi
+			fi
+		else
+			if [ "${O_BOARD}" = "C2" ]; then
+				cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+			else
+				if [ "${NUMCARDS}" = "1" ]; then
+					cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+				else
+					# Two cards, boot to Android on Boot card
+					if [ "${BOOT_CARDTYPE}" = "SD" ]; then
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk0/\/dev\/block\/mmcblk1/g" > _fstab_
+					else
+						cat /mnt_a/${ODROID_FSTAB}${1} | sed "s/\/dev\/block\/mmcblk1/\/dev\/block\/mmcblk0/g" > _fstab_
+					fi
+				fi
+			fi
+		fi
+		cp _fstab_ /mnt_a/${ODROID_FSTAB}${1} > /dev/null 2>&1
+		rm _fstab_ > /dev/null 2>&1
+	elif [ "${1}" = "" ]; then
+		printf "\033[31m\033[1m %s not found\033[22m\033[37m" "${ODROID_FSTAB}${1}"
+		cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+		[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+		sleep 3
+		umount /mnt_a > /dev/null 2>&1
+		return 1
+	fi
+	return 0
+}
+#-----------------------------------------------------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------------------------------------
+# =======================================================================
+# On C2 boot drive is always mmcblk0 and is mounted on /mnt1
+# On XU3/XU4 boot drive can be mmcblk0 or mmcblk1 and is mounted on /mnt1
+# =======================================================================
+do_boot() {
+	[ "${1}" = "none" ] && return 0
+
+	local change_drive="no"
+	local _oncard=""
+	_actmount="mnt1"
+	if [ "${3}" = "2" ]; then
+		_actmount="mnt2"
+		change_drive="yes"
+	fi
+
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
+		else
+			_oncard=" on ${OTHER_CARDTYPE}"
+		fi
+	fi
+
+	if [ -f /${_actmount}/${_ini_prefix}/${1} ]; then
+		boot_fail="yes"
+		printf "\r\033[2K"
+		printf "    Booting to \033[32m%s\033[37m\033[36m%s\033[37m" "${2}" "${_oncard}"
+
+		# === Copy selected boot.ini to BOOT partition
+		cp /${_actmount}/${_ini_prefix}/${1} /mnt1/boot.ini > /dev/null 2>&1
+		if [ ! $? -eq 0 ]; then
+			cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+			[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+			printf "\033[31m\033[1m ERROR copying /%s/%s/%s\033[22m\033[37m" "${_actmount}" "${_ini_prefix}" "${1}"
+			sleep 3
+			return 1
+		fi
+		sleep 1
+
+		if [ "${change_drive}" = "yes" ]; then
+			# === boot.ini from NON-BOOT card, prepare for boot from BOOT card ===
+			if [ "${O_BOARD}" = "C2" ]; then
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/fatload mmc 0:1/fatload mmc 1:1/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+				# for boot.ini loading from /multiboot (it was changed with previous sed operation!)
+				cat /mnt1/boot.ini | sed "s/1:1 0x60000000/0:1 0x60000000/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			else
+				# for kernel/initrd/dtb loading
+				cat /mnt1/boot.ini | sed "s/setenv change_osdev no/setenv change_osdev yes/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			fi
+		fi
+
+		if [ "${1}" = "boot.ini.android" ]; then
+			# === mount android system partition to prepare android fstab ===
+			mkdir /mnt_a > /dev/null 2>&1
+			if [ "${change_drive}" = "yes" ]; then
+				mount -t ext4 /dev/mmcblk${OTHER_CARDDEV}p2 /mnt_a > /dev/null 2>&1
+			else
+				mount -t ext4 /dev/mmcblk${BOOT_CARDDEV}p2 /mnt_a > /dev/null 2>&1
+			fi
+			if [ $? -ne 0 ]; then
+				printf "\033[31m\033[1m Mount Android system partition ERROR\033[22m\033[37m"
+				cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+				[ "${O_BOARD}" = "XU" ] && cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+				sleep 3
+				umount /mnt_a > /dev/null 2>&1
+				return 1
+			fi
+
+			# === Configure Android fstab to mount the right partitions ===
+			change_afstab "" "${change_drive}"
+			[ $? -ne 0 ] && return 1
+			change_afstab ".sdcard" "${change_drive}"
+			change_afstab ".sdboot" "${change_drive}"
+			umount /mnt_a > /dev/null 2>&1
+			# =============================================================
+
+			if [ "${O_BOARD}" = "C2" ] && [ "${change_drive}" = "yes" ]; then
+				# on C2 prepare boot.ini for boot from sdcard, not needed on XU
+				cat /mnt1/boot.ini | sed "s/root=\/dev\/mmcblk0p2/root=\/dev\/mmcblk1p2/g" > _bini_
+				cp _bini_ /mnt1/boot.ini
+				rm _bini_
+			fi
+		fi
+
+		if [ "${O_BOARD}" = "XU" ]; then
+			# Convert boot.ini to boot.scr
+			mkimage -C none -A arm -T script -d /mnt1/boot.ini /mnt1/boot.scr > /dev/null 2>&1
+			if [ $? -ne 0 ]; then
+				printf "\033[31m\033[1m mkimage (boot.scr) ERROR\033[22m\033[37m"
+				cp /mnt1/${_ini_prefix}/boot.ini.multi /mnt1/boot.ini > /dev/null 2>&1
+				cp /mnt1/${_ini_prefix}/boot.scr.multi /mnt1/boot.scr > /dev/null 2>&1
+				sleep 3
+				umount /mnt_a > /dev/null 2>&1
+				return 1
+			fi
+		fi
+		sleep 1
+		umount /mnt1
+		umount /mnt2 > /dev/null 2>&1
+		reboot
+	fi
+}
+#----------------------------------------------------------------------------------------------------------------------
+
+#------------------------------------------------------
+set_menu_key() {
+	_menu_key="\\$(printf '%03o' ${_menu_no})"
+
+	if [ $_menu_no -eq 49 ]; then
+		_menuitem_1="${1}"
+		_mndscr_1="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_1="2"
+	elif [ $_menu_no -eq 50 ]; then
+		_menuitem_2="${1}"
+		_mndscr_2="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_2="2"
+	elif [ $_menu_no -eq 51 ]; then
+		_menuitem_3="${1}"
+		_mndscr_3="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_3="2"
+	elif [ $_menu_no -eq 52 ]; then
+		_menuitem_4="${1}"
+		_mndscr_4="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_4="2"
+	elif [ $_menu_no -eq 53 ]; then
+		_menuitem_5="${1}"
+		_mndscr_5="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_5="2"
+	elif [ $_menu_no -eq 54 ]; then
+		_menuitem_6="${1}"
+		_mndscr_6="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_6="2"
+	elif [ $_menu_no -eq 55 ]; then
+		_menuitem_7="${1}"
+		_mndscr_7="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_7="2"
+	elif [ $_menu_no -eq 56 ]; then
+		_menuitem_8="${1}"
+		_mndscr_8="${_desc}"
+		[ "${_actmount}" = "mnt2" ] && _mncrd_8="2"
+	fi
+
+	let _menu_no=_menu_no+1
+	let _numos=_numos+1
+}
+#------------------------------------------------------
+
+#---------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+get_menu_items() {
+	local _oncard=""
+	if [ "${NUMCARDS}" = "2" ]; then
+		if [ "${_actmount}" = "mnt1" ]; then
+			_oncard=" on ${BOOT_CARDTYPE}"
+		else
+			_oncard=" on ${OTHER_CARDTYPE}"
+		fi
+	fi
+	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.android ]; then
+		get_descr "boot.ini.android" "Android"
+		set_menu_key "boot.ini.android"
+		printf "\033[36m    \033[32m\033[1m${_menu_key}\033[22m\033[36m  boot to \033[32m${_desc}\033[36m${_oncard}\n"
+	fi
+	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.linux ]; then
+		get_descr "boot.ini.linux" "Linux"
+		set_menu_key "boot.ini.linux"
+		printf "\033[36m    \033[33m\033[1m${_menu_key}\033[22m\033[36m  boot to \033[33m${_desc}\033[36m${_oncard}\n"
+	fi
+	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.oelec ]; then
+		get_descr "boot.ini.oelec" "OpenElec"
+		set_menu_key "boot.ini.oelec"
+		printf "\033[36m    \033[37m\033[1m${_menu_key}\033[22m\033[36m  boot to \033[37m${_desc}\033[36m${_oncard}\n"
+	fi
+	if [ -f /${_actmount}/${_ini_prefix}/boot.ini.linux2 ]; then
+		get_descr "boot.ini.linux2" "Linux #2"
+		set_menu_key "boot.ini.linux2"
+		printf "\033[36m    \033[33m\033[1m${_menu_key}\033[22m\033[36m  boot to \033[33m${_desc}\033[36m${_oncard}\n"
+	fi
+}
+#---------------------------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------------------------------
+do_halt() {
+	umount /mnt1 > /dev/null 2>&1
+	umount /mnt2 > /dev/null 2>&1
+	local B="X"
+	local _reboot_delay=60
+	while [ $_reboot_delay -gt 0 ]; do
+		printf "\r\033[2K"
+		printf "    \033[31m\033[1m%s, press R to reboot %s\033[22m\033[37m\r" "${1}" "$_reboot_delay"
+		if read -n 1 -t 1 -s B; then
+			_reboot_delay=60
+			if [ "${B}" = "r" ] || [ "${B}" = "R" ]; then
+				printf "\r\033[2K"
+				reboot
+			fi
+		else
+			let _reboot_delay=_reboot_delay-1
+		fi
+	done
+	reboot
+}
+#-----------------------------------------------------------------------------------------------------
+
+#-----------------------------------------------------------------------------------------------------------------
+os_detect() {
+	_desc=""
+	_ini_prefix="multiboot"
+	_actmount="mnt1"
+	_numos=0
+	_menu_no=49
+	_menu_key="1"
+	_menuitem_1=""
+	_menuitem_2=""
+	_menuitem_3=""
+	_menuitem_4=""
+	_menuitem_5=""
+	_menuitem_6=""
+	_menuitem_7=""
+	_menuitem_8=""
+	_mndscr_1=""
+	_mndscr_2=""
+	_mndscr_3=""
+	_mndscr_4=""
+	_mndscr_5=""
+	_mndscr_6=""
+	_mndscr_7=""
+	_mndscr_8=""
+	_mncrd_1="1"
+	_mncrd_2="1"
+	_mncrd_3="1"
+	_mncrd_4="1"
+	_mncrd_5="1"
+	_mncrd_6="1"
+	_mncrd_7="1"
+	_mncrd_8="1"
+	_boot_delay=2
+	_defboot="none"
+	_defdescr="none"
+	_defcard="1"
+
+	# prepare cards mount points
+	mkdir /mnt1 > /dev/null 2>&1
+	mkdir /mnt2 > /dev/null 2>&1
+	umount /mnt1 > /dev/null 2>&1
+	umount /mnt2 > /dev/null 2>&1
+	umount /mnt > /dev/null 2>&1
+
+	clear
+	# Detect new partitions after install
+	blkid  > /dev/null 2>&1
+
+	# ================================
+	# Mount available cards
+	# ================================
+	mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt1 > /dev/null 2>&1
+	if [ $? -eq 0 ]; then
+		if [ "${NUMCARDS}" = "2" ]; then
+			mount -t vfat /dev/mmcblk${OTHER_CARDDEV}p1 /mnt2 > /dev/null 2>&1
+			if [ $? -ne 0 ]; then
+				OTHER_CARDDEV="9"
+			fi
+		fi
+	else
+		# === SOMETHING IS VERY WRONG ===
+		do_halt "BOOT CARD NOT MOUNTABLE"
+	fi
+
+	clear
+	printf "\n"
+	printf "\033[36m\033[1m\n"
+	if [ "${O_BOARD}" = "C2" ]; then
+		printf "    ============================\n"
+		printf "    = ODROID C2 BOOT MENU %s =\n" "${SCRIPT_VERSION}"
+		printf "    ============================\n"
+	else
+		printf "    =================================\n"
+		printf "    = ODROID XU3/XU4 BOOT MENU %s =\n" "${SCRIPT_VERSION}"
+		printf "    =================================\n"
+	fi
+	if [ "${NUMCARDS}" = "2" ]; then
+		printf "\033[22m    Two cards detected, booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	else
+		printf "\033[22m    Booted from \033[1m%s\033[22m\033[37m\n\n" "${BOOT_CARDTYPE}"
+	fi
+
+
+	#===================================================
+	# === Detect available OS's and print menu items ===
+	#===================================================
+	_menu_no=49
+	# Scan boot card first
+	_actmount="mnt1"
+	if [ -b /dev/disk/by-label/sduserdata ] || [ -b /dev/disk/by-label/emuserdata ]; then
+		get_menu_items
+		if [ "${NUMCARDS}" = "2" ]; then
+			_actmount="mnt2"
+			[ ! ${_numos} -eq 0 ] && printf "\n"
+			get_menu_items
+		fi
+		[ ${_numos} -eq 0 ] && printf "\033[36m    \033[36m\033[1m!\033[22m  NO OS DETECTED\033[36m\n"
+	else
+		[ ${_numos} -eq 0 ] && printf "\033[36m    \033[36m\033[1m!\033[22m  NO MULTIBOOT CARD DETECTED\033[36m\n"
+	fi
+
+	printf "\n"
+	printf "    \033[36m\033[1mB\033[22m  Backup Android/Linux/OpenElec\033[36m\n"
+	printf "    \033[36m\033[1mU\033[22m  Update Android\033[36m\n"
+	printf "    \033[33m\033[1mI\033[22m  Prepare the card for MultiBoot, Install OS's\033[36m\n"
+	printf "\n"
+	printf "    \033[36m\033[1mX\033[22m  Exit to busybox shell\033[36m\n"
+	printf "    \033[33m\033[1mR\033[22m  Reboot\033[36m\n"
+
+	printf "\n"
+	printf "\n"
+
+	# === Get default boot ===
+
+	if [ "${DEFAULTBOOT}" = "1" ] && [ ! "${_menuitem_1}" = "none" ]; then
+		_defboot="${_menuitem_1}"
+		_defdescr="${_mndscr_1}"
+		_defcard="${_mncrd_1}"
+	elif [ "${DEFAULTBOOT}" = "2" ] && [ ! "${_menuitem_2}" = "none" ]; then
+		_defboot="${_menuitem_2}"
+		_defdescr="${_mndscr_2}"
+		_defcard="${_mncrd_2}"
+	elif [ "${DEFAULTBOOT}" = "3" ] && [ ! "${_menuitem_3}" = "none" ]; then
+		_defboot="${_menuitem_3}"
+		_defdescr="${_mndscr_3}"
+		_defcard="${_mncrd_3}"
+	elif [ "${DEFAULTBOOT}" = "4" ] && [ ! "${_menuitem_4}" = "none" ]; then
+		_defboot="${_menuitem_4}"
+		_defdescr="${_mndscr_4}"
+		_defcard="${_mncrd_4}"
+	elif [ "${DEFAULTBOOT}" = "5" ] && [ ! "${_menuitem_5}" = "none" ]; then
+		_defboot="${_menuitem_5}"
+		_defdescr="${_mndscr_5}"
+		_defcard="${_mncrd_5}"
+	elif [ "${DEFAULTBOOT}" = "6" ] && [ ! "${_menuitem_6}" = "none" ]; then
+		_defboot="${_menuitem_6}"
+		_defdescr="${_mndscr_6}"
+		_defcard="${_mncrd_6}"
+	elif [ "${DEFAULTBOOT}" = "7" ] && [ ! "${_menuitem_7}" = "none" ]; then
+		_defboot="${_menuitem_7}"
+		_defdescr="${_mndscr_7}"
+		_defcard="${_mncrd_7}"
+	elif [ "${DEFAULTBOOT}" = "8" ] && [ ! "${_menuitem_8}" = "none" ]; then
+		_defboot="${_menuitem_8}"
+		_defdescr="${_mndscr_8}"
+		_defcard="${_mncrd_8}"
+	fi
+
+	if [ "${_defboot}" = "none" ]; then
+		if [ ! "${_menuitem_1}" = "none" ]; then
+			_defboot="${_menuitem_1}"
+			_defdescr="${_mndscr_1}"
+			_defcard="${_mncrd_1}"
+			DEFAULTBOOT="1"
+		elif [ ! "${_menuitem_2}" = "none" ]; then
+			_defboot="${_menuitem_2}"
+			_defdescr="${_mndscr_2}"
+			_defcard="${_mncrd_2}"
+			DEFAULTBOOT="2"
+		elif [ ! "${_menuitem_3}" = "none" ]; then
+			_defboot="${_menuitem_3}"
+			_defdescr="${_mndscr_3}"
+			_defcard="${_mncrd_3}"
+			DEFAULTBOOT="3"
+		elif [ ! "${_menuitem_4}" = "none" ]; then
+			_defboot="${_menuitem_4}"
+			_defdescr="${_mndscr_4}"
+			_defcard="${_mncrd_4}"
+			DEFAULTBOOT="4"
+		elif [ ! "${_menuitem_5}" = "none" ]; then
+			_defboot="${_menuitem_5}"
+			_defdescr="${_mndscr_5}"
+			_defcard="${_mncrd_5}"
+			DEFAULTBOOT="5"
+		elif [ ! "${_menuitem_6}" = "none" ]; then
+			_defboot="${_menuitem_6}"
+			_defdescr="${_mndscr_6}"
+			_defcard="${_mncrd_6}"
+			DEFAULTBOOT="6"
+		elif [ ! "${_menuitem_7}" = "none" ]; then
+			_defboot="${_menuitem_7}"
+			_defdescr="${_mndscr_7}"
+			_defcard="${_mncrd_7}"
+			DEFAULTBOOT="7"
+		elif [ ! "${_menuitem_8}" = "none" ]; then
+			_defboot="${_menuitem_8}"
+			_defdescr="${_mndscr_8}"
+			_defcard="${_mncrd_8}"
+			DEFAULTBOOT="8"
+		fi
+	fi
+}
+#-----------------------------------------------------------------------------------------------------------------
+
+os_detect
+
+# ======================================
+# ===      Main loop, never exit     ===
+# === Wait for user OS/action select ===
+# ======================================
+_boot_delay=$BOOTDELAY
+
+# === Detect available Operating Systems ===
+while true; do
+	printf "\r\033[2K"
+    printf "\033[37m    Select an option or boot to menu item \033[36m\033[1m%s\033[22m in\033[31m\033[1m %s \033[22m\033[37mseconds" "${DEFAULTBOOT}" "${_boot_delay}"
+
+	A="Z"
+    if read -n 1 -t 1 -s A; then
+		_boot_delay=$BOOTDELAY
+		if [ "${A}" = "B" ]; then
+			# === BACKUP ===
+			if [ -f /backup.script ]; then
+				umount /mnt1  > /dev/null 2>&1
+				umount /mnt2  > /dev/null 2>&1
+				sleep 1
+				# =========================
+				# Execute the backup script
+				/backup.script
+				# =========================
+				A="Z"
+				os_detect
+				_boot_delay=$BOOTDELAY
+			else
+				printf "\r\033[2K"
+				printf "    BACKUP SCRIPT NOT FOUND!"
+				sleep 4
+			fi
+		elif [ "${A}" = "I" ]; then
+			# === UNIVERSAL INSTALLER ===
+			if [ -f /install.script ]; then
+				umount /mnt1  > /dev/null 2>&1
+				umount /mnt2  > /dev/null 2>&1
+				sleep 1
+				# ============================
+				# Execute the installer script
+				/install.script
+				# ============================
+				A="Z"
+				os_detect
+				_boot_delay=$BOOTDELAY
+			else
+				printf "\r\033[2K"
+				printf "    INSTALL SCRIPT NOT FOUND!"
+				sleep 4
+			fi
+		elif [ "${A}" = "U" ]; then
+			# === ANDROID UPGRADE ====
+			printf "\r\033[2K"
+			printf "    NOT SUPPORTED"
+			sleep 4
+		elif [ "${A}" = "X" ]; then
+			# === ENTER BUSYBOX ===
+			clear
+			printf "\n\n\n    Entering \033[32mBusybox\033[37m shell\n"
+			printf "    Execute \033[32mexit\033[37m to return to menu\n\n"
+			umount /mnt1  > /dev/null 2>&1
+			umount /mnt2  > /dev/null 2>&1
+			sleep 1
+			#For C2 show cursor
+			[ "${O_BOARD}" = "C2" ] && tput cnorm
+			#===============
+			break="bbox"
+			maybe_break bbox
+			#===============
+			printf "\n    \033[32mBusybox exited\033[37m\n"
+			sleep 2
+			#For C2 hide cursor
+			[ "${O_BOARD}" = "C2" ] && tput civis
+			A="Z"
+			os_detect
+			_boot_delay=$BOOTDELAY
+		elif [ "${A}" = "R" ]; then
+			# REBOOT ===
+			_reboot_delay=10
+			B="X"
+			while [ $_reboot_delay -gt 0 ]; do
+				printf "\r\033[2K"
+				printf "    \033[33m\033[1mREBOOT in %s sec, press \033[22ma\033[1m to abort \033[22m\033[37m\r" "$_reboot_delay"
+				if read -n 1 -t 1 -s B; then
+					_reboot_delay=10
+					if [ "${B}" = "a" ] || [ "${B}" = "A" ]; then
+						printf "\r\033[2K"
+						break
+					fi
+				else
+					let _reboot_delay=_reboot_delay-1
+				fi
+			done
+			if [ $_reboot_delay -eq 0 ]; then
+				cp -f /*.ppm /mnt1 > /dev/null 2>&1
+				umount /mnt1 > /dev/null 2>&1
+				umount /mnt2 > /dev/null 2>&1
+				reboot
+			fi
+		elif [ "${A}" = "s" ]; then
+			# SCREENSHOT ===
+			fbcat > /mb_menu.ppm
+		elif [ $_numos -gt 0 ]; then
+			# === BOOT to selected OS
+			boot_fail="no"
+			[ "${A}" = "1" ] && [ ! "${_menuitem_1}" = "none" ] && do_boot "${_menuitem_1}" "${_mndscr_1}" "${_mncrd_1}"
+			[ "${A}" = "2" ] && [ ! "${_menuitem_2}" = "none" ] && do_boot "${_menuitem_2}" "${_mndscr_2}" "${_mncrd_2}"
+			[ "${A}" = "3" ] && [ ! "${_menuitem_3}" = "none" ] && do_boot "${_menuitem_3}" "${_mndscr_3}" "${_mncrd_3}"
+			[ "${A}" = "4" ] && [ ! "${_menuitem_4}" = "none" ] && do_boot "${_menuitem_4}" "${_mndscr_4}" "${_mncrd_4}"
+			[ "${A}" = "5" ] && [ ! "${_menuitem_5}" = "none" ] && do_boot "${_menuitem_5}" "${_mndscr_5}" "${_mncrd_5}"
+			[ "${A}" = "6" ] && [ ! "${_menuitem_6}" = "none" ] && do_boot "${_menuitem_6}" "${_mndscr_6}" "${_mncrd_6}"
+			[ "${A}" = "7" ] && [ ! "${_menuitem_7}" = "none" ] && do_boot "${_menuitem_7}" "${_mndscr_7}" "${_mncrd_7}"
+			[ "${A}" = "8" ] && [ ! "${_menuitem_8}" = "none" ] && do_boot "${_menuitem_8}" "${_mndscr_8}" "${_mncrd_8}"
+
+			if [ "${boot_fail}" = "yes" ]; then
+				# === BOOT ERROR ===
+				sleep 4
+				os_detect
+				_boot_delay=$BOOTDELAY
+			fi
+		fi
+    else
+        let _boot_delay=_boot_delay-1
+		if [ $_boot_delay -eq 0 ]; then
+			# Default boot
+			[ $_numos -gt 0 ] && [ ! "${_defboot}" = "none" ] && do_boot "${_defboot}" "${_defdescr}" "${_defcard}"
+
+			# === BOOT ERROR ===
+			sleep 4
+			os_detect
+			_boot_delay=$BOOTDELAY
+		fi
+    fi
+
+    printf "\r"
+done
+
+# Just in case...
+printf "\n\n"
+umount /mnt1 > /dev/null 2>&1
+umount /mnt2 > /dev/null 2>&1
+printf "\033[36m    REBOOT ...\n"
+
+reboot
+#---------------------------------------------------------------------------

+ 2158 - 0
scripts/install.script

@@ -0,0 +1,2158 @@
+#!/bin/bash
+
+# === Detect instalation source ===
+
+echo "1 1 1 1" > /proc/sys/kernel/printk
+
+mkdir /mnt > /dev/null 2>&1
+mkdir /multiboot > /dev/null 2>&1
+mkdir /run/inst > /dev/null 2>&1
+
+#-------------------------------------------------------
+print_header() {
+    clear
+    printf "\n"
+    printf "\n"
+    printf "\033[36m\033[1m\n"
+	if [ "${O_BOARD}" = "C2" ]; then
+		printf "    ======================================\n"
+		printf "    = Odroid C2 Universal installer %s =\n" "${SCRIPT_VERSION}"
+		printf "    ======================================\n"
+	else
+		printf "    ===========================================\n"
+		printf "    = Odroid XU3/XU4 Universal installer %s =\n" "${SCRIPT_VERSION}"
+		printf "    ===========================================\n"
+	fi
+    printf "\033[22m\033[37m\n"
+}
+#-------------------------------------------------------
+
+
+print_header
+
+# Set variables
+CARD1=""
+CARD2=""
+CARD1_EMMC=""
+CARD2_EMMC=""
+DEST_CARD=""
+DEST_EMMC=""
+INST_ANDROID=""
+INST_OELEC=""
+INST_LINUX=""
+INST_LINUX2=""
+A_FROMDIR=""
+L_FROMDIR=""
+L2_FROMDIR=""
+O_FROMDIR=""
+INST_DELAY=60
+SYSTEM_SIZE=1024
+SYSTEM_MINSIZE=768
+DATA_SIZE=1024
+DATA_MINSIZE=1024
+CACHE_SIZE=256
+CACHE_MINSIZE=128
+USERDATA_SIZE=1024
+USERDATA_MINSIZE=512
+LINUX_SIZE=2048
+LINUX_MINSIZE=2048
+LINUX2_SIZE=2048
+LINUX2_MINSIZE=2048
+OELEC_SIZE=512
+OELEC_MINSIZE=512
+LINUX_FSTYPE="ext4"
+
+#-----------------------------------------------------
+# Check card type
+#----------------
+CARD1="/dev/mmcblk${BOOT_CARDDEV}"
+CARD1_EMMC="${BOOT_CARDTYPE}"
+if [ "${NUMCARDS}" = "2" ]; then
+	CARD2="/dev/mmcblk${OTHER_CARDDEV}"
+	CARD2_EMMC="${OTHER_CARDTYPE}"
+fi
+#-----------------------------------------------------
+
+
+#-----------------------------------------------------
+# Check where the installation files are located
+check_source() {
+	local _instfound="no"
+
+    if [ -b ${1} ]; then
+		/bin/mountx ${1} /mnt > /dev/null 2>&1
+		[ $? -ne 0 ] && return 1
+	else
+		return 1
+    fi
+    sleep 1
+    # === Source drive found and 1st partition mounted on /mnt ===
+
+    # === Check installation files on source drive ===
+    # ANDROID
+    if [ -d /mnt/${BKP_PREFIX}_backup/android ]; then
+		if [ -f /mnt/${BKP_PREFIX}_backup/android/system.raw.img ]; then
+			INST_ANDROID="yes"
+			_instfound="yes"
+			A_FROMDIR="yes"
+		fi
+    else
+		if [ -f /mnt/update.tar.gz ] || [ -f /mnt/update.zip ]; then
+			INST_ANDROID="yes"
+			_instfound="yes"
+			if [ "${1}" = "/dev/mmcblk0p1" ] || [ "${1}" = "/dev/mmcblk1p1" ]; then
+				return 0
+			fi
+		fi
+	fi
+
+    # LINUX
+    if [ -d /mnt/${BKP_PREFIX}_backup/linux ]; then
+		if [ -f /mnt/${BKP_PREFIX}_backup/linux/linux.img ]; then
+			INST_LINUX="yes"
+			_instfound="yes"
+			L_FROMDIR="yes"
+		fi
+    else
+		if [ -f /mnt/linux.img ]; then
+			INST_LINUX="yes"
+			_instfound="yes"
+		fi
+	fi
+
+    # LINUX2
+	if [ "${INST_LINUX}" = "yes" ]; then
+		if [ -d /mnt/${BKP_PREFIX}_backup/linux2 ]; then
+			if [ -f /mnt/${BKP_PREFIX}_backup/linux2/linux.img ]; then
+				INST_LINUX2="yes"
+				_instfound="yes"
+				L2_FROMDIR="yes"
+			fi
+		else
+			if [ -f /mnt/linux2.img ]; then
+				INST_LINUX2="yes"
+			fi
+		fi
+	fi
+
+    if [ -d /mnt/${BKP_PREFIX}_backup/oelec/target ] && [ -d /mnt/${BKP_PREFIX}_backup/oelec/3rdparty ]; then
+		INST_OELEC="yes"
+		O_FROMDIR="yes"
+    else
+		if [ -f /mnt/oelec.tar ]; then
+			INST_OELEC="yes"
+		fi
+	fi
+
+	[ "${_instfound}" = "no" ] && return 1
+    return 0
+}
+#-----------------------------------------------------
+
+#----------------------------------------------------------------------------------------------------
+exit_script() {
+	local _delay=60
+	local B="X"
+	echo ""
+	while [ $_delay -gt 0 ]; do
+		printf "    \033[33mPress \033[1mE\033[22m to exit to main menu (%s)  \033[37m\r" "${_delay}"
+		if read -n 1 -t 1 -s B; then
+			_delay=60
+			if [ "${B}" = "E" ] || [ "${B}" = "e" ]; then
+				break
+			elif [ "${B}" = "s" ]; then
+				# SCREENSHOT ===
+				fbcat > /install_exit.ppm
+			fi
+		else
+			let _delay=_delay-1
+		fi
+	done
+
+	printf "\r\033[2K"
+	umount /mnt1 > /dev/null 2>&1
+	umount /mnt2 > /dev/null 2>&1
+	umount /mnt > /dev/null 2>&1
+	exit 0
+}
+#----------------------------------------------------------------------------------------------------
+
+print_header
+
+# === Copy multiboot files from boot drive to RAMfs directory ===
+mount -t vfat /dev/mmcblk${BOOT_CARDDEV}p1 /mnt > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+	printf "    ERROR mounting boot card"
+	exit_script
+fi
+
+cp /mnt/multiboot/*.multi /multiboot > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+	printf "    ERROR copying multiboot files"
+	exit_script
+fi
+
+umount /mnt > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+	printf "    ERROR unmounting boot card"
+	exit_script
+fi
+sleep 1
+
+#=================================================
+printf "    Searching for installation drive ... "
+
+# === Set default dest card to sdcard if exists ===
+DEST_CARD=${CARD1}
+DEST_EMMC=${CARD1_EMMC}
+if [ "${NUMCARDS}" = "2" ]; then
+	DEST_CARD=${CARD2}
+	DEST_EMMC=${CARD2_EMMC}
+fi
+
+check_source "/dev/sda1"
+if [ $? -ne 0 ]; then
+	check_source "/dev/sda2"
+	if [ $? -ne 0 ]; then
+		check_source "/dev/sda3"
+		if [ $? -ne 0 ]; then
+			check_source "/dev/sda4"
+			if [ $? -ne 0 ]; then
+				printf "    \033[33m\033[1mNOT FOUND\033[22m\033[37m\n"
+				printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n\n"
+				exit_script
+			fi
+		fi
+	fi
+fi
+
+if [ ! "${INST_ANDROID}" = "yes" ]; then
+	SYSTEM_MINSIZE=8
+	DATA_MINSIZE=8
+	SYSTEM_SIZE=8
+	DATA_SIZE=8
+	CACHE_SIZE=8
+	CACHE_MINSIZE=8
+	USERDATA_MINSIZE=256
+	USERDATA_SIZE=256
+fi
+if [ ! "${INST_OELEC}" = "yes" ]; then
+	OELEC_MINSIZE=8
+	OELEC_SIZE=512
+fi
+if [ ! "${INST_LINUX}" = "yes" ]; then
+	LINUX_MINSIZE=8
+	LINUX_SIZE=8
+fi
+if [ "${INST_LINUX2}" = "yes" ]; then
+	let LINUX_MINSIZE=LINUX_MINSIZE+LINUX_MINSIZE
+	let LINUX_SIZE=LINUX_SIZE+LINUX_SIZE
+else
+	LINUX2_MINSIZE=0
+	LINUX2_SIZE=0
+fi
+#=================================================
+
+
+#=================================================
+
+if [ "${O_BOARD}" = "C2" ]; then
+	part_start=65536       # RESERVE 32M AT CARD START
+else
+	part_start=131072      # RESERVE 64MB AT CARD START
+fi
+
+PARTSIZE_INC=128
+export CARD_SIZE=8000
+export ONLY_ANDROID="no"
+export ONLY_LINUX="no"
+export MULTI_BOOT="yes"
+export source_mount="/mnt"
+export TWO_CARDS="no"
+
+rm /mnt/install.log > /dev/null 2>&1
+log_file="/mnt/install.log"
+#log_file="ls/dev/null"
+
+#--------------------------------------------------------------------------------------------------------------------------------------
+if [ "${INST_LINUX}" = "yes" ] && [ "${INST_ANDROID}" != "yes" ] && [ "${INST_OELEC}" != "yes" ] && [ "${INST_LINUX2}" != "yes" ]; then
+	ONLY_LINUX="yes"
+	MULTI_BOOT="no"
+fi
+if [ "${INST_ANDROID}" = "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
+	ONLY_ANDROID="yes"
+	MULTI_BOOT="no"
+fi
+if [ "${CARD1}" != "" ] && [ "${CARD1}" != "" ]; then
+	TWO_CARDS="yes"
+fi
+#-----------------------------------------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------------------
+# Detect and set installation card size, leave 32M at end unused
+set_cardsize() {
+	_card_sectno=`fdisk -l ${DEST_CARD} | grep "Disk ${DEST_CARD}" | awk '{print $7}'`
+	CARD_SIZE=$(( ( $_card_sectno - $part_start - 65536 ) / 2048))
+}
+#---------------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------------------------------
+# Set linux or userdata partition size to fill card size
+set_auto_partsize() {
+    if [ "${INST_LINUX}" = "yes" ]; then
+		LINUX_SIZE=$(( $CARD_SIZE - $USERDATA_SIZE - $SYSTEM_SIZE - $DATA_SIZE -$CACHE_SIZE - $OELEC_SIZE))
+        if [ "${LINUX_SIZE}" -lt "${LINUX_MINSIZE}" ]; then
+            LINUX_SIZE=${LINUX_MINSIZE}
+            return 1
+        else
+            return 0
+        fi
+    else
+		USERDATA_SIZE=$(( $CARD_SIZE - $SYSTEM_SIZE - $DATA_SIZE -$CACHE_SIZE - $OELEC_SIZE - $LINUX_SIZE))
+        if [ "${USERDATA_SIZE}" -lt "${USERDATA_MINSIZE}" ]; then
+            USERDATA_SIZE=${USERDATA_MINSIZE}
+            return 1
+        else
+            return 0
+        fi
+    fi
+}
+#--------------------------------------------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+print_settings() {
+    set_auto_partsize
+
+    printf "                    Install:"
+	if [ "${INST_ANDROID}" = "yes" ]; then
+		printf " \033[36mAndroid\033[37m from "
+		if [ "${A_FROMDIR}" = "yes" ]; then
+			printf "backup"
+		else
+			printf "image"
+		fi
+		if [ "${MULTI_BOOT}" = "yes" ]; then
+			printf "\033[32m &\033[37m"
+		fi
+	fi
+	if [ "${INST_LINUX}" = "yes" ]; then
+		printf " \033[36mLinux\033[37m from "
+		if [ "${L_FROMDIR}" = "yes" ]; then
+			printf "backup"
+		else
+			printf "image"
+		fi
+		if [ "${MULTI_BOOT}" = "yes" ] && [ "${INST_OELEC}" = "yes" ]; then
+			printf "\033[32m &\033[37m"
+		fi
+
+		if [ "${INST_LINUX2}" = "yes" ]; then
+			printf " \033[36mLinux2\033[37m from "
+			if [ "${L2_FROMDIR}" = "yes" ]; then
+				printf "backup"
+			else
+				printf "image"
+			fi
+			if [ "${MULTI_BOOT}" = "yes" ] && [ "${INST_OELEC}" = "yes" ]; then
+				printf "\033[32m &\033[37m"
+			fi
+		fi
+	fi
+	if [ "${INST_OELEC}" = "yes" ]; then
+		printf " \033[36mOpenElec\033[37m from "
+		if [ "${O_FROMDIR}" = "yes" ]; then
+			printf "backup"
+		else
+			printf "image"
+		fi
+	fi
+	printf "\033[37m\n"
+    printf "                 Install to: \033[36m${DEST_EMMC} Card (${DEST_CARD})\033[37m (${CARD_SIZE}M)\n"
+    printf "          Installation type: \033[36m"
+    if [ "${ONLY_LINUX}" = "yes" ]; then
+		printf "Linux"
+	elif [ "${ONLY_ANDROID}" = "yes" ]; then
+		printf "Android"
+	else
+		printf "Multi Boot"
+	fi
+	printf "\033[37m\n\n"
+    printf "                  Card size: \033[36m${CARD_SIZE}M\033[37m\n"
+    if [ "${ONLY_LINUX}" = "yes" ]; then
+		printf "        boot partition size: \033[36m${USERDATA_SIZE}M\033[37m\n"
+	else
+		printf "    userdata partition size: \033[36m${USERDATA_SIZE}M\033[37m\n"
+	fi
+    [ "${ONLY_LINUX}" != "yes" ] && printf "      system partition size: \033[36m${SYSTEM_SIZE}M\033[37m\n"
+    [ "${ONLY_LINUX}" != "yes" ] && printf "        data partition size: \033[36m${DATA_SIZE}M\033[37m\n"
+    [ "${INST_ANDROID}" = "yes" ] && printf "       cache partition size: \033[36m${CACHE_SIZE}M\033[37m\n"
+	if [ "${INST_OELEC}" = "yes" ]; then
+		[ "${MULTI_BOOT}" = "yes" ] && printf "    openELEC partition size: \033[36m${OELEC_SIZE}M\033[37m\n"
+	else
+		[ "${MULTI_BOOT}" = "yes" ] && printf "    swap/aux partition size: \033[36m${OELEC_SIZE}M\033[37m\n"
+	fi
+	if [ "${INST_LINUX}" = "yes" ]; then
+		if [ "${INST_LINUX2}" = "yes" ]; then
+			printf "   linux 1&2 partition size: \033[36m${LINUX_SIZE}M\033[37m\n"
+		else
+			printf "       linux partition size: \033[36m${LINUX_SIZE}M\033[37m\n"
+		fi
+	fi
+    [ "${INST_LINUX}" = "yes" ] && printf "     linux file system type: \033[36m${LINUX_FSTYPE}\033[37m\n"
+    printf "\033[36m\n"
+
+    [ "${TWO_CARDS}" = "yes" ] && printf "    \033[32m\033[1m1\033[22m  Change installation \033[1mcard\033[22m\033[36m\n"
+    if [ "${INST_LINUX}" = "yes" ]; then
+		printf "    \033[32m\033[1m2\033[22m  Change \033[1m"
+		if [ "${ONLY_LINUX}" = "yes" ]; then
+			printf "boot"
+		else
+			printf "userdata"
+		fi
+		printf "\033[22m partition size\033[36m\n"
+	fi
+    [ "${INST_ANDROID}" = "yes" ] && printf "    \033[32m\033[1m3\033[22m  Change \033[1msystem\033[22m partition size\033[36m\n"
+    [ "${INST_ANDROID}" = "yes" ] && printf "    \033[32m\033[1m4\033[22m  Change \033[1mdata\033[22m partition size\033[36m\n"
+    [ "${INST_ANDROID}" = "yes" ] && printf "    \033[32m\033[1m5\033[22m  Change \033[1mcache\033[22m partition size\033[36m\n"
+	if [ "${INST_OELEC}" = "yes" ]; then
+		[ "${MULTI_BOOT}" = "yes" ] && printf "    \033[32m\033[1m6\033[22m  Change \033[1moElec\033[22m partition size\033[36m\n"
+	else
+		[ "${MULTI_BOOT}" = "yes" ] && printf "    \033[32m\033[1m6\033[22m  Change \033[1mswap/aux\033[22m partition size\033[36m\n"
+	fi
+    if [ "${INST_LINUX}" = "yes" ]; then
+		if [ "${INST_LINUX2}" = "yes" ]; then
+			printf "    \033[32m\033[1mL\033[22m  Change \033[1mLinux 2\033[22m partition size\033[36m\n"
+		fi
+		printf "\n"
+		printf "    \033[32m\033[1mt\033[22m  Change Linux \033[1mfile system type\033[22m\033[36m\n"
+		printf "\n"
+	else
+		printf "\n"
+    fi
+    printf "    \033[35m\033[1mI\033[22m  Start installation\033[36m\n"
+	printf "\n"
+    printf "    \033[33m\033[1mE\033[22m  EXIT\033[36m\n"
+    printf "\033[37m\n"
+    if [ "${LINUX_FSTYPE}" = "btrfs" ]; then
+		printf "\033[32m\033[1m    WARNING\033[22m: only install to btrfs if Linux install image is prepared for it\n"
+		printf "             if not shure, use ext4\033[36m\n"
+    fi
+}
+#---------------------------------------------------------------------------------------------------------------------------
+
+#---- Select destination card -------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_dest() {
+    printf "    Press \033[35m+\033[37m key to change installation card, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    Install to: \033[36m${DEST_EMMC} Card (${DEST_CARD})\033[37m            \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				if [ "${NUMCARDS}" = "2" ]; then
+					if [ "${DEST_CARD}" = "${CARD1}" ]; then
+						if [ ! "${CARD2}" = "" ]; then
+							DEST_CARD=${CARD2}
+							DEST_EMMC=${CARD2_EMMC}
+						fi
+					elif [ "${DEST_CARD}" = "${CARD2}" ]; then
+						if [ ! "${CARD1}" = "" ]; then
+							DEST_CARD=${CARD1}
+							DEST_EMMC=${CARD1_EMMC}
+						fi
+					fi
+				elif [ "${O_BOARD}" = "C2" ]; then
+					if [ "${DEST_EMMC}" = "SD" ]; then
+						DEST_EMMC="EMMC"
+					else
+						DEST_EMMC="SD"
+					fi
+				fi
+			elif [ "${A}" = "9" ]; then
+				set_cardsize
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#-----------------------------------------------------------------------------
+
+
+#---- Set Linux fs type -------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_linfstype() {
+    printf "    Press \033[35m+\033[37m key to change Linux filesystem type, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    Linux fs type: \033[36m${LINUX_FSTYPE}\033[37m            \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				if [ "${LINUX_FSTYPE}" = "btrfs" ]; then
+					LINUX_FSTYPE="ext4"
+				else
+					LINUX_FSTYPE="btrfs"
+				fi
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#-----------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_systemsize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change system partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    system partition size: \033[36m${SYSTEM_SIZE}M\033[37m         \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let SYSTEM_SIZE=SYSTEM_SIZE+PARTSIZE_INC
+				set_auto_partsize
+			if [ $? -ne 0 ]; then
+				let SYSTEM_SIZE=SYSTEM_SIZE-PARTSIZE_INC
+				set_auto_partsize
+			fi
+			elif [ "${A}" = "-" ]; then
+				let SYSTEM_SIZE=SYSTEM_SIZE-${PARTSIZE_INC}
+				[ $SYSTEM_SIZE -lt $SYSTEM_MINSIZE ] && SYSTEM_SIZE=$SYSTEM_MINSIZE
+				set_auto_partsize
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#----------------------------------------------------------------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_datasize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change data partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    data partition size: \033[36m${DATA_SIZE}M\033[37m         \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let DATA_SIZE=DATA_SIZE+PARTSIZE_INC
+				set_auto_partsize
+				if [ $? -ne 0 ]; then
+					let DATA_SIZE=DATA_SIZE-PARTSIZE_INC
+					set_auto_partsize
+				fi
+			elif [ "${A}" = "-" ]; then
+				let DATA_SIZE=DATA_SIZE-PARTSIZE_INC
+				[ $DATA_SIZE -lt $DATA_MINSIZE ] && DATA_SIZE=$DATA_MINSIZE
+				set_auto_partsize
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#--------------------------------------------------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_userdatasize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change "
+	if [ "${ONLY_LINUX}" = "yes" ]; then
+		printf "boot"
+	else
+		printf "userdata"
+	fi
+    printf " partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		if [ "${ONLY_LINUX}" = "yes" ]; then
+			printf "    boot"
+		else
+			printf "    userdata"
+		fi
+		printf " partition size: \033[36m${USERDATA_SIZE}M\033[37m         \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let USERDATA_SIZE=USERDATA_SIZE+PARTSIZE_INC
+				set_auto_partsize
+				if [ $? -ne 0 ]; then
+					let USERDATA_SIZE=USERDATA_SIZE-PARTSIZE_INC
+					set_auto_partsize
+				fi
+			elif [ "${A}" = "-" ]; then
+				let USERDATA_SIZE=USERDATA_SIZE-PARTSIZE_INC
+				[ $USERDATA_SIZE -lt $USERDATA_MINSIZE ] && USERDATA_SIZE=$USERDATA_MINSIZE
+				set_auto_partsize
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#------------------------------------------------------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_cachesize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change cache partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    cache partition size: \033[36m${CACHE_SIZE}M\033[37m         \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let CACHE_SIZE=CACHE_SIZE+PARTSIZE_INC
+				set_auto_partsize
+				if [ $? -ne 0 ]; then
+					let CACHE_SIZE=CACHE_SIZE-PARTSIZE_INC
+					set_auto_partsize
+				fi
+			elif [ "${A}" = "-" ]; then
+				let CACHE_SIZE=CACHE_SIZE-PARTSIZE_INC
+				[ ${CACHE_SIZE} -lt $CACHE_MINSIZE ] && CACHE_SIZE=$CACHE_MINSIZE
+				set_auto_partsize
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#------------------------------------------------------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_linuxsize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change Linux 2 partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    local _linux1size=1024
+    while [ $_wait_delay -gt 0 ]; do
+		printf "    Linux 2 partition size: \033[36m${LINUX2_SIZE}M\033[37m         \r"
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let LINUX2_SIZE=LINUX2_SIZE+PARTSIZE_INC
+				let _linux1size=LINUX_SIZE-LINUX2_SIZE
+				if [ ${_linux1size} -lt $LINUX2_MINSIZE ]; then
+					let LINUX2_SIZE=LINUX2_SIZE-PARTSIZE_INC
+				fi
+			elif [ "${A}" = "-" ]; then
+				let LINUX2_SIZE=LINUX2_SIZE-PARTSIZE_INC
+				[ ${LINUX2_SIZE} -lt $LINUX2_MINSIZE ] && LINUX2_SIZE=$LINUX2_MINSIZE
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#------------------------------------------------------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+set_oelecsize() {
+    printf "    Press \033[35m+\033[37m|\033[35m-\033[37m key to change swap/aux partition size, \033[35m9\033[37m to select\n\n"
+
+    _wait_delay=30
+    while [ $_wait_delay -gt 0 ]; do
+		if [ "${INST_OELEC}" = "yes" ]; then
+			printf "    openElec partition size: \033[36m${OELEC_SIZE}M\033[37m         \r"
+		else
+			printf "    swap/aux partition size: \033[36m${OELEC_SIZE}M\033[37m         \r"
+		fi
+		if read -n 1 -t 1 -s A; then
+			_wait_delay=30
+			if [ "${A}" = "+" ]; then
+				let OELEC_SIZE=OELEC_SIZE+PARTSIZE_INC
+				set_auto_partsize
+				if [ $? -ne 0 ]; then
+					let OELEC_SIZE=OELEC_SIZE-PARTSIZE_INC
+					set_auto_partsize
+				fi
+			elif [ "${A}" = "-" ]; then
+				let OELEC_SIZE=OELEC_SIZE-PARTSIZE_INC
+				[ ${OELEC_SIZE} -lt $OELEC_MINSIZE ] && OELEC_SIZE=$OELEC_MINSIZE
+				set_auto_partsize
+			elif [ "${A}" = "9" ]; then
+				break
+			fi
+		else
+			let _wait_delay=_wait_delay-1
+		fi
+		printf "\r"
+    done
+}
+#------------------------------------------------------------------------------------------------------------------------------
+
+
+#-----------------------------------------------------
+# caclulate partitions boundaries in block unuts
+get_partsizes() {
+    _userdata_size=$(( $USERDATA_SIZE * 2048))
+    userpart_end=$(( $_userdata_size + $part_start))
+	_system_size=$(( $SYSTEM_SIZE * 2048))
+	_cache_size=$(( $CACHE_SIZE * 2048))
+	syspart_start=$(( $userpart_end + 1))
+	syspart_end=$(( $_system_size + $syspart_start))
+	cachepart_start=$(( $syspart_end + 1))
+	cachepart_end=$(( $_cache_size + $cachepart_start))
+	extpart_start=$(( $cachepart_end + 1))
+}
+#-----------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------
+# Partition and format installation card
+prepare_card() {
+	echo "==== PREPARE CARD ====" >> ${log_file}
+	if [ "${INST_LINUX}" = "yes" ]; then
+		if [ "${INST_LINUX2}" = "yes" ]; then
+			_linux1size=$(( $LINUX_SIZE - $LINUX2_SIZE ))
+			_linux2size=${LINUX2_SIZE}
+		else
+			_linux1size=${LINUX_SIZE}
+			_linux2size=8
+		fi
+	else
+		_linux1size=8
+		_linux2size=8
+	fi
+
+	printf "    Partitioning the card "
+
+	# ---- Erase card -------------------------------------------------------
+	/bin/dd if=/dev/zero of=${DEST_CARD} bs=512 count=${part_start} >> ${log_file} 2>&1
+	sync
+	sleep 1
+	/bin/partprobe -s ${DEST_CARD} >> ${log_file} 2>&1
+	sleep 1
+
+	#---- Make new partition table --------------------------
+	echo -e "o\nw" | /bin/fdisk ${DEST_CARD} >> ${log_file} 2>&1
+	sync
+	sleep 1
+	/bin/partprobe -s ${DEST_CARD} >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "    ERROR creating partition table."
+		return 1
+    fi
+    sleep 1
+
+	# == MULTI BOOT PARTITION LAYOUT ===
+	# userdata
+	# android
+	# system
+	# extended
+	#   data
+	#   cache
+	#   oelec/swap/aux
+	#   linux
+	#   linux2
+	echo "n
+p
+1
+$part_start
+$userpart_end
+t
+c
+n
+p
+2
+$syspart_start
+$syspart_end
+n
+p
+3
+$cachepart_start
+$cachepart_end
+n
+e
+$extpart_start
+
+n
+
++${DATA_SIZE}M
+n
+
++${OELEC_SIZE}M
+n
+
++${_linux1size}M
+n
+
++${_linux2size}M
+w" | fdisk ${DEST_CARD} >> ${log_file} 2>&1
+
+	if [ $? -ne 0 ]; then
+		printf "    fdisk ERROR "
+		return 1
+	fi
+
+	sleep 2
+	/bin/partprobe -s ${DEST_CARD} >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "    ERROR creating partitions."
+		return 1
+	fi
+	sleep 1
+	sync
+	echo "OK"
+	sleep 1
+
+	# *** FORMATING partitions ***************************************
+	printf "    Formating partitions... "
+
+	# === USERDATA/BOOT =======================================================
+	printf "\033[36muserdata\033[37m... "
+	dd if=/dev/zero of=${DEST_CARD}p1 bs=512 count=2048 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR"
+        return 1
+    fi
+	sync
+	mkfs -t vfat -F 32 -n ${label_pref}userdata ${DEST_CARD}p1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "mkfs ERROR"
+        return 1
+    fi
+    sync
+    sleep 1
+
+	if [ "${INST_ANDROID}" = "yes" ]; then
+		printf "\033[36msystem\033[37m... "
+		# === system ===================================================
+		dd if=/dev/zero of=${DEST_CARD}p2 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		mkfs.ext4 -L ${label_pref}system ${DEST_CARD}p2 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+
+		# === data ===================================================
+		printf "\033[36mdata\033[37m... "
+		dd if=/dev/zero of=${DEST_CARD}p5 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		mkfs.ext4 -L ${label_pref}data ${DEST_CARD}p5 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+
+		# === cache =================================================================
+		printf "\033[36mcache\033[37m... "
+		dd if=/dev/zero of=${DEST_CARD}p3 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		mkfs.ext4 -L ${label_pref}cache ${DEST_CARD}p3 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+	fi
+
+	if [ "$INST_OELEC" = "yes" ]; then
+		printf "\033[36moelec\033[37m... "
+		# === swap/aux ==============================================
+		dd if=/dev/zero of=${DEST_CARD}p6 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		mkfs.ext4 -L ${label_pref}aux ${DEST_CARD}p6 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+	fi
+
+	if [ "${INST_LINUX}" = "yes" ]; then
+		# === linux =========================================================================
+		printf "\033[36mlinux\033[37m... "
+		dd if=/dev/zero of=${DEST_CARD}p7 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		if [ "${LINUX_FSTYPE}" = "btrfs" ] ; then
+			mkfs.btrfs -f -L ${label_pref}linux ${DEST_CARD}p7 >> ${log_file} 2>&1
+		else
+			mkfs.ext4 -L ${label_pref}linux ${DEST_CARD}p7 >> ${log_file} 2>&1
+		fi
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+	fi
+
+	if [ "${INST_LINUX2}" = "yes" ]; then
+		printf "\033[36mlinux2\033[37m... "
+		# === linux =========================================================================
+		dd if=/dev/zero of=${DEST_CARD}p8 bs=512 count=2048 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR"
+			return 1
+		fi
+		sync
+		if [ "${LINUX_FSTYPE}" = "btrfs" ] ; then
+			mkfs.btrfs -f -L ${label_pref}linux ${DEST_CARD}p8 >> ${log_file} 2>&1
+		else
+			mkfs.ext4 -L ${label_pref}linux ${DEST_CARD}p8 >> ${log_file} 2>&1
+		fi
+		if [ $? -ne 0 ]; then
+			echo "mkfs ERROR"
+			return 1
+		fi
+		sync
+		sleep 1
+	fi
+
+	/bin/partprobe -s ${DEST_CARD} >> ${log_file} 2>&1
+    echo "OK"
+    return 0
+}
+#----------------------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------
+# copy Odroid boot files to installation card
+install_boot_c2() {
+	echo "==== INSTALL BOOT ====" >> ${log_file}
+	printf "    Installing Odroid boot files ... "
+	dd if=/multi/bl1.bin of=${DEST_CARD} bs=1 count=442 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing bl1.bin."
+		return 1
+	fi
+	dd if=/multi/bl1.bin of=${DEST_CARD} bs=512 skip=1 seek=1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing bl1.bin."
+		return 1
+	fi
+	sync
+	dd if=/multi/u-boot.bin of=${DEST_CARD} bs=512 seek=97 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing u-boot.bin."
+		return 1
+	fi
+	sync
+	echo "OK"
+    sleep 1
+}
+#----------------------------------------------------------------------------
+
+#----------------------------------------------------------------------------
+# copy Odroid boot files to installation card
+install_boot_xu() {
+	if [ "${label_pref}" = "sd" ]; then
+		printf "    Installing Odroid boot files to SD Card ... "
+		dd if=/multi/bl1.bin of=${DEST_CARD} bs=512 seek=1 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing bl1.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/bl2.bin of=${DEST_CARD} seek=31 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing bl2.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/u-boot.bin of=${DEST_CARD} seek=63 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing u-boot.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/tzsw.bin of=${DEST_CARD} seek=2111 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing tzsw.bin."
+			return 1
+		fi
+		sync
+		echo "OK"
+	else
+		# UNLOCK boot0
+		_dest_card_=$(basename ${DEST_CARD})
+		printf "    Installing Odroid boot files to EMMC Card (%s [%s])... " "${DEST_CARD}" "${_dest_card_}"
+		if [ -e /sys/block/${_dest_card_}boot0/force_ro ]; then
+			echo 0 > /sys/block/${_dest_card_}boot0/force_ro
+			if [ $? -ne 0 ]; then
+				echo "ERROR enabling boot0."
+				return 1
+			fi
+		else
+			echo "ERROR: boot0 not found."
+			return 1
+		fi
+
+		dd if=/dev/zero of=${DEST_CARD}boot0 count=8192 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			printf "WARNING: error erasing boot0 "
+		fi
+		sync
+
+		dd if=/multi/bl1.bin of=${DEST_CARD}boot0 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing bl1.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/bl2.bin of=${DEST_CARD}boot0 seek=30 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing bl2.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/u-boot.bin of=${DEST_CARD}boot0 seek=62 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing u-boot.bin."
+			return 1
+		fi
+		sync
+		dd if=/multi/tzsw.bin of=${DEST_CARD}boot0 seek=2110 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing tzsw.bin."
+			return 1
+		fi
+		sync
+		echo 1 > /sys/block/${_dest_card_}boot0/force_ro
+		echo "OK"
+    fi
+    sleep 1
+}
+#----------------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------------------------------------------
+install_multi_sel() {
+	echo "==== INSTALL MULTIBOOT SUPPORT ====" >> ${log_file}
+
+	# Update userdata partition for multiboot
+	/bin/mountx -t vfat ${DEST_CARD}p1 /mnt2 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "    ERROR mounting boot partition."
+		return 1
+	fi
+	sleep 1
+
+	mkdir /mnt2/multiboot >> ${log_file} 2>&1
+
+	if [ ! -d /multiboot ]; then
+		echo "    ERROR: missing multiboot directory."
+		return 1
+	fi
+
+	if [ "${O_BOARD}" = "XU" ]; then
+		cp /multiboot/boot.scr.multi /mnt2/multiboot >> ${log_file} 2>&1
+		[ $? -ne 0 ] && return 1
+		cp /multiboot/boot.scr.multi /mnt2/boot.scr >> ${log_file} 2>&1
+		[ $? -ne 0 ] && return 1
+	fi
+	cp /multiboot/boot.ini.multi /mnt2/multiboot >> ${log_file} 2>&1
+	[ $? -ne 0 ] && return 1
+	cp /multiboot/boot.ini.multi /mnt2/boot.ini >> ${log_file} 2>&1
+	[ $? -ne 0 ] && return 1
+	cp /multiboot/${ODROID_IMAGE}.multi /mnt2/multiboot >> ${log_file} 2>&1
+	[ $? -ne 0 ] && return 1
+	cp /multiboot/uInitrd.multi /mnt2/multiboot >> ${log_file} 2>&1
+	[ $? -ne 0 ] && return 1
+	cp /multiboot/*.dtb.multi /mnt2/multiboot >> ${log_file} 2>&1
+	[ $? -ne 0 ] && return 1
+
+	return 0
+}
+#---------------------------------------------------------------------------------------------------------
+
+#------------------------------------------------------------------------------
+set_android_sizes() {
+	_img_size=$(/bin/lsx -ls ${andro_dest}/system.raw.img | awk '{print $1}')
+	_img_size_=$(( $_img_size / 1024 / $PARTSIZE_INC * $PARTSIZE_INC ))
+	while [ $SYSTEM_MINSIZE -lt $_img_size_ ]
+	do
+		let SYSTEM_MINSIZE=SYSTEM_MINSIZE+PARTSIZE_INC
+	done
+	let SYSTEM_MINSIZE=SYSTEM_MINSIZE+256
+	SYSTEM_SIZE=${SYSTEM_MINSIZE}
+
+	_img_size=$(/bin/lsx -ls ${andro_dest}/cache.raw.img | awk '{print $1}')
+	_img_size_=$(( $_img_size / 1024 / $PARTSIZE_INC * $PARTSIZE_INC ))
+	while [ $CACHE_MINSIZE -lt $_img_size_ ]
+	do
+		let CACHE_MINSIZE=CACHE_MINSIZE+PARTSIZE_INC
+	done
+	CACHE_SIZE=${CACHE_MINSIZE}
+
+	_img_size=$(/bin/lsx -ls ${andro_dest}/data.raw.img | awk '{print $1}')
+	_img_size_=$(( $_img_size / 1024 / $PARTSIZE_INC * $PARTSIZE_INC ))
+	while [ $DATA_MINSIZE -lt $_img_size_ ]
+	do
+		let DATA_MINSIZE=DATA_MINSIZE+PARTSIZE_INC
+	done
+	DATA_SIZE=${DATA_MINSIZE}
+}
+#------------------------------------------------------------------------------
+
+#--------------------------------------------------------------------------------------------------------------------------------
+check_android_backup() {
+    andro_dest="${source_mount}/${BKP_PREFIX}_backup/android"
+
+    if [ ! -f ${andro_dest}/system.raw.img ] || [ ! -f ${andro_dest}/data.raw.img ] || [ ! -f ${andro_dest}/cache.raw.img ]; then
+		if [ ! -f ${andro_source}/system.raw.img ]; then
+			echo "    system.img missing."
+		fi
+		if [ ! -f ${andro_source}/data.raw.img ]; then
+			echo "    data.img missing."
+		fi
+		if [ ! -f ${andro_source}/cache.raw.img ]; then
+			echo "    cache.img missing."
+		fi
+		sleep 2
+		return 1
+    fi
+	if [ ! -f ${andro_dest}/${ODROID_IMAGE} ]; then
+		echo "    KERNEL (%s) not found!" "${ODROID_IMAGE}"
+		sleep 2
+		return 1
+    fi
+	if [ "${O_BOARD}" = "C2" ] && [ ! -f ${andro_dest}/${ODROID_DTB} ]; then
+		echo "    %s not found!" "${ODROID_DTB}"
+		sleep 2
+		return 1
+    fi
+
+    set_android_sizes
+    return 0
+}
+#--------------------------------------------------------------------------------------------------------------------------------
+
+# Extract Android images from tar and expand sparse image files
+#----------------------------------------------------------------------------
+unpack_android() {
+	echo "==== UNPACK ANDROID ====" >> ${log_file}
+	mkdir /run/inst >> ${log_file} 2>&1
+	mkdir /run/inst/android >> ${log_file} 2>&1
+
+	printf "    Extracting Android partition images, please wait ... "
+
+	if [ -f ${source_mount}/update.tar.gz ]; then
+		mkdir ${source_mount}/android >> ${log_file} 2>&1
+		rm -rf ${source_mount}/android/* >> ${log_file} 2>&1
+
+		cp ${source_mount}/update.tar.gz ${source_mount}/android/update.tar.gz
+		cd ${source_mount}/android
+		tar -xf update.tar.gz --warning=no-timestamp >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR extracting archive."
+			cd /
+			return 1
+		fi
+		rm update.tar.gz
+		_name=$(ls)
+		if [ ! -d "${_name}" ]; then
+			echo "install directory not found in archive!"
+			cd /
+			return 1
+		fi
+		if [ ! -f ${_name}/${ODROID_ASYSTEMIMAGE} ]; then
+			echo "system.img not found!"
+			cd /
+			return 1
+		fi
+		andro_source="${source_mount}/android/${_name}"
+		cd /
+	else
+		if [ -f ${source_mount}/update.zip ]; then
+			mkdir ${source_mount}/android >> ${log_file} 2>&1
+			rm -rf ${source_mount}/android/* >> ${log_file} 2>&1
+			# unzip, dont make directories
+			unzip -qq -j ${source_mount}/update.zip -d ${source_mount}/android >> ${log_file} 2>&1
+			if [ $? -ne 0 ]; then
+				echo "ERROR unpacking \"update.zip\"."
+				return 1
+			fi
+			sync
+			andro_source="${source_mount}/android"
+		else
+			echo "ERROR: archive file not found."
+			return 1
+		fi
+	fi
+	sync
+	echo "OK."
+
+	printf "    Preparing Android partition images ...\n"
+
+	if [ ! -f ${andro_source}/${ODROID_IMAGE} ]; then
+		echo "    KERNEL (%s) not found!" "${ODROID_IMAGE}"
+		sleep 2
+		return 1
+    fi
+	if [ "${O_BOARD}" = "C2" ] && [ ! -f ${andro_source}/${ODROID_DTB} ]; then
+		echo "    %s not found!" "${ODROID_DTB}"
+		sleep 2
+		return 1
+    fi
+
+    if [ ! -f ${andro_source}/${ODROID_ASYSTEMIMAGE} ] || [ ! -f ${andro_source}/userdata.img ] || [ ! -f ${andro_source}/cache.img ]; then
+		if [ ! -f ${andro_source}/userdata.img ]; then
+			if [ ! "${O_BOARD}" = "C2" ]; then
+				# CM for XU3/XU4 can have different userdata.img names
+				if [ -f ${andro_source}/userdata_8.img ]; then
+					mv ${andro_source}/userdata_8.img ${andro_source}/userdata.img
+				else
+					if [ -f ${andro_source}/userdata_16.img ]; then
+						mv ${andro_source}/userdata_16.img ${andro_source}/userdata.img
+					else
+						if [ -f ${andro_source}/userdata_32.img ]; then
+							mv ${andro_source}/userdata_32.img ${andro_source}/userdata.img
+						else
+							if [ -f ${andro_source}/userdata_64.img ]; then
+								mv ${andro_source}/userdata_64.img ${andro_source}/userdata.img
+							fi
+						fi
+					fi
+				fi
+			fi
+			if [ ! -f ${andro_source}/userdata.img ]; then
+				echo "    userdata.img missing."
+				sleep 2
+				return 1
+			fi
+		fi
+		if [ ! -f ${andro_source}/${ODROID_ASYSTEMIMAGE} ]; then
+			echo "    system.img missing."
+			sleep 2
+			return 1
+		fi
+		if [ ! -f ${andro_source}/cache.img ]; then
+			echo "    cache.img missing."
+			sleep 2
+			return 1
+		fi
+    fi
+	
+    # All needed images and files are present, get sizes
+	_ramfs_free=$(df | grep tmpfs | awk '{print $4}')
+	_ramfs_free=$(( $_ramfs_free / 1024 - 100 ))
+
+	_img_size=$(/bin/lsx -ls ${andro_source}/${ODROID_ASYSTEMIMAGE} | awk '{print $1}')
+	size_of_images=$_img_size
+	_img_size=$(/bin/lsx -ls ${andro_source}/userdata.img | awk '{print $1}')
+	size_of_images=$(( $size_of_images + $_img_size))
+	_img_size=$(/bin/lsx -ls ${andro_source}/cache.img | awk '{print $1}')
+	size_of_images=$(( $size_of_images + $_img_size))
+
+	size_of_images=$(( $size_of_images / 1024 ))
+    if [ $size_of_images -gt $_ramfs_free ]; then
+		andro_dest="${andro_source}"
+		echo "    Decompressing to source drive (${size_of_images} MB)"
+    else
+		andro_dest="/run/inst/android"
+		echo "    Decompressing to RAMfs (${size_of_images} MB)"
+		cp ${andro_source}/${ODROID_DTB} ${andro_dest} >> ${log_file} 2>&1
+		cp ${andro_source}/${ODROID_IMAGE} ${andro_dest} >> ${log_file} 2>&1
+		sync
+    fi
+
+	# === Decompress sparse images ===
+	printf "    system ... "
+	simg2img ${andro_source}/${ODROID_ASYSTEMIMAGE} ${andro_dest}/system.raw.img >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR."
+		return 1
+	fi
+	sync
+	rm ${andro_source}/${ODROID_ASYSTEMIMAGE}
+
+	printf "cache... "
+	simg2img ${andro_source}/cache.img ${andro_dest}/cache.raw.img >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR."
+		return 1
+	fi
+	sync
+	rm ${andro_source}/cache.img
+
+	printf "data... "
+	simg2img ${andro_source}/userdata.img ${andro_dest}/data.raw.img >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR."
+		return 1
+	fi
+	sync
+	rm ${andro_source}/userdata.img
+
+	echo "OK."
+
+	set_android_sizes
+    return 0
+}
+#----------------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------------------------------
+change_android_fstab() {
+    # Prepare fstab for changed partition layout
+    if [ -f /mnt2/${1} ]; then
+		if [ "${O_BOARD}" = "C2" ]; then
+			# Change data partition number (4 -> 5)
+			cat /mnt2/${1} | sed "s/\/dev\/block\/mmcblk0p4/\/dev\/block\/mmcblk0p5/g" > _fstab_
+			cp _fstab_ /mnt2/${1}
+			rm _fstab_
+		else
+			# Change data partition number (3 -> 5)
+			cat /mnt2/${1} | sed "s/\/dev\/block\/mmcblk0p4/\/dev\/block\/mmcblk0p5/g" > _fstab_
+			cp _fstab_ /mnt2/${1}
+			rm _fstab_
+			# Change cache partition number (4 -> 3)
+			cat /mnt2/${1} | sed "s/\/dev\/block\/mmcblk0p4/\/dev\/block\/mmcblk0p3/g" > _fstab_
+			cp _fstab_ /mnt2/${1}
+			rm _fstab_
+		fi
+    fi
+}
+#---------------------------------------------------------------------------------------------
+
+#------------------------------------------------------------
+prepare_android_multi() {
+	echo "==== PREPARE ANDROID FOR MULTIBOOT ====" >> ${log_file}
+    # Prepare fstab for changed partition layout
+	change_android_fstab "${ODROID_FSTAB}"
+	if [ -f /mnt2/${ODROID_FSTAB}.sdcard ]; then
+		change_android_fstab "${ODROID_FSTAB}.sdcard"
+	elif [ -f /mnt2/${ODROID_FSTAB}.sdboot ]; then
+		change_android_fstab "${ODROID_FSTAB}.sdboot"
+	fi
+    return 0
+}
+#------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------------------------------
+install_android() {
+	echo "==== INSTALL ANDROID ====" >> ${log_file}
+	printf "\n    \033[33mInstalling \033[1mAndroid\033[22m\033[37m"
+    if [ -d ${source_mount}/backup/android/system ]; then
+		printf " (from backup)\n"
+	else
+		printf "\n"
+	fi
+
+    mkdir /mnt1 >> ${log_file} 2>&1
+    mkdir /mnt2 >> ${log_file} 2>&1
+
+    # === Copy system partition ===
+    printf "    Installing \033[36msystem\033[37m ... "
+    # mount source
+	mount -t ext4 -o ro,loop ${andro_dest}/system.raw.img /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR mounting system image."
+		return 1
+	fi
+	# mount destination
+    mount -t ext4 ${DEST_CARD}p2 /mnt2 >> ${log_file} 2>&1
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        echo "ERROR mounting system partition."
+        return 1
+    fi
+    sleep 1
+    rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s -A -X --no-specials /mnt1/ /mnt2/ >> ${log_file} 2>&1
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        umount /mnt2 >> ${log_file} 2>&1
+        echo "ERROR copying system."
+        return 1
+    fi
+    sync
+
+    prepare_android_multi
+
+    umount /mnt1 >> ${log_file} 2>&1
+    umount /mnt2 >> ${log_file} 2>&1
+    sleep 1
+    printf "OK  "
+
+    # === Copy data partition ===
+	printf "\033[36mdata\033[37m ... "
+    # mount source
+	mount -t ext4 -o ro,loop ${andro_dest}/data.raw.img /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR mounting data image."
+		return 1
+	fi
+	# mount destination
+	mount -t ext4 ${DEST_CARD}p5 /mnt2 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		echo "ERROR mounting data partition."
+		return 1
+	fi
+	sleep 1
+
+	rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s -A -X --no-specials /mnt1/ /mnt2/ >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		umount /mnt2 >> ${log_file} 2>&1
+		echo "ERROR copying userdata."
+		return 1
+	fi
+	sync
+
+	umount /mnt1 >> ${log_file} 2>&1
+	umount /mnt2 >> ${log_file} 2>&1
+	sleep 1
+	printf "OK  "
+
+    # === Copy cache partition ===
+	printf "\033[36mcache\033[37m ... "
+    # mount source
+	mount -t ext4 -o ro,loop ${andro_dest}/cache.raw.img /mnt1 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR mounting cache image."
+		return 1
+	fi
+	# mount destination
+	mount -t ext4 ${DEST_CARD}p3 /mnt2 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		echo "ERROR mounting cache partition."
+		return 1
+	fi
+	sleep 1
+	rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s -A -X --no-specials /mnt1/ /mnt2/ >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		umount /mnt1 >> ${log_file} 2>&1
+		umount /mnt2 >> ${log_file} 2>&1
+		echo "ERROR copying cache."
+		return 1
+	fi
+	sync
+	umount /mnt1 >> ${log_file} 2>&1
+	umount /mnt2 >> ${log_file} 2>&1
+	sleep 1
+	printf "OK  "
+
+    # Install kernel
+    printf "\033[36mkernel\033[37m ... "
+    if [ "${O_BOARD}" = "xC2" ]; then
+		dd if=${andro_dest}/${ODROID_DTB} of=${DEST_CARD} seek=1504 >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR installing Android kernel (DTB)."
+			return 1
+		else
+			dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1632 >> ${log_file} 2>&1
+		fi
+    elif [ "${O_BOARD}" = "xXU" ]; then
+		dd if=${andro_dest}/${ODROID_IMAGE} of=${DEST_CARD} seek=1263 >> ${log_file} 2>&1
+	else
+		printf "not needed "
+	fi
+	if [ $? -ne 0 ]; then
+		echo "ERROR installing Android kernel."
+		return 1
+	fi
+	echo "OK"
+    sync
+    sleep 1
+
+	# Prepare for multiboot
+	printf "    Preparing for multi boot ... "
+
+	/bin/mountx -t vfat ${DEST_CARD}p1 /mnt2 >> ${log_file} 2>&1
+	if [ $? -ne 0 ]; then
+		echo "ERROR mounting userdata partition."
+		return 1
+	fi
+	sleep 1
+
+	mkdir /mnt2/multiboot >> ${log_file} 2>&1
+
+    if [ "${A_FROMDIR}" = "yes" ]; then
+        cp -rf ${andro_dest}/* /mnt2 >> ${log_file} 2>&1
+    fi
+
+	cp /multi/boot.ini.android /mnt2/multiboot >> ${log_file} 2>&1
+	[ ! -f /mnt2/multiboot/boot.ini.android ] && print "ini file? "
+
+	cp ${andro_dest}/${ODROID_DTB} /mnt2/multiboot/${ODROID_DTB}.android >> ${log_file} 2>&1
+	cp ${andro_dest}/${ODROID_IMAGE} /mnt2/multiboot/${ODROID_IMAGE}.android >> ${log_file} 2>&1
+
+	sync
+	umount /mnt2 >> ${log_file} 2>&1
+	sleep 1
+	echo "OK."
+
+    return 0
+}
+#----------------------------------------------------------------------------------------------------------------
+
+
+#-------------------------------------------------------------------------
+# Calculate partitions offsets and sizes of the linux installation image
+get_lin_partstruct() {
+	echo "==== CHECK LINUX IMAGE ====" >> ${log_file}
+    printf "    Checking Linux image ... "
+    _card_sectno=`fdisk -l ${1} | grep "Disk ${1}" | awk '{print $7}'`
+    if [ "${_card_sectno}" = "" ]; then
+        _card_sectno=`fdisk -l ${1} | grep total | awk '{print $8}'`
+    fi
+    if [ "${_card_sectno}" = "" ]; then
+        echo "ERROR: sectNo?"
+        return 1
+    fi
+    #_card_end=$(( $_card_sectno - 1024))
+
+    _card_sectsize=`fdisk -l ${1} | grep "Sector size" | awk '{print $4}'`
+    if [ "${_card_sectsize}" = "" ]; then
+        echo "ERROR: sectSize?"
+        return 1
+    fi
+
+    _partstart=`fdisk -l ${1} | grep ${1}1 | awk '{print $2}'`
+    if [ "${_partstart}" = "" ]; then
+        echo "ERROR: FATpartStart?"
+        return 1
+    fi
+    _fat_partstart=$(( $_partstart * $_card_sectsize ))
+    _partstart=`fdisk -l ${1} | grep ${1}2 | awk '{print $2}'`
+    if [ "${_partstart}" = "" ]; then
+        echo "ERROR: LINpartStart?"
+        return 1
+    fi
+    _linux_partstart=$(( $_partstart * $_card_sectsize ))
+
+    echo "OK."
+    return 0
+}
+#-------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------------------------------------------
+prepare_linux_boot() {
+	echo "==== PREPARE LINUX BOOT ====" >> ${log_file}
+    # Prepare for multi boot
+    if [ -d /mnt2/etc ]; then
+        if [ "${LINUX_FSTYPE}" = "btrfs" ] ; then
+            echo "LABEL=${label_pref}linux  /       btrfs   noatime,nodiratime,compress=lzo  0 1" > /mnt2/etc/fstab
+        else
+            echo "LABEL=${label_pref}linux  /       ext4    errors=remount-ro,noatime,nodiratime  0 1" > /mnt2/etc/fstab
+        fi
+        echo "LABEL=${label_pref}userdata   /media/boot vfat    defaults        0   1" >> /mnt2/etc/fstab
+
+		if [ -f /mnt2/etc/rc.local ]; then
+			cat /mnt2/etc/rc.local | sed "s/^exit 0//g" > _rcloc_
+			if [ -f /mnt2/.first_boot ]; then
+				echo "if [ -f /.first_boot ]; then" >> _rcloc_
+				echo "  rm -f /.first_boot" >> _rcloc_
+				echo "  [ ! -f /etc/ssh/ssh_host_rsa_key ] && dpkg-reconfigure openssh-server" >> _rcloc_
+				echo "fi" >> _rcloc_
+			fi
+			echo "exit 0" >> _rcloc_
+			cp _rcloc_ /mnt2/etc/rc.local
+			rm _rcloc_
+			chmod 0755 /mnt2/etc/rc.local
+			if [ -f /mnt2/aafirstboot ]; then
+				rm -f /mnt2/aafirstboot
+			fi
+		fi
+    else
+        echo "ERROR: \"etc\" directory not found!"
+        return 1
+    fi
+
+    if [ -d /mnt2/media/odroid ]; then
+		chown 1000:1000 /mnt2/media/odroid >> ${log_file} 2>&1
+		chmod 0666 /mnt2/media/odroid >> ${log_file} 2>&1
+    fi
+
+	return 0
+}
+#----------------------------------------------------------------------------------------------------------------------------
+
+
+#----------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2050
+install_linux() {
+	echo "==== INSTALL LINUX ====" >> ${log_file}
+
+	local lin_fromdir="no"
+	if [ "${1}" = "linux.img" ] && [ "${L_FROMDIR}" = "yes" ]; then
+		lin_fromdir="yes"
+	elif [ "${1}" = "linux2.img" ] && [ "${L2_FROMDIR}" = "yes" ]; then
+		lin_fromdir="yes"
+	fi
+
+	if [ "${1}" = "linux2.img" ]; then
+		printf "\n    \033[33mInstalling \033[1mLinux 2\033[22m\033[37m\n"
+	else
+		printf "\n    \033[33mInstalling \033[1mLinux\033[22m\033[37m\n"
+	fi
+
+	if [ "${lin_fromdir}" = "no" ]; then
+		get_lin_partstruct "/mnt/${1}"
+		if [ $? -ne 0 ]; then
+			printf "    \033[35mWRONG Linux image partition structure!\033[37m\n"
+			return 1
+		fi
+		sleep 1
+	fi
+
+    mkdir /mnt1 >> ${log_file} 2>&1
+    mkdir /mnt2 >> ${log_file} 2>&1
+
+    local _linpart="p7"
+    local _linsufix=""
+    if [ "${1}" = "linux2.img" ]; then
+		_linpart="p8"
+		_linsufix="2"
+	fi
+
+    # === Copy Linux partition ===
+	printf "    \033[35mcopying Linux can take more than 15 min to complete on SDCard!\033[37m\n"
+    printf "    Installing Linux root file system ... "
+
+    if [ "${lin_fromdir}" = "no" ]; then
+		/bin/mountx -t ext4 -o ro,loop,offset=${_linux_partstart} ${source_mount}/${1} /mnt1
+		if [ $? -ne 0 ]; then
+			echo "    ERROR mounting Linux source image."
+			return 1
+		fi
+	else
+		/bin/mountx -t ext4 ${source_mount}/${BKP_PREFIX}_backup/linux${_linsufix}/linux.img /mnt1
+		if [ $? -ne 0 ]; then
+			echo "    ERROR mounting Linux backup image."
+			return 1
+		fi
+	fi
+
+    if [ "${LINUX_FSTYPE}" = "btrfs" ] ; then
+        /bin/mountx -t btrfs -o compress-force=lzo ${DEST_CARD}${_linpart} /mnt2
+    else
+        /bin/mountx -t ext4 ${DEST_CARD}${_linpart} /mnt2
+    fi
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        echo "    ERROR mounting Linux destination partition."
+        return 1
+    fi
+
+    printf "copying... "
+    rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s --stats /mnt1/ /mnt2/ >> ${log_file} 2>&1
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        umount /mnt2 >> ${log_file} 2>&1
+        echo "ERROR copying Linux."
+        return 1
+    fi
+    sync
+
+    printf "preparing... "
+    prepare_linux_boot
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        umount /mnt2 >> ${log_file} 2>&1
+        return 1
+    fi
+
+    umount /mnt1 >> ${log_file} 2>&1
+    umount /mnt2 >> ${log_file} 2>&1
+    sleep 1
+    echo "OK"
+
+    # === Update userdata partition for Linux multiboot ===
+    printf "    Copying Linux boot files ... "
+
+    local boot_src="/mnt1"
+    if [ "${lin_fromdir}" = "no" ]; then
+		/bin/mountx -t vfat -o ro,loop,offset=${_fat_partstart} ${source_mount}/${1} /mnt1
+		if [ $? -ne 0 ]; then
+			echo "ERROR mounting Linux boot image."
+			return 1
+		fi
+	else
+		boot_src="${source_mount}/${BKP_PREFIX}_backup/linux${_linsufix}"
+	fi
+
+    /bin/mountx -t vfat ${DEST_CARD}p1 /mnt2 >> ${log_file} 2>&1
+    if [ $? -ne 0 ]; then
+        umount /mnt1 >> ${log_file} 2>&1
+        echo "ERROR mounting boot partition."
+        return 1
+    fi
+	sync
+    sleep 1
+
+    # Prepare boot.ini
+    if [ -f ${boot_src}/${ODROID_DTB} ] && [ -f ${boot_src}/${ODROID_IMAGE} ] && [ -f ${boot_src}/uInitrd ]; then
+		mkdir /mnt2/multiboot >> ${log_file} 2>&1
+		cp /multi/boot.ini.linux${_linsufix} /mnt2/multiboot/boot.ini.linux${_linsufix}
+		cat /mnt2/multiboot/boot.ini.linux${_linsufix} | sed "s/root=LABEL=XXlinux/root=LABEL=${label_pref}linux/g"  > _bini_
+		cp _bini_ /mnt2/multiboot/boot.ini.linux${_linsufix}
+		cp ${boot_src}/${ODROID_DTB} /mnt2/multiboot/${ODROID_DTB}.linux${_linsufix} >> ${log_file} 2>&1
+		cp ${boot_src}/${ODROID_IMAGE} /mnt2/multiboot/${ODROID_IMAGE}.linux${_linsufix} >> ${log_file} 2>&1
+		cp ${boot_src}/uInitrd /mnt2/multiboot/uInitrd.linux${_linsufix} >> ${log_file} 2>&1
+        rm _bini_ >> ${log_file} 2>&1
+
+    else
+        echo "ERROR: not all Linux boot files found! "
+		umount /mnt1 >> ${log_file} 2>&1
+		umount /mnt2 >> ${log_file} 2>&1
+		return 1
+    fi
+
+    umount /mnt1 >> ${log_file} 2>&1
+    umount /mnt2 >> ${log_file} 2>&1
+    sleep 1
+    echo "OK"
+}
+#----------------------------------------------------------------------------------------------------------
+
+
+#------------------------------------------------------------------------------------------------------------------------------------------------------
+# shellcheck disable=SC2059
+install_oelec() {
+	echo "==== INSTALL OpenElec ====" >> ${log_file}
+	printf "\n    \033[33mInstalling \033[1mOpenELEC\033[22m\033[37m\n"
+
+	_oelec_source="/run/oelec"
+
+	if [ "${O_FROMDIR}" = "yes" ]; then
+		_name="${source_mount}/${BKP_PREFIX}_backup/oelec"
+
+		if [ -f ${_name}/oelec.img ]; then
+			printf "    Restoring oelec partition... "
+			mkdir /oelecbkp >> ${log_file} 2>&1
+			/bin/mountx -t ext4 ${_name}/oelec.img /oelecbkp >> ${log_file} 2>&1
+			if [ $? -eq 0 ]; then
+				/bin/mountx ${DEST_CARD}p6 /mnt2 > /dev/null 2>&1
+				if [ $? -eq 0 ]; then
+					rsync -r -t -p -o -g -x -l -H -D --numeric-ids -s --stats /oelecbkp/ /mnt2/ > /dev/null 2>&1
+					if [ $? -ne 0 ]; then
+						echo "ERROR: copy"
+					else
+						echo "OK"
+					fi
+				fi
+			else
+				echo "ERROR: mount"
+			fi
+			umount /oelecbkp >> ${log_file} 2>&1
+			umount /mnt2 >> ${log_file} 2>&1
+			rmdir /oelecbkp >> ${log_file} 2>&1
+		fi
+	else
+		_ramfs_free=$(df | grep tmpfs | awk '{print $4}')
+		_ramfs_free=$(( $_ramfs_free / 1024 - 100 ))
+		_tarsize_=$(/bin/tar -vtf ${source_mount}/oelec.tar |awk '{SUM += $3} END {print SUM}')
+		_tarsize_=$(( $_tarsize_ / 1024 / 1024 ))
+
+		printf "    Unpacking archive "
+		if [ $_tarsize_ -lt $_ramfs_free ]; then
+			mkdir /run/oelec >> ${log_file} 2>&1
+			printf "to RAMfs  (${_tarsize_}M) ... "
+		else
+			mkdir ${source_mount}/tmp_oelec >> ${log_file} 2>&1
+			_oelec_source="${source_mount}/tmp_oelec"
+			printf "to source drive  (${_tarsize_}M) ... "
+		fi
+		rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+
+		cd ${_oelec_source}
+		/bin/tar -xf ${source_mount}/oelec.tar --warning=no-timestamp >> ${log_file} 2>&1
+		if [ $? -ne 0 ]; then
+			echo "ERROR extracting archive."
+			cd /
+			rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+			return 1
+		fi
+		_name=$(ls)
+		echo "OK."
+	fi
+
+	printf "    Copying files from %s ... " "${_name}"
+	if [ ! -f ${_name}/3rdparty/bootloader/${ODROID_DTB} ]; then
+		echo "ERROR: ${ODROID_DTB} not found!"
+		cd /
+		[ ! "${O_FROMDIR}" = "yes" ] && rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+		return 1
+	fi
+	if [ ! -f ${_name}/target/KERNEL ] || [ ! -f ${_name}/target/SYSTEM ]; then
+		echo "ERROR SYSTEM or KERNEL not found"
+		cd /
+		[ ! "${O_FROMDIR}" = "yes" ] && rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+		return 1
+	fi
+	if [ ! "${O_BOARD}" = "C2" ]; then
+		if [ ! -f ${_name}/target/INITRD ]; then
+			echo "ERROR: INITRD not found!"
+			cd /
+			[ ! "${O_FROMDIR}" = "yes" ] && rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+			return 1
+		fi
+	fi
+	echo "OK."
+
+    # Update userdata partition for OpenELEC multiboot
+	printf "    Copying OpenELEC files ... "
+    /bin/mountx -t vfat ${DEST_CARD}p1 /mnt2 >> ${log_file} 2>&1
+    if [ $? -ne 0 ]; then
+        echo "ERROR mounting boot partition."
+		[ ! "${O_FROMDIR}" = "yes" ] && rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+        return 1
+    fi
+    sleep 1
+
+    mkdir /mnt2/multiboot >> ${log_file} 2>&1
+
+    #cp /multi/INITRD /mnt2/multiboot
+	cp ${_name}/target/KERNEL /mnt2/multiboot
+	if [ ! "${O_BOARD}" = "C2" ]; then
+		cp ${_name}/target/INITRD /mnt2/multiboot
+	fi
+	cp ${_name}/target/SYSTEM /mnt2
+	cp ${_name}/3rdparty/bootloader/${ODROID_DTB} /mnt2/multiboot/${ODROID_DTB}.oelec
+
+    cd /
+
+	cp /multi/boot.ini.oelec /mnt2/multiboot
+	cat /mnt2/multiboot/boot.ini.oelec | sed "s/boot=LABEL=userdata disk=LABEL=oelec/boot=LABEL=${label_pref}userdata disk=LABEL=${label_pref}aux/g" > _bsel_
+	cp _bsel_ /mnt2/multiboot/boot.ini.oelec
+	rm _bsel_
+	sync
+
+    umount /mnt2 >> ${log_file} 2>&1
+    echo "OK."
+
+	[ ! "${O_FROMDIR}" = "yes" ] && rm -rf ${_oelec_source:?}/* >> ${log_file} 2>&1
+	return 0
+}
+#------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+#-----------------------------------------------------------------------------------------------------------------
+check_inst() {
+	# INSTALLATION DRIVE IS MOUNTED ON /MNT
+	if [ "${INST_ANDROID}" != "yes" ] && [ "${INST_LINUX}" != "yes" ]; then
+		printf "    \033[33m\033[1mNo installation file found!\033[22m\033[37m\n"
+		printf "    \033[33m\033[1mTo install from image\033[22m\033[37m\n"
+		printf "    \033[33m\033[1m\"update.zip\" and/or \"linux.img\" must be on source drive.\033[22m\033[37m\n"
+		printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n"
+		umount ${source_mount} > /dev/null 2>&1
+		exit_script
+	fi
+}
+#-----------------------------------------------------------------------------------------------------------------
+
+
+# ====================================================================================================
+# START
+# ====================================================================================================
+
+set_cardsize
+print_header
+
+check_inst
+
+#----------------------------------------------------------------
+if [ "${INST_ANDROID}" = "yes" ]; then
+	if [ "${A_FROMDIR}" = "yes" ]; then
+		check_android_backup
+		if [ $? -ne 0 ]; then
+			echo "    ANDROID won't be installed!"
+			INST_ANDROID="no"
+			if [ "${INST_LINUX}" = "yes" ] && [ "${INST_ANDROID}" != "yes" ] && [ "${INST_OELEC}" != "yes" ] && [ "${INST_LINUX2}" != "yes" ]; then
+				ONLY_LINUX="yes"
+				MULTI_BOOT="no"
+			fi
+			if [ "${INST_ANDROID}" = "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
+				ONLY_ANDROID="yes"
+				MULTI_BOOT="no"
+			fi
+			sleep 1
+		fi
+	else
+		echo "==== UNPACK AND DECOMPRESS ANDROID IMAGES ====" >> ${log_file}
+		# Unpack and decompress android install images to RAM or disk
+		unpack_android
+		if [ $? -ne 0 ]; then
+			echo "    ANDROID won't be installed!"
+			INST_ANDROID="no"
+			if [ "${INST_LINUX}" = "yes" ] && [ "${INST_ANDROID}" != "yes" ] && [ "${INST_OELEC}" != "yes" ] && [ "${INST_LINUX2}" != "yes" ]; then
+				ONLY_LINUX="yes"
+				MULTI_BOOT="no"
+			fi
+			if [ "${INST_ANDROID}" = "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
+				ONLY_ANDROID="yes"
+				MULTI_BOOT="no"
+			fi
+			sleep 1
+		fi
+		rm -rf rm ${source_mount}/android/* >> ${log_file} 2>&1
+		rmdir rm ${source_mount}/android >> ${log_file} 2>&1
+	fi
+    sleep 2
+fi
+#----------------------------------------------------------------
+
+print_header
+check_inst
+print_settings
+
+#---- Main menu -------------------
+_inst_delay=${INST_DELAY}
+
+# shellcheck disable=SC2059
+while [ $_inst_delay -gt 0 ]; do
+    [ $INST_DELAY -lt 60 ] && printf "    Auto start install in $_inst_delay sec       \r"
+    A="z"
+    if read -n 1 -t 1 -s A; then
+		_inst_delay=${INST_DELAY}
+		if [ "${A}" = "1" ] && [ "${TWO_CARDS}" = "yes" ]; then
+			print_header
+			set_dest
+			print_header
+			print_settings
+		elif [ "${A}" = "2" ] && [ "${INST_LINUX}" = "yes" ]; then
+			print_header
+			set_userdatasize
+			print_header
+			print_settings
+		elif [ "${A}" = "3" ] && [ "${INST_ANDROID}" = "yes" ]; then
+			print_header
+			set_systemsize
+			print_header
+			print_settings
+		elif [ "${A}" = "4" ] && [ "${INST_ANDROID}" = "yes" ]; then
+			print_header
+			set_datasize
+			print_header
+			print_settings
+		elif [ "${A}" = "5" ] && [ "${INST_ANDROID}" = "yes" ]; then
+			print_header
+			set_cachesize
+			print_header
+			print_settings
+		elif [ "${A}" = "6" ] && [ "${MULTI_BOOT}" = "yes" ]; then
+			print_header
+			set_oelecsize
+			print_header
+			print_settings
+		elif [ "${A}" = "t" ] && [ "${INST_LINUX}" = "yes" ]; then
+			print_header
+			set_linfstype
+			print_header
+			print_settings
+		elif [ "${A}" = "E" ]; then
+			echo ""
+			_reboot_delay=10
+			while [ $_reboot_delay -gt 0 ]; do
+				printf "    \033[33m\033[1mEXIT in $_reboot_delay sec, press \033[22ma\033[1m to abort, \033[22me\033[1m to exit \033[22m\033[37m\r"
+				if read -n 1 -t 1 -s B; then
+					_reboot_delay=10
+					if [ "${B}" = "a" ] || [ "${B}" = "A" ]; then
+						break
+					elif [ "${B}" = "e" ] || [ "${B}" = "E" ]; then
+						_reboot_delay=0
+						break
+					fi
+				else
+					let _reboot_delay=_reboot_delay-1
+				fi
+			done
+			if [ $_reboot_delay -eq 0 ]; then
+				umount ${source_mount} > /dev/null 2>&1
+				exit 0
+			else
+				print_header
+				print_settings
+			fi
+		elif [ "${A}" = "I" ]; then
+			echo ""
+			_reboot_delay=15
+			while [ $_reboot_delay -gt 0 ]; do
+				printf "    \033[31m\033[1mWARNING: !! ALL DATA ON ${DEST_EMMC} CARD WILL BE ERASED !!, PRESS Y TO CONTINUE\033[22m\033[37m\r"
+				B="Z"
+				if read -n 1 -t 1 -s B; then
+					break
+				else
+					let _reboot_delay=_reboot_delay-1
+				fi
+			done
+			if [ "${B}" = "Y" ]; then
+				break
+			else
+				print_header
+				print_settings
+			fi
+		elif [ "${A}" = "s" ]; then
+			# SCREENSHOT ===
+			fbcat > /install.ppm
+		fi
+    else
+		[ $INST_DELAY -lt 60 ] && let _inst_delay=_inst_delay-1
+    fi
+done
+
+
+# --- Set partition label prefix ---
+if [ "${DEST_EMMC}" = "EMMC" ]; then
+    label_pref="em"
+else
+    label_pref="sd"
+fi
+
+if [ "${INST_ANDROID}" != "yes" ] && [ "${INST_LINUX}" != "yes" ] && [ "${INST_OELEC}" != "yes" ]; then
+    printf "    \033[33m\033[1mNothing to install!\033[22m\033[37m\n"
+    printf "    \033[33m\033[1mAndroid or Linux must be installed!\033[22m\033[37m\n"
+    printf "    \033[33m\033[1mInstallation aborted.\033[22m\033[37m\n"
+	umount ${source_mount} > /dev/null 2>&1
+	exit_script
+fi
+# --------------------------------------------------------------------------------------------------------------------
+
+# --- Set partitions sizes ---------
+get_partsizes
+
+sleep 1
+print_header
+
+# --- Partition and format the card ----------------------------
+prepare_card
+if [ $? -ne 0 ]; then
+    printf "    \033[35mERROR PREPARING SD/EMMC CARD!\033[37m\n"
+else
+	# shellcheck disable=SC2059
+	# install bootloader
+	if [ "${O_BOARD}" = "C2" ]; then
+		install_boot_c2
+	else
+		install_boot_xu
+	fi
+	if [ $? -eq 0 ]; then
+		if [ "${INST_ANDROID}" = "yes" ]; then
+			# --- Install Android ---
+			install_android
+			if [ $? -ne 0 ]; then
+				printf "    \033[35mERROR INSTALLING ANDROID!\033[37m\n"
+			else
+				printf "    \033[36mAndroid PREPARED!\033[37m\n"
+				printf "    \033[35mFIRST BOOT CAN TAKE MORE THAN 5 MIN TO COMPLETE!\033[37m\n"
+			fi
+			rm -rf /run/inst/android/* >> ${log_file} 2>&1
+			rmdir /run/inst/android >> ${log_file} 2>&1
+		fi
+
+		if [ "${INST_LINUX}" = "yes" ]; then
+			# --- Install Linux ---
+			install_linux "linux.img"
+			if [ $? -ne 0 ]; then
+				printf "    \033[35mERROR INSTALLING LINUX!\033[37m\n"
+			else
+				printf "    \033[36mLinux PREPARED!\033[37m\n"
+			fi
+		fi
+
+		if [ "${INST_LINUX2}" = "yes" ]; then
+			# --- Install Linux ---
+			install_linux "linux2.img"
+			if [ $? -ne 0 ]; then
+				printf "    \033[35mERROR INSTALLING LINUX 2!\033[37m\n"
+			else
+				printf "    \033[36mLinux 2 PREPARED!\033[37m\n"
+			fi
+		fi
+
+		if [ "${INST_OELEC}" = "yes" ]; then
+			# --- Install OpenELEC ---
+			install_oelec
+			if [ $? -ne 0 ]; then
+				printf "    \033[35mERROR INSTALLING OpenELEC!\033[37m\n"
+			else
+				printf "    \033[36mOpenELEC PREPARED!\033[37m\n"
+			fi
+		fi
+
+		printf "\n    \033[33mInstalling \033[1mMulti Boot support\033[22m\033[37m\n"
+		install_multi_sel
+		if [ $? -ne 0 ]; then
+			printf "    \033[35mERROR INSTALLING Multi Boot!\033[37m\n"
+		else
+			printf "    \033[36m%s CARD PREPARED FOR MULTI BOOT!\033[37m\n" "${DEST_EMMC}"
+		fi
+		umount /mnt2 >> ${log_file} 2>&1
+	fi
+fi
+
+echo ""
+umount ${source_mount} > /dev/null 2>&1
+
+exit_script
+
+reboot