OpenWrt support for Netgear EAX15 v3 (MT7981)

Hi,

I have a Netgear EAX15 v2 and put OpenWrt on it. It was a painless experience and the form factor for having an extender function as a mesh point couldn't be better.

Unfortunately calling the v2 "rare" would be an understatement. It seems like I bought the last used one on the face of the planet.

Now, there's a v3 and it's fairly easy to find. I did a little sleuthing and trom the GPL tarball and firmware, it appears to use an MT7981. Other MT7981 devices are supported in OpenWrt, so it seems like it would be possible to put it on the EAX15 v3 and retain that amazing form factor (w/ surprisingly good specs, too).

I just pulled the trigger on a v3 and should have it in my hands in a few weeks. What is the process for adding support? Is there anything I can do to help make this happen? Is there an existing build for a different MT7981 device that would just work or would a specific build for the EAX15 v3 need to made?

Thanks!

Are you able to find the dts in tarball

EAX17_EAX16_EAX15v3_GPL_V1.0.1.34_src.tar.gz extracts to EAX17_GPL_V1.0.1.34_src so I assume the EAX17 deconfig applies to the EAX15v3

mt7981_spim_nand_EAX17_defconfig sets CONFIG_DEFAULT_DEVICE_TREE=mt7981-spim-nand-rfb.
Tweaks live under package/tw/tw_base-files/files/EAX17/cfg/EAX15v3/

here's the tarball https://www.downloads.netgear.com/files/GPL/EAX17_EAX16_EAX15v3_GPL_V1.0.1.34_src.tar.gz

Well then should be quite easy.
Compare it with other mt7981 devices and ask here if you have questions.

1 Like

Ok. I used the openwrt-one dts as a template/starting point and then added everything I could using the demo dts in the gpl tarball.

I also added a stanza for the eax in filogic.mk, 01_leds, and 02_network

it'll be another ~10 days before I have the hardware in hand and then I'll validate everything.

Ok. I've been at this for a while now and i have questions.

My firmware.img is being rejected and I don't really know where to begin in terms of figuring out why.

The behavior is that the web ui accepts the file, goes through the copying process and then shows the progress bar (circle) which makes it all the way to 100% but then, instead of rebooting into OpenWrt, the page just reloads and kicks me back to the Netgear login page (mywifiext.local)

I've confirmed that my header includes the correct hardware id and model name. I've confirmed that the encryption keys in openwrt are still valid because i was able to use them to decrypt the oem firmware.

I made sure the decrypted oem firmware and my firmware both extract to a directory of the same name. The contents of both are a sysupgrade-mt7981-spim-nand-rfb directory with CONTROL, kernel, and root.

CONTROL are identical

I used dtc to get useful info from the kernels and compared them. The only differences between them is that the oem has a top level node called rootfs w/ size, hash-1 and hash-2. Openwrt provides a "with-rootfs" that I can add to the KERNEL := line in the device makefile stanza (in filogic.mk), but

  1. this puts a node named rootfs-1 inside image, rather than top level
  2. absolutely no other filogic boards do this

At this point, I'm basically just guessing. Any ideas for how to move forward?

1 Like

I found a difference in the appended metadata between my decrypted image and the oem image

the oem shows the target as mediatek/mt7981 while the openwrt target is mediatek/filogic

could this be the reason?

tail -c 2048 oem.img | strings | head -n40

{ "metadata_version": "1.1", "compat_version": "1.0", "supported_devices":["mediatek,mt7981-spim-snand-rfb"], "version": { "dist": "OpenWrt", "version": "21.02-SNAPSHOT", "revision": "r0-68f907cc5", "target": "mediatek/mt7981", "board": "mt7981-spim-nand-rfb" } }
FWx0

tail -c 2048 openwrt.img | strings | head -n40

{ "metadata_version": "1.1", "compat_version": "1.0", "supported_devices":["mediatek,mt7981-spim-snand-rfb"], "version": { "dist": "OpenWrt", "version": "SNAPSHOT", "revision": "r31252+12-8f4f7cce76", "target": "mediatek/filogic", "board": "mt7981-spim-nand-rfb" } }
FWx0

Do you have serial console access to the device?
Or do you have a git repo that we can look at

yes. I got the uart working.. sort of. I can get to U-boot, but I haven't figured out the login and pass for full shell access

here's what I've done so far

update: I just confirmed making the target in the metadata match oem didn't fix the issue.

update: I've finally managed to put an initramfs on it via tftp from uboot.

I verified everything that I could and am now trying to flash sysupgrade.bin

I'm getting a vague and generic error of

invalid sysupgrade file
Image check failed.

I'm not really sure how to sleuth out why I'm getting this error.

EDIT: I had a look at your github, it seems you're past these suggestions

Did you make sure the flash definitions and partitions match OEM?
First question: NAND or NOR?
OpenWrt One actually has both, so maybe it's not a great starting point.

Since initramfs works for you, you should grab a complete flash dump and store it on your computer. The actual DT can be extracted from it (not the demo DTS)

Make a pull request and mark it as draft.
I think at the current progress it's easier to get feedback there.

Thanks!

I did that here:

I'm currently stuck w/ the error

No rootfs node found in FIT image!
Error: rootfs verification failed
Firmware integrity verification failed

I decompiled the oem kernel to compare to my own and I'm missing a top level node called rootfs that only has 3 things inside it: size, hash-1 and hash-2

Not sure how to add these to my kernel. there's a "with-rootfs" I can stick on the KERNEL := line, but that adds a node called rootfs-1 inside the images node rather than creating a top level node.

Any ideas? FWIW, I'm only guessing that this is what's causing the error, but it seems plausible.

Other than this one difference in the kernel, my tar looks the same as the decrypted oem firmware

They're both a single directory containing 3 files: CONTROL, kernel, and a squashfs root.

Both kernels are "Device Tree Blob version 17"

Update: I added a script adds the missing node but I'm still getting an error on boot. this time it's

UBI partition 'ubi' already selected
Image slot 0 was marked invalid.
Image slot 1 was marked invalid.

Web failsafe UI started
URL: http://192.168.1.1/

Press Ctrl+C to exit

Not sure how to move forward from here.

OK. I figured out that in order to get meaningful error messages, I had to manually setenv the image slot marked invalid back to valid and then boot again.

these are the actual error messages from both slot 1 and slot 0

Trying to boot from image slot 1
Read 64 bytes from volume kernel2 to 0000000046000000
Read 4476712 bytes from volume kernel2 to 0000000046000000
## Checking hash(es) for FIT Image at 46000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+ 
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+ 
Read 48 bytes from volume rootfs2 to 0000000046444f28
Read 4757052 bytes from volume rootfs2 to 0000000046444f28
No rootfs node found in FIT image!
Error: rootfs verification failed
Firmware integrity verification failed
Failed to boot from current image slot, error -74
Saving Environment to UBI... UBI partition 'ubi' already selected
done
OK
Saving Environment to UBI... UBI partition 'ubi' already selected
done
OK
Trying to boot from image slot 0
Read 64 bytes from volume kernel to 0000000046000000
Read 4475649 bytes from volume kernel to 0000000046000000
## Checking hash(es) for FIT Image at 46000000 ...
   Hash(es) for Image 0 (kernel-1): crc32+ sha1+ 
   Hash(es) for Image 1 (fdt-1): crc32+ sha1+ 
Read 48 bytes from volume rootfs to 0000000046444b04
Read 4757048 bytes from volume rootfs to 0000000046444b04
Incomplete rootfs
Error: rootfs verification failed
Firmware integrity verification failed
Failed to boot from next image slot, error -74
Saving Environment to UBI... UBI partition 'ubi' already selected
done
OK

the issue appears to be that my actual rootfs size is a tiny bit smaller (or not?) than what I'm flashing.

the root in my image is 4757504, and the fit_rootfs_size field matches that exactly, but only 4757048 is being read as the rootfs size. The flashed rootfs is getting truncated by 456 bytes, or at least the read gets truncated.

Volume information dump shows used_bytes is 4825088 for the rootfs volume, which is actually bigger (and exactly 4712kb)

I'm pretty confused at this point. I'm not sure what's causing these size mismatches

ok another update. I'm increasingly confused about this.

the EAX is a dual boot device and has a slot 0 and slot 1, and I think this is (maybe?) the source of my problems

in the log I posted above, slot 1 has a kernel size that does not match what's in the image, complains about a missing rootfs node in the FIT image, but has the correct rootfs size that matches what's in the image

meanwhile, the other slot has the correct kernel size that matches whats in my image, does not complain about a missing rootfs node in the FIT, but the rootfs is 456 bytes shy of what its supposed to be so I get the Incomplete rootfs error.

if I switch which slot I'm on and repeat the process the errors flip flop and slot 0 cries Incomplete rootfs while slot 1 throws the No rootfs node found in FIT image

My kernel and root appear to be ending up on the wrong slots from each other, regardless of what slot I'm on when I perform the flash.

Do you have stock firmware boot log?
Usually it can sort of tell you the partition.

not anymore, but that isn't really the issue.

I know what the partitions are and I know what the volumes on the ubi partition are called

MT7981> ubi part ubi
UBI partition 'ubi' already selected
MT7981> ubi list
0: u-boot-env
1: kernel
2: rootfs
3: rootfs_data
4: kernel2
5: rootfs2

it just seems that when I run sysupgrade it flashes the kernel to the correct kernel volume but flashes the root to the wrong one (rootfs2).

there's a env dual_boot.current_slot=1 and if I change that to 0, then the exact opposite happens. Kernel gets flashed to kernel2, but root gets flashed to rootfs (and somehow the other ones break in the process)

one slot has a kernel that's missing the top level rootfs node in the FIT that I had to add because there's some annoying validation stuff that insists its there

the other slot will have the correct kernel where it finds the rootfs node that I added, and the size value in that node is correct, but for whatever reason, the size of the actual rootfs on that slot is 458 bytes shy and it throws the "Incomplete rootfs" error. Boot log shows that the other slot (with the bad kernel) has the correctly sized rootfs.

not anymore, but that isn't really the issue.

I know what the partitions are and I know what the volumes on the ubi partition are called

MT7981> ubi part ubi
UBI partition 'ubi' already selected
MT7981> ubi list
0: u-boot-env
1: kernel
2: rootfs
3: rootfs_data
4: kernel2
5: rootfs2

it just seems that when I run sysupgrade it flashes the kernel to the correct kernel volume but flashes the root to the wrong one (rootfs2).

there's a env dual_boot.current_slot=1 and if I change that to 0, then the exact opposite happens. Kernel gets flashed to kernel2, but root gets flashed to rootfs (and somehow the other ones break in the process)

one slot has a kernel that's missing the top level rootfs node in the FIT that I had to add because there's some annoying validation stuff that insists its there

the other slot will have the correct kernel where it finds the rootfs node that I added, and the size value in that node is correct, but for whatever reason, the size of the actual rootfs on that slot is 458 bytes shy and it throws the "Incomplete rootfs" error. Boot log shows that the other slot (with the bad kernel) has the correctly sized rootfs.

UPDATE: fixed this particular issue.

I should have been using the Filesystem size from unsquashfs4 instead of the root file's size.

also, I added a case for the this device in the filogic platform.sh that flashes both slots.

Now I'm working on the next problem

Hash(es) for rootfs: crc32- sha1- 
Error: at lease one hash node failed verification

wish me luck lol

Update: I got everything working!

2 Likes