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

Hi everyone,

I've starting collecting info on this device in the wiki:

These things are 2-stream entry-level AX1800 routers based on MT7621, so I had expected them to be successors of the SGE-manufactured EXO-devices (DIR-887, DIR-1960, DIR-2660 etc.)

However, after dumping the bootlog (c.f. wiki) and firmware, it turns out this one is actually manufactured by Alpha Networks, so this is more like a successor of DIR-869, using the same factory encryption as DIR-842 and DIR-859:

As usual, the key/iv can be dumped from the encimg binary:

  SEAMA_SIGNATURE := wrgax10_dlink_dirx1860
  IMAGE/factory.bin := ??? | alpha_encimg $$(SEAMA_SIGNATURE) \
	9I92bgRMPu+0fgFzo/ZwCyuBTNrtpeQ7 tTc4XS3LiRBq+Muv

I just realized my PR does not include decryption yet (as it's not needed for generating the image), but the OEM tool found in the flash can be used for that as well... (decrypted firmware)

Now the next steps would be: create a dts, build the image, encrypt it... and finally brick the device! :sweat_smile:

@Lucky1 @kar200: While I know ath79 quite well, you guys seem to have a lot more experience with ramips, MT7621, booting from NAND, FIT, dual boot, wifi configuration for MT7xxxx (assuming .ax would be working at all) ....

So what could be a good starting point here? I think I would try taking mt7621_dlink_dir-xx60-a1.dtsi as a template and modding from there, getting MT7621 to work as a first stage.

Is there anything else I should take care of regarding the factory image, to avoid bricking this in the first attempt?

Looking forward to see this device being among the first AX routers supported, even without over-complicated flashing instructions :innocent:

UBoot environment:

=> help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootmenu- ANSI terminal bootmenu
bootp   - boot image via network using BOOTP/TFTP protocol
chpart  - change active partition
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
echo    - echo args to console
editenv - edit environment variable
env     - environment handling commands
fdt     - flattened device tree utility commands
go      - start application at address 'addr'
gpio    - query and control gpio pins
help    - print command description/usage
httpd   - Start failsafe HTTP server
iminfo  - print header information for application image
itest   - return true/false on integer compare
led     - manage LEDs
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loadx   - load binary file over serial line (xmodem mode)
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
md      - memory display
mm      - memory modify (auto-incrementing address)
mnbc    - MT7621 NAND bad block compatible management
mtdparts- define flash/nand partitions
mtkautoboot- Display MediaTek bootmenu
mtkboardboot- Boot MT7621 firmware
mtkload - MTK image loading utility
mtkupgrade- MTK firmware/bootloader upgrading utility
mw      - memory write (fill)
nand    - NAND sub-system
nboot   - boot from NAND device
nm      - memory modify (constant address)
printenv- print environment variables
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
setexpr - set environment variable as the result of eval expression
sleep   - delay execution for some time
source  - run script from memory
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
=> printenv
bank_id=0
baudrate=115200
bootargs=console=ttyS0,115200
bootcmd=mtkautoboot
bootdelay=0
bootmenu_0=Startup system (Default)=mtkboardboot
bootmenu_1=Upgrade firmware=mtkupgrade fw
bootmenu_2=Upgrade bootloader=mtkupgrade bl
bootmenu_3=Upgrade bootloader (advanced mode)=mtkupgrade bladv
bootmenu_4=Load image and run=mtkload run
cycle=0
fdtcontroladdr=8fff19f0
ipaddr=192.168.0.1
netmask=255.255.255.0
serverip=192.168.0.10
stderr=uartlite0@1e000c00
stdin=uartlite0@1e000c00
stdout=uartlite0@1e000c00

Environment size: 500/131068 bytes
=>

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: