aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh
blob: d3da22d496e1fb916374392e0633d815d16747b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
REQUIRE_IMAGE_METADATA=1

# Full system upgrade including preloader for MediaTek SoCs on eMMC or SD
mtk_mmc_full_upgrade() {
	local diskdev partdev diff oldrecovery

	if grep -q root=/dev/mmcblk0p2 /proc/cmdline; then
	    oldrecovery=1
	else
	    oldrecovery=2
	fi

	export_bootdevice && export_partdevice diskdev 0 || {
		echo "Unable to determine upgrade device"
		return 1
	}

	#Keep the persistent random mac address (if it exists)
	mkdir -p /tmp/recovery
	export_partdevice recoverydev $oldrecovery
	if mount -o rw,noatime "/dev/$recoverydev" -tvfat /tmp/recovery; then
		[ -f "/tmp/recovery/mac_addr" ] && cp /tmp/recovery/mac_addr /tmp/
		umount /tmp/recovery
	fi
	sync

	if [ "$SAVE_PARTITIONS" = "1" ]; then
		get_partitions "/dev/$diskdev" bootdisk

		#extract the boot sector from the image
		get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b

		get_partitions /tmp/image.bs image

		#compare tables
		diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
	else
		diff=1
	fi

	if [ -n "$diff" ]; then
		get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync

		# Separate removal and addition is necessary; otherwise, partition 1
		# will be missing if it overlaps with the old partition 2
		partx -d - "/dev/$diskdev"
		partx -a - "/dev/$diskdev"
	else
		# iterate over each partition from the image and write it to the boot disk
		while read part start size; do
			part="$(($part - 2))"
			if export_partdevice partdev $part; then
				echo "Writing image to /dev/$partdev..."
				get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
			else
			    echo "Unable to find partition $part device, skipped."
			fi
		done < /tmp/partmap.image

		#copy partition uuid
		echo "Writing new UUID to /dev/$diskdev..."
		get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
	fi

	export_partdevice recoverydev 2
	if mount -o rw,noatime "/dev/$recoverydev" -t vfat /tmp/recovery; then
		[ -f "/tmp/mac_addr" ] && cp /tmp/mac_addr /tmp/recovery

		if [ "$diskdev" = "mmcblk0" -a -r /tmp/recovery/eMMCboot.bin ]; then
			echo 0 > /sys/block/mmcblk0boot0/force_ro
			dd if=/tmp/recovery/eMMCboot.bin of=/dev/mmcblk0boot0 conv=fsync
			sync
			echo 1 > /sys/block/mmcblk0boot0/force_ro
		fi
		sync
		umount /tmp/recovery
	fi
}

platform_do_upgrade() {
	local board=$(board_name)

	case "$board" in
	bananapi,bpi-r2)
		mtk_mmc_full_upgrade "$1"
		;;

	unielec,u7623-02-emmc-512m)
		local magic="$(get_magic_long "$1")"
		if [ "$magic" = "53444d4d" ]; then
			mtk_mmc_full_upgrade "$1"
		else # Old partial image starting with uImage
			# Keep the persistent random mac address (if it exists)
			recoverydev=mmcblk0p1
			mkdir -p /tmp/recovery
			mount -o rw,noatime /dev/$recoverydev /tmp/recovery
			[ -f "/tmp/recovery/mac_addr" ] && \
				mv -f /tmp/recovery/mac_addr /tmp/
			umount /tmp/recovery

			# 1310720 is the offset in bytes from the start of eMMC and to
			# the location of the kernel (2560 512 byte sectors)
			get_image "$1" | dd of=/dev/mmcblk0 bs=1310720 seek=1 conv=fsync

			mount -o rw,noatime /dev/$recoverydev /tmp/recovery
			[ -f "/tmp/mac_addr" ] && mv -f /tmp/mac_addr /tmp/recovery
			sync
			umount /tmp/recovery
		fi
		;;
	*)
		default_do_upgrade "$1"
		;;
	esac
}

PART_NAME=firmware

platform_check_image() {
	local board=$(board_name)
	local magic="$(get_magic_long "$1")"
	local diskdev partdev diff

	[ "$#" -gt 1 ] && return 1

	case "$board" in
	bananapi,bpi-r2)
		[ "$magic" != "53444d4d" ] && {
			echo "Invalid image type."
			return 1
		}
		export_bootdevice && export_partdevice diskdev 0 || {
			echo "Unable to determine upgrade device"
			return 1
		    }

		get_partitions "/dev/$diskdev" bootdisk

		#extract the boot sector from the image
		get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null

		get_partitions /tmp/image.bs image

		#compare tables
		diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"

		rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image

		if [ -n "$diff" ]; then
			echo "Partition layout has changed. Full image will be written."
			ask_bool 0 "Abort" && exit 1
			return 0
		fi
		;;
	unielec,u7623-02-emmc-512m)
		# Can always upgrade to the new-style full image
		[ "$magic" = "53444d4d" ] && return 0

		# Legacy uImage directly at 0xA00 on the eMMC.
		[ "$magic" != "27051956" ] && {
			echo "Invalid image type."
			return 1
		}
		rootpart=$(cat /proc/cmdline)
		rootpart="${rootpart##*root=}"
		rootpart="${rootpart%% *}"
		[ "$rootpart" != "/dev/mmcblk0p2" ] && {
			echo "Cannot downgrade to legacy image."
			return 1
		}
		return 0
		;;
	*)
		echo "Sysupgrade is not supported on your board yet."
		return 1
		;;
	esac

	return 0
}

platform_copy_config() {
	case "$(board_name)" in
	bananapi,bpi-r2|\
	unielec,u7623-02-emmc-512m)
		# platform_do_upgrade() will have set $recoverydev
		if [ -n "$recoverydev" ]; then
			mkdir -p /tmp/recovery
			mount -o rw,noatime "/dev/$recoverydev" -t vfat /tmp/recovery
			cp -af "$UPGRADE_BACKUP" "/tmp/recovery/$BACKUP_FILE"
			sync
			umount /tmp/recovery
		fi
		;;
	esac
}