mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-08 22:12:49 +00:00
a6b7c3e672
Add EFI platform bootable images for x86 platforms. These images can also boot from legacy BIOS platform. EFI System Partition need to be fat12/fat16/fat32 (not need to load filesystem drivers), so the first partition of EFI images are not ext4 filesystem any more. GPT partition table has an alternate partition table, we did not generate it. This may cause problems when use these images as qemu disk (kernel can not find rootfs), we pad enough sectors will be ok. Signed-off-by: 李国 <uxgood.org@gmail.com> [part_magic_* refactoring, removed genisoimage checks] Signed-off-by: Petr Štetiar <ynezz@true.cz>
134 lines
3.4 KiB
Bash
134 lines
3.4 KiB
Bash
RAMFS_COPY_BIN='grub-bios-setup'
|
|
|
|
platform_check_image() {
|
|
local diskdev partdev diff
|
|
[ "$#" -gt 1 ] && return 1
|
|
|
|
case "$(get_magic_word "$1")" in
|
|
eb48|eb63) ;;
|
|
*)
|
|
echo "Invalid image type"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
export_bootdevice && export_partdevice diskdev 0 || {
|
|
echo "Unable to determine upgrade device"
|
|
return 1
|
|
}
|
|
|
|
get_partitions "/dev/$diskdev" bootdisk
|
|
|
|
#extract the boot sector from the image
|
|
get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b 2>/dev/null
|
|
|
|
get_partitions /tmp/image.bs image
|
|
|
|
#compare tables
|
|
diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
|
|
|
|
rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image
|
|
|
|
if [ -n "$diff" ]; then
|
|
echo "Partition layout has changed. Full image will be written."
|
|
ask_bool 0 "Abort" && exit 1
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
platform_copy_config() {
|
|
local partdev parttype=ext4
|
|
|
|
if export_partdevice partdev 1; then
|
|
part_magic_fat "/dev/$partdev" && parttype=vfat
|
|
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
|
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
|
|
umount /mnt
|
|
fi
|
|
}
|
|
|
|
platform_do_bootloader_upgrade() {
|
|
local bootpart parttable=msdos
|
|
local diskdev="$1"
|
|
|
|
if export_partdevice bootpart 1; then
|
|
mkdir -p /tmp/boot
|
|
mount -o rw,noatime "/dev/$bootpart" /tmp/boot
|
|
echo "(hd0) /dev/$diskdev" > /tmp/device.map
|
|
part_magic_efi "/dev/$diskdev" && parttable=gpt
|
|
|
|
echo "Upgrading bootloader on /dev/$diskdev..."
|
|
grub-bios-setup \
|
|
-m "/tmp/device.map" \
|
|
-d "/tmp/boot/boot/grub" \
|
|
-r "hd0,${parttable}1" \
|
|
"/dev/$diskdev" \
|
|
&& touch /boot/grub/upgraded
|
|
|
|
umount /tmp/boot
|
|
fi
|
|
}
|
|
|
|
platform_do_upgrade() {
|
|
local diskdev partdev diff
|
|
|
|
export_bootdevice && export_partdevice diskdev 0 || {
|
|
echo "Unable to determine upgrade device"
|
|
return 1
|
|
}
|
|
|
|
sync
|
|
|
|
if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
|
|
get_partitions "/dev/$diskdev" bootdisk
|
|
|
|
#extract the boot sector from the image
|
|
get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b >/dev/null
|
|
|
|
get_partitions /tmp/image.bs image
|
|
|
|
#compare tables
|
|
diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)"
|
|
else
|
|
diff=1
|
|
fi
|
|
|
|
if [ -n "$diff" ]; then
|
|
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
|
|
|
|
# Separate removal and addtion is necessary; otherwise, partition 1
|
|
# will be missing if it overlaps with the old partition 2
|
|
partx -d - "/dev/$diskdev"
|
|
partx -a - "/dev/$diskdev"
|
|
|
|
return 0
|
|
fi
|
|
|
|
#iterate over each partition from the image and write it to the boot disk
|
|
while read part start size; do
|
|
if export_partdevice partdev $part; then
|
|
echo "Writing image to /dev/$partdev..."
|
|
get_image "$@" | dd of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync
|
|
else
|
|
echo "Unable to find partition $part device, skipped."
|
|
fi
|
|
done < /tmp/partmap.image
|
|
|
|
#copy partition uuid
|
|
echo "Writing new UUID to /dev/$diskdev..."
|
|
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
|
|
|
platform_do_bootloader_upgrade "$diskdev"
|
|
local parttype=ext4
|
|
part_magic_efi "/dev/$diskdev" || return 0
|
|
|
|
if export_partdevice partdev 1; then
|
|
part_magic_fat "/dev/$partdev" && parttype=vfat
|
|
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
|
set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
|
|
sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg
|
|
umount /mnt
|
|
fi
|
|
|
|
}
|