Adding support for TP-Link RE190 v4 (AC750 2.4/5GHz Wi-Fi Range Extender)

check git, see who submitted those devices.

1 Like

@andyboeh @misanthropos @adrianschmutzler @ambassador86 you guys were responsible for TP-Link RE200, RE220 & RE305 contributions and thank you for that!
Because of you, today we have a (relatively-stable) support for those mt7628-based devices...
Would you mind assisting me a little bit and pointing me in right direction regarding adding support for RE190 (identically-specced & fully-compatible hardware-wise, see posts in this thread above)?

Cheers and thank you!

I only did some porting work, I was in no way involved in getting any real hardware support in. So the hard part was done by others.

Anyway, what I usually do is: Get access to the boot loader and see if there is support for tftpboot, i.e. booting an image via Ethernet. Then I create a new device target with a minimal DTS and try to get as much as possible working. Look at one of the support commits and take it as a template (e.g.;a=commit;h=6d6f36ae787c3b339b16c1d345a90faa1d9f4011, just keep in mind that parts of the infrastructure might have changed, so use it just as a reference for which files need to be treated). Build an initramfs image.
The hardest part is usually figuring out the GPIO assignments. The stock boot log might give some hints, U-Boot might contain hints, the OEM source code might contain hints or you might just have to do trial-and-error. There are scripts in the Wiki for the trial-and-error case. Most of the time, I just define all GPIOs as outputs and see what happens. Then I define the remaining ones as inputs and try to figure out the buttons.
Once this is done, figure out how to flash it and how to create a flashable image. A Hex editor comes in handy to get the device ID and check the resulting image against the OEM update.

1 Like

Hello @edupaag,
thanks for pinging me. For the devices I did, I used the tarball from TP-Link to figure out what they have done. Usually it should not be too much if the devices are similar. You have to create the dts file from the information provided in the tarball and include it like I did in;a=commit;h=93a4c8afbff550886c0d8413d219d64dc63d72bf

1 Like

@andyboeh does the infamous mktplinkfw tool still work?
I can see that it is referenced in the OpenWrt repo tree...
Is it a way to go when (re)building the image? Any other gotchas?
One of the options could be to modify the original firmware just enough to get a (reverse) shell and then gather all the relevant hardware info from there I guess...

@ambassador86 you mean, you used the squashfs image extracted from official stock firmware package?

Depends on the device, it's probably tplink-safeloader.c and you will need to add the partition layout and device IDs to it. Most newer TP-Link devices are safeloader-based. Just the RE200v1 was not, that one was mktplinkfw-based.

You could do that, but IMHO that's a waste of time if you have access to the source code (I tend to be quicker extracting information from source code than having to break into the firmware and gather information from there. YMMV).

1 Like

I used the tarball obtainable via

1 Like

Reviving an old thread... Finally caught some time to contribute with the porting attempt work.
If you are willing to provide me with some guidance on the high-level process, it would be appreciated.

NOTE: Mistakenly deleted the above post due to my inexperience with the OpenWrt Discourse UI...

I would appreciate some guidance on the process from you as well...
Extracting the archive presents the following structure:

Readme mentions that the build system is for the OpenWrt distro.
It contains a classic mention of make menuconfig etc....
What about other dirs?

  • ibase - ???
  • opensource - strictly GPL-licensed code separated for clarity / legal reasons (???)
  • package - contains standalone OpenWrt packages (???)
  • scripts - helper scripts as seen in the standard OpenWrt SDK (???)
  • tools - helper tools, also a part of the standard OpenWrt SDK (???)

Please correct the above information if any part is incorrectly stated.
Any help is appreciated!
Thanks in advance.

Try to open such files first and read comments inside

Usually they are self explanatory.

Thanks for the advice! However, in the meantime, I realized that if I am not going to be making core contributions at the moment, deep diving into the project structure might not be necessary right now.
I believe the most efficient way to attempt a successful port of OpenWrt to this device is by comparing the commits related to the most similar device which is already supported.
And that is RE200.

Now, the question is how to extract the relevant information from this GPL archive, such as required DTS changes, included makefiles changes, tplink-safeloader.c modifications (I believe this device might even use mktplinkfw, since only its source file is available in the GPL archive's tools/firmware-utils/src dir...

Pardon my inexperience with such an embedded open-source project codebase, I am primarily not an embedded / C dev.

Update: I ran a diff -r on TP-Link's RE200 v4 & RE190 v4 GPL archive.
They are basically identical, so I won't be able to extract too much hardware nor driver info from there.
If we assume that the device has the same partition layout, as well as similar internals (e.g. MT76xx), I could literally just cherry-pick the RE200 v4 commit, do some minor string replacements and attempt a build?

Update2: I ran a build process inside the openwrt/imagebuilder:ramips-mt76x8-master docker image.
I added the following files (copied from re200-v4 + string replacement):

  • target/linux/ramips/dts/mt7628an_tplink_re190-v4.dts
  • target/linux/ramips/dts/mt7628an_tplink_re190.dtsi

I modified the following files (copied from re200-v4 + string replacement):

  • target/linux/ramips/image/
    • added re190-v4 profile
  • target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
    • added re190-v4 to the list of devices with the shared mapping
  • target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
    • added re190-v4 to the list of devices with the shared mapping

Here are the contents / differences:

diff -r /builder/.config /mnt/vol/builder/.config
> CONFIG_TARGET_DEVICE_ramips_mt76x8_DEVICE_tplink_re190-v4=y
> CONFIG_TARGET_DEVICE_PACKAGES_ramips_mt76x8_DEVICE_tplink_re190-v4=""
Only in /mnt/vol/builder/:
Only in /mnt/vol/builder/target/linux/ramips/dts: mt7628an_tplink_re190.dtsi
Only in /mnt/vol/builder/target/linux/ramips/dts: mt7628an_tplink_re190-v4.dts
diff -r /builder/target/linux/ramips/image/ /mnt/vol/builder/target/linux/ramips/image/
> define Device/tplink_re190-v4
>   $(Device/tplink-safeloader)
>   IMAGE_SIZE := 7808k
>   DEVICE_PACKAGES := kmod-mt76x0e
> endef
> TARGET_DEVICES += tplink_re190-v4
diff -r /builder/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds /mnt/vol/builder/target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds
> tplink,re190-v4|\
diff -r /builder/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network /mnt/vol/builder/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network
> 	tplink,re190-v4|\
diff -r /builder/.targetinfo /mnt/vol/builder/.targetinfo
> Target-Profile: DEVICE_tplink_re190-v4
> Target-Profile-Name: TP-Link RE190 v4
> Target-Profile-Packages: kmod-mt76x0e
> Target-Profile-hasImageMetadata: 1
> Target-Profile-SupportedDevices: tplink,re190-v4
> Target-Profile-Description:
> Build firmware images for TP-Link RE190 v4
> @@

However, here is the problem - when I run make image PROFILE=tplink_re190-v4, it produces the following error:

Collected errors:
 * pkg_hash_check_unresolved: cannot find dependency kernel (= 5.15.112-1-b1eb8a426db9a23f666a15005d902a32) for kmod-mac80211
 * satisfy_dependencies_for: Cannot satisfy the following dependencies for kmod-mt7603:
 * 	kernel (= 5.15.112-1-b1eb8a426db9a23f666a15005d902a32)
 * opkg_install_cmd: Cannot install package kmod-mt7603.
make[2]: *** [Makefile:186: package_install] Error 255
make[1]: *** [Makefile:141: _call_image] Error 2
make: *** [Makefile:259: image] Error 2

This message is cryptic to me, I expected it to complain about the pre-compiled mktplinkfw or tplink-safeloader inside staging_dir/host/bin (included with the mentioned docker image) failing to produce an image, due to lack of support for RE190-v4.
Of course, something like this (UNTESTED) would need to be added to tplink-safeloader.c:

		.id     = "RE190-V4",
		.vendor = "",
		.support_list =
		.support_trail = '\x00',
		.soft_ver = "soft_ver:1.1.0\n",

		.partitions = {
			{"fs-uboot", 0x00000, 0x20000},
			{"firmware", 0x20000, 0x7a0000},
			{"partition-table", 0x7c0000, 0x02000},
			{"default-mac", 0x7c2000, 0x00020},
			{"pin", 0x7c2100, 0x00020},
			{"product-info", 0x7c3100, 0x01000},
			{"soft-version", 0x7c4200, 0x01000},
			{"support-list", 0x7c5200, 0x01000},
			{"profile", 0x7c6200, 0x08000},
			{"config-info", 0x7ce200, 0x00400},
			{"user-config", 0x7d0000, 0x10000},
			{"default-config", 0x7e0000, 0x10000},
			{"radio", 0x7f0000, 0x10000},
			{NULL, 0, 0}

		.first_sysupgrade_partition = "os-image",
		.last_sysupgrade_partition = "file-system"

But still, the above-mentioned error is not even related to the anticipated tplink-safeloader incompatibility error... Or is it??

@andyboeh & @ambassador86 hey guys, can you two please help me answer this trivial question: what is the role of tplink-safeloader in the image build process? when is it included? it is obviously moved to a dedicated openwrt/firmware-utils repo, leaving only a single Makefile in the mentioned core repo dir... how do I then modify tplink-safeloader.c and include it in the build process?
or let's try a different approach: once you made the mentioned .mk & .dts[i] file changes for RE200-v4, how did you guys compile and finish adding support for RE200-v4?
also, I firmly believe that the device has the same partition IDs & layouts as RE200-v4, but how could I verify that myself using the provided GPL firmware archive (without having shell access + cat /proc/mtd)?

You need tplink-safeloader to make the firmware compatible with TP-Link devices so that they can be flash from the OEM GUI (I'm not sure if it's required for TFTP). It is run at the end of the build process, triggered by the Makefile (

firmware-utils can be checked out as any other OpenWrt package. You can add support there and override your build directory with a link to the new firmware-utils.

I don't know if this can be achieved with the ImageBuilder that you seem to be using - I strongly suggest you set up a proper dev environment as per the developer guide.

You call make menuconfig and select your newly added device as target. Then, you run make -j9 V=s (on an 8-core system).

The stock boot log usually contains a dump of the partition table. Since you need serial access anyway, that's the easiest way.
As an alternative, the partition table is also included in any firmware update files towards the beginning IIRC, just use a hex editor to view its contents. The supportList that you need for the patch to tplink-safeloader.c can also be found in any firmware update (towards the end, if I'm not mistaken).

IIRC, just use a hex editor to view its contents. The supportList that you need for the patch to tplink-safeloader.c can also be found in any firmware update (towards the end, if I'm not mistaken).

You were correct, SupportList object was located in plain text at the end of the OEM firmware update file. Here are the contents:


As an alternative, the partition table is also included in any firmware update files towards the beginning.

You were also correct about this one, however I found 2 conflicting sections of plain text which might look like a partition table definition:

  • Section #1
    fwup-ptn fs-uboot base 0x01000 size 0x181b9	
    fwup-ptn os-image base 0x191b9 size 0xd5dd1	
    fwup-ptn file-system base 0xeef8a size 0x6a6001	
    fwup-ptn partition-table base 0x00800 size 0x00800	
    fwup-ptn soft-version base 0x794f8b size 0x00015	
    fwup-ptn support-list base 0x794fa0 size 0x00350	
    fwup-ptn profile base 0x7952f0 size 0x00779	
    fwup-ptn default-config base 0x795a69 size 0x01099
  • Section #2
    partition fs-uboot base 0x00000 size 0x20000
    partition os-image base 0x20000 size 0xe0000
    partition file-system base 0x100000 size 0x6c0000
    partition partition-table base 0x7c0000 size 0x02000
    partition default-mac base 0x7c2000 size 0x00020
    partition pin base 0x7c2100 size 0x00020
    partition product-info base 0x7c3100 size 0x01000
    partition soft-version base 0x7c4200 size 0x01000
    partition support-list base 0x7c5200 size 0x01000
    partition profile base 0x7c6200 size 0x08000
    partition config-info base 0x7ce200 size 0x00400
    partition user-config base 0x7d0000 size 0x10000
    partition default-config base 0x7e0000 size 0x10000
    partition radio base 0x7f0000 size 0x10000

Which one of these is the correct one (my probable guess is Section #2)? What are fwup-ptn definitions?

Update3: I downloaded the same-dated OEM RE200v4 firmware, extracted SupportList & partition data, and compared it to the OEM RE190v4 firmware. I can confirm that everything is identical.
I truly believe that we can all now agree that the naive .dts[i] & make target adjustments are sufficient for the OpenWrt support for this device to be added.

@andyboeh I have 1 additional question for you, now having set up & provisioned a full build environment / build system, how can I checkout the firmware-utils source in relation to the core repo and build it from source (introducing necessary tplink-safeloader.c changes beforehand)?

There are several options that I am aware of: CONFIG_SRC_TREE_OVERRIDE, a custom package feed and a manual compile.

  1. See the Wiki
  2. See the Forum or Wiki, especially step 4
  3. Check it out separately and build it directly. As it's a host tool, you will not need the OpenWrt environment. You can then move your compiled tplink-safeloader binary to the OpenWrt staging_dir/host/bin directory. It was as simple as calling cmake (with appropriate source and build dir options) and make.

Last time I tried, I couldn't get CONFIG_SRC_TREE_OVERRIDE working for firmware-utils and I ended up going with option 3. I never tried option 2.

@andyboeh Do you have experience with using the patches? tools/firmware-utils/patches dir indicates that a pluggable firmware-utils patching functionality might be supported...