1 # SPDX-License-Identifier: GPL-2.0-or-later
3 RAMFS_COPY_BIN
="/usr/sbin/blkid"
5 platform_check_image
() {
6 local board
=$
(board_name
)
7 local diskdev partdev
diff
8 [ "$#" -gt 1 ] && return 1
12 export_bootdevice
&& export_partdevice diskdev
0 ||
{
13 v
"platform_check_image: Unable to determine upgrade device"
17 get_partitions
"/dev/$diskdev" bootdisk
19 v
"Extract boot sector from the image"
20 get_image_dd
"$1" of
=/tmp
/image.bs count
=63 bs
=512b
22 get_partitions
/tmp
/image.bs image
25 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
27 rm -f /tmp
/image.bs
/tmp
/partmap.bootdisk
/tmp
/partmap.image
29 if [ -n "$diff" ]; then
30 v
"Partition layout has changed. Full image will be written."
31 ask_bool
0 "Abort" && exit 1
36 platform_copy_config
() {
37 local partdev parttype
=ext4
39 if export_partdevice partdev
1; then
40 part_magic_fat
"/dev/$partdev" && parttype
=vfat
41 mount
-t $parttype -o rw
,noatime
"/dev/$partdev" /mnt
42 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
45 v
"ERROR: Unable to find partition to copy config data to"
51 # To avoid writing over any firmware
52 # files (e.g ubootefi.var or firmware/X/ aka EBBR)
53 # Copy efi/openwrt and efi/boot from the new image
55 platform_do_upgrade_efi_system_partition
() {
57 local target_partdev
=$2
58 local image_efisp_start
=$3
59 local image_efisp_size
=$4
61 v
"Updating ESP on ${target_partdev}"
62 NEW_ESP_DIR
="/mnt/new_esp_loop"
63 CUR_ESP_DIR
="/mnt/cur_esp"
64 mkdir
"${NEW_ESP_DIR}"
65 mkdir
"${CUR_ESP_DIR}"
67 get_image_dd
"$image_file" of
="/tmp/new_efi_sys_part.img" \
68 skip
="$image_efisp_start" count
="$image_efisp_size"
70 mount
-t vfat
-o loop
-o ro
/tmp
/new_efi_sys_part.img
"${NEW_ESP_DIR}"
71 if [ ! -d "${NEW_ESP_DIR}/efi/boot" ]; then
72 v
"ERROR: Image does not contain EFI boot files (/efi/boot)"
76 mount
-t vfat
"/dev/$partdev" "${CUR_ESP_DIR}"
78 for d
in $
(find "${NEW_ESP_DIR}/efi/" -mindepth 1 -maxdepth 1 -type d
); do
80 newdir_bname
=$
(basename "${d}")
81 rm -rf "${CUR_ESP_DIR}/efi/${newdir_bname}"
82 cp -r "${d}" "${CUR_ESP_DIR}/efi"
83 v
"rm -rf \"${CUR_ESP_DIR}/efi/${newdir_bname}\""
84 v
"cp -r \"${d}\" \"${CUR_ESP_DIR}/efi\""
87 umount
"${NEW_ESP_DIR}"
88 umount
"${CUR_ESP_DIR}"
91 platform_do_upgrade
() {
92 local board
=$
(board_name
)
93 local diskdev partdev
diff
95 export_bootdevice
&& export_partdevice diskdev
0 ||
{
96 v
"platform_do_upgrade: Unable to determine upgrade device"
102 if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
103 get_partitions
"/dev/$diskdev" bootdisk
105 v
"Extract boot sector from the image"
106 get_image_dd
"$1" of
=/tmp
/image.bs count
=63 bs
=512b
108 get_partitions
/tmp
/image.bs image
111 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
116 # Only change the partition table if sysupgrade -p is set,
117 # otherwise doing so could interfere with embedded "single storage"
118 # (e.g SoC boot from SD card) setups, as well as other user
119 # created storage (like uvol)
120 if [ -n "$diff" ] && [ "${UPGRADE_OPT_SAVE_PARTITIONS}" = "0" ]; then
121 # Need to remove partitions before dd, otherwise the partitions
122 # that are added after will have minor numbers offset
123 partx
-d - "/dev/$diskdev"
125 get_image_dd
"$1" of
="/dev/$diskdev" bs
=4096 conv
=fsync
127 # Separate removal and addtion is necessary; otherwise, partition 1
128 # will be missing if it overlaps with the old partition 2
129 partx
-a - "/dev/$diskdev"
134 #iterate over each partition from the image and write it to the boot disk
135 while read part start size
; do
136 if export_partdevice partdev
$part; then
137 v
"Writing image to /dev/$partdev..."
138 if [ "$part" = "1" ]; then
139 platform_do_upgrade_efi_system_partition \
140 $1 $partdev $start $size ||
return 1
142 v
"Normal partition, doing DD"
143 get_image_dd
"$1" of
="/dev/$partdev" ibs
=512 obs
=1M skip
="$start" \
144 count
="$size" conv
=fsync
147 v
"Unable to find partition $part device, skipped."
149 done < /tmp
/partmap.image
153 if (blkid
> /dev
/null
) && export_partdevice partdev
1; then
154 part_magic_fat
"/dev/$partdev" && parttype
=vfat
155 mount
-t $parttype -o rw
,noatime
"/dev/$partdev" /mnt
156 if export_partdevice partdev
2; then
157 THIS_PART_BLKID
=$
(blkid
-o value
-s PARTUUID
"/dev/${partdev}")
158 v
"Setting rootfs PARTUUID=${THIS_PART_BLKID}"
159 sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1${THIS_PART_BLKID}/ig" \
160 /mnt
/efi
/openwrt
/grub.cfg
164 # Provide time for the storage medium to flush before system reset
165 # (despite the sync/umount it appears NVMe etc. do it in the background)