platform.sh 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # SPDX-License-Identifier: GPL-2.0-or-later
  2. RAMFS_COPY_BIN="/usr/sbin/blkid"
  3. platform_check_image() {
  4. local board=$(board_name)
  5. local diskdev partdev diff
  6. [ "$#" -gt 1 ] && return 1
  7. v "Board is ${board}"
  8. export_bootdevice && export_partdevice diskdev 0 || {
  9. v "platform_check_image: Unable to determine upgrade device"
  10. return 1
  11. }
  12. get_partitions "/dev/$diskdev" bootdisk
  13. v "Extract boot sector from the image"
  14. get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
  15. get_partitions /tmp/image.bs image
  16. #compare tables
  17. diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
  18. rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
  19. if [ -n "$diff" ]; then
  20. v "Partition layout has changed. Full image will be written."
  21. ask_bool 0 "Abort" && exit 1
  22. return 0
  23. fi
  24. }
  25. platform_copy_config() {
  26. local partdev parttype=ext4
  27. if export_partdevice partdev 1; then
  28. part_magic_fat "/dev/$partdev" && parttype=vfat
  29. mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
  30. cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
  31. umount /mnt
  32. else
  33. v "ERROR: Unable to find partition to copy config data to"
  34. fi
  35. sleep 5
  36. }
  37. # To avoid writing over any firmware
  38. # files (e.g ubootefi.var or firmware/X/ aka EBBR)
  39. # Copy efi/openwrt and efi/boot from the new image
  40. # to the existing ESP
  41. platform_do_upgrade_efi_system_partition() {
  42. local image_file=$1
  43. local target_partdev=$2
  44. local image_efisp_start=$3
  45. local image_efisp_size=$4
  46. v "Updating ESP on ${target_partdev}"
  47. NEW_ESP_DIR="/mnt/new_esp_loop"
  48. CUR_ESP_DIR="/mnt/cur_esp"
  49. mkdir "${NEW_ESP_DIR}"
  50. mkdir "${CUR_ESP_DIR}"
  51. get_image_dd "$image_file" of="/tmp/new_efi_sys_part.img" \
  52. skip="$image_efisp_start" count="$image_efisp_size"
  53. mount -t vfat -o loop -o ro /tmp/new_efi_sys_part.img "${NEW_ESP_DIR}"
  54. if [ ! -d "${NEW_ESP_DIR}/efi/boot" ]; then
  55. v "ERROR: Image does not contain EFI boot files (/efi/boot)"
  56. return 1
  57. fi
  58. mount -t vfat "/dev/$partdev" "${CUR_ESP_DIR}"
  59. for d in $(find "${NEW_ESP_DIR}/efi/" -mindepth 1 -maxdepth 1 -type d); do
  60. v "Copying ${d}"
  61. newdir_bname=$(basename "${d}")
  62. rm -rf "${CUR_ESP_DIR}/efi/${newdir_bname}"
  63. cp -r "${d}" "${CUR_ESP_DIR}/efi"
  64. done
  65. umount "${NEW_ESP_DIR}"
  66. umount "${CUR_ESP_DIR}"
  67. }
  68. platform_do_upgrade() {
  69. local board=$(board_name)
  70. local diskdev partdev diff
  71. export_bootdevice && export_partdevice diskdev 0 || {
  72. v "platform_do_upgrade: Unable to determine upgrade device"
  73. return 1
  74. }
  75. sync
  76. if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
  77. get_partitions "/dev/$diskdev" bootdisk
  78. v "Extract boot sector from the image"
  79. get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
  80. get_partitions /tmp/image.bs image
  81. #compare tables
  82. diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
  83. else
  84. diff=1
  85. fi
  86. # Only change the partition table if sysupgrade -p is set,
  87. # otherwise doing so could interfere with embedded "single storage"
  88. # (e.g SoC boot from SD card) setups, as well as other user
  89. # created storage (like uvol)
  90. if [ -n "$diff" ] && [ "${UPGRADE_OPT_SAVE_PARTITIONS}" = "0" ]; then
  91. # Need to remove partitions before dd, otherwise the partitions
  92. # that are added after will have minor numbers offset
  93. partx -d - "/dev/$diskdev"
  94. get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
  95. # Separate removal and addtion is necessary; otherwise, partition 1
  96. # will be missing if it overlaps with the old partition 2
  97. partx -a - "/dev/$diskdev"
  98. return 0
  99. fi
  100. #iterate over each partition from the image and write it to the boot disk
  101. while read part start size; do
  102. if export_partdevice partdev $part; then
  103. v "Writing image to /dev/$partdev..."
  104. if [ "$part" = "1" ]; then
  105. platform_do_upgrade_efi_system_partition \
  106. $1 $partdev $start $size || return 1
  107. else
  108. v "Normal partition, doing DD"
  109. get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
  110. count="$size" conv=fsync
  111. fi
  112. else
  113. v "Unable to find partition $part device, skipped."
  114. fi
  115. done < /tmp/partmap.image
  116. local parttype=ext4
  117. if (blkid > /dev/null) && export_partdevice partdev 1; then
  118. part_magic_fat "/dev/$partdev" && parttype=vfat
  119. mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
  120. if export_partdevice partdev 2; then
  121. THIS_PART_BLKID=$(blkid -o value -s PARTUUID "/dev/${partdev}")
  122. v "Setting rootfs PARTUUID=${THIS_PART_BLKID}"
  123. sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1${THIS_PART_BLKID}/ig" \
  124. /mnt/efi/openwrt/grub.cfg
  125. fi
  126. umount /mnt
  127. fi
  128. # Provide time for the storage medium to flush before system reset
  129. # (despite the sync/umount it appears NVMe etc. do it in the background)
  130. sleep 5
  131. }