diff --git a/config/Config-images.in b/config/Config-images.in index 339ddeb096..a50547c29b 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -188,28 +188,28 @@ menu "Target Images" select PACKAGE_grub2 default y - config EFI_IMAGES - bool "Build EFI GRUB images (Linux x86 or x86_64 host only)" + 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_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS + 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 || EFI_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default y config GRUB_SERIAL string "Serial port device" - depends on GRUB_IMAGES || EFI_IMAGES - default "hvc0" if TARGET_x86_xen_domu - default "ttyS0" if ! TARGET_x86_xen_domu + depends on GRUB_IMAGES || GRUB_EFI_IMAGES + default "ttyS0" config GRUB_BAUDRATE int "Serial port baud rate" - depends on GRUB_IMAGES || EFI_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default 38400 if TARGET_x86_generic default 115200 @@ -220,21 +220,20 @@ menu "Target Images" config GRUB_BOOTOPTS string "Extra kernel boot options" - depends on GRUB_IMAGES || EFI_IMAGES - default "xencons=hvc" if TARGET_x86_xen_domu + 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 || EFI_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default "0" 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 || EFI_IMAGES + depends on GRUB_IMAGES || GRUB_EFI_IMAGES default "OpenWrt" help This is the title of the GRUB menu entry. @@ -243,39 +242,21 @@ menu "Target Images" 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 || TARGET_x86_64 - select GRUB_IMAGES - select TARGET_IMAGES_PAD + depends on TARGET_x86 + depends on GRUB_IMAGES || GRUB_EFI_IMAGES select PACKAGE_kmod-e1000 config VMDK_IMAGES bool "Build VMware image files (VMDK)" - depends on TARGET_x86 || TARGET_x86_64 - select GRUB_IMAGES - select TARGET_IMAGES_PAD + depends on TARGET_x86 + depends on GRUB_IMAGES || GRUB_EFI_IMAGES select PACKAGE_kmod-e1000 default y - config VHD_IMAGES - bool "Build Hyper-V image files (VHD)" - depends on TARGET_x86 || TARGET_x86_64 - depends on GRUB_IMAGES || EFI_IMAGES - select TARGET_IMAGES_PAD - select PACKAGE_kmod-tulip - default n - - config QCOW2_IMAGES - bool "Build PVE/KVM image files (QCOW2)" - depends on TARGET_x86 || TARGET_x86_64 - depends on GRUB_IMAGES || EFI_IMAGES - select TARGET_IMAGES_PAD - select PACKAGE_kmod-e1000 - default n - config TARGET_IMAGES_PAD bool "Pad images to filesystem size (for JFFS2)" depends on GRUB_IMAGES || EFI_IMAGES @@ -307,7 +288,7 @@ menu "Target Images" config TARGET_ROOTFS_PARTNAME string "Root partition on target device" - depends on GRUB_IMAGES || EFI_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 diff --git a/include/image.mk b/include/image.mk index cdbc129ded..00235daeb3 100644 --- a/include/image.mk +++ b/include/image.mk @@ -42,6 +42,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$ 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 diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index 1da87b975d..e2b3ff9664 100755 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -98,6 +98,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 uuid disk uevent line local MAJOR MINOR DEVNAME DEVTYPE @@ -144,6 +162,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/${disk##*/}/uevent" ;; @@ -203,17 +232,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 } diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh index 5162be11dd..9d05b6254e 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 ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID}) 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 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" diff --git a/target/linux/x86/64/target.mk b/target/linux/x86/64/target.mk index 95e32b3360..637bef1a09 100644 --- a/target/linux/x86/64/target.mk +++ b/target/linux/x86/64/target.mk @@ -1,5 +1,5 @@ ARCH:=x86_64 -BOARDNAME:=x64 64bit +BOARDNAME:=x64_64 DEFAULT_PACKAGES += kmod-button-hotplug kmod-e1000e kmod-e1000 kmod-igb kmod-bnx2 define Target/Description 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 aff720a52c..8dc44e772b 100644 --- a/target/linux/x86/base-files/lib/preinit/79_move_config +++ b/target/linux/x86/base-files/lib/preinit/79_move_config @@ -2,15 +2,16 @@ # 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 - if [ -f /boot/sysupgrade.tgz ]; then - mv -f /boot/sysupgrade.tgz / + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /boot + if [ -f "/boot/sysupgrade.tgz" ]; then + mv -f "/boot/sysupgrade.tgz" / fi mount --bind /boot/boot /boot fi diff --git a/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader new file mode 100644 index 0000000000..42f04d76a7 --- /dev/null +++ b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader @@ -0,0 +1,18 @@ +upgrade_bootloader() { + local diskdev + + . /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" \ + -d "/boot/grub" \ + -r "hd0,msdos1" \ + "/dev/$diskdev" \ + && touch /boot/grub/upgraded + fi +} + +[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main upgrade_bootloader diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh index 439ba8f512..9147ddcf2a 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh @@ -1,3 +1,5 @@ +RAMFS_COPY_BIN='grub-bios-setup' + platform_check_image() { local diskdev partdev diff [ "$#" -gt 1 ] && return 1 @@ -17,8 +19,8 @@ platform_check_image() { 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 + echo "Extract boot sector from the image" + get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b get_partitions /tmp/image.bs image @@ -35,15 +37,38 @@ platform_check_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 - cp -af "$CONF_TAR" /mnt/ + part_magic_fat "/dev/$partdev" && parttype=vfat + mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt + cp -af "$CONF_TAR" "/mnt/" 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 /tmp/boot/boot/grub/upgraded + + umount /tmp/boot + fi +} + platform_do_upgrade() { local diskdev partdev diff @@ -54,11 +79,11 @@ platform_do_upgrade() { sync - if [ "$SAVE_PARTITIONS" = "1" ]; then + 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=1 bs=512b + echo "Extract boot sector from the image" + get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b get_partitions /tmp/image.bs image @@ -69,7 +94,7 @@ platform_do_upgrade() { fi if [ -n "$diff" ]; then - get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync + get_image_dd "$1" 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 @@ -83,13 +108,24 @@ platform_do_upgrade() { 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 "$1" 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 + get_image_dd "$1" 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 } diff --git a/target/linux/x86/generic/config-4.14 b/target/linux/x86/generic/config-4.14 index b752f2e55b..9a37b735da 100644 --- a/target/linux/x86/generic/config-4.14 +++ b/target/linux/x86/generic/config-4.14 @@ -126,6 +126,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 afd3c55c0a..7d59d2531c 100644 --- a/target/linux/x86/generic/config-4.19 +++ b/target/linux/x86/generic/config-4.19 @@ -138,6 +138,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 @@ -458,4 +459,4 @@ CONFIG_XEN_XENBUS_FRONTEND=y CONFIG_XPS=y CONFIG_ZLIB_DEFLATE=y # CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set -# CONFIG_INTEL_ATOMISP2_PM is not set \ No newline at end of file +# CONFIG_INTEL_ATOMISP2_PM is not set diff --git a/target/linux/x86/generic/config-4.9 b/target/linux/x86/generic/config-4.9 index 2eb30069c1..84b3d1a23f 100644 --- a/target/linux/x86/generic/config-4.9 +++ b/target/linux/x86/generic/config-4.9 @@ -127,6 +127,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/target.mk b/target/linux/x86/generic/target.mk index 70527d001d..90586f56d6 100644 --- a/target/linux/x86/generic/target.mk +++ b/target/linux/x86/generic/target.mk @@ -1,4 +1,4 @@ -BOARDNAME:=x86 32bit +BOARDNAME:=Generic CPU_TYPE :=pentium4 FEATURES += audio pci pcie usb DEFAULT_PACKAGES += kmod-button-hotplug diff --git a/target/linux/x86/legacy/target.mk b/target/linux/x86/legacy/target.mk index a82e49ea8f..bd0a87d67f 100644 --- a/target/linux/x86/legacy/target.mk +++ b/target/linux/x86/legacy/target.mk @@ -1,4 +1,4 @@ -BOARDNAME:=Legacy x86 (i586) +BOARDNAME:=Legacy define Target/Description Build firmware images for legacy x86 based boards