From a6b7c3e672764858fd294998406ae791f5964b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=9B=BD?= Date: Thu, 26 Mar 2020 14:05:33 +0800 Subject: x86: generate EFI platform bootable images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: 李国 [part_magic_* refactoring, removed genisoimage checks] Signed-off-by: Petr Štetiar --- package/base-files/files/lib/upgrade/common.sh | 62 ++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) (limited to 'package/base-files') diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index a986cc0b5c..2cbc69e5dd 100644 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -102,6 +102,24 @@ get_magic_long() { (get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null } +get_magic_gpt() { + (get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null +} + +get_magic_vfat() { + (get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null +} + +part_magic_efi() { + local magic=$(get_magic_gpt "$@") + [ "$magic" = "EFI PART" ] +} + +part_magic_fat() { + local magic=$(get_magic_vfat "$@") + [ "$magic" = "FAT" ] +} + export_bootdevice() { local cmdline bootdisk rootpart uuid blockdev uevent line class local MAJOR MINOR DEVNAME DEVTYPE @@ -136,6 +154,17 @@ export_bootdevice() { fi done ;; + PARTUUID=????????-????-????-????-??????????02) + uuid="${rootpart#PARTUUID=}" + uuid="${uuid%02}00" + for disk in $(find /dev -type b); do + set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"') + if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then + uevent="/sys/class/block/${disk##*/}/uevent" + break + fi + done + ;; /dev/*) uevent="/sys/class/block/${rootpart##*/}/../uevent" ;; @@ -207,17 +236,34 @@ get_partitions() { # rm -f "/tmp/partmap.$filename" local part - for part in 1 2 3 4; do - set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") + part_magic_efi "$disk" && { + #export_partdevice will fail when partition number is greater than 15, as + #the partition major device number is not equal to the disk major device number + for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do + set -- $(hexdump -v -n 48 -s "$((0x380 + $part * 0x80))" -e '4/4 "%08x"" "4/4 "%08x"" "4/4 "0x%08X "' "$disk") - local type="$(( $(hex_le32_to_cpu $1) % 256))" - local lba="$(( $(hex_le32_to_cpu $2) ))" - local num="$(( $(hex_le32_to_cpu $3) ))" + local type="$1" + local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))" + local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))" + local num="$(( $end - $lba ))" - [ $type -gt 0 ] || continue + [ "$type" = "00000000000000000000000000000000" ] && continue - printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" - done + printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" + done + } || { + for part in 1 2 3 4; do + set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk") + + local type="$(( $(hex_le32_to_cpu $1) % 256))" + local lba="$(( $(hex_le32_to_cpu $2) ))" + local num="$(( $(hex_le32_to_cpu $3) ))" + + [ $type -gt 0 ] || continue + + printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename" + done + } fi } -- cgit v1.2.3