aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/base-files/lib/upgrade/uDPU.sh
blob: f87ff4f9ca0550f0f25955b392ca0616ffa1d280 (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
udpu_check_emmc() {
# uDPU uses combined ext4 and f2fs partitions.
# partition layout:
#	1. boot	(ext4)
#	2. recovery  (ext4)
#	3. rootfs (f2fs)
#	4. misc (f2fs)

	# Check which device is available, depending on the board revision
	if [ -b "/dev/mmcblk1" ]; then
		emmc_dev=/dev/mmcblk1
	elif [ -b "/dev/mmcblk0" ]; then
		emmc_dev=/dev/mmcblk0
	else
		echo "Cannot detect eMMC flash, aborting.."
		exit 1
	fi
}

udpu_part_prep() {
	 if [ "$(grep $1 /proc/mounts)" ]; then
		mounted_part="$(grep $1 /proc/mounts | awk '{print $2}' | head -1)"
		umount $mounted_part
		[ "$(grep -wo $mounted_part /proc/mounts)" ] && umount -l $mounted_part
	fi
}

udpu_do_part_check() {
	local emmc_parts="1 2 3 4"
	local part_valid="1"

	# Check if the block devices exist
	for num in ${emmc_parts}; do
		[[ ! -b ${emmc_dev}p${num} ]] && part_valid="0"
	done

	# If partitions are missing create a new partition table
	if [ "$part_valid" != "1" ]; then
		printf "Invalid partition table, creating a new one\n"
		printf "o\nn\np\n1\n\n+256M\nn\np\n2\n\n+256M\nn\np\n3\n\n+1536M\nn\np\n\n\nw\n" | fdisk -W always $emmc_dev  > /dev/null 2>&1

		# Format the /misc part right away as we will need it for the firmware
		printf "Formating /misc partition, this make take a while..\n"
		udpu_part_prep ${emmc_dev}p4
		mkfs.f2fs -q -l misc ${emmc_dev}p4
		[ $? -eq 0 ] && printf "/misc partition formated successfully\n" || printf "/misc partition formatting failed\n"

		udpu_do_initial_setup
	else
		printf "Partition table looks ok\n"
	fi
}

udpu_do_misc_prep() {
	if [ ! "$(grep -wo /misc /proc/mounts)" ]; then
		mkdir -p /misc
		mount ${emmc_dev}p4 /misc

		# If the mount fails, try to reformat partition
		# Leaving possiblity for multiple iterations
		if [ $? -ne 0 ]; then
			printf "Error while mounting /misc, trying to reformat..\n"

			format_count=0
			while [ "$format_count" -lt "1" ]; do
				udpu_part_prep ${emmc_dev}p4
				mkfs.f2fs -q -l misc ${emmc_dev}p4
				mount ${emmc_dev}p4 /misc
				if [ $? -ne 0 ]; then
					umount -l /misc
					printf "Failed while mounting /misc\n"
					format_count=$((format_count +1))
				else
					printf "Mounted /misc successfully\n"
					break
				fi
			done
		fi
	fi
}

udpu_do_initial_setup() {
	# Prepare /recovery parition
	udpu_part_prep ${emmc_dev}p2
	mkfs.ext4 -q ${emmc_dev}p2 | echo y &> /dev/null

	# Prepare /boot partition
	udpu_part_prep ${emmc_dev}p1
	mkfs.ext4 -q ${emmc_dev}p1 | echo y &> /dev/null

	# Prepare /root partition
	printf "Formating /root partition, this may take a while..\n"
	udpu_part_prep ${emmc_dev}p3
	mkfs.f2fs -q -l rootfs ${emmc_dev}p3
	[ $? -eq 0 ] && printf "/root partition reformated\n"
}

udpu_do_regular_upgrade() {
	# Clean /boot partition - mfks.ext4 is not available in chroot
	[ "$(grep -wo /boot /proc/mounts)" ] && umount /boot
	mkdir -p /tmp/boot
	mount ${emmc_dev}p1 /tmp/boot
	rm -rf /tmp/boot/*

	# Clean /root partition - mkfs.f2fs is not available in chroot
	[ "$(grep -wo /dev/root /proc/mounts)" ] && umount /
	mkdir -p /tmp/rootpart
	mount ${emmc_dev}p3 /tmp/rootpart
	rm -rf /tmp/rootpart/*
}

platform_do_upgrade_uDPU() {
	udpu_check_emmc

	# Prepare and extract firmware on /misc partition
	udpu_do_misc_prep

	[ -f "/misc/firmware" ] && rm -r /misc/firmware
	mkdir -p /misc/firmware
	tar xzf "$1" -C /misc/firmware/

	udpu_do_regular_upgrade

	printf "Updating /boot partition\n"
	tar xzf /misc/firmware/boot.tgz -C /tmp/boot
	[ $? -eq 0 ] && printf "/boot partition updated successfully\n" || printf "/boot partition update failed\n"
	sync

	printf "Updating /root partition\n"
	tar xzf /misc/firmware/rootfs.tgz -C /tmp/rootpart
	[ $? -eq 0 ] && printf "/root partition updated successfully\n" || printf "/root partition update failed\n"
	sync

	# Saving configuration files over sysupgrade
	platform_copy_config_uDPU

	# Remove tmp mounts
	tmp_parts=$(grep "${emmc_dev}" /proc/mounts | awk '{print $2}')
	for part in ${tmp_parts}; do
		umount $part
		# Force umount is necessary
		[ "$(grep "${part}" /proc/mounts)" ] && umount -l $part
	done

	# Sysupgrade complains about /tmp and /dev, so we can detach them here
	umount -l /tmp
	umount -l /dev
}

platform_copy_config_uDPU() {
	# Config is saved on the /misc partition and copied on the rootfs after the reboot
	if [ -f "$CONF_TAR" ]; then
		cp -f "$CONF_TAR" /misc
		sync
	fi
}