platform.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. v "rm -rf \"${CUR_ESP_DIR}/efi/${newdir_bname}\""
  65. v "cp -r \"${d}\" \"${CUR_ESP_DIR}/efi\""
  66. done
  67. umount "${NEW_ESP_DIR}"
  68. umount "${CUR_ESP_DIR}"
  69. }
  70. platform_do_upgrade() {
  71. local board=$(board_name)
  72. local diskdev partdev diff
  73. export_bootdevice && export_partdevice diskdev 0 || {
  74. v "platform_do_upgrade: Unable to determine upgrade device"
  75. return 1
  76. }
  77. sync
  78. if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
  79. get_partitions "/dev/$diskdev" bootdisk
  80. v "Extract boot sector from the image"
  81. get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
  82. get_partitions /tmp/image.bs image
  83. #compare tables
  84. diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
  85. else
  86. diff=1
  87. fi
  88. # Only change the partition table if sysupgrade -p is set,
  89. # otherwise doing so could interfere with embedded "single storage"
  90. # (e.g SoC boot from SD card) setups, as well as other user
  91. # created storage (like uvol)
  92. if [ -n "$diff" ] && [ "${UPGRADE_OPT_SAVE_PARTITIONS}" = "0" ]; then
  93. # Need to remove partitions before dd, otherwise the partitions
  94. # that are added after will have minor numbers offset
  95. partx -d - "/dev/$diskdev"
  96. get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
  97. # Separate removal and addtion is necessary; otherwise, partition 1
  98. # will be missing if it overlaps with the old partition 2
  99. partx -a - "/dev/$diskdev"
  100. return 0
  101. fi
  102. #iterate over each partition from the image and write it to the boot disk
  103. while read part start size; do
  104. if export_partdevice partdev $part; then
  105. v "Writing image to /dev/$partdev..."
  106. if [ "$part" = "1" ]; then
  107. platform_do_upgrade_efi_system_partition \
  108. $1 $partdev $start $size || return 1
  109. else
  110. v "Normal partition, doing DD"
  111. get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" \
  112. count="$size" conv=fsync
  113. fi
  114. else
  115. v "Unable to find partition $part device, skipped."
  116. fi
  117. done < /tmp/partmap.image
  118. local parttype=ext4
  119. if (blkid > /dev/null) && export_partdevice partdev 1; then
  120. part_magic_fat "/dev/$partdev" && parttype=vfat
  121. mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
  122. if export_partdevice partdev 2; then
  123. THIS_PART_BLKID=$(blkid -o value -s PARTUUID "/dev/${partdev}")
  124. v "Setting rootfs PARTUUID=${THIS_PART_BLKID}"
  125. sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1${THIS_PART_BLKID}/ig" \
  126. /mnt/efi/openwrt/grub.cfg
  127. fi
  128. umount /mnt
  129. fi
  130. # Provide time for the storage medium to flush before system reset
  131. # (despite the sync/umount it appears NVMe etc. do it in the background)
  132. sleep 5
  133. }