From cfe79f2eb8b3c874f3d1a4441b8a60af32169974 Mon Sep 17 00:00:00 2001 From: Martin Kennedy Date: Wed, 22 Dec 2021 13:08:33 -0500 Subject: [PATCH] mpc85xx: Patch HiveAP 330 u-boot to fix boot When Kernel 5.10 was enabled for mpc85xx, the kernel once again became too large upon decompression (>7MB or so) to decompress itself on boot (see FS#4110[1]). There have been many attempts to fix booting from a compressed kernel on the HiveAP-330: - b683f1c36d8a ("mpc85xx: Use gzip compressed kernel on HiveAP-330") - 98089bb8ba82 ("mpc85xx: Use uncompressed kernel on the HiveAP-330") - 26cb167a5ca7 ("mpc85xx: Fix Aerohive HiveAP-330 initramfs image") We can no longer compress the kernel due to size, and the stock bootloader does not support any other types of compression. Since an uncompressed kernel no longer fits in the 8MiB kernel partition at 0x2840000, we need to patch u-boot to autoboot by running variable which isn't set by the bootloader on each autoboot. This commit repartitions the HiveAP, requiring a new COMPAT_VERSION, and uses the DEVICE_COMPAT_MESSAGE to guide the user to patch u-boot, which changes the variable run on boot to be `owrt_boot`; the user can then set the value of that variable appropriately. The following has been documented in the device's OpenWrt wiki page: . Please look there first/too for more information. The from-stock and upgrade from a previous installation now becomes: 0) setup a network with a dhcp server and a tftp server at serverip (192.168.1.101) with the initramfs image in the servers root directory. 1) Hook into UART (9600 baud) and enter U-Boot. You may need to enter a password of administrator or AhNf?d@ta06 if prompted. If the password doesn't work. Try reseting the device by pressing and holding the reset button with the stock OS. 2) Once in U-Boot, set the new owrt_boot and tftp+boot the initramfs image: Use copy and paste! # fw_setenv owrt_boot 'setenv bootargs \"console=ttyS0,$baudrate\";bootm 0xEC040000 - 0xEC000000' # save # dhcp # setenv bootargs console=ttyS0,$baudrate # tftpboot 0x1000000 192.168.1.101:openwrt-mpc85xx-p1020-aerohive_hiveap-330-initramfs-kernel.bin # bootm 3) Once openwrt booted: carefully copy and paste this into the root shell. One step at a time # 3.0 install kmod-mtd-rw from the internet and load it opkg update; opkg install kmod-mtd-rw insmod mtd-rw i_want_a_brick=y # 3.1 create scripts that modifies uboot cat <<- "EOF" > /tmp/uboot-update.sh . /lib/functions/system.sh cp "/dev/mtd$(find_mtd_index 'u-boot')" /tmp/uboot cp /tmp/uboot /tmp/uboot_patched ofs=$(strings -n80 -td < /tmp/uboot | grep '^ [0-9]* setenv bootargs.*cp\.l' | cut -f2 -d' ') for off in $ofs; do printf "run owrt_boot; " | dd of=/tmp/uboot_patched bs=1 seek=${off} conv=notrunc done md5sum /tmp/uboot* EOF # 3.2 run the script to do the modification sh /tmp/uboot-update.sh # verify that /tmp/uboot and /tmp/uboot_patched are good # # my uboot was: (is printed during boot) # U-Boot 2009.11 (Jan 12 2017 - 00:27:25), Build: jenkins-HiveOS-Honolulu_AP350_Rel-245 # # d84b45a2e8aca60d630fbd422efc6b39 /tmp/uboot # 6dc420f24c2028b9cf7f0c62c0c7f692 /tmp/uboot_patched # 98ebc7e7480ce9148cd2799357a844b0 /tmp/uboot-update.sh <-- just for reference # 3.3 this produces the /tmp/u-boot_patched file. mtd write /tmp/uboot_patched u-boot 3) scp over the sysupgrade file to /tmp/ and run sysupgrade to flash OpenWrt: sysupgrade -n /tmp/openwrt-mpc85xx-p1020-aerohive_hiveap-330-squashfs-sysupgrade.bin 4) after the reboot, you are good to go. Other notes: - Note that after this sysupgrade, the AP will be unavailable for 7 minutes to reformat flash. The tri-color LED does not blink in any way to indicate this, though there is no risk in interrupting this process, other than the jffs2 reformat being reset. - Add a uci-default to fix the compat version. This will prevent updates from previous versions without going through the installation process. - Enable CONFIG_MTD_SPLIT_UIMAGE_FW and adjust partitioning to combine the kernel and rootfs into a single dts partition to maximize storage space, though in practice the kernel can grow no larger than 16MiB due to constraints of the older mpc85xx u-boot platform. - Because of that limit, KERNEL_SIZE has been raised to 16m. - A .tar.gz of the u-boot source for the AP330 (a.k.a. Goldengate) can be found here[2]. - The stock-jffs2 partition is also removed to make more space -- this is possible only now that it is no longer split away from the rootfs. - the console-override is gone. The device will now get the console through the bootargs. This has the advantage that you can set a different baudrate in uboot and the linux kernel will stick with it! - due to the repartitioning, the partition layout and names got a makeover. - the initramfs+fdt method is now combined into a MultiImage initramfs. The separate fdt download is no longer needed. - added uboot-envtools to the mpc85xx target. All targets have uboot and this way its available in the initramfs. [1]: https://bugs.openwrt.org/index.php?do=details&task_id=4110 [2]: magnet:?xt=urn:btih:e53b27006979afb632af5935fa0f2affaa822a59 Tested-by: Martin Kennedy Signed-off-by: Martin Kennedy (rewrote parts of the commit message, Initramfs-MultiImage, dropped bootargs-override, added wiki entry + link, uboot-envtools) Signed-off-by: Christian Lamparter --- package/boot/uboot-envtools/files/mpc85xx | 3 + target/linux/mpc85xx/Makefile | 3 +- .../etc/uci-defaults/05_fix-compat-version | 11 ++++ .../arch/powerpc/boot/dts/hiveap-330.dts | 60 +++++++----------- target/linux/mpc85xx/image/p1020.mk | 61 ++++++++++++++++--- target/linux/mpc85xx/p1020/config-default | 1 + 6 files changed, 91 insertions(+), 48 deletions(-) create mode 100644 target/linux/mpc85xx/base-files/etc/uci-defaults/05_fix-compat-version diff --git a/package/boot/uboot-envtools/files/mpc85xx b/package/boot/uboot-envtools/files/mpc85xx index 004ec24131..df6e5f670b 100644 --- a/package/boot/uboot-envtools/files/mpc85xx +++ b/package/boot/uboot-envtools/files/mpc85xx @@ -12,6 +12,9 @@ ocedo,panda) ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x20000" "0x20000" ubootenv_add_uci_config "/dev/mtd2" "0x0" "0x20000" "0x20000" ;; +aerohive,hiveap-330) + ubootenv_add_uci_config "$(find_mtd_part 'u-boot-env')" "0x0" "0x20000" "0x10000" + ;; esac config_load ubootenv diff --git a/target/linux/mpc85xx/Makefile b/target/linux/mpc85xx/Makefile index b89bfc3ed1..6bf096740e 100644 --- a/target/linux/mpc85xx/Makefile +++ b/target/linux/mpc85xx/Makefile @@ -19,6 +19,7 @@ include $(INCLUDE_DIR)/target.mk DEFAULT_PACKAGES += \ kmod-input-core kmod-input-gpio-keys kmod-button-hotplug \ - kmod-leds-gpio swconfig kmod-ath9k wpad-basic-wolfssl kmod-usb2 + kmod-leds-gpio swconfig kmod-ath9k wpad-basic-wolfssl kmod-usb2 \ + uboot-envtools $(eval $(call BuildTarget)) diff --git a/target/linux/mpc85xx/base-files/etc/uci-defaults/05_fix-compat-version b/target/linux/mpc85xx/base-files/etc/uci-defaults/05_fix-compat-version new file mode 100644 index 0000000000..253c22900d --- /dev/null +++ b/target/linux/mpc85xx/base-files/etc/uci-defaults/05_fix-compat-version @@ -0,0 +1,11 @@ +. /lib/functions.sh +. /lib/functions/system.sh + +case "$(board_name)" in +aerohive,hiveap-330) + uci set system.@system[0].compat_version="2.0" + uci commit system + ;; +esac + +exit 0 diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/hiveap-330.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/hiveap-330.dts index 9eb6e2613a..359b123bc6 100644 --- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/hiveap-330.dts +++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/hiveap-330.dts @@ -22,10 +22,6 @@ label-mac-device = &enet0; }; - chosen { - bootargs-override = "console=ttyS0,9600"; - }; - memory { device_type = "memory"; }; @@ -47,36 +43,41 @@ #address-cells = <1>; #size-cells = <1>; + firmware@0 { + reg = <0x0 0x3f00000>; + label = "firmware"; + /* + * This unknown/invalid compatible prevents + * openwrt's mtdsplit_fit to go off a tangent if it + * finds a magic value inside the uncompressed kernel + * at a blocksized aligned place. + */ + compatible = "areohive,hiveap-330-image"; + }; + partition@0 { reg = <0x0 0x40000>; label = "dtb"; }; partition@40000 { - reg = <0x40000 0x40000>; - label = "initrd"; - }; - - partition@80000 { - reg = <0x80000 0x27c0000>; - label = "rootfs"; - }; - - partition@2840000 { - reg = <0x2840000 0x800000>; + compatible = "openwrt,uimage", "denx,uimage"; + reg = <0x40000 0x3ec0000>; label = "kernel"; }; - partition@3040000 { - reg = <0x3040000 0xec0000>; - label = "stock-jffs2"; - read-only; - }; - - hwinfo: partition@3f00000 { + partition@3f00000 { reg = <0x3f00000 0x20000>; label = "hw-info"; read-only; + + compatible = "nvmem-cells"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_hwinfo_0: macaddr@0 { + reg = <0x0 0x6>; + }; }; partition@3f20000 { @@ -101,11 +102,6 @@ label = "u-boot"; read-only; }; - - firmware@0 { - reg = <0x0 0x3040000>; - label = "firmware"; - }; }; }; }; @@ -242,13 +238,3 @@ }; }; /include/ "fsl/p1020si-post.dtsi" - -&hwinfo { - compatible = "nvmem-cells"; - #address-cells = <1>; - #size-cells = <1>; - - macaddr_hwinfo_0: macaddr@0 { - reg = <0x0 0x6>; - }; -}; diff --git a/target/linux/mpc85xx/image/p1020.mk b/target/linux/mpc85xx/image/p1020.mk index a127723e89..fff2c3931f 100644 --- a/target/linux/mpc85xx/image/p1020.mk +++ b/target/linux/mpc85xx/image/p1020.mk @@ -1,17 +1,58 @@ +define Build/MultiImage + rm -rf $@.fakerd $@.new + + dd if=/dev/zero of=$@.fakerd bs=32 count=1 conv=sync + + -$(STAGING_DIR_HOST)/bin/mkimage -A $(LINUX_KARCH) -O linux -T multi -C $(1) \ + -a $(KERNEL_LOADADDR) -e $(KERNEL_ENTRY) -n '$(BOARD_NAME) initramfs' \ + -d $@:$@.fakerd:$(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb $@.new + mv $@.new $@ + rm -rf $@.fakerd +endef + define Device/aerohive_hiveap-330 DEVICE_VENDOR := Aerohive DEVICE_MODEL := HiveAP-330 DEVICE_PACKAGES := kmod-tpm-i2c-atmel BLOCKSIZE := 128k - KERNEL := kernel-bin | gzip | uImage gzip - KERNEL_SIZE := 8m - KERNEL_INITRAMFS := copy-file $(KDIR)/vmlinux-initramfs | uImage none - IMAGES := fdt.bin sysupgrade.bin - IMAGE/fdt.bin := append-dtb - IMAGE/sysupgrade.bin := append-dtb | pad-to 256k | check-size 256k | \ - append-uImage-fakehdr ramdisk | pad-to 256k | check-size 512k | \ - append-rootfs | pad-rootfs $$(BLOCKSIZE) | pad-to 41216k | check-size 41216k | \ - append-kernel | append-metadata + KERNEL := kernel-bin | uImage none + KERNEL_INITRAMFS := kernel-bin | MultiImage none + KERNEL_SIZE := 16m + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-dtb | pad-to 256k | append-kernel | \ + append-rootfs | pad-rootfs | check-size | append-metadata + IMAGE_SIZE = 63m + DEVICE_COMPAT_VERSION := 2.0 + DEVICE_COMPAT_MESSAGE := \n$\ + !The partitioning of the HiveAP 330 has changed! \n$\ + To upgrade, please take a look at the install instructions over \ + at the device's wiki: \n$\ + An abridged version for the console is provided here for comfort. \n$\ + Run the following script into a shell on the device and retry this \ + sysupgrade again: \n$\ + cat <<- "EOF" > /tmp/uboot-fix.sh; sh /tmp/uboot-fix.sh \n$\ + . /lib/functions.sh \n$\ + . /lib/functions/system.sh \n$\ + opkg update && opkg install uboot-envtools kmod-mtd-rw || exit 2 \n$\ + insmod mtd-rw i_want_a_brick=y || exit 3 \n$\ + echo "/dev/mtd$$$$(find_mtd_index u-boot-env) 0x0 0x20000 0x10000" > "/etc/fw_env.config" \n$\ + fw_setenv owrt_boot 'setenv bootargs console=ttyS0,9600;bootm 0xEC040000 - 0xEC000000' \n$\ + cp "/dev/mtd$$$$(find_mtd_index 'u-boot')" /tmp/uboot \n$\ + cp /tmp/uboot /tmp/uboot_patched \n$\ + strings -td < /tmp/uboot | grep '^ *[0-9]* *\\(run owrt_boot\\|setenv bootargs\\).*cp\\.l' | \n$\ + awk '{print $$$$1}' | \n$\ + while read offset; do \n$\ + echo -n "run owrt_boot; " | dd of=/tmp/uboot_patched bs=1 seek=$$$${offset} conv=notrunc \n$\ + done \n$\ + mtd write /tmp/uboot_patched u-boot \n$\ + uci set system.@system[0].compat_version=2.0; uci commit; \n$\ + EOF \n$\ + \n$\ + Note that if this fails, you will need to use the serial console \n$\ + to re-install OpenWrt. \n$\ + Note that after this sysupgrade, the AP will be unavailable for 7 \n$\ + minutes to reformat flash." + endef TARGET_DEVICES += aerohive_hiveap-330 @@ -28,7 +69,7 @@ TARGET_DEVICES += enterasys_ws-ap3710i define Device/ocedo_panda DEVICE_VENDOR := OCEDO DEVICE_MODEL := Panda - DEVICE_PACKAGES := kmod-rtc-ds1307 uboot-envtools + DEVICE_PACKAGES := kmod-rtc-ds1307 KERNEL = kernel-bin | gzip | fit gzip $(KDIR)/image-$$(DEVICE_DTS).dtb PAGESIZE := 2048 SUBPAGESIZE := 512 diff --git a/target/linux/mpc85xx/p1020/config-default b/target/linux/mpc85xx/p1020/config-default index d0bf770768..31fce8b60a 100644 --- a/target/linux/mpc85xx/p1020/config-default +++ b/target/linux/mpc85xx/p1020/config-default @@ -24,6 +24,7 @@ CONFIG_MTD_NAND_FSL_ELBC=y CONFIG_MTD_PHYSMAP=y CONFIG_MTD_SPLIT_FIRMWARE=y CONFIG_MTD_SPLIT_FIT_FW=y +CONFIG_MTD_SPLIT_UIMAGE_FW=y CONFIG_MTD_UBI=y CONFIG_MTD_UBI_BEB_LIMIT=20 CONFIG_MTD_UBI_BLOCK=y -- 2.30.2