aboutsummaryrefslogtreecommitdiff
path: root/target/linux/ipq40xx/base-files/lib/upgrade/linksys.sh
blob: 860c3fd2de997a271d62df92318bdc677c98ec82 (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
linksys_get_target_firmware() {
	local cur_boot_part mtd_ubi0

	cur_boot_part="$(/usr/sbin/fw_printenv -n boot_part)"
	if [ -z "${cur_boot_part}" ]; then
		mtd_ubi0=$(cat /sys/class/ubi/ubi0/mtd_num)
		case "$(grep -E "^mtd${mtd_ubi0}:" /proc/mtd | cut -d '"' -f 2)" in
		kernel|rootfs)
			cur_boot_part=1
			;;
		alt_kernel|alt_rootfs)
			cur_boot_part=2
			;;
		esac
		>&2 printf "Current boot_part='%s' selected from ubi0/mtd_num='%s'" \
			"${cur_boot_part}" "${mtd_ubi0}"
	fi

	# OEM U-Boot for EA6350v3, EA8300 and MR8300; bootcmd=
	#  if test $auto_recovery = no;
	#      then bootipq;
	#  elif test $boot_part = 1;
	#      then run bootpart1;
	#      else run bootpart2;
	#  fi

	case "$cur_boot_part" in
	1)
		fw_setenv -s - <<-EOF
			boot_part 2
			auto_recovery yes
		EOF
		printf "alt_kernel"
		return
		;;
	2)
		fw_setenv -s - <<-EOF
			boot_part 1
			auto_recovery yes
		EOF
		printf "kernel"
		return
		;;
	*)
		return
		;;
	esac
}

linksys_is_factory_image() {
	local board=$(board_name)
	board=${board##*,}

	# check matching footer signature
	tail -c 256 $1 | grep -q -i "\.LINKSYS\.........${board}"
}

platform_do_upgrade_linksys() {
	local magic_long="$(get_magic_long "$1")"

	local rm_oem_fw_vols="squashfs ubifs"	# from OEM [alt_]rootfs UBI
	local vol

	mkdir -p /var/lock
	local part_label="$(linksys_get_target_firmware)"
	touch /var/lock/fw_printenv.lock

	if [ -z "$part_label" ]; then
		echo "cannot find target partition"
		exit 1
	fi

	local target_mtd=$(find_mtd_part "$part_label")

	[ "$magic_long" = "73797375" ] && {
		CI_KERNPART="$part_label"
		if [ "$part_label" = "kernel" ]; then
			CI_UBIPART="rootfs"
		else
			CI_UBIPART="alt_rootfs"
		fi

		local mtdnum="$(find_mtd_index "$CI_UBIPART")"
		if [ ! "$mtdnum" ]; then
			echo "cannot find ubi mtd partition $CI_UBIPART"
			return 1
		fi

		local ubidev="$(nand_find_ubi "$CI_UBIPART")"
		if [ ! "$ubidev" ]; then
			ubiattach -m "$mtdnum"
			sync
			ubidev="$(nand_find_ubi "$CI_UBIPART")"
		fi

		if [ "$ubidev" ]; then
			for vol in $rm_oem_fw_vols; do
				ubirmvol "/dev/$ubidev" -N "$vol" 2>/dev/null
			done
		fi

		# complete std upgrade
		if nand_upgrade_tar "$1" ; then
			nand_do_upgrade_success
		else
			nand_do_upgrade_failed
		fi

	}

	[ "$magic_long" = "27051956" ] && {
		echo "writing \"$1\" image to \"$part_label\""
		get_image "$1" | mtd write - "$part_label"
	}

	[ "$magic_long" = "d00dfeed" ] && {
		if ! linksys_is_factory_image "$1"; then
			echo "factory image doesn't match device"
			return 1
		fi

		echo "writing \"$1\" factory image to \"$part_label\""
		get_image "$1" | mtd -e "$part_label" write - "$part_label"
	}
}

linksys_get_cmdline_rootfs_device() {
	if read cmdline < /proc/cmdline; then
		case "$cmdline" in
		*root=*)
			local str="${cmdline##*root=}"
			echo "${str%% *}"
			return
			;;
		esac
	fi
	return 1
}

linksys_get_current_boot_part_emmc() {
	local boot_part="$(fw_printenv -n boot_part)"
	if [ "$boot_part" = 1 ] || [ "$boot_part" = 2 ]; then
		v "Current boot_part=$boot_part selected from bootloader environment"
	else
		local rootfs_device="$(linksys_get_cmdline_rootfs_device)"
		if [ "$rootfs_device" = "$(find_mmc_part "rootfs")" ]; then
			boot_part=1
		elif [ "$rootfs_device" = "$(find_mmc_part "alt_rootfs")" ]; then
			boot_part=2
		else
			v "Could not determine current boot_part"
			return 1
		fi
		v "Current boot_part=$boot_part selected from cmdline rootfs=$rootfs_device"
	fi
	echo $boot_part
}

linksys_set_target_partitions_emmc() {
	local current_boot_part="$1"

	if [ "$current_boot_part" = 1 ]; then
		CI_KERNPART="alt_kernel"
		CI_ROOTPART="alt_rootfs"
		fw_setenv -s - <<-EOF
			boot_part 2
			auto_recovery yes
		EOF
	elif [ "$current_boot_part" = 2 ]; then
		CI_KERNPART="kernel"
		CI_ROOTPART="rootfs"
		fw_setenv -s - <<-EOF
			boot_part 1
			auto_recovery yes
		EOF
	else
		v "Could not set target eMMC partitions"
		return 1
	fi

	v "Target eMMC partitions: $CI_KERNPART, $CI_ROOTPART"
}

platform_do_upgrade_linksys_emmc() {
	local file="$1"

	mkdir -p /var/lock
	local current_boot_part="$(linksys_get_current_boot_part_emmc)"
	linksys_set_target_partitions_emmc "$current_boot_part" || exit 1
	touch /var/lock/fw_printenv.lock

	emmc_do_upgrade "$file"
}