ramips: add support for Ubiquiti EdgeRouter X (UBNT-ERX)

This router is based on MT7621 SoC, no wifi, no usb, nand.

Works:
* Boots.
* Ethernet.
* Switch.
* Button (reset).
* Flashing OpenWrt from stock firmware.
* Upgrading OpenWrt.

Doesn't work:
* No GPIO leds. All leds are controlled by switch,
  but stock firmware was able to control them.
* SoC has crypto engine but no open driver.
* SoC has nat acceleration, but no open driver.
* This router has 2MB spi flash soldered in but MT
  nand/spi drivers do not support pin sharing,
  so it is not accessable and disabled. Stock
  firmware could read it and it was empty.
* PoE out.

Router has serial pins populated. If looking at the top
of the router, then counting from Eth sockets pins go as:
'GND, RX, TX, GND'. 3.3v, 57600.

U-boot bootloader supports tftpboot, controlled from serial.
This router has two kernel partitions: 'live' and 'backup'.
They are swapped during flashing (on both stock and OpenWrt).
Active partition is controlled by a flag in a factory partition.
U-boot has custom command to switch active kernel partition.
Kernel partitions are 'bare flash' 3MB. Stock bootloader has
no UBI support. Stock rootfs is UBIFS.

Flashing procedure.
Stock firmware uses custom kernel patch to mount squashfs
from a file that is located on UBIFS volume. This makes wiping
out this volume from within stock firmware difficult.
Instead this patch builds image that is flashable by stock firmware
and contains initrams image (with minimal set of packages
to fit into kernel partition). Once this is flashed one can reboot
into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
rootfs into nand.
Note: factory image is only built if initramfs image is enabled.

Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>

SVN-Revision: 47881
This commit is contained in:
John Crispin 2015-12-12 07:38:06 +00:00
parent 1c6c9549d6
commit 4e31b2e869
7 changed files with 301 additions and 2 deletions

View File

@ -114,6 +114,7 @@ ramips_setup_interfaces()
f5d8235-v2|\
hg255d|\
rt-n14u|\
ubnt-erx|\
ur-326n4g|\
wrtnode|\
wt3020|\

View File

@ -349,6 +349,9 @@ ramips_board_detect() {
*"TEW-692GR")
name="tew-692gr"
;;
*"UBNT-ERX")
name="ubnt-erx"
;;
*"UR-326N4G")
name="ur-326n4g"
;;
@ -399,7 +402,7 @@ ramips_board_detect() {
;;
*"WizFi630A")
name="wizfi630a"
;;
;;
*"WL-330N")
name="wl-330n"
;;

View File

@ -182,12 +182,36 @@ platform_check_image() {
}
return 0
;;
ubnt-erx)
nand_do_platform_check "$board" "$1"
return $?;
;;
esac
echo "Sysupgrade is not yet supported on $board."
return 1
}
platform_nand_pre_upgrade() {
local board=$(ramips_board_name)
case "$board" in
ubnt-erx)
platform_upgrade_ubnt_erx "$ARGV"
;;
esac
}
platform_pre_upgrade() {
local board=$(ramips_board_name)
case "$board" in
ubnt-erx)
nand_do_upgrade "$ARGV"
;;
esac
}
platform_do_upgrade() {
local board=$(ramips_board_name)

View File

@ -0,0 +1,76 @@
#
# Copyright (C) 2015 OpenWrt.org
#
. /lib/functions.sh
#Note: this code also uses some functions from nand.sh, but it is expected to be run by nand.sh, so we are not
#sourcing it explicitly here
UBNT_ERX_KERNEL_INDEX_OFFSET=160
ubnt_get_target_kernel() {
local factory_mtd=$1
local current_kernel_index=$(hexdump -s $UBNT_ERX_KERNEL_INDEX_OFFSET -n 1 -e '/1 "%X "' ${factory_mtd})
if [ $current_kernel_index == "0" ]; then
echo 'kernel2'
elif [ $current_kernel_index == "1" ]; then
echo 'kernel1'
fi
}
ubnt_update_target_kernel() {
local factory_mtd=$1
local kernel_part=$2
local new_kernel_index
if [ $kernel_part == "kernel1" ]; then
new_kernel_index="\x00"
elif [ $kernel_part == "kernel2" ]; then
new_kernel_index="\x01"
else
echo 'Unknown kernel image index' >&2
return 1
fi
if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
echo 'Failed to update kernel bootup index' >&2
return 1
fi
}
platform_upgrade_ubnt_erx() {
local factory_mtd=$(find_mtd_part factory)
if [ -z "$factory_mtd" ]; then
echo "cannot find factory partition" >&2
exit 1
fi
local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
if [ -z "$kernel_part" ]; then
echo "cannot find factory partition" >&2
exit 1
fi
# This is a global defined in nand.sh, sets partition kernel will be flashed into
CI_KERNPART=${kernel_part}
#Remove volume possibly left over from stock firmware
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
if [ -z "$ubidev" ]; then
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
if [ -z "$mtdnum" ]; then
echo "cannot find ubi mtd partition $CI_UBIPART" >&2
exit 1
fi
ubiattach -m "$mtdnum"
sync
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
fi
if [ -n "$ubidev" ]; then
local troot_ubivol="$( nand_find_volume $ubidev troot )"
[ -n "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
fi
ubnt_update_target_kernel ${factory_mtd} ${kernel_part} || exit 1
}

View File

@ -0,0 +1,119 @@
#include <dt-bindings/input/input.h>
/dts-v1/;
#include "mt7621.dtsi"
/ {
compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
model = "UBNT-ERX";
memory@0 {
device_type = "memory";
reg = <0x0 0x10000000>;
};
chosen {
bootargs = "console=ttyS0,57600";
};
palmbus@1E000000 {
spi@b00 {
/* This board has 2Mb spi flash soldered in and visible
from manufacturer's firmware.
But this SoC shares spi and nand pins,
and current driver does't handle this sharing well */
status = "disabled";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p80";
reg = <1>;
linux,modalias = "m25p80";
spi-max-frequency = <10000000>;
partition@0 {
label = "spi";
reg = <0x0 0x200000>;
read-only;
};
};
};
};
nand@1e003000 {
compatible = "mtk,mt7621-nand";
bank-width = <2>;
reg = <0x1e003000 0x800
0x1e003800 0x800>;
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "u-boot";
reg = <0x0 0x80000>;
read-only;
};
partition@80000 {
label = "u-boot-env";
reg = <0x80000 0x60000>;
read-only;
};
factory: partition@e0000 {
label = "factory";
reg = <0xe0000 0x60000>;
};
partition@140000 {
label = "kernel1";
reg = <0x140000 0x300000>;
};
partition@440000 {
label = "kernel2";
reg = <0x440000 0x300000>;
};
partition@740000 {
label = "ubi";
reg = <0x740000 0xf7c0000>;
};
};
ethernet@1e100000 {
mtd-mac-address = <&factory 0x22>;
};
pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
ralink,function = "gpio";
};
};
};
sdhci@1E130000 {
status = "disabled";
};
pcie@1e140000 {
status = "disabled";
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <20>;
reset {
label = "reset";
gpios = <&gpio0 12 1>;
linux,code = <KEY_RESTART>;
};
};
};

View File

@ -69,6 +69,51 @@ define Build/relocate-kernel
mv $@.new $@
endef
define Build/ubnt-erx-factory-compat
echo '21001:6' > $@.compat
$(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
$(RM) $@.compat
endef
define Build/ubnt-erx-factory-kernel
if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
$(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
\
md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
$(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
$(RM) $@.md5; \
fi
endef
define Build/ubnt-erx-factory-rootfs
echo "dummy" > $@.rootfs
$(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
$(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
$(RM) $@.md5
$(RM) $@.rootfs
endef
define Build/ubnt-erx-factory-version
echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
$(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
$(RM) $@.version
endef
#We need kernel+initrams fit into kernel partition
define Build/ubnt-erx-factory-check-size
@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
$(RM) -f $@; \
}
@[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
echo "WARNING: Kernel for image $@ not found" >&2; \
$(RM) -f $@; \
}
endef
define MkCombineduImage
$(call PatchKernelLzma,$(2),$(3))
if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
@ -954,7 +999,7 @@ endif
#
ifeq ($(SUBTARGET),mt7621)
TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 witi wf-2881 zbt-wg2626
TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 ubnt-erx witi wf-2881 zbt-wg2626
endif
define Device/mt7621
@ -1023,6 +1068,20 @@ define Device/wf-2881
IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
endef
define Device/ubnt-erx
DTS := UBNT-ERX
FILESYSTEMS := squashfs
KERNEL_SIZE := 3145728
KERNEL := $(KERNEL_DTB) | uImage lzma
IMAGES := sysupgrade.tar factory-initramfs.tar
IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
ubnt-erx-factory-kernel | \
ubnt-erx-factory-rootfs | \
ubnt-erx-factory-version | \
ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
IMAGE/sysupgrade.tar := sysupgrade-nand
endef
#
# MT7628 Profiles
#

View File

@ -0,0 +1,17 @@
#
# Copyright (C) 2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
define Profile/UBNT-ERX
NAME:=Ubiquiti EdgeRouter X
FEATURES+=nand -usb
PACKAGES:=-kmod-mt76 -wpad-mini -kmod-cfg80211
endef
define Profile/UBNT-ERX/Description
Package set compatible with the Ubiquiti EdgeRouter X
endef
$(eval $(call Profile,UBNT-ERX))