Преглед на файлове

x86: generate EFI platform bootable images

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: 李国 <[email protected]>
[part_magic_* refactoring, removed genisoimage checks]
Signed-off-by: Petr Štetiar <[email protected]>
李国 преди 5 години
родител
ревизия
a6b7c3e672

+ 19 - 10
config/Config-images.in

@@ -188,19 +188,28 @@ menu "Target Images"
 		select PACKAGE_grub2
 		select PACKAGE_grub2
 		default y
 		default y
 
 
+	config GRUB_EFI_IMAGES
+		bool "Build GRUB EFI images (Linux x86 or x86_64 host only)"
+		depends on TARGET_x86
+		depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
+		select PACKAGE_grub2
+		select PACKAGE_grub2-efi
+		select PACKAGE_kmod-fs-vfat
+		default y
+
 	config GRUB_CONSOLE
 	config GRUB_CONSOLE
 		bool "Use Console Terminal (in addition to Serial)"
 		bool "Use Console Terminal (in addition to Serial)"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		default y
 		default y
 
 
 	config GRUB_SERIAL
 	config GRUB_SERIAL
 		string "Serial port device"
 		string "Serial port device"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		default "ttyS0"
 		default "ttyS0"
 
 
 	config GRUB_BAUDRATE
 	config GRUB_BAUDRATE
 		int "Serial port baud rate"
 		int "Serial port baud rate"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		default 38400 if TARGET_x86_generic
 		default 38400 if TARGET_x86_generic
 		default 115200
 		default 115200
 
 
@@ -211,20 +220,20 @@ menu "Target Images"
 
 
 	config GRUB_BOOTOPTS
 	config GRUB_BOOTOPTS
 		string "Extra kernel boot options"
 		string "Extra kernel boot options"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		help
 		help
 		  If you don't know, just leave it blank.
 		  If you don't know, just leave it blank.
 
 
 	config GRUB_TIMEOUT
 	config GRUB_TIMEOUT
 		string "Seconds to wait before booting the default entry"
 		string "Seconds to wait before booting the default entry"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		default "5"
 		default "5"
 		help
 		help
 		  If you don't know, 5 seconds is a reasonable default.
 		  If you don't know, 5 seconds is a reasonable default.
 
 
 	config GRUB_TITLE
 	config GRUB_TITLE
 		string "Title for the menu entry in GRUB"
 		string "Title for the menu entry in GRUB"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		default "OpenWrt"
 		default "OpenWrt"
 		help
 		help
 		  This is the title of the GRUB menu entry.
 		  This is the title of the GRUB menu entry.
@@ -233,18 +242,18 @@ menu "Target Images"
 	config ISO_IMAGES
 	config ISO_IMAGES
 		bool "Build LiveCD image (ISO)"
 		bool "Build LiveCD image (ISO)"
 		depends on TARGET_x86
 		depends on TARGET_x86
-		select GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 
 
 	config VDI_IMAGES
 	config VDI_IMAGES
 		bool "Build VirtualBox image files (VDI)"
 		bool "Build VirtualBox image files (VDI)"
 		depends on TARGET_x86
 		depends on TARGET_x86
-		select GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		select PACKAGE_kmod-e1000
 		select PACKAGE_kmod-e1000
 
 
 	config VMDK_IMAGES
 	config VMDK_IMAGES
 		bool "Build VMware image files (VMDK)"
 		bool "Build VMware image files (VMDK)"
 		depends on TARGET_x86
 		depends on TARGET_x86
-		select GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		select PACKAGE_kmod-e1000
 		select PACKAGE_kmod-e1000
 
 
 	config TARGET_IMAGES_GZIP
 	config TARGET_IMAGES_GZIP
@@ -272,7 +281,7 @@ menu "Target Images"
 
 
 	config TARGET_ROOTFS_PARTNAME
 	config TARGET_ROOTFS_PARTNAME
 		string "Root partition on target device"
 		string "Root partition on target device"
-		depends on GRUB_IMAGES
+		depends on GRUB_IMAGES || GRUB_EFI_IMAGES
 		help
 		help
 		  Override the root partition on the final device. If left empty,
 		  Override the root partition on the final device. If left empty,
 		  it will be mounted by PARTUUID which makes the kernel find the
 		  it will be mounted by PARTUUID which makes the kernel find the

+ 1 - 0
include/image.mk

@@ -45,6 +45,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$
 IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
 IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
 IMG_COMBINED:=$(IMG_PREFIX)-combined
 IMG_COMBINED:=$(IMG_PREFIX)-combined
 IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | cut -b1-8)
 IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | cut -b1-8)
+IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | mkhash md5 | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
 
 
 MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
 MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
 
 

+ 54 - 8
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_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() {
 export_bootdevice() {
 	local cmdline bootdisk rootpart uuid blockdev uevent line class
 	local cmdline bootdisk rootpart uuid blockdev uevent line class
 	local MAJOR MINOR DEVNAME DEVTYPE
 	local MAJOR MINOR DEVNAME DEVTYPE
@@ -136,6 +154,17 @@ export_bootdevice() {
 					fi
 					fi
 				done
 				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/*)
 			/dev/*)
 				uevent="/sys/class/block/${rootpart##*/}/../uevent"
 				uevent="/sys/class/block/${rootpart##*/}/../uevent"
 			;;
 			;;
@@ -207,17 +236,34 @@ get_partitions() { # <device> <filename>
 		rm -f "/tmp/partmap.$filename"
 		rm -f "/tmp/partmap.$filename"
 
 
 		local part
 		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
 	fi
 }
 }
 
 

+ 8 - 2
scripts/gen_image_generic.sh

@@ -20,7 +20,7 @@ sect=63
 cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512)))
 cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512)))
 
 
 # create partition table
 # create partition table
-set $(ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE})
+set $(ptgen -o "$OUTPUT" -h $head -s $sect ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID})
 
 
 KERNELOFFSET="$(($1 / 512))"
 KERNELOFFSET="$(($1 / 512))"
 KERNELSIZE="$2"
 KERNELSIZE="$2"
@@ -30,6 +30,12 @@ ROOTFSSIZE="$(($4 / 512))"
 [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
 [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
 dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
 dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
 
 
-make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
+if [ -n "$GUID" ]; then
+    [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect"
+    mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))"
+    mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
+else
+    make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
+fi
 dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
 dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
 rm -f "$OUTPUT.kernel"
 rm -f "$OUTPUT.kernel"

+ 3 - 2
target/linux/x86/base-files/lib/preinit/79_move_config

@@ -2,13 +2,14 @@
 # Copyright (C) 2012-2015 OpenWrt.org
 # Copyright (C) 2012-2015 OpenWrt.org
 
 
 move_config() {
 move_config() {
-	local partdev
+	local partdev parttype=ext4
 
 
 	. /lib/upgrade/common.sh
 	. /lib/upgrade/common.sh
 
 
 	if export_bootdevice && export_partdevice partdev 1; then
 	if export_bootdevice && export_partdevice partdev 1; then
 		mkdir -p /boot
 		mkdir -p /boot
-		mount -t ext4 -o rw,noatime "/dev/$partdev" /boot
+		part_magic_fat "/dev/$partdev" && parttype=vfat
+		mount -t $parttype -o rw,noatime "/dev/$partdev" /boot
 		if [ -f "/boot/$BACKUP_FILE" ]; then
 		if [ -f "/boot/$BACKUP_FILE" ]; then
 			mv -f "/boot/$BACKUP_FILE" /
 			mv -f "/boot/$BACKUP_FILE" /
 		fi
 		fi

+ 1 - 0
target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader

@@ -6,6 +6,7 @@ upgrade_bootloader() {
 	. /lib/upgrade/common.sh
 	. /lib/upgrade/common.sh
 
 
 	if [ ! -f /boot/grub/upgraded ] && export_bootdevice && export_partdevice diskdev 0; then
 	if [ ! -f /boot/grub/upgraded ] && export_bootdevice && export_partdevice diskdev 0; then
+		part_magic_efi "/dev/$diskdev" && return 0
 		echo "(hd0) /dev/$diskdev" > /tmp/device.map
 		echo "(hd0) /dev/$diskdev" > /tmp/device.map
 		/usr/sbin/grub-bios-setup \
 		/usr/sbin/grub-bios-setup \
 			-m "/tmp/device.map" \
 			-m "/tmp/device.map" \

+ 20 - 7
target/linux/x86/base-files/lib/upgrade/platform.sh

@@ -20,7 +20,7 @@ platform_check_image() {
 	get_partitions "/dev/$diskdev" bootdisk
 	get_partitions "/dev/$diskdev" bootdisk
 
 
 	#extract the boot sector from the image
 	#extract the boot sector from the image
-	get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
+	get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b 2>/dev/null
 
 
 	get_partitions /tmp/image.bs image
 	get_partitions /tmp/image.bs image
 
 
@@ -37,29 +37,31 @@ platform_check_image() {
 }
 }
 
 
 platform_copy_config() {
 platform_copy_config() {
-	local partdev
+	local partdev parttype=ext4
 
 
 	if export_partdevice partdev 1; then
 	if export_partdevice partdev 1; then
-		mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
+		part_magic_fat "/dev/$partdev" && parttype=vfat
+		mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
 		cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
 		cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
 		umount /mnt
 		umount /mnt
 	fi
 	fi
 }
 }
 
 
 platform_do_bootloader_upgrade() {
 platform_do_bootloader_upgrade() {
-	local bootpart
+	local bootpart parttable=msdos
 	local diskdev="$1"
 	local diskdev="$1"
 
 
 	if export_partdevice bootpart 1; then
 	if export_partdevice bootpart 1; then
 		mkdir -p /tmp/boot
 		mkdir -p /tmp/boot
 		mount -o rw,noatime "/dev/$bootpart" /tmp/boot
 		mount -o rw,noatime "/dev/$bootpart" /tmp/boot
 		echo "(hd0) /dev/$diskdev" > /tmp/device.map
 		echo "(hd0) /dev/$diskdev" > /tmp/device.map
+		part_magic_efi "/dev/$diskdev" && parttable=gpt
 
 
 		echo "Upgrading bootloader on /dev/$diskdev..."
 		echo "Upgrading bootloader on /dev/$diskdev..."
 		grub-bios-setup \
 		grub-bios-setup \
 			-m "/tmp/device.map" \
 			-m "/tmp/device.map" \
 			-d "/tmp/boot/boot/grub" \
 			-d "/tmp/boot/boot/grub" \
-			-r "hd0,msdos1" \
+			-r "hd0,${parttable}1" \
 			"/dev/$diskdev" \
 			"/dev/$diskdev" \
 		&& touch /boot/grub/upgraded
 		&& touch /boot/grub/upgraded
 
 
@@ -81,7 +83,7 @@ platform_do_upgrade() {
 		get_partitions "/dev/$diskdev" bootdisk
 		get_partitions "/dev/$diskdev" bootdisk
 
 
 		#extract the boot sector from the image
 		#extract the boot sector from the image
-		get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
+		get_image "$@" | dd of=/tmp/image.bs count=63 bs=512b >/dev/null
 
 
 		get_partitions /tmp/image.bs image
 		get_partitions /tmp/image.bs image
 
 
@@ -106,7 +108,7 @@ platform_do_upgrade() {
 	while read part start size; do
 	while read part start size; do
 		if export_partdevice partdev $part; then
 		if export_partdevice partdev $part; then
 			echo "Writing image to /dev/$partdev..."
 			echo "Writing image to /dev/$partdev..."
-			get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
+			get_image "$@" | dd of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync
 		else
 		else
 			echo "Unable to find partition $part device, skipped."
 			echo "Unable to find partition $part device, skipped."
 		fi
 		fi
@@ -117,4 +119,15 @@ platform_do_upgrade() {
 	get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
 	get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
 
 
 	platform_do_bootloader_upgrade "$diskdev"
 	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
+
 }
 }

+ 1 - 0
target/linux/x86/generic/config-4.19

@@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y
 CONFIG_FB_EFI=y
 CONFIG_FB_EFI=y
 CONFIG_FB_HYPERV=y
 CONFIG_FB_HYPERV=y
 # CONFIG_FB_I810 is not set
 # CONFIG_FB_I810 is not set
+CONFIG_FB_SIMPLE=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FOPS=y
 CONFIG_FB_SYS_FOPS=y

+ 1 - 0
target/linux/x86/generic/config-5.4

@@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y
 CONFIG_FB_EFI=y
 CONFIG_FB_EFI=y
 CONFIG_FB_HYPERV=y
 CONFIG_FB_HYPERV=y
 # CONFIG_FB_I810 is not set
 # CONFIG_FB_I810 is not set
+CONFIG_FB_SIMPLE=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FOPS=y
 CONFIG_FB_SYS_FOPS=y

+ 38 - 8
target/linux/x86/image/Makefile

@@ -38,6 +38,8 @@ endif
 
 
 ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
 ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
 ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
 ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
+GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
+GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/'))
 
 
 GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
 GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
 GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
 GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
@@ -47,7 +49,12 @@ BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
 define Build/combined
 define Build/combined
 	$(CP) $(KDIR)/$(KERNEL_NAME) [email protected]/boot/vmlinuz
 	$(CP) $(KDIR)/$(KERNEL_NAME) [email protected]/boot/vmlinuz
 	-$(CP) $(STAGING_DIR_ROOT)/boot/. [email protected]/boot/
 	-$(CP) $(STAGING_DIR_ROOT)/boot/. [email protected]/boot/
-	PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \
+	$(if $(filter $(1),efi),
+		$(INSTALL_DIR) [email protected]/efi/boot
+		$(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi [email protected]/efi/boot/
+	)
+	PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
+		$(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \
 		$@ \
 		$@ \
 		$(CONFIG_TARGET_KERNEL_PARTSIZE) [email protected] \
 		$(CONFIG_TARGET_KERNEL_PARTSIZE) [email protected] \
 		$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
 		$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
@@ -61,6 +68,7 @@ define Build/grub-config
 		-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
 		-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
 		-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
 		-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
 		-e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
 		-e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
+		-e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
 		-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
 		-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
 		-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
 		-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
 		-e 's#@TITLE@#$(GRUB_TITLE)#g' \
 		-e 's#@TITLE@#$(GRUB_TITLE)#g' \
@@ -71,12 +79,12 @@ define Build/grub-install
 	rm -fR [email protected]
 	rm -fR [email protected]
 	$(INSTALL_DIR) [email protected]
 	$(INSTALL_DIR) [email protected]
 	$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img [email protected]/
 	$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img [email protected]/
-	$(CP) $(STAGING_DIR_IMAGE)/grub2/$(GRUB2_VARIANT)-core.img [email protected]/core.img
+	$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img [email protected]/core.img
 	echo '(hd0) $@' > [email protected]/device.map
 	echo '(hd0) $@' > [email protected]/device.map
 	$(STAGING_DIR_HOST)/bin/grub-bios-setup \
 	$(STAGING_DIR_HOST)/bin/grub-bios-setup \
 		-m "[email protected]/device.map" \
 		-m "[email protected]/device.map" \
 		-d "[email protected]" \
 		-d "[email protected]" \
-		-r "hd0,msdos1" \
+		-r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \
 		$@
 		$@
 endef
 endef
 
 
@@ -87,7 +95,15 @@ define Build/iso
 		$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
 		$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
 		> [email protected]/boot/grub/eltorito.img
 		> [email protected]/boot/grub/eltorito.img
 	-$(CP) $(STAGING_DIR_ROOT)/boot/. [email protected]/boot/
 	-$(CP) $(STAGING_DIR_ROOT)/boot/. [email protected]/boot/
+	$(if $(filter $(1),efi),
+		mkfs.fat -C [email protected]/boot/grub/isoboot.img -S 512 1440
+		mmd -i [email protected]/boot/grub/isoboot.img ::/efi ::/efi/boot
+		mcopy -i [email protected]/boot/grub/isoboot.img \
+			$(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
+			::/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi
+	)
 	mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
 	mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
+		$(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \
 		-o $@ [email protected] $(TARGET_DIR)
 		-o $@ [email protected] $(TARGET_DIR)
 endef
 endef
 
 
@@ -100,23 +116,37 @@ define Device/Default
   IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
   IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
   IMAGE/rootfs.img := append-rootfs
   IMAGE/rootfs.img := append-rootfs
   IMAGE/rootfs.img.gz := append-rootfs | gzip
   IMAGE/rootfs.img.gz := append-rootfs | gzip
+  ARTIFACT/image-efi.iso := grub-config iso | iso efi
+  IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi
+  IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip
+  IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi
+  IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
   ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
   ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
-    IMAGES := combined.img.gz rootfs.img.gz
+    IMAGES-y := rootfs.img.gz
+    IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz
+    IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
   else
   else
-    IMAGES := combined.img rootfs.img
+    IMAGES-y := rootfs.img
+    IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
+    IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
   endif
   endif
   KERNEL := kernel-bin
   KERNEL := kernel-bin
   KERNEL_INSTALL := 1
   KERNEL_INSTALL := 1
   KERNEL_NAME := bzImage
   KERNEL_NAME := bzImage
   ifeq ($(CONFIG_ISO_IMAGES),y)
   ifeq ($(CONFIG_ISO_IMAGES),y)
-    ARTIFACTS := image.iso
+    ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso
+    ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso
   endif
   endif
   ifeq ($(CONFIG_VDI_IMAGES),y)
   ifeq ($(CONFIG_VDI_IMAGES),y)
-    IMAGES += combined.vdi
+    IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi
+    IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi
   endif
   endif
   ifeq ($(CONFIG_VMDK_IMAGES),y)
   ifeq ($(CONFIG_VMDK_IMAGES),y)
-    IMAGES += combined.vmdk
+    IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk
+    IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk
   endif
   endif
+  IMAGES := $$(IMAGES-y)
+  ARTIFACTS := $$(ARTIFACTS-y)
 endef
 endef
 
 
 $(eval $(call Image/gzip-ext4-padded-squashfs))
 $(eval $(call Image/gzip-ext4-padded-squashfs))

+ 13 - 0
target/linux/x86/image/grub-efi.cfg

@@ -0,0 +1,13 @@
+@SERIAL_CONFIG@
+@TERMINAL_CONFIG@
+
+set default="0"
+set timeout="@TIMEOUT@"
+set root='(hd0,gpt1)'
+
+menuentry "@TITLE@" {
+	linux /boot/vmlinuz @GPT_ROOTPART@ @CMDLINE@ noinitrd
+}
+menuentry "@TITLE@ (failsafe)" {
+	linux /boot/vmlinuz failsafe=true @GPT_ROOTPART@ @CMDLINE@ noinitrd
+}

+ 6 - 1
target/linux/x86/image/grub-iso.cfg

@@ -3,7 +3,12 @@
 
 
 set default="0"
 set default="0"
 set timeout="@TIMEOUT@"
 set timeout="@TIMEOUT@"
-set root='(cd)'
+
+if [ "${grub_platform}" = "efi" ]; then
+    set root='(cd0)'
+else
+    set root='(cd)'
+fi
 
 
 menuentry "@TITLE@" {
 menuentry "@TITLE@" {
 	linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd
 	linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd