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
2; then
40 mount
-t $parttype -o rw
,noatime
"/dev/$partdev" /mnt
41 cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
44 v
"ERROR: Unable to find partition to copy config data to"
50 # To avoid writing over any firmware
51 # files (e.g ubootefi.var or firmware/X/ aka EBBR)
52 # Copy efi/openwrt and efi/boot from the new image
54 platform_do_upgrade_efi_system_partition
() {
56 local target_partdev
=$2
57 local image_efisp_start
=$3
58 local image_efisp_size
=$4
60 v
"Updating ESP on ${target_partdev}"
61 NEW_ESP_DIR
="/mnt/new_esp_loop"
62 CUR_ESP_DIR
="/mnt/cur_esp"
63 mkdir
"${NEW_ESP_DIR}"
64 mkdir
"${CUR_ESP_DIR}"
66 get_image_dd
"$image_file" of
="/tmp/new_efi_sys_part.img" \
67 skip
="$image_efisp_start" count
="$image_efisp_size"
69 mount
-t vfat
-o loop
-o ro
/tmp
/new_efi_sys_part.img
"${NEW_ESP_DIR}"
70 if [ ! -d "${NEW_ESP_DIR}/efi/boot" ]; then
71 v
"ERROR: Image does not contain EFI boot files (/efi/boot)"
75 mount
-t vfat
"/dev/$partdev" "${CUR_ESP_DIR}"
77 for d
in $
(find "${NEW_ESP_DIR}/efi/" -mindepth 1 -maxdepth 1 -type d
); do
79 newdir_bname
=$
(basename "${d}")
80 rm -rf "${CUR_ESP_DIR}/efi/${newdir_bname}"
81 cp -r "${d}" "${CUR_ESP_DIR}/efi"
84 umount
"${NEW_ESP_DIR}"
85 umount
"${CUR_ESP_DIR}"
88 platform_do_upgrade
() {
89 local board
=$
(board_name
)
90 local diskdev partdev
diff
92 export_bootdevice
&& export_partdevice diskdev
0 ||
{
93 v
"platform_do_upgrade: Unable to determine upgrade device"
99 if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
100 get_partitions
"/dev/$diskdev" bootdisk
102 v
"Extract boot sector from the image"
103 get_image_dd
"$1" of
=/tmp
/image.bs count
=63 bs
=512b
105 get_partitions
/tmp
/image.bs image
108 diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
113 # Only change the partition table if sysupgrade -p is set,
114 # otherwise doing so could interfere with embedded "single storage"
115 # (e.g SoC boot from SD card) setups, as well as other user
116 # created storage (like uvol)
117 if [ -n "$diff" ] && [ "${UPGRADE_OPT_SAVE_PARTITIONS}" = "0" ]; then
118 # Need to remove partitions before dd, otherwise the partitions
119 # that are added after will have minor numbers offset
120 partx
-d - "/dev/$diskdev"
122 get_image_dd
"$1" of
="/dev/$diskdev" bs
=4096 conv
=fsync
124 # Separate removal and addtion is necessary; otherwise, partition 1
125 # will be missing if it overlaps with the old partition 2
126 partx
-a - "/dev/$diskdev"
131 #iterate over each partition from the image and write it to the boot disk
132 while read part start size
; do
133 if export_partdevice partdev
$part; then
134 v
"Writing image to /dev/$partdev..."
135 if [ "$part" = "1" ]; then
136 platform_do_upgrade_efi_system_partition \
137 $1 $partdev $start $size ||
return 1
139 v
"Normal partition, doing DD"
140 get_image_dd
"$1" of
="/dev/$partdev" ibs
=512 obs
=1M skip
="$start" \
141 count
="$size" conv
=fsync
144 v
"Unable to find partition $part device, skipped."
146 done < /tmp
/partmap.image
150 if (blkid
> /dev
/null
) && export_partdevice partdev
1; then
151 part_magic_fat
"/dev/$partdev" && parttype
=vfat
152 mount
-t $parttype -o rw
,noatime
"/dev/$partdev" /mnt
153 if export_partdevice partdev
2; then
154 THIS_PART_BLKID
=$
(blkid
-o value
-s PARTUUID
"/dev/${partdev}")
155 v
"Setting rootfs PARTUUID=${THIS_PART_BLKID}"
156 sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1${THIS_PART_BLKID}/ig" \
157 /mnt
/efi
/openwrt
/grub.cfg
161 # Provide time for the storage medium to flush before system reset
162 # (despite the sync/umount it appears NVMe etc. do it in the background)