Support for Mikrotik RB3011UiAS-RM?

Probably the best, we can allways leave some info on the wiki about 256MB models, and change needed to use all 256MB in dts...

Or leave that for later and work on making other things work....

1 Like

Simply have an empty memory node, but I dont think that it will work here.

1 Like

I'm making good progress,

have SPI Flash chip working ( pinmux gpios 55,56,57. CS is GPIO 54 )
Ethernet is also working

Created new DTS file.

root@OpenWrt:/# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr DA:9D:B7:19:4C:D1  
          inet addr:10.128.41.200  Bcast:10.128.41.255  Mask:255.255.255.0
          inet6 addr: fe80::d89d:b7ff:fe19:4cd1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:723 errors:0 dropped:22 overruns:0 frame:0
          TX packets:76 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:98880 (96.5 KiB)  TX bytes:7954 (7.7 KiB)

root@OpenWrt:/# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 0000e000 00010000 "RouterBoot"
mtd1: 00001000 00001000 "hard_config"
mtd2: 00010000 00010000 "dts_config"
mtd3: 00001000 00001000 "soft_config"
mtd4: 00f00000 00010000 "firmware"
root@OpenWrt:/# cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 67.03
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

processor       : 1
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 67.03
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

processor       : 2
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 67.03
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

processor       : 3
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 67.03
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : Generic DT based system
Revision        : 0000
Serial          : 0000000000000000
1 Like

USB works, usb-power-off is on GPIO 2

root@OpenWrt:/sys/class/gpio# echo 2 > export
root@OpenWrt:/sys/class/gpio# echo out > gpio2/direction 
root@OpenWrt:/sys/class/gpio# [ 74.082191] usb 1-1: USB disconnect, device number 2
root@OpenWrt:/sys/class/gpio# echo 0 > gpio2/value

root@OpenWrt:/sys/class/gpio# echo 1 > gpio2/value
root@OpenWrt:/sys/class/gpio# [ 86.462170] usb 1-1: new high-speed USB device number 3 using xhci-hcd
root@OpenWrt:/sys/class/gpio# lsusb
Bus 003 Device 001: ID 1d6b:0002
Bus 001 Device 001: ID 1d6b:0002
Bus 001 Device 003: ID 04e8:6860
Bus 004 Device 001: ID 1d6b:0003
Bus 002 Device 001: ID 1d6b:0003

Here is updated DTS file, only need to finish WiFi.

/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019, David Hutchison <dhutchison@bluemesh.net>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "qcom-ipq4019.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/soc/qcom,tcsr.h>

/ {
	model = "Mikrotik RouterBOARD hAP AC2";
	compatible = "mikrotik,rbd52g";

	memory {
		device_type = "memory";
		reg = <0x80000000 0x08000000>; /* 128MB */
	};

	reserved-memory {
                #address-cells = <1>;
                #size-cells = <1>;
                ranges;
                rsvd1@87000000 {
                        /* Reserved for other subsystem */
                        reg = <0x87000000 0x500000>;
                        no-map;
                };
                wifi_dump@87500000 {
                        reg = <0x87500000 0x600000>;
                        no-map;
                };

                rsvd2@87B00000 {
                        /* Reserved for other subsystem */
                        reg = <0x87B00000 0x500000>;
                        no-map;
                };
	};

	chosen {
		stdout-path = "serial0:115200n8";
	};

	aliases {
		led-boot = &user;
		led-failsafe = &user;
		led-running = &user;
		led-upgrade = &user;
	};

	soc {
		mdio@90000 {
			status = "okay";
		};

		counter@4a1000 {
			compatible = "qcom,qca-gcnt";
			reg = <0x4a1000 0x4>;
		};

		tcsr@1949000 {
			compatible = "qcom,tcsr";
			reg = <0x1949000 0x100>;
			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
		};

		tcsr@194b000 {
			/* select hostmode */
			compatible = "qcom,tcsr";
			reg = <0x194b000 0x100>;
			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
			status = "okay";
		};

		ess_tcsr@1953000 {
			compatible = "qcom,tcsr";
			reg = <0x1953000 0x1000>;
			qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
		};

		tcsr@1957000 {
			compatible = "qcom,tcsr";
			reg = <0x1957000 0x100>;
			qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
		};

		crypto@8e3a000 {
			status = "okay";
		};

		wifi@a000000 {
                        status = "ok";
                };

                wifi@a800000 {
                        status = "ok";
                };

		usb2@60f8800 {
                        status = "okay";
                };

                usb3@8af8800 {
                        status = "okay";
                };

		watchdog@b017000 {
			status = "okay";
		};

		ess-switch@c000000 {
			status = "okay";
		};

		edma@c080000 {
			status = "okay";
		};
	};

	keys {
		compatible = "gpio-keys";

		reset {
			label = "reset";
			gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
		
		mode {
			label = "mode";
			gpios = <&tlmm 5 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
	};

	leds {
		compatible = "gpio-leds";

		power: power {
			label = "rbd52g:green:power";
			gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
			default-state = "keep";
			panic-indicator;
		};

		user: user {
			label = "rbd52g:green:user";
			gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
		};
	};
};

&tlmm {
	serial_pins: serial_pinmux {
		mux {
			pins = "gpio60", "gpio61";
			function = "blsp_uart0";
			bias-disable;
		};
	};

	spi_0_pins: spi-0-pinmux {
		pinmux {
			function = "blsp_spi0";
			pins = "gpio55", "gpio56", "gpio57";
			bias-disable;
		};

		pinmux_cs {
			function = "gpio";
			pins = "gpio54";
			bias-disable;
			output-high;
		};
	};
};

&blsp_dma {
	status = "okay";
};

&blsp1_spi1 {
	pinctrl-0 = <&spi_0_pins>;
	pinctrl-names = "default";
	cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
	status = "okay";

	m25p80@0 {
		reg = <0>;
		compatible = "jedec,spi-nor";
		spi-max-frequency = <24000000>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition0@0 {
				label = "RouterBoot";
				reg = <0x80000 0xe000>;
				read-only;
			};

			partition1@8e000 {
				label = "hard_config";
				reg = <0x8e000 0x01000>;
			};

			partition2@90000 {
				label = "dts_config";
				reg = <0x90000 0x10000>;
				read-only;
			};

			partition3@bd000 {
				label = "soft_config";
				reg = <0xbd000 0x01000>;
			};

			partition4@1000000 {
				compatible = "mikrotik,minor";
				label = "firmware";
				reg = <0x100000 0xf00000>;
			};
		};
	};
};

&blsp1_uart1 {
	pinctrl-0 = <&serial_pins>;
	pinctrl-names = "default";
	status = "okay";
};

&cryptobam {
	status = "okay";
};

&usb3_hs_phy {
	status = "okay";
};

&usb3_ss_phy {
        status = "okay";
};

&usb2_hs_phy {
	status = "okay";
};
1 Like

Mikrotik has always put their radio calibration data in the hard_config. I copied over the arch/mips/ath79/routerboot.c and kludged it together to work on ARM.

I so far have the kernel reporting the following:

[    2.040067] rb: Board: RBD52G-5HacD2HnD
[    2.042339] rb: Serial Number: B4A30A591AC6
[    2.046153] rb: Running rb_sysfs_init for SysFS file
[    2.050311] rb: Search for calibration
[    2.055536] rb: Find Tag: 22

I can set the board name, serial number, and mac address now.

The RB_ID_WLAN_DATA found where the ART calibration data is located.

I couldn't get rle_decode() or lzo1x_decompress_safe() to handle this new format. For now I took the RB_ID_WLAN_DATA and passed it directly to /sys/firmware/routerboot/ext_wlan_data so we can see it.

root@OpenWrt:/sys/firmware/routerboot# hexdump -C ext_wlan_data 
00000000  4c 5a 4f 52 00 0f 44 52  45 00 01 00 3f 2f fc 20  |LZOR..DRE...?/. |
00000010  2f bd f5 02 01 fa 74 4d  28 5d a5 69 02 00 fc 20  |/.....tM(].i... |
00000020  00 2a 20 03 00 ff 60 74  90 00 17 07 06 00 ff 10  |.* ...`t........|
00000030  02 00 fe 10 33 03 00 fd  08 00 08 15 00 02 29 fe  |....3.........).|
00000040  33 01 05 00 03 33 ff f4  02 f2 ed 00 3c 14 06 00  |3....3......<...|
00000050  f8 e3 8f 3f ec 00 00 11  03 14 39 00 ff c0 10 00  |...?......9.....|
00000060  fe 90 01 04 00 fe 01 00  04 ff 2a 00 ff 0f 09 00  |..........*.....|

There is a new MAGIC header: 4c 5a 4f 52
The RB_MAGIC_ERD is still found further down: 44 52 45 00

The new header is "LZOR" since Mikrotik in the past has always used either RLE or LZO, i am speculating that "LZOR" is "lzo-rle". I am not entirely sure about that, as it appears to be a Mikrotik header.

Any ideas with how to possibly extract the ART data?

1 Like

A post was split to a new topic: Mikrotik CCR1016-12g stuck at Starting services

Is anyone booting LHGG-60ad from flash or net booting only? I read back through this thread but could not answer that for myself. The initramfs image I'm building is quite a bit larger than the mtd0 partition...

Any progress on RB3011? Are there any patches available for testing?

I would love to test and improve the port, if something is available. I have a RB3011 ready to work on this.

If I understand you correctly, Mikrotik compresses the calibration data?

On other devices with the same hardware, the calibration data seems to take 2x 12 KB:


So, it seems a bit tight to fit 24 KB of data into a 4 KB partition, even with compression! Maybe that's why they had to switch to a new compression scheme.

I have uploaded the partitions extracted from a hAP ac² device here: https://pub.polyno.me/openwrt/hap-ac2/

The "ext_wlan_data" you noticed is in mtd3_hard_config.bin, at offset 0x148 (328 decimal).

I just found out that this hard_config partition is formatted as little-endian TLVs on ARM, while on MIPS it was big-endian TLVs. Other than that it's the same overall format.

Regarding the calibration data itself, I extracted the ath10k calibration data from another device that uses the same hardware, to see what kind of format we should obtain after decoding: https://pub.polyno.me/openwrt/nbg6617/
After playing a bit with decoding, the Mikrotik does seem to be using some sort of RLE encoding. I managed to get an output that looks very much like the expected format (but it's not complete yet)

I'm getting a 403 forbidden error while trying to download your calibration bin files.

How did you extract/decode the data so far?

I'll post my routerboot.c modifications here in a little bit.

Oops, fixed the download links.

You mean the data from the nbg6617? I just copied it from /lib/firmware/ath10k/, the hotplug script extracts the calibration data there. In the non-mikrotik world this is just locating the data on flash + copying it.

If you are changing routerboot.c, make sure to read package/boot/rbcfg/src/main.c, they already handle things like endianness.

In my experiments with decoding the LZOR data, I wrote a small python script for RLE decoding, and I also used the miniLZO source for raw LZO decompression. So far, neither of those gave a complete result yet :frowning:

I'm getting a 403 forbidden error while trying to download your calibration bin files.
How did you extract the data so far?

I'll post my routerboot.c modifications here in a little bit.

@idahorazor I put all my data / tools here if you're interested: https://github.com/zorun/openwrt-hacking
If you want to add some things, I can give you access.

The last example of the readme (RLE decoding) is the closest I got to decoding the LZOR data. If you compare it with a hexdump of the ath10k caldata from nbg6617, the start is really similar.

I'm still not sure if it is encoded with RLE or LZO, because they are not that different after all.

@adron Hello, thanks for the hard work on this thread. Were you able to continue work on RB3011?

It's lzo1x, but there's a twist: the first 1380 bytes of the compressed stream are static.

This script recovers 13768 bytes of data from mtd3_hard_config.bin (install liblzo2 if needed).

It looks a bit different compared to the samples you posted, but it seems to decompress alright.

Wow! How did you figure that out, and how did you get these first 1380 bytes?

I found this tool that is supposed to read this kind of data:

The tool is able to parse the output of your script, but the content looks weird: https://gist.github.com/zorun/c2f51a30d87a93bc7052ca33efd76244

Specifically, the parsed MAC address is not correct (it's completly different from the device MAC, and produces no match in the OUI database). Also, some values are impossibly high.

It guess it's possible that atheepmgr cannot correctly parse this kind of data because the chip is too recent.

By reverse engineering flash.ko from system.squashfs of RouterOS for ARM.

There are multiple handlers related to radio data ('cr'/'er'/'dr'). I might be looking at the wrong one. In any case, when compressing 'ER' radio data it will check whether the lzo compressed data size is > 2496, if that's the case it will also apply RLE encoding.

Going by the magic (LZOR) and the output this seems to be the case. I've updated the script, but am not entirely sure I got the algorithm right.

(Swapping the if/else case in the RLE decoder produces a file which the tool you linked at least tries to interpret, but neither the script output nor decoded data looks right in that case)

Might be useful to figure out the ioctl used to read caldata using flash.ko, and then dump it on a device running the MikroTik kernel.

Unfortunately, I don't have a (spare) device with serial/a shell right now. Considering picking up a hEX S or hAP ac² to run OpenWRT, if it ends up being the latter I might be able to investigate further (I do have a hAP ac², don't feel like busting it open for serial though).

Doesnt hAP ac2 have a USB port?
You could easily get root shell by exploit from a USB storage media.

But you cant really figure out the ioctl used as ftrace is disabled in Mikrotiks kernel so you dont have a way to trace syscals used by the kernel module.

So you basically have a similar problem to me and the LHGG 60ad which has some kind of obfuscation protection for the wil6210 firmware and board files and wil6210.ko driver will decode it.
I have been looking and trying for days to somehow dump the kernel memory but both fmem and LiMe fail because I cant replicate the exact kernel configuration to properly compile them.
So, I am now pretty much stuck like you are, as I cant use strace to trace syscalls or gdb to dump the memory as kernel will prevent using ptrace on its memory space.