Add Netgear WNCE2001 (OF version)

Add Netgear WNCE2001.

This is a small RT3052 device with 4MB spi flash and 32MB ram.
2 built-in antennas, 1x fastE, no USB, reset & wps switch.
On my model the AP/RT switch is unpopulated, but I verified the gpio
mapping for it.
The stock firmware is running an unprotected tftpd which allows you
to read any file from the filesystem.
Serial port is present on testpads (See image on the wiki page).
There are more testpads below the shield near the SoC, which
may have JTAG.

Slight annoyance: The bootloader is checksumming kernel&rootfs, but
can be tricked by zeroing checksum and length fields in the checksum
partition, see
target/linux/ramips/base-files/lib/preinit/04_disable_wnce2001_flash_checksumming

The manufacturer image is very similar to the DAP one, so I slightly
modified mkdapimg to support generating it.

The resulting
openwrt-ramips-rt305x-wnce2001-squashfs-factory-(worldwide|northamerica).bin
can be used to flash from stock to OpenWRT using the stock firmware
upgrade function, without using the serial port.

http://www.netgear.com/landing/wnce2001.aspx
http://wiki.openwrt.org/toh/netgear/wnce2001

Signed-off-by: Tobias Diedrich <ranma+openwrt@tdiedrich.de>

SVN-Revision: 36289
This commit is contained in:
John Crispin 2013-04-09 14:19:33 +00:00
parent e468abcae0
commit 48feea4861
11 changed files with 251 additions and 4 deletions

View file

@ -111,6 +111,9 @@ get_status_led() {
wr512-3gn) wr512-3gn)
status_led="wr512:green:wps" status_led="wr512:green:wps"
;; ;;
wnce2001)
status_led="netgear:green:power"
;;
mzk-w300nh2) mzk-w300nh2)
status_led="mzkw300nh2:green:power" status_led="mzkw300nh2:green:power"
;; ;;

View file

@ -93,6 +93,7 @@ case "$FIRMWARE" in
wl-330n3g | \ wl-330n3g | \
wl-351 | \ wl-351 | \
wli-tx4-ag300n | \ wli-tx4-ag300n | \
wnce2001 | \
wr512-3gn | \ wr512-3gn | \
wr6202 | \ wr6202 | \
mzk-w300nh2 | \ mzk-w300nh2 | \

View file

@ -112,6 +112,9 @@ case $board in
wcr-150gn) wcr-150gn)
set_usb_led "wcr150gn:amber:user" set_usb_led "wcr150gn:amber:user"
;; ;;
wnce2001)
set_wifi_led "netgear:green:wlan"
;;
esac esac
ucidef_commit_leds ucidef_commit_leds

View file

@ -41,7 +41,8 @@ ramips_setup_interfaces()
w150m | \ w150m | \
all0256n | \ all0256n | \
all5002 | \ all5002 | \
broadway) broadway | \
wnce2001)
ucidef_add_switch "switch0" "1" "0" ucidef_add_switch "switch0" "1" "0"
ucidef_set_interface_lan "eth0" ucidef_set_interface_lan "eth0"
;; ;;
@ -242,7 +243,8 @@ ramips_setup_macs()
all0239-3g | \ all0239-3g | \
carambola | \ carambola | \
w502u) w502u | \
wnce2001)
lan_mac=$(mtd_get_mac_binary factory 40) lan_mac=$(mtd_get_mac_binary factory 40)
wan_mac=$(mtd_get_mac_binary factory 46) wan_mac=$(mtd_get_mac_binary factory 46)
;; ;;

View file

@ -0,0 +1,43 @@
#!/bin/sh
# Netgear WNCE2001 has does a checksum check on boot and goes into recovery
# tftp mode when the check fails. Initializing the JFFS2 partition triggers
# this, so we make sure to zero checksum and size to be checksummed before
# that happens, so this needs to run very early during boot.
do_wnce2001_checksumming_disable() {
. /lib/ramips.sh
local board=$(ramips_board_name)
case "$board" in
wnce2001)
echo "Board is WNCE2001, updating checksum partition..."
local zeroes=/dev/zero
local tmpfile=/tmp/wnce2001_checksum
local partname=checksum
local mtd=$(find_mtd_part $partname)
dd if=$mtd of=$tmpfile bs=80 count=1 2>/dev/null
signature=$(dd if=$tmpfile bs=1 skip=24 count=20 2>/dev/null)
checksum=$(dd if=$tmpfile bs=1 count=4 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"')
if [ "$signature" != "RT3052-AP-WNCE2001-3" ]; then
echo "Signature of checksum partition is wrong, bailing."
return 0
fi
if [ "$checksum" != "00000000" ]; then
echo "Checksum is set, zeroing."
# zero out checksum
dd if=$zeroes of=$tmpfile conv=notrunc bs=1 seek=0 count=4 2>/dev/null
# zero out bytecount to be checksummed
dd if=$zeroes of=$tmpfile conv=notrunc bs=1 seek=60 count=4 2>/dev/null
mtd write $tmpfile $partname
else
echo "Checksum is already zero, nothing to do."
fi
;;
esac
return 0
}
boot_hook_add preinit_main do_wnce2001_checksumming_disable

View file

@ -64,6 +64,7 @@ preinit_set_mac_address() {
w306r-v20 |\ w306r-v20 |\
w502u |\ w502u |\
wr6202 |\ wr6202 |\
wnce2001 |\
xdxrn502j) xdxrn502j)
mac=$(mtd_get_mac_binary factory 40) mac=$(mtd_get_mac_binary factory 40)
ifconfig eth0 hw ether $mac 2>/dev/null ifconfig eth0 hw ether $mac 2>/dev/null

View file

@ -120,6 +120,9 @@ ramips_board_detect() {
*"NBG-419N") *"NBG-419N")
name="nbg-419n" name="nbg-419n"
;; ;;
*"Netgear WNCE2001")
name="wnce2001"
;;
*"NexAira BC2") *"NexAira BC2")
name="bc2" name="bc2"
;; ;;

View file

@ -59,6 +59,7 @@ platform_check_image() {
wl341v3 | \ wl341v3 | \
wl-330n | \ wl-330n | \
wl-351 | \ wl-351 | \
wnce2001 | \
wli-tx4-ag300n | \ wli-tx4-ag300n | \
whr-g300n |\ whr-g300n |\
ur-326n4g |\ ur-326n4g |\

View file

@ -0,0 +1,142 @@
/dts-v1/;
/include/ "rt3050.dtsi"
/ {
#address-cells = <1>;
#size-cells = <1>;
compatible = "WNCE2001", "ralink,rt3052-soc";
model = "Netgear WNCE2001";
memorydetect {
ralink,memory = <0x0 0x200000 0x4000000>;
};
chosen {
bootargs = "console=ttyS0,115200";
};
palmbus@10000000 {
sysc@0 {
ralink,pinmux = "spi", "uartlite", "jtag", "sdram";
ralink,gpiomux = "i2c", "mdio", "rgmii";
ralink,uartmux = "gpio";
ralink,wdtmux = <1>;
};
gpio0: gpio@600 {
status = "okay";
};
spi@b00 {
status = "okay";
m25p80@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "mx25l3205d";
reg = <0 0>;
linux,modalias = "m25p80", "mx25l3205d";
spi-max-frequency = <10000000>;
partition@0 {
label = "u-boot";
reg = <0x0 0x30000>;
read-only;
};
factory: partition@30000 {
label = "factory";
reg = <0x30000 0x10000>;
read-only;
};
partition@40000 {
label = "config";
reg = <0x40000 0x20000>;
read-only;
};
partition@60000 {
label = "language";
reg = <0x60000 0x30000>;
read-only;
};
partition@90000 {
label = "pot";
reg = <0x90000 0x10000>;
read-only;
};
partition@a0000 {
label = "checksum";
reg = <0xa0000 0x10000>;
};
partition@b0000 {
label = "firmware";
reg = <0xb0000 0x350000>;
};
};
};
};
ethernet@10100000 {
status = "okay";
};
esw@10110000 {
status = "okay";
};
wmac@10180000 {
status = "okay";
};
gpio-leds {
compatible = "gpio-leds";
power-green {
label = "netgear:green:power";
gpios = <&gpio0 8 1>;
};
power-red {
label = "netgear:red:power";
gpios = <&gpio0 9 1>;
};
wlan-green {
label = "netgear:green:wlan";
gpios = <&gpio0 12 0>;
};
wlan-red {
label = "netgear:red:wlan";
gpios = <&gpio0 13 0>;
};
};
gpio-keys-polled {
compatible = "gpio-keys-polled";
#address-cells = <1>;
#size-cells = <0>;
poll-interval = <20>;
reset {
label = "reset";
gpios = <&gpio0 10 1>;
linux,code = <0x198>;
};
wps {
label = "wps";
gpios = <&gpio0 0 1>;
linux,code = <0x211>;
};
rt {
label = "rt";
gpios = <&gpio0 11 1>;
linux,code = <0x100>;
};
ap {
label = "ap";
gpios = <&gpio0 7 1>;
linux,code = <0x101>;
};
};
};

View file

@ -392,6 +392,18 @@ Image/Build/Profile/WL341V3=$(call BuildFirmware/WL341V3/$(1),$(1))
Image/Build/Profile/WL-351=$(call BuildFirmware/Default4M/$(1),$(1),wl-351,WL-351) Image/Build/Profile/WL-351=$(call BuildFirmware/Default4M/$(1),$(1),wl-351,WL-351)
define BuildFirmware/WNCE2001/squashfs
$(call BuildFirmware/Default4M/$(1),$(1),$(2),$(3))
-mkdapimg -s RT3052-AP-WNCE2001-3 -r WW -v 1.0.0.99 \
-i $(call sysupname,$(1),$(2)) \
-o $(call imgname,$(1),$(2))-factory-worldwide.bin
-mkdapimg -s RT3052-AP-WNCE2001-3 -r NA -v 1.0.0.99 \
-i $(call sysupname,$(1),$(2)) \
-o $(call imgname,$(1),$(2))-factory-northamerica.bin
endef
BuildFirmware/WNCE2001/initramfs=$(call BuildFirmware/OF/initramfs,$(1),$(2),$(3))
Image/Build/Profile/WNCE2001=$(call BuildFirmware/WNCE2001/$(1),$(1),wnce2001,WNCE2001)
Image/Build/Profile/WR512-3GN=$(call BuildFirmware/DefaultDualSize/$(1),$(1),wr512-3ng,WR512-3GN) Image/Build/Profile/WR512-3GN=$(call BuildFirmware/DefaultDualSize/$(1),$(1),wr512-3ng,WR512-3GN)
Image/Build/Profile/UR-326N4G=$(call BuildFirmware/Default4M/$(1),$(1),ur-326n4g,UR-326N4G) Image/Build/Profile/UR-326N4G=$(call BuildFirmware/Default4M/$(1),$(1),ur-326n4g,UR-326N4G)
@ -451,6 +463,7 @@ define Image/Build/Profile/Default
$(call Image/Build/Profile/WL_330N3G,$(1)) $(call Image/Build/Profile/WL_330N3G,$(1))
$(call Image/Build/Profile/WL341V3,$(1)) $(call Image/Build/Profile/WL341V3,$(1))
$(call Image/Build/Profile/WL-351,$(1)) $(call Image/Build/Profile/WL-351,$(1))
$(call Image/Build/Profile/WNCE2001,$(1))
$(call Image/Build/Profile/WR512-3GN,$(1)) $(call Image/Build/Profile/WR512-3GN,$(1))
$(call Image/Build/Profile/WR6202,$(1)) $(call Image/Build/Profile/WR6202,$(1))
$(call Image/Build/Profile/XDXRN502J,$(1)) $(call Image/Build/Profile/XDXRN502J,$(1))

View file

@ -27,6 +27,8 @@
#define MAX_MODEL_NAME_LEN 20 #define MAX_MODEL_NAME_LEN 20
#define MAX_SIG_LEN 30 #define MAX_SIG_LEN 30
#define MAX_REGION_LEN 4
#define MAX_VERSION_LEN 12
struct img_hdr_struct { struct img_hdr_struct {
uint32_t checksum; uint32_t checksum;
@ -51,7 +53,7 @@ perrexit(int code, char *msg)
void void
usage() usage()
{ {
fprintf(stderr, "usage: %s [-p] [-m model] -s signature -i input -o output\n", progname); fprintf(stderr, "usage: %s [-p] [-m model] [-r region] [-v version] -s signature -i input -o output\n", progname);
exit(1); exit(1);
} }
@ -60,8 +62,11 @@ main(int ac, char *av[])
{ {
char model[MAX_MODEL_NAME_LEN+1]; char model[MAX_MODEL_NAME_LEN+1];
char signature[MAX_SIG_LEN+1]; char signature[MAX_SIG_LEN+1];
char region[MAX_REGION_LEN+1];
char version[MAX_VERSION_LEN+1];
int patchmode = 0; int patchmode = 0;
int fixmode = 0; int fixmode = 0;
int have_regionversion = 0;
FILE *ifile, *ofile; FILE *ifile, *ofile;
int c; int c;
@ -71,11 +76,13 @@ main(int ac, char *av[])
progname = basename(av[0]); progname = basename(av[0]);
memset(model, 0, sizeof(model)); memset(model, 0, sizeof(model));
memset(signature, 0, sizeof(signature)); memset(signature, 0, sizeof(signature));
memset(region, 0, sizeof(region));
memset(version, 0, sizeof(version));
while ( 1 ) { while ( 1 ) {
int c; int c;
c = getopt(ac, av, "pxm:s:i:o:"); c = getopt(ac, av, "pxm:r:v:s:i:o:");
if (c == -1) if (c == -1)
break; break;
@ -94,6 +101,24 @@ main(int ac, char *av[])
} }
strcpy(model, optarg); strcpy(model, optarg);
break; break;
case 'r':
if (strlen(optarg) > MAX_REGION_LEN) {
fprintf(stderr, "%s: region exceeds %d chars\n",
progname, MAX_REGION_LEN);
exit(1);
}
have_regionversion = 1;
strcpy(region, optarg);
break;
case 'v':
if (strlen(optarg) > MAX_VERSION_LEN) {
fprintf(stderr, "%s: version exceeds %d chars\n",
progname, MAX_VERSION_LEN);
exit(1);
}
have_regionversion = 1;
strcpy(version, optarg);
break;
case 's': case 's':
if (strlen(optarg) > MAX_SIG_LEN) { if (strlen(optarg) > MAX_SIG_LEN) {
fprintf(stderr, "%s: signature exceeds %d chars\n", fprintf(stderr, "%s: signature exceeds %d chars\n",
@ -150,6 +175,10 @@ main(int ac, char *av[])
imghdr.checksum = htonl(cksum); imghdr.checksum = htonl(cksum);
imghdr.partition = 0 ; // don't care? imghdr.partition = 0 ; // don't care?
imghdr.hdr_len = sizeof(imghdr); imghdr.hdr_len = sizeof(imghdr);
if (have_regionversion) {
imghdr.hdr_len += MAX_REGION_LEN;
imghdr.hdr_len += MAX_VERSION_LEN;
}
imghdr.flash_byte_cnt = htonl(bcnt); imghdr.flash_byte_cnt = htonl(bcnt);
} else { } else {
if (ntohl(imghdr.checksum) != cksum) { if (ntohl(imghdr.checksum) != cksum) {
@ -176,6 +205,12 @@ main(int ac, char *av[])
if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0) if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
perrexit(2, "fwrite header on output"); perrexit(2, "fwrite header on output");
if (have_regionversion) {
if (fwrite(&region, MAX_REGION_LEN, 1, ofile) < 0)
perrexit(2, "fwrite header on output");
if (fwrite(&version, MAX_VERSION_LEN, 1, ofile) < 0)
perrexit(2, "fwrite header on output");
}
while ((c = fgetc(ifile)) != EOF) { while ((c = fgetc(ifile)) != EOF) {
if (fputc(c, ofile) == EOF) if (fputc(c, ofile) == EOF)