From 86a61e716efe2e0ef2f4ce9b2fdd7a532661ef56 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Sat, 10 Jul 2021 16:35:47 +0100 Subject: [PATCH] mediatek: rework Bananapi BPi-R2 * introduce recovery (=initramfs) vs. production dual boot scheme * make use of uImage.FIT (instead of FAT partition) * generate images using build steps (instead of external scripts) * simplify sysupgrade and config restore (thanks to uImage.FIT) * make sure mmc devices are ordered persistently (set DT aliases) This commit breaks sysupgrade from existing installations, you will have to re-install using the sdcard.img.gz image. Signed-off-by: Daniel Golle --- target/linux/mediatek/image/Config.in | 2 +- target/linux/mediatek/image/mt7623.mk | 144 +++++++++++++----- .../mediatek/image/mt7623n_bpir2-uEnv.txt | 78 ---------- .../base-files/lib/preinit/79_move_config | 3 - .../mt7623/base-files/lib/upgrade/platform.sh | 50 +++--- target/linux/mediatek/mt7623/config-5.10 | 1 + .../160-dts-mt7623-bpi-r2-earlycon.patch | 11 ++ ...1-dts-mt7623-bpi-r2-mmc-device-order.patch | 11 ++ 8 files changed, 153 insertions(+), 147 deletions(-) delete mode 100644 target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt create mode 100644 target/linux/mediatek/patches-5.10/160-dts-mt7623-bpi-r2-earlycon.patch create mode 100644 target/linux/mediatek/patches-5.10/161-dts-mt7623-bpi-r2-mmc-device-order.patch diff --git a/target/linux/mediatek/image/Config.in b/target/linux/mediatek/image/Config.in index ef8536ebab..63329d386a 100644 --- a/target/linux/mediatek/image/Config.in +++ b/target/linux/mediatek/image/Config.in @@ -1,4 +1,4 @@ config MTK_BOOT_PARTSIZE int "Boot (SD Card/eMMC) filesystem partition size (in MiB)" - depends on TARGET_mediatek_mt7623_DEVICE_bpi_bananapi-r2 || TARGET_DEVICE_mediatek_mt7623_DEVICE_bpi_bananapi-r2 || TARGET_mediatek_mt7623_DEVICE_unielec_u7623-emmc || TARGET_DEVICE_mediatek_mt7623_DEVICE_unielec_u7623-emmc + depends on TARGET_mediatek_mt7623_DEVICE_unielec_u7623-emmc || TARGET_DEVICE_mediatek_mt7623_DEVICE_unielec_u7623-emmc default 32 diff --git a/target/linux/mediatek/image/mt7623.mk b/target/linux/mediatek/image/mt7623.mk index 56f67c0e89..c404b333ba 100644 --- a/target/linux/mediatek/image/mt7623.mk +++ b/target/linux/mediatek/image/mt7623.mk @@ -1,59 +1,123 @@ KERNEL_LOADADDR := 0x80008000 DEVICE_VARS += UBOOT_TARGET UBOOT_OFFSET UBOOT_ENVSIZE -ifneq ($(CONFIG_MTK_BOOT_PARTSIZE),) -BOOTFS_BLOCK_SIZE := 1024 -BOOTFS_BLOCKS := $(shell echo $$(($(CONFIG_MTK_BOOT_PARTSIZE)*1024*1024/$(BOOTFS_BLOCK_SIZE)))) -endif +# The bootrom of MT7623 expects legacy MediaTek headers present in +# exactly the location also used for the primary GPT partition table. +# (*MMC_BOOT and BRLYT) +# Hence only MSDOS/MBR partitioning can work here. +# +# ------------------------ Sector Offset +# | MBR + SDMMC_BOOT | 0 0x0 +# |----------------------| +# | BRLYT header | 1 0x200 +# |----------------------| +# . . +# . . +# |----------------------| +# | | 4 0x800 +# | | +# | Preloader | +# . . +# . . +# | | 639 +# |----------------------| +# | MBR partition #1 | 640 0x50000 +# | | +# | U-Boot | +# . . +# . . +# | | 1663 +# |----------------------| +# | MBR partition #2 | +# | | +# | Recovery | +# . . +# . (uImage.FIT) . +# | | +# |----------------------| +# | MBR partition #3 | +# | | +# | Production | +# | | +# | (uImage.FIT, | +# . rootfs_Data.) . +# . . +# | | +# ------------------------ +# +# For eMMC boot, everything up to and including the preloader must be +# written to /dev/mmcblk0boot0, with the SDMMC_BOOT header changed to +# read EMMC_BOOT\0 instead. +# +# The contents of the main eMMC are identical to the SD card layout, +# with the preloader loading 512KiB of U-Boot starting at 0x50000. -define Build/mtk-mmc-img - rm -f $@.boot - mkfs.fat -C $@.boot $(BOOTFS_BLOCKS) +define Build/mt7623-mbr + cp $@ $@.tmp 2>/dev/null || true + ptgen -o $@.tmp -h 4 -s 63 -a 0 -l 1024 \ + -t 0x41 -N uboot -p 3584k@320k \ + -t 0xea -N recovery -p 40M@4M \ + $(if $(findstring sdmmc,$1), \ + -t 0x2e -N production -p 208M@48M \ + ) \ + $(if $(findstring emmc,$1), \ + -t 0x2e -N production -p 976M@48M \ + ) - if [ -r $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-preloader.bin ]; then \ - ./gen_mtk_mmc_img.sh emmc $@.emmc \ - $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-preloader.bin; \ - mcopy -i $@.boot $@.emmc ::eMMCboot.bin; \ - fi - mkenvimage -s $(UBOOT_ENVSIZE) -o $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-uboot.env $(UBOOT_TARGET)-uEnv.txt - mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-uboot.env ::uboot.env - mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage - ./gen_mtk_mmc_img.sh sd $@ \ - $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-preloader.bin \ - $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-u-boot*.bin \ - $(UBOOT_OFFSET) \ - $@.boot \ - $(IMAGE_ROOTFS) \ - $(CONFIG_MTK_BOOT_PARTSIZE) \ - $(CONFIG_TARGET_ROOTFS_PARTSIZE) + echo -en \ + $(if $(findstring sdmmc,$1),"SDMMC_BOOT\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00") \ + $(if $(findstring emmc,$1),"EMMC_BOOT\x00\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00") \ + | dd bs=1 of="$@.tmp" seek=0 conv=notrunc + + echo -en "BRLYT\x00\x00\x00\x01\x00\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x42\x42\x42\x42\x08\x00\x01\x00\x00\x08\x00\x00\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\ + | dd bs=1 of="$@.tmp" seek=512 conv=notrunc + + cat $@.tmp >> $@ + rm $@.tmp endef -define Build/preloader - $(CP) $(STAGING_DIR_IMAGE)/$1-preloader.bin $@ +define Build/append-preloader + cat $(STAGING_DIR_IMAGE)/$1-preloader.bin >> $@ endef -define Build/scatterfile - ./gen_scatterfile.sh $(subst mt,MT,$(SUBTARGET)) "$1" \ - $(subst -scatter.txt,,$(notdir $@)) "$(DEVICE_TITLE)" > $@ +define Build/append-bootloader + cat $(STAGING_DIR_IMAGE)/$1-u-boot.bin >> $@ endef -define Device/bpi_bananapi-r2 - DEVICE_VENDOR := Bpi - DEVICE_MODEL := Banana Pi R2 +define Device/bananapi_bpi-r2 + DEVICE_VENDOR := Bananapi + DEVICE_MODEL := BPi-R2 DEVICE_DTS := mt7623n-bananapi-bpi-r2 - DEVICE_PACKAGES := kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc \ - mkf2fs e2fsprogs kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk - UBOOT_ENVSIZE := 0x2000 + DEVICE_PACKAGES := kmod-mmc mkf2fs e2fsprogs kmod-usb3 kmod-ata-ahci + UBOOT_ENVSIZE := 0x10000 UBOOT_OFFSET := 320k UBOOT_TARGET := mt7623n_bpir2 - IMAGES := img.gz - IMAGE/img.gz := mtk-mmc-img | gzip | append-metadata - ARTIFACT/preloader.bin := preloader $$(UBOOT_TARGET) - ARTIFACT/scatter.txt := scatterfile $$(firstword $$(FILESYSTEMS))-$$(firstword $$(IMAGES)) - ARTIFACTS = preloader.bin scatter.txt + UBOOT_PATH := $(STAGING_DIR_IMAGE)/mt7623n_bpir2-u-boot.bin + IMAGES := sysupgrade.itb + KERNEL := kernel-bin | gzip + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb with-initrd + IMAGE/sysupgrade.itb := append-kernel | fit gzip $$(DTS_DIR)/$$(DEVICE_DTS).dtb external-static-with-rootfs | append-metadata + ARTIFACT/preloader.bin := append-preloader $$(UBOOT_TARGET) + ARTIFACT/u-boot.bin := append-uboot + ARTIFACT/sdcard.img.gz := mt7623-mbr sdmmc |\ + pad-to 2k | append-preloader $$(UBOOT_TARGET) |\ + pad-to 320k | append-bootloader $$(UBOOT_TARGET) |\ + pad-to 4092k | mt7623-mbr emmc |\ + pad-to 4M | append-image-stage initramfs-recovery.itb |\ + pad-to 48M | append-image squashfs-sysupgrade.itb |\ + gzip + ARTIFACTS = u-boot.bin preloader.bin scatter.txt sdcard.img.gz SUPPORTED_DEVICES := bananapi,bpi-r2 endef -TARGET_DEVICES += bpi_bananapi-r2 +TARGET_DEVICES += bananapi_bpi-r2 + + + +define Build/scatterfile + ./gen_scatterfile.sh $(subst mt,MT,$(SUBTARGET)) "$1" \ + $(subst -scatter.txt,,$(notdir $@)) "$(DEVICE_TITLE)" > $@ +endef # Full eMMC image including U-Boot and partition table define Device/unielec_u7623-emmc diff --git a/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt b/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt deleted file mode 100644 index f260ed9176..0000000000 --- a/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt +++ /dev/null @@ -1,78 +0,0 @@ -# Boot menu for Banana Pi R2 -# Copyright © 2020 David Woodhouse - -kernel=uImage -loadaddr=0x88000000 -dtaddr=0x83f00000 -fdt_high=0xffffffff - -console=ttyS2,115200 -bootopts=rootfstype=squashfs,ext4 rootwait - -# Create the command line (with appropriate root=) and boot the Linux FIT image. -boot1=setenv bootargs "console=${console} root=${rootdev} ${bootopts}";printenv bootargs;\ - fatload mmc ${partition} ${loadaddr} ${kernel}; bootm - -# The preloader leaves a breadcrumb behind to say what it booted from. -checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi; - -# Build the boot menu one item at a time -bm_count=0 -checkkernel=test -e mmc ${bm_part} ${kernel} -addbm=if run checkkernel; then setenv bootmenu_${bm_count} "Boot from ${bm_dev}.=setenv partition ${bm_part};setenv rootdev ${bm_root};run boot1";if test "${bootedfrom}" = "${bm_dev}"; then setenv bootmenu_default ${bm_count};fi;setexpr bm_count ${bm_count} + 1; fi -# Here we assume that SD card id mmcblk1 and eMMC is mmcblk0 in linux. Swap them if your DTS define them in reverse order. -addeMMCbm=setenv bm_part 0:2;setenv bm_root /dev/mmcblk0p3;setenv bm_dev eMMC;run addbm -addSDbm=setenv bm_part 1:2;setenv bm_root /dev/mmcblk1p3;setenv bm_dev SD;run addbm -addinstallbm=if test "${bootedfrom}" = "SD";then run checkinstall; if run validparts; then setenv bootmenu_${bm_count} "Install OpenWrt from SD to internal eMMC.=run doinstall";setexpr bm_count ${bm_count} + 1;fi;fi - -runbootmenu=if test "${bootedfrom}" = "";then run checkbootedfrom;fi;\ - setenv bm_count 0;run addeMMCbm;run addSDbm;run addinstallbm;setenv bootmenu_${bm_count};\ - bootmenu - -bootdelay=0 -bootcmd=run checkbootedfrom;run runbootmenu - -# XX: Can we read this from the device, or must we trust they're all the same as mine? -# Probably not that important as we're unlikely ever to hit the limit anyway. -maxsect=0xe8ffff -validparts=false - -# We could use 'part size' here but I'd like to check the types too. -checkinstall=mmc dev 1;\ - mmc read 0x88000002 0 1;\ - setenv validparts true;\ - test -e mmc 1:2 eMMCboot.bin || setenv validparts false && echo "eMMCboot.bin not present on SD partition 2";\ - if run validparts && itest.b *0x880001c4 != 0x41; then echo "SD partition 1 is not a PReP Boot partition"; setenv validparts false; fi;\ - if run validparts && itest.l *0x880001c8 != 0x280; then echo "SD partition 1 does not start at 320KiB for U-Boot"; mmc part; exit; fi;\ - if run validparts && itest.l *0x880001cc != 0x400; then echo "SD partition 1 is not 512KiB in size for U-Boot"; mmc part; exit; fi;\ - if run validparts && itest.b *0x880001d4 != 0x0c; then echo "SD partition 2 is not a FAT32 partition"; setenv validparts false; fi;\ - if run validparts && itest.b *0x880001e4 != 0x83; then echo "SD partition 3 is not a Linux partition"; setenv validparts false; fi;\ - setexpr.l part2_start *0x880001d8;setexpr.l part2_len *0x880001dc;setexpr.l part3_start *0x880001e8;setexpr.l part3_len *0x880001ec;\ - if run validparts && test 0x${part2_start} -gt ${maxsect}; then echo "SD partition 2 start too high"; setenv validparts false; fi;\ - if run validparts && test 0x${part2_len} -gt ${maxsect}; then echo "SD partition 2 is too large"; setenv validparts false; fi;\ - if run validparts && test 0x${part3_start} -gt ${maxsect}; then echo "SD partition 3 start too high"; setenv validparts false; fi;\ - if run validparts && test 0x${part3_len} -gt ${maxsect}; then echo "SD partition 2 is too large"; setenv validparts false; fi;\ - setexpr.l part2_end 0x$(part2_start} + 0x${part2_len};setexpr.l part3_end 0x${part3_start} + 0x${part3_len};\ - if run validparts && test 0x${part2_end} -ge ${maxsect}; then echo "SD partition 2 end too high"; setenv validparts false; fi;\ - if run validparts && test 0x${part3_end} -ge ${maxsect}; then echo "SD partition 3 end too high"; setenv validparts false; fi; - -# Copy a single chunk, up to 0x8000 sectors / 16MiB, from SD to eMMC at the specified offset. -writechunk=setenv thislen 8000; if test 0x${partlen} -lt 0x${thislen}; then setenv thislen ${partlen};fi;\ - mmc dev 1;mmc read ${loadaddr} 0x${partofs} 0x${thislen};\ - mmc dev 0; mmc write ${loadaddr} 0x${partofs} 0x${thislen};\ - setexpr partofs 0x${partofs} + 0x${thislen};setexpr partlen 0x${partlen} - 0x${thislen} - -# Copy a partition defined by ${partofs} / ${partlen} from SD to eMMC -writepart=while test 0x${partlen} -ne 0; do run writechunk; done - -# Configure the eMMC boot partition and write eMMCboot.bin to it -writeboot=mmc partconf 0 1 1 0;fatload mmc 1:2 ${loadaddr} eMMCboot.bin;\ - setexpr filesize ${filesize} + 0x1ff;setexpr blocks ${filesize} / 0x200;\ - mmc dev 0 1;mmc write ${loadaddr} 0 ${blocks} - -# Install OpenWrt from the SD card to internal eMMC. -doinstall=run checkinstall;if run validparts;then run writeboot;\ - echo "Copying preloader and U-Boot";setenv partofs 0;setenv partlen 680;run writepart;\ - echo "Copying FAT boot partition";setenv partofs ${part2_start};setenv partlen ${part2_len};run writepart;\ - echo "Copying root partition";setenv partofs ${part3_start};setenv partlen ${part3_len};run writepart;\ - echo "Installed OpenWrt to eMMC";setenv bootedfrom eMMC;run runbootmenu;fi diff --git a/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config b/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config index f47894c0fd..9dfb06bd81 100644 --- a/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config +++ b/target/linux/mediatek/mt7623/base-files/lib/preinit/79_move_config @@ -6,9 +6,6 @@ move_config() { local partdev partnum case $(board_name) in - bananapi,bpi-r2) - partnum=2 - ;; unielec,u7623-02-emmc-512m) if grep -q root=/dev/mmcblk0p2 /proc/cmdline; then partnum=1; diff --git a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh index d3da22d496..4564bc61dd 100755 --- a/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/mt7623/base-files/lib/upgrade/platform.sh @@ -1,5 +1,6 @@ REQUIRE_IMAGE_METADATA=1 +RAMFS_COPY_BIN='blockdev' # Full system upgrade including preloader for MediaTek SoCs on eMMC or SD mtk_mmc_full_upgrade() { @@ -83,7 +84,18 @@ platform_do_upgrade() { case "$board" in bananapi,bpi-r2) - mtk_mmc_full_upgrade "$1" + export_bootdevice + export_partdevice rootdev 0 + export_partdevice fitpart 3 + [ "$fitpart" ] || return 1 + dd if=/dev/zero of=/dev/$fitpart bs=4096 count=1 2>/dev/null + blockdev --rereadpt /dev/$rootdev + get_image "$1" | dd of=/dev/$fitpart + blockdev --rereadpt /dev/$rootdev + local datapart=$(get_partition_by_name $rootdev "rootfs_data") + [ "$datapart" ] || return 0 + dd if=/dev/zero of=/dev/$datapart bs=4096 count=1 2>/dev/null + echo $datapart > /tmp/sysupgrade.datapart ;; unielec,u7623-02-emmc-512m) @@ -126,32 +138,10 @@ platform_check_image() { case "$board" in bananapi,bpi-r2) - [ "$magic" != "53444d4d" ] && { + [ "$magic" != "d00dfeed" ] && { echo "Invalid image type." return 1 } - export_bootdevice && export_partdevice diskdev 0 || { - echo "Unable to determine upgrade device" - return 1 - } - - 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_partitions /tmp/image.bs image - - #compare tables - diff="$(grep -F -x -v -f /tmp/partmap.bootdisk /tmp/partmap.image)" - - rm -f /tmp/image.bs /tmp/partmap.bootdisk /tmp/partmap.image - - if [ -n "$diff" ]; then - echo "Partition layout has changed. Full image will be written." - ask_bool 0 "Abort" && exit 1 - return 0 - fi ;; unielec,u7623-02-emmc-512m) # Can always upgrade to the new-style full image @@ -180,9 +170,19 @@ platform_check_image() { return 0 } +platform_copy_config_mmc() { + [ -e "$UPGRADE_BACKUP" ] || return + local datapart=$(cat /tmp/sysupgrade.datapart) + [ "$datapart" ] || echo "no rootfs_data partition, cannot keep configuration." >&2 + dd if="$UPGRADE_BACKUP" of=/dev/$datapart + sync +} + platform_copy_config() { case "$(board_name)" in - bananapi,bpi-r2|\ + bananapi,bpi-r2) + platform_copy_config_mmc + ;; unielec,u7623-02-emmc-512m) # platform_do_upgrade() will have set $recoverydev if [ -n "$recoverydev" ]; then diff --git a/target/linux/mediatek/mt7623/config-5.10 b/target/linux/mediatek/mt7623/config-5.10 index 4a43b51675..ca1f92ae78 100644 --- a/target/linux/mediatek/mt7623/config-5.10 +++ b/target/linux/mediatek/mt7623/config-5.10 @@ -229,6 +229,7 @@ CONFIG_HARDIRQS_SW_RESEND=y CONFIG_HAS_DMA=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y +CINFIG_HAVE_ARM_ARCH_TIMER=y CONFIG_HAVE_SMP=y CONFIG_HDMI=y CONFIG_HIGHMEM=y diff --git a/target/linux/mediatek/patches-5.10/160-dts-mt7623-bpi-r2-earlycon.patch b/target/linux/mediatek/patches-5.10/160-dts-mt7623-bpi-r2-earlycon.patch new file mode 100644 index 0000000000..bd386c8420 --- /dev/null +++ b/target/linux/mediatek/patches-5.10/160-dts-mt7623-bpi-r2-earlycon.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -19,7 +19,7 @@ + + chosen { + stdout-path = "serial2:115200n8"; +- bootargs = "console=ttyS2,115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11004000 console=ttyS2,115200n8"; + }; + + connector { diff --git a/target/linux/mediatek/patches-5.10/161-dts-mt7623-bpi-r2-mmc-device-order.patch b/target/linux/mediatek/patches-5.10/161-dts-mt7623-bpi-r2-mmc-device-order.patch new file mode 100644 index 0000000000..d1bafc1526 --- /dev/null +++ b/target/linux/mediatek/patches-5.10/161-dts-mt7623-bpi-r2-mmc-device-order.patch @@ -0,0 +1,11 @@ +--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +@@ -15,6 +15,8 @@ + + aliases { + serial2 = &uart2; ++ mmc0 = &mmc0; ++ mmc1 = &mmc1; + }; + + chosen { -- 2.30.2