select PACKAGE_grub2
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
bool "Use Console Terminal (in addition to Serial)"
- depends on GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default y
config GRUB_SERIAL
string "Serial port device"
- depends on GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default "ttyS0"
config GRUB_BAUDRATE
int "Serial port baud rate"
- depends on GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
default 38400 if TARGET_x86_generic
default 115200
config GRUB_BOOTOPTS
string "Extra kernel boot options"
- depends on GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_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 || GRUB_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 || GRUB_EFI_IMAGES
default "OpenWrt"
help
This is the title of the GRUB menu entry.
config ISO_IMAGES
bool "Build LiveCD image (ISO)"
depends on TARGET_x86
- select GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
config VDI_IMAGES
bool "Build VirtualBox image files (VDI)"
depends on TARGET_x86
- select GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-e1000
config VMDK_IMAGES
bool "Build VMware image files (VMDK)"
depends on TARGET_x86
- select GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_EFI_IMAGES
select PACKAGE_kmod-e1000
config TARGET_IMAGES_GZIP
config TARGET_ROOTFS_PARTNAME
string "Root partition on target device"
- depends on GRUB_IMAGES
+ depends on GRUB_IMAGES || GRUB_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
IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
IMG_COMBINED:=$(IMG_PREFIX)-combined
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
(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
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"
;;
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
}
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 ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID})
KERNELOFFSET="$(($1 / 512))"
KERNELSIZE="$2"
[ -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 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
rm -f "$OUTPUT.kernel"
# Copyright (C) 2012-2015 OpenWrt.org
move_config() {
- local partdev
+ local partdev 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
+ part_magic_fat "/dev/$partdev" && parttype=vfat
+ mount -t $parttype -o rw,noatime "/dev/$partdev" /boot
if [ -f "/boot/$BACKUP_FILE" ]; then
mv -f "/boot/$BACKUP_FILE" /
fi
. /lib/upgrade/common.sh
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
/usr/sbin/grub-bios-setup \
-m "/tmp/device.map" \
get_partitions "/dev/$diskdev" bootdisk
#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
}
platform_copy_config() {
- local partdev
+ local partdev parttype=ext4
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"
umount /mnt
fi
}
platform_do_bootloader_upgrade() {
- local bootpart
+ 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,msdos1" \
+ -r "hd0,${parttable}1" \
"/dev/$diskdev" \
&& touch /boot/grub/upgraded
get_partitions "/dev/$diskdev" bootdisk
#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
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
+ 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
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
+
}
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
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
ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
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_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
define Build/combined
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
- PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" $(SCRIPT_DIR)/gen_image_generic.sh \
+ $(if $(filter $(1),efi),
+ $(INSTALL_DIR) $@.boot/efi/boot
+ $(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi $@.boot/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) $@.boot \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#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#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
rm -fR $@.grub2
$(INSTALL_DIR) $@.grub2
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/
- $(CP) $(STAGING_DIR_IMAGE)/grub2/$(GRUB2_VARIANT)-core.img $@.grub2/core.img
+ $(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img $@.grub2/core.img
echo '(hd0) $@' > $@.grub2/device.map
$(STAGING_DIR_HOST)/bin/grub-bios-setup \
-m "$@.grub2/device.map" \
-d "$@.grub2" \
- -r "hd0,msdos1" \
+ -r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \
$@
endef
$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
> $@.boot/boot/grub/eltorito.img
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
+ $(if $(filter $(1),efi),
+ mkfs.fat -C $@.boot/boot/grub/isoboot.img -S 512 1440
+ mmd -i $@.boot/boot/grub/isoboot.img ::/efi ::/efi/boot
+ mcopy -i $@.boot/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 \
+ $(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \
-o $@ $@.boot $(TARGET_DIR)
endef
IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
IMAGE/rootfs.img := append-rootfs
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)
- 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
- IMAGES := combined.img rootfs.img
+ IMAGES-y := rootfs.img
+ IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
+ IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
endif
KERNEL := kernel-bin
KERNEL_INSTALL := 1
KERNEL_NAME := bzImage
ifeq ($(CONFIG_ISO_IMAGES),y)
- ARTIFACTS := image.iso
+ ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso
+ ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso
endif
ifeq ($(CONFIG_VDI_IMAGES),y)
- IMAGES += combined.vdi
+ IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi
+ IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi
endif
ifeq ($(CONFIG_VMDK_IMAGES),y)
- IMAGES += combined.vmdk
+ IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk
+ IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk
endif
+ IMAGES := $$(IMAGES-y)
+ ARTIFACTS := $$(ARTIFACTS-y)
endef
$(eval $(call Image/gzip-ext4-padded-squashfs))
--- /dev/null
+@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
+}
set default="0"
set timeout="@TIMEOUT@"
-set root='(cd)'
+
+if [ "${grub_platform}" = "efi" ]; then
+ set root='(cd0)'
+else
+ set root='(cd)'
+fi
menuentry "@TITLE@" {
linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd