Adding OpenWrt support for D-Link DIR-X1860 (MT7621 + MT7915 AX1800)

1st ting to do is draw on the factory OEM's firmware boot log
try to reconstruct the memory partition layout
2nd thing to find out how to load into ram only
so getting a working initramfs-kernel.bin is the 1st thing
this may involve just getting the oem firmware to boot from ram

one you have a working openwrt initramfs-kernel.bin image
you can backup the untouched flash

if you get this far you will have learn alot about the format's & headers required
and a better understanding how to recover the OEM firmware way before you 1st flash attempt

1 Like

I have a full backup already :innocent: (OpenWrt failsafe can be entered by pressing on the serial line, during boot of OEM firmware :joy: c.f. last chapter in wiki), but flashing this back into the device is indeed somewhat more complicated than with spi - so initramfs via tftpboot is probably still the best way to go.

Otherwise, I guess the NAND setup should just work in the same way as with DIR-xx60?

it was the same for the DIR-878 & DIR-1960
but getting you initramfs-kernel.bin to access the flash
and getting the flash layout correct
is a must before flashing
you should be able to compare your backup with the initramfs-kernel.bin mtd saved files

1 Like

bootloader is not so happy with the 0x27051956 uimage header, I think it is expecting 0xDOODFEED for the FIT devicetree for tftp ramboot as well:

*** Loading image ***

Available load methods:
    0 - TFTP client (Default)
    1 - Xmodem
    2 - Ymodem
    3 - Kermit
    4 - S-Record

Select (enter for default): 0

Input U-Boot's IP address: 192.168.0.1
Input TFTP server's IP address: 192.168.0.42
Input IP netmask: 255.255.255.0
Input file name: openwrt-ramips-mt7621-dlink_dir-x1860-a1-initramfs-kernel.bin

Using eth@1e100000 device
TFTP from server 192.168.0.42; our IP address is 192.168.0.1
Filename 'openwrt-ramips-mt7621-dlink_dir-x1860-a1-initramfs-kernel.bin'.
Load address: 0x80010000
Loading: #################################################################
         #################################################################
         #################################################################
         ##########################################
         640.6 KiB/s
done
Bytes transferred = 3473099 (34fecb hex)

*** Loaded 3473099 (0x34fecb) bytes at 0x80010000 ***

## Booting kernel from Legacy Image at 80010000 ...
Bad Header Checksum
ERROR: can't get kernel image!
=>

seems I need compatible = "denx,fit"; here, having a look at Unifi AC Lite, which seems to be one of two devices with FIT in the MT7621 subtarget.

https://git.openwrt.org/?p=openwrt/staging/nbd.git;a=commit;h=d17a54faeef413febbb4635714871d9c1aada6c3

2 Likes

:joy:
Thanks, good to know someone has started doing the same work already, I think we should have a database or something, where people could leave a note about their current progress
(also somewhat reminds me of Discourse "saved searches" plugin?).

@nbd Thanks, I'm building your code now, and will try to see if factory encryption works with the parameters as stated in post #1 :+1:

After building the images from Felix's code, factory and sysupgrade also have the uimage header (0x27051956).

@nbd: What would be the flashing instructions for the image built from your staging tree, I would assume the partitions need to be written manually?

I have tried to feed the router with the decrypted D-Link OEM image (see first post) via tftp from the bootmenu (starting with 0xD00DFEED, i.e. the dtb partition, followed by uimage lzma kernel), and it will accept that and actually boot from RAM - until there is a kernel panic when trying to mount the root filesystem (OEM image is not initramfs after all), it will then reboot and proceed to loading the regular image from the flash :joy:

So, initramfs would still be the way to go I guess, but it needs to be in denx,fit format(?).

Still no luck with initramfs, bootloader is complaining about lzma error :thinking:

Tried the -a0 argument as with DIR-860L, but no success. Maybe lzma compression level for the fit recipe needs to be modified, rather than for kernel-bin?

// edit: relocate-kernel was indeed helpful, now it's complaining about the image being too big:

Uncompressing Kernel Image ... Image too large: increase CONFIG_SYS_BOOTM_LEN

Couldn't find any further hints from other devices regarding how to generate this image, so I'll probably just flash and hope the Image too large error will not affect the final kernel, but only initramfs :thinking:
Does anyone happen to know when exactly relocate-kernel is used/needed?

did you manage to find the main OEM firmware partition
and could you back upthis partition ?
I'm going to presume this is decrypted compared to an OEM firmware image
did it have the basic u-boot header ? "27051956"
did this image work uploading into ram ?

1 Like

OEM firmware partition mtd3 (at 0x00180000 in flash) does indeed not contain the 27051956 header, neither does the decrypted oem firmware.
however, re-decrypting my generated image, there was indeed the uboot header at offset 0xe4, so I guess the kernel should be (lzma'ed?) binary instead.
Thanks for spotting that! Trying to fix...

uploading the decrypted oem firmware to ram is accepted, but results in kernel panic since rootfs could not be mounted (it is not an initramfs image).

at lest you have a format that's accepted into ram
some where to start
so it may have an extra header in front of uboot
it's weird to be 0xE4 but oh well
if you can some how get me a copy I'll have a look at it all

please check the link in the first post, "(decrypted firmware)"

1 Like

Still no luck with lzma, even without relocate-kernel etc.
It's always giving error 1, which is the return value SZ_ERROR_DATA coming directly from the lzma library... so this could be anything, most probably happens when the partition is cropped?
There's another if-statement in the uboot code returning that value when the image uses 64bit values to declare uncompressed size, instead of 32bit, but I don't think this is the issue here.

binwalk -e will perfectly unpack the kernel from both the decrypted OEM image as well as my image without complaining, the output for the lzma data at 0xe4 is the same, the header is 0x6D000080, only the OEM kernel is actually even a little bigger than the OpenWrt one, but I don't think there's a minimum or even maximum size, so probably no use in adding lzma-loader...

So it's probably time to try building the OEM image from D-Link GPL release... :thinking:

have You consider scrap factory partition and install breed ?
I've did with Mercusys MR1800x (aka MR70X) mt7621da + 16MB spi . This solution allow me to boot OpenWrt and Padavan .
I've done this to kill tplink safeboot and non standard partitions. Nice outcome from ~27EUR router

Actually, the mid-term goal would be supporting this device in OpenWrt, so that the user could flash it via the regular OEM web updater. As mentioned above, the crypto part is already solved in #3109, also @nbd seems to have completed device support for manual flashing already; now all that's missing is the FIT devicetree and image packing to make it boot, but I'm not very familiar with devices using FIT images, thus I asked here.
Maybe it's only an initrams-related issue after all? I had not attempted to actually write an image file to flash yet.

Found some more time to dig this device back out, rebuilt the image from staging-nbd and looked at the images generated... Turns out, the factory image can actually be flashed via recovery bootloader, and depending on the current active partition, this will be written either to the correct (first) or wrong (second) partition. This can only be observed on the serial console: When the bootloader writes the image to 0x02C80000 (firmware2), there will be a bootloop caused by kernel panic, since rootfs (ubi) could not be mounted, which is declared in dts to be located within the first firmware partition at 0x00180000.

Curiously, the factory image does even not use the same FIT header (0xD00DFEED) as the d-link image, but just a regular 0x27051956 header, which is also still understood by uboot.

So basically, without opening the case, it currently just needs multiple flashing attempts of the factory image via the bootloader recovery Web UI, until it happens to be written to the correct partition. After that, I have not yet observed any regression, i.e. bootloader switching back to the other partition after some failed boot etc.

But in the long term, we should find a solution for dual boot, since this seems to apply to the vast majority of mt7621 devices with NAND these days. I thought about placing an OKLI loader etc. to the second partition, just to make sure the bootloader would not accidentally try to boot the wrong image (which might even be the factory one) after an unexpected reboot / power loss during boot / etc.

But the OEM Web updater obviously just writes to one partition, so we couldn't write that loader during the initial flashign procedure. Thus, upon first boot, there should be a script detecting the position in flash, where the image was written, and then place an OKLI loader etc. to the other partition? Or copy itself to the first partition first - this way we could leave the loader as a gap, and reuse the remaining flash area of the second firmware partition by utilizing mtd-concat.

In any case, the wifi of the two MT7915 was not yet working when trying to configure from LuCI, though it should be considered that mt76 is under heavy development regarding these chips, and updating the driver to the latest trunk might already solve it.

there are a few device that do this the most of the linksys ones do this
they also switch between UBI partitions
anyway off the top of my head I know my EA8100v1 (MT7621-MT7615's) is like this
it may shed some lite for you on at lest how they do it

What's the current status of the work on supporting this router? What work remains to be done? Depending upon the complexity of what's left, I might be able to help.

I see that @nbd commited some work in progress code recently. I've been running builds of his work over the past 6 months and haven't encountered any issues - everything seems fine from a stability and functionality perspective.

I'm pretty sure (it was a while ago so I'm not 100% certain) that I flashed over serial rather than with the recovery bootloader mentioned by @s_2. Not having to replicate the OEM firmware encryption definitely simplifies things.

// edit: Sorry, wrong Thread. So this time I confused DIR and DAP-X1860 myself :innocent:

Factory image structure and encryption scheme is known, so we could actually implement factory encryption, the format is the same as e.g. for DIR-842.

For some devices (e.g. COVR-C1200 / P2500 / ...) it is sufficient to just encrypt the image for flashing via bootloader, since the signature itself would not be verified, but I had eventually closed my crypto PRs for several routers back then, for some models, including the DIR-842 and also the DIR-X1860, the PR was open for more than 1.5 years and I could not see any progress except for the constant need to rebase (maybe publishing vendor firmware keys is not quite appreciated by some project members), so those devices are not supported for now.

However with DIR-X1860, luckily the bootloader also seems to accept the unencrypted image, so we can flash that way (let's see for how long - Firefox is causing trouble already, but recent versions of Chromium still seem to work). For some older D-Link devices, I can no longer flash them via bootloader on Linux at all, not even using curl, some models (e.g. COVR-C1200) will only work on Windows with IE 10, and it takes several attempts :joy: