Add EFI bootable images for x86 platforms. These images can also
boot from legacy BIOS. And iso images can boot from EFI now.

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....@gmail.com>
---
 config/Config-images.in                            |  27 ++++--
 package/base-files/files/lib/upgrade/common.sh     |  15 +++
 scripts/gen_image_generic.sh                       |  10 +-
 .../x86/base-files/lib/preinit/79_move_config      |   6 +-
 .../linux/x86/base-files/lib/upgrade/platform.sh   |   6 +-
 target/linux/x86/generic/config-4.14               |   1 +
 target/linux/x86/generic/config-4.19               |   1 +
 target/linux/x86/image/Makefile                    | 103 ++++++++++++++++++++-
 target/linux/x86/image/grub-iso.cfg                |   7 +-
 9 files changed, 157 insertions(+), 19 deletions(-)

diff --git a/config/Config-images.in b/config/Config-images.in
index 6610601d..7e64c12 100644
--- a/config/Config-images.in
+++ b/config/Config-images.in
@@ -194,19 +194,28 @@ menu "Target Images"
                select PACKAGE_grub2
                default y
 
+       config EFI_IMAGES
+               bool "Build EFI images (Linux x86 or x86_64 host only)"
+               depends on TARGET_x86
+               depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || 
TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
+               select PACKAGE_grub2
+               select PACKAGE_grub2-efi
+               select PACKAGE_kmod-fs-vfat
+               default n
+
        config GRUB_CONSOLE
                bool "Use Console Terminal (in addition to Serial)"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                default y
 
        config GRUB_SERIAL
                string "Serial port device"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                default "ttyS0"
 
        config GRUB_BAUDRATE
                int "Serial port baud rate"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                default 38400 if TARGET_x86_generic
                default 115200
 
@@ -217,20 +226,20 @@ menu "Target Images"
 
        config GRUB_BOOTOPTS
                string "Extra kernel boot options"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                help
                  If you don't know, just leave it blank.
 
        config GRUB_TIMEOUT
                string "Seconds to wait before booting the default entry"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                default "5"
                help
                  If you don't know, 5 seconds is a reasonable default.
 
        config GRUB_TITLE
                string "Title for the menu entry in GRUB"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                default "OpenWrt"
                help
                  This is the title of the GRUB menu entry.
@@ -265,21 +274,21 @@ menu "Target Images"
 
        config TARGET_KERNEL_PARTSIZE
                int "Kernel partition size (in MB)"
-               depends on GRUB_IMAGES || USES_BOOT_PART
+               depends on GRUB_IMAGES || EFI_IMAGES || USES_BOOT_PART
                default 8 if TARGET_apm821xx_sata
                default 20 if TARGET_brcm2708
                default 16
 
        config TARGET_ROOTFS_PARTSIZE
                int "Root filesystem partition size (in MB)"
-               depends on GRUB_IMAGES || USES_ROOTFS_PART || 
TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_omap || TARGET_rb532 || 
TARGET_sunxi || TARGET_uml
+               depends on GRUB_IMAGES || EFI_IMAGES || USES_ROOTFS_PART || 
TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_omap || TARGET_rb532 || 
TARGET_sunxi || TARGET_uml
                default 256
                help
                  Select the root filesystem partition size.
 
        config TARGET_ROOTFS_PARTNAME
                string "Root partition on target device"
-               depends on GRUB_IMAGES
+               depends on GRUB_IMAGES || EFI_IMAGES
                help
                  Override the root partition on the final device. If left 
empty,
                  it will be mounted by PARTUUID which makes the kernel find the
diff --git a/package/base-files/files/lib/upgrade/common.sh 
b/package/base-files/files/lib/upgrade/common.sh
index b3a29fb..f319692 100644
--- a/package/base-files/files/lib/upgrade/common.sh
+++ b/package/base-files/files/lib/upgrade/common.sh
@@ -128,6 +128,21 @@ export_bootdevice() {
                                        fi
                                done
                        ;;
+                       
PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]\
+-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]\
+-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]\
+-[a-f0-9][a-f0-9][a-f0-9][a-f0-9]\
+-[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]02)
+                               uuid="${disk#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/${disk##*/}/uevent"
                        ;;
diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh
index d9beeb0..cc5a4d5 100755
--- a/scripts/gen_image_generic.sh
+++ b/scripts/gen_image_generic.sh
@@ -20,7 +20,7 @@ sect=63
 cyl=$(( ($KERNELSIZE + $ROOTFSSIZE) * 1024 * 1024 / ($head * $sect * 512)))
 
 # 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 ${EFI_SIGNATURE:+-g} -p 
${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 
0x$SIGNATURE} ${EFI_SIGNATURE:+-G $EFI_SIGNATURE}`
 
 KERNELOFFSET="$(($1 / 512))"
 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"
 dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
 
-make_ext4fs -J -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
+if [ -n "$EFI_SIGNATURE" ]; then
+    [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 
seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect"
+    mkfs.fat -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))"
+    mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
+else
+    make_ext4fs -J -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
+fi
 dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
 rm -f "$OUTPUT.kernel"
diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config 
b/target/linux/x86/base-files/lib/preinit/79_move_config
index aff720a..8eea97c 100644
--- a/target/linux/x86/base-files/lib/preinit/79_move_config
+++ b/target/linux/x86/base-files/lib/preinit/79_move_config
@@ -2,13 +2,15 @@
 # Copyright (C) 2012-2015 OpenWrt.org
 
 move_config() {
-       local partdev
+       local partdev magic parttype=ext4
 
        . /lib/upgrade/common.sh
 
        if export_bootdevice && export_partdevice partdev 1; then
                mkdir -p /boot
-               mount -t ext4 -o rw,noatime "/dev/$partdev" /boot
+               magic=$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null)
+               [ "$magic" = "FAT" ] && parttype=vfat
+               mount -t $parttype -o rw,noatime "/dev/$partdev" /boot
                if [ -f /boot/sysupgrade.tgz ]; then
                        mv -f /boot/sysupgrade.tgz /
                fi
diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh 
b/target/linux/x86/base-files/lib/upgrade/platform.sh
index 439ba8f..ea66b4a 100644
--- a/target/linux/x86/base-files/lib/upgrade/platform.sh
+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh
@@ -35,10 +35,12 @@ platform_check_image() {
 }
 
 platform_copy_config() {
-       local partdev
+       local partdev magic parttype=ext4
 
        if export_partdevice partdev 1; then
-               mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
+               magic=$(dd if="/dev/$partdev" bs=1 count=3 skip=54 2>/dev/null)
+               [ "$magic" = "FAT" ] && parttype=vfat
+               mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
                cp -af "$CONF_TAR" /mnt/
                umount /mnt
        fi
diff --git a/target/linux/x86/generic/config-4.14 
b/target/linux/x86/generic/config-4.14
index 92380f5..8f4b518 100644
--- a/target/linux/x86/generic/config-4.14
+++ b/target/linux/x86/generic/config-4.14
@@ -125,6 +125,7 @@ CONFIG_FB_EFI=y
 CONFIG_FB_HYPERV=y
 # CONFIG_FB_I810 is not set
 # CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA is not set
+CONFIG_FB_SIMPLE=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FOPS=y
diff --git a/target/linux/x86/generic/config-4.19 
b/target/linux/x86/generic/config-4.19
index e769835..89a6e14 100644
--- a/target/linux/x86/generic/config-4.19
+++ b/target/linux/x86/generic/config-4.19
@@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y
 CONFIG_FB_EFI=y
 CONFIG_FB_HYPERV=y
 # CONFIG_FB_I810 is not set
+CONFIG_FB_SIMPLE=y
 CONFIG_FB_SYS_COPYAREA=y
 CONFIG_FB_SYS_FILLRECT=y
 CONFIG_FB_SYS_FOPS=y
diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile
index 84a3d88..aacb1b4 100644
--- a/target/linux/x86/image/Makefile
+++ b/target/linux/x86/image/Makefile
@@ -11,6 +11,7 @@ export PATH=$(TARGET_PATH):/sbin
 
 GRUB2_MODULES = biosdisk boot chain configfile ext2 linux ls part_msdos reboot 
serial test vga
 GRUB2_MODULES_ISO = biosdisk boot chain configfile iso9660 linux ls part_msdos 
reboot serial test vga
+GRUB2_MODULES_EFI = boot chain configfile ext2 fat linux ls part_msdos 
part_gpt reboot serial test efi_gop efi_uga
 GRUB_TERMINALS =
 GRUB_SERIAL_CONFIG =
 GRUB_TERMINAL_CONFIG =
@@ -43,6 +44,9 @@ endif
 SIGNATURE:=$(shell perl -e 'printf("%08x", rand(0xFFFFFFFF))')
 ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
 ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(SIGNATURE)-02)
+EFI_SIGNATURE:=$(strip $(shell uuidgen | sed 's/[a-zA-Z0-9]\{2\}$$/00/'))
+EFI_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
+EFI_ROOTPART:=$(if $(EFI_ROOTPART),$(EFI_ROOTPART),PARTUUID=$(shell echo 
$(EFI_SIGNATURE) | sed 's/00$$/02/'))
 
 GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
 GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
@@ -93,12 +97,71 @@ ifneq ($(CONFIG_GRUB_IMAGES),)
   endef
 endif
 
+ifneq ($(CONFIG_EFI_IMAGES),)
+
+  BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
+
+  define Image/cmdline/ext4/efi
+    root=$(EFI_ROOTPART) rootfstype=ext4 rootwait
+  endef
+
+  define Image/cmdline/squashfs/efi
+    root=$(EFI_ROOTPART) rootfstype=squashfs rootwait
+  endef
+
+  define Image/Build/grub2/efi
+       # left here because the image builder doesnt need these
+       $(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2 
$(KDIR)/root.grub/efi/boot
+       $(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
+       sed -e 's#msdos1#gpt1#g' ./grub-early.cfg > $(KDIR)/grub2/grub-early.cfg
+
+       grub-mkimage \
+               -p /boot/grub \
+               -d $(STAGING_DIR_HOST)/lib/grub/$(CONFIG_ARCH)-efi \
+               -o $(KDIR)/root.grub/efi/boot/boot$(if 
$(CONFIG_x86_64),x64,ia32).efi \
+               -O $(CONFIG_ARCH)-efi \
+               -c $(KDIR)/grub2/grub-early.cfg \
+               $(GRUB2_MODULES_EFI)
+
+       grub-mkimage \
+               -p /boot/grub \
+               -d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
+               -o $(KDIR)/grub2/core.img \
+               -O i386-pc \
+               -c $(KDIR)/grub2/grub-early.cfg \
+               $(GRUB2_MODULES) part_gpt fat
+
+       $(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/
+       echo '(hd0) $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-efi.img' > 
$(KDIR)/grub2/device.map
+       sed \
+               -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
+               -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
+               -e 's#@CMDLINE@#$(strip $(call Image/cmdline/$(1)/efi) 
$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
+               -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
+               -e 's#@TITLE@#$(GRUB_TITLE)#g' \
+               -e 's#msdos1#gpt1#g' \
+               ./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
+       -$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
+       EFI_SIGNATURE=$(EFI_SIGNATURE) PADDING="$(CONFIG_TARGET_IMAGES_PAD)" 
SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" 
$(SCRIPT_DIR)/gen_image_generic.sh \
+               $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-efi.img \
+               $(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \
+               $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \
+               256
+       grub-bios-setup \
+               --device-map="$(KDIR)/grub2/device.map" \
+               -d "$(KDIR)/grub2" \
+               -r "hd0,gpt1" \
+               "$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-efi.img"
+  endef
+endif
+
 define Image/Build/squashfs
        dd if=/dev/zero bs=128k count=1 >> $(KDIR)/root.squashfs
 endef
 
 define Image/Build/iso
        $(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
+       $(INSTALL_DIR) $(KDIR)/root.grub/efi/boot
        $(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
        grub-mkimage \
                -p /boot/grub \
@@ -111,6 +174,17 @@ define Image/Build/iso
                $(STAGING_DIR_HOST)/lib/grub/i386-pc/cdboot.img \
                $(KDIR)/grub2/eltorito.img \
                > $(KDIR)/root.grub/boot/grub/eltorito.img
+       grub-mkimage \
+               -p /boot/grub \
+               -d $(STAGING_DIR_HOST)/lib/grub/$(CONFIG_ARCH)-efi \
+               -o $(KDIR)/root.grub/efi/boot/boot$(if 
$(CONFIG_x86_64),x64,ia32).efi \
+               -O $(CONFIG_ARCH)-efi \
+               -c ./grub-early.cfg \
+               $(GRUB2_MODULES_EFI) iso9660
+
+       rm -f $(KDIR)/root.grub/efiboot.img
+       mkfs.fat -C $(TARGET_DIR)/efiboot.img -S 512 1440
+       mcopy -s -i $(TARGET_DIR)/efiboot.img $(KDIR)/root.grub/efi ::/
        sed \
                -e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
                -e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
@@ -120,11 +194,12 @@ define Image/Build/iso
                ./grub-iso.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
        -$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
        mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
+               -boot-load-size 4 -c boot.cat -eltorito-alt-boot -e efiboot.img 
-no-emul-boot \
                -o $(KDIR)/root.iso $(KDIR)/root.grub $(TARGET_DIR)
 endef
 
 ifneq ($(CONFIG_VDI_IMAGES),)
-  define Image/Build/vdi
+  define Image/Build/vdi/default
        rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi || true
        qemu-img convert -f raw -O vdi \
                $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
@@ -133,7 +208,7 @@ ifneq ($(CONFIG_VDI_IMAGES),)
 endif
 
 ifneq ($(CONFIG_VMDK_IMAGES),)
-  define Image/Build/vmdk
+  define Image/Build/vmdk/default
        rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vmdk || true
        qemu-img convert -f raw -O vmdk \
                $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
@@ -141,8 +216,27 @@ ifneq ($(CONFIG_VMDK_IMAGES),)
   endef
 endif
 
+ifneq ($(CONFIG_GRUB_IMAGES),)
+  define Image/Build/vdi
+       $(call Image/Build/vdi/default,$(1))
+  endef
+  define Image/Build/vmdk
+       $(call Image/Build/vmdk/default,$(1))
+  endef
+endif
+
+ifneq ($(CONFIG_EFI_IMAGES),)
+  define Image/Build/vdi/efi
+       $(call Image/Build/vdi/default,$(1)-efi)
+  endef
+  define Image/Build/vmdk/efi
+       $(call Image/Build/vmdk/default,$(1)-efi)
+  endef
+endif
+
 define Image/Build/gzip
-       gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img
+       $(if $(CONFIG_GRUB_IMAGES),gzip -f9n 
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img)
+       $(if $(CONFIG_EFI_IMAGES),gzip -f9n 
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-efi.img)
        gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
 endef
 
@@ -173,6 +267,9 @@ define Image/Build
        $(call Image/Build/grub2,$(1))
        $(call Image/Build/vdi,$(1))
        $(call Image/Build/vmdk,$(1))
+       $(call Image/Build/grub2/efi,$(1))
+       $(call Image/Build/vdi/efi,$(1))
+       $(call Image/Build/vmdk/efi,$(1))
        $(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
   else
        $(CP) $(KDIR)/root.iso $(BIN_DIR)/$(IMG_PREFIX).iso
diff --git a/target/linux/x86/image/grub-iso.cfg 
b/target/linux/x86/image/grub-iso.cfg
index 9c59bdf..4530258 100644
--- a/target/linux/x86/image/grub-iso.cfg
+++ b/target/linux/x86/image/grub-iso.cfg
@@ -3,7 +3,12 @@
 
 set default="0"
 set timeout="@TIMEOUT@"
-set root='(cd)'
+
+if [ x${grub_platform} = xefi ]; then
+    set root='(cd0)'
+else
+    set root='(cd)'
+fi
 
 menuentry "@TITLE@" {
        linux /boot/vmlinuz @CMDLINE@ noinitrd
-- 
1.8.3.1


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to