openwrt/target/linux/apm821xx/image/nand.mk
Christian Lamparter 82c8c38a5c apm821xx: prepare WNDR4700 for 6.6 - add preliminary u-boot-env access
With the default BUILD_BOT configuration on a linux 6.6 kernel,
the WNDR4700's kernel no longer fits into the alloted ~3.5MiB,
even with LZMA compression.

Bigger kernels are possible, but there's a problem with Netgear's
"bootcmd":

> if loadn_dniimg 0 0x180000 0x4e0000 && chk_dniimg 0x4e0000; then nand read 0x800000 0x180000 0x20000;bootm 0x500000 - 0x800040;else fw_recovery; fi"

This loads the dni-image starting offset 0x180000 from the NAND
flash (which is the DTB partition) to 0x4e0000 in the RAM. It then
checks whenever the provided image is "valid". If it is then it
reads the DTB again to 0x800000 in the RAM and starts the extraction
and boot process. (If the image wasn't valid then it starts the
automated firmware recovery).

The issues here are that first: the kernel image gets "squeezed"
between 0x500040 and 0x7fffff... And second, the decompressor
only has area 0x0 - 0x500000 for decompression.

Hence the image now requires to update the bootcmd by providing
new values (which have been successfully tested with the original
Netgear WNDR4700 v1.0.0.56 firmware) for the RAM locations and
make full use of the fact that loadn_dniimg loads the DTB as well.

This needs to be done only once. Just connect a serial adapter to
interface with uboot and overwrite (and save) the new bootcmd.

WARNING: The serial port needs a TTL/RS-232 3.3v level converter!

Steps:
 0. Power-off the WNDR4700
 1. Connect the serial interface (you need to open the WNDR4700)
 2. Power-up the WNDR4700
 3. Monitor the boot-sequence and hit "Enter"-key when it says:

  "Hit any key to stop autoboot" (Be quick, you have a ~2 second window)

 4. in the Prompt enter the following commands (copy & paste)

 setenv bootcmd "if loadn_dniimg 0 0x180000 0xce0000 && chk_dniimg 0xce0000; then bootm 0xd00000 - 0xce0040;else fw_recovery; fi"
 saveenv
 run bootcmd

Note: This new bootcmd will also unbrick devices that were bricked
by the bigger 4.19-6.1 kernels.

Note2: This method was tested with a WNDR4700. A big kernel with most
debug features enabled on v6.6.22 measured 4.30 MiB when compressed
with lzma. The uncompressed kernel is 12.34 MiB. This is over the 3 MiB,
the device reserves for the kernel... But it booted! For bigger kernels,
the device needs repartitioning of the the ubi partition due to the
kernel+dtb not fitting into the partition.

Note3: For initramfs development. I would advice to load the initramfs
images to 0x800000 (or higher). i.e.: tftp 800000 wndr4700.bin

Note4: the fw_recovery uboot command to transfer the factory image to
the flash still works.

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
2024-04-05 09:26:26 +02:00

127 lines
4.3 KiB
Makefile

define Build/create-uImage-dtb
# flat_dt target expect FIT image - which WNDR4700's uboot doesn't support
-$(STAGING_DIR_HOST)/bin/mkimage -A $(LINUX_KARCH) \
-O linux -T kernel -C none \
-n '$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION)' \
-d "$(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb" "$@.dtb.uimage"
endef
define Build/prepend-dtb-uImage
cat "$@.dtb.uimage" "$@" > "$@.new"
mv "$@.new" "$@"
endef
define Build/meraki-header
-$(STAGING_DIR_HOST)/bin/mkmerakifw \
-B $(BOARD_NAME) -s \
-i $@ \
-o $@.new
@cp $@.new $@
endef
define Device/meraki_mr24
DEVICE_VENDOR := Cisco Meraki
DEVICE_MODEL := MR24
DEVICE_PACKAGES := kmod-spi-gpio -swconfig
BOARD_NAME := mr24
IMAGES := sysupgrade.bin
DEVICE_DTC_FLAGS := --space 64512
IMAGE_SIZE := 8191k
KERNEL := kernel-bin | lzma | uImage lzma | prepend-dtb | meraki-header
KERNEL_INITRAMFS := kernel-bin | lzma | MuImage-initramfs lzma
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
UBINIZE_OPTS := -E 5
SUPPORTED_DEVICES += mr24
endef
TARGET_DEVICES += meraki_mr24
define Device/meraki_mx60
DEVICE_VENDOR := Cisco Meraki
DEVICE_MODEL := MX60
DEVICE_ALT0_VENDOR := Cisco Meraki
DEVICE_ALT0_MODEL := MX60W
DEVICE_PACKAGES := kmod-spi-gpio kmod-usb-ledtrig-usbport kmod-usb-dwc2 \
kmod-usb-storage block-mount
BLOCKSIZE := 128k
IMAGES := sysupgrade.bin
DEVICE_DTC_FLAGS := --space 20480
IMAGE_SIZE := 1021m
KERNEL := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
UBINIZE_OPTS := -E 5
DEVICE_COMPAT_VERSION := 2.0
DEVICE_COMPAT_MESSAGE := uboot's bootcmd has to be updated to support standard multi-image uImages. \
Upgrade via sysupgrade mechanism is not possible.
endef
TARGET_DEVICES += meraki_mx60
define Device/netgear_wndap6x0
DEVICE_VENDOR := NETGEAR
DEVICE_PACKAGES := kmod-eeprom-at24
SUBPAGESIZE := 256
PAGESIZE := 512
BLOCKSIZE := 16k
DEVICE_DTC_FLAGS := --space 32768
IMAGE_SIZE := 27392k
IMAGES := sysupgrade.bin factory.img
KERNEL_SIZE := 6080k
KERNEL := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
UBINIZE_OPTS := -E 5
DEVICE_COMPAT_VERSION := 2.0
DEVICE_COMPAT_MESSAGE := kernel and ubi partitions had to be resized. \
Upgrade via sysupgrade mechanism is not possible.
endef
define Device/netgear_wndap620
$(Device/netgear_wndap6x0)
DEVICE_MODEL := WNDAP620 (Premium Wireless-N)
endef
TARGET_DEVICES += netgear_wndap620
define Device/netgear_wndap660
$(Device/netgear_wndap6x0)
DEVICE_MODEL := WNDAP660 (Dual Radio Dual Band Wireless-N)
endef
TARGET_DEVICES += netgear_wndap660
define Device/netgear_wndr4700
DEVICE_VENDOR := NETGEAR
DEVICE_MODEL := Centria N900 WNDR4700
DEVICE_ALT0_VENDOR := NETGEAR
DEVICE_ALT0_MODEL := Centria N900 WNDR4720
DEVICE_PACKAGES := badblocks block-mount e2fsprogs kmod-hwmon-drivetemp \
kmod-dm kmod-fs-ext4 kmod-fs-vfat kmod-usb-ledtrig-usbport \
kmod-md-mod kmod-nls-cp437 kmod-nls-iso8859-1 kmod-nls-iso8859-15 \
kmod-nls-utf8 kmod-usb3 kmod-usb-dwc2 kmod-usb-storage \
partx-utils kmod-ata-dwc
BOARD_NAME := wndr4700
PAGESIZE := 2048
SUBPAGESIZE := 512
BLOCKSIZE := 128k
DEVICE_DTC_FLAGS := --space 131008
IMAGE_SIZE := 24960k
IMAGES := factory.img sysupgrade.bin
ARTIFACTS := device-tree.dtb
KERNEL_SIZE := 4608k
# append a fake/empty rootfs to fool netgear's uboot
# CHECK_DNI_FIRMWARE_ROOTFS_INTEGRITY in do_chk_dniimg()
KERNEL := kernel-bin | lzma -d16 | uImage lzma | pad-offset $$(BLOCKSIZE) 64 | \
append-uImage-fakehdr filesystem | create-uImage-dtb | prepend-dtb-uImage
KERNEL_INITRAMFS := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | \
netgear-dni | check-size
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
ARTIFACT/device-tree.dtb := export-dtb | uImage none
NETGEAR_BOARD_ID := WNDR4700
NETGEAR_HW_ID := 29763875+128+256
UBINIZE_OPTS := -E 5
SUPPORTED_DEVICES += wndr4700
DEVICE_COMPAT_VERSION := 2.0
DEVICE_COMPAT_MESSAGE := kernel and ubi partitions had to be resized. \
Upgrade via sysupgrade mechanism is not possible.
endef
TARGET_DEVICES += netgear_wndr4700