Guide: Flashing Without Serial Access
Anything not explained here is probably well explained in other parts of this thread / the net.
I wrote this guide over the past 24 hours as I went along. I discovered 3 methods. I think if you want to "chew'n'screw" you should go for Option 1b.. My favorite is 1a but it's a splat of development rather than a tool.
The 2 main options are:
Modify u-boot-env
Modify u-boot
Let's learn a little about U-Boot's environment on WNR2000v4. There are 2 environments. Only one can be loaded at a time. The unit first looks for a valid crc32'd environment in the u-boot-env partition. I might call this "preferences." If that's corrupted, or missing, it goes into u-boot partition's internal "default" environment. The thing that's nice about modifying the default is that if you find yourself installing the stock firmware again in the future, which could happen sooner than you think, the default will be on your side to save you
.. Otherwise you'll have to repeat one of the other processes if that's what you go with... This all stems from the fact that WNR2000v4 stock firmware (1.0.0.58 at least) overwrites the preferences with a copy of ART data.
Anyways, let's begin, shall we?
Option 1
Warning (option 1 only): If you reboot back into stock firmware after applying the changes below, your work will be undone. This is part of the "stock" wireless boot-up check. Don't let this happen. You can always redo the work if necessary.
Sub-Options
Make your own image -- difficult, tailored to your environment
Use a pre-made u-boot-env image == easy, might be risky
Make your own image
This way is probably the most guaranteed safe secure way. Follow my lead conceptually:
* on host PC
python telnetenable.py 192.168.1.1 28C68E26DA82 admin password
telnet router
# from router root telnet session:
dd if=/dev/mtd0 of=/tmp/u-boot.backup
# it's good to make this backup anyways.. Keep it for your records
hexdump -C /tmp/u-boot.backup # verify you dumped the right thing.. Look for the environment variables. See Appendix A for an example.
cd tmp; tftp -p -r u-boot.backup 192.168.1.10 69
Now Open up the file in a hex editor on host PC, and find the environment variables... I found mine @ 0x2c7c0. Copy from the first letter of the first variable right down to the last letter of the last variable, but also include the null char after.. Because these variables all have to be NULL-padded. Anyways It's 1 big chunk of information.
Create a new file in your hex editor and paste what you copied. I called my file "u-boot-env-variables.bin"
you can manually adjust the bootcmd or do it the pretty way. Let's try the pretty way.
sed 's/\x0/\xa/g' u-boot-env-variables.bin > u-boot-env-vars.txt
vi u-boot-env-vars.txt
bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ath-nor0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1408k(uImage),64k(mib0),64k(ART)
bootcmd=sleep 1; nmrp; nor_two_part_fw_integrity_check 0x9f040000; bootm 0x9f040000
bootdelay=1
baudrate=115200
ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee
ipaddr=192.168.1.1
serverip=192.168.1.10
dir=
lu=tftp 0x80060000 ${dir}u-boot.bin&&erase 0x9f000000 +$filesize;cp.b $fileaddr 0x9f000000 $filesize
lf=tftp 0x80060000 ${dir}db12x${bc}-jffs2&&erase 0x9f050000 +0x630000;cp.b $fileaddr 0x9f050000 $filesize
lk=tftp 0x80060000 ${dir}vmlinux${bc}.lzma.uImage&&erase 0x9f680000 +$filesize;cp.b $fileaddr 0x9f680000 $filesize
That makes it nice and easy to work with as regular text.. Now edit the bootcmd line to be like the following:
Save the file.
tr -s '\n' '\000' < u-boot-env-vars.txt > u-boot-env-vars-hacked.bin
Use this C program:
crc32.c
#include <zlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#define min(x,y) ((x < y) ? x:y)
#define BUFSIZE 1000
int main(int argc, char **argv)
{
// too lazy for error checking :D
char fbuf[BUFSIZE];
int r;
int fd;
uLong crc = crc32(0L, Z_NULL, 0);
fd = open(argv[1],O_RDONLY);
if (!fd) exit(1);
struct stat buf;
fstat(fd, &buf);
while ( (r = read (fd, fbuf, BUFSIZE)) > 0)
{
crc = crc32(crc, fbuf, r);
//write(1, fbuf, r);
}
//printf("%04lX", crc);
putchar( (crc >> 24) & 0xff);
putchar( (crc >> 16) & 0xff);
putchar( (crc >> 8) & 0xff);
putchar( (crc) & 0xff);
return 0;
}
compile with gcc crc32.c -lz -o crc32
# pad the file
dd if=/dev/zero bs=1 count=65532 of=padded.bin
dd if=u-boot-env-vars-hacked.bin of=padded.bin conv=notrunc
./crc32 padded.bin > final_env.bin; cat padded.bin >> final_env.bin
Back in router telnet root shell, in /tmp
tftp -g -r final_env.bin 192.168.1.10 69
mtd -f write final_env.bin u-boot-env
Now, we have to verify we did this right. And the best way is to use a clean application rather than reboot. I've hacked together a fw_printenv/setenv that works on stock firmware (tested on 1.0.0.58). It works by disabling the lock file (broken on stock firmware), and hard-coding the MTD configuration. Relative files are located in my openwrt build at openwrt/build_dir/target-mips_34kc_uClibc-0.9.33.2/u-boot-2014.10/tools/env
We can use this as follows:
Lines starting with # are my own comments.
root@WNR2000v4:/tmp# tftp -g -r fw_printenv 192.168.1.10 69
root@WNR2000v4:/tmp# chmod +x ./fw_printenv
root@WNR2000v4:/tmp# ./fw_printenv
Warning: Bad CRC, using default environment
# this means the u-boot-env is not programmed correctly. This is what we will fix now.
root@WNR2000v4:/tmp# tftp -g -r fe.bin 192.168.1.10 69
root@WNR2000v4:/tmp# mtd -f write fe.bin u-boot-env
Unlocking u-boot-env ...
Writing from fe.bin to u-boot-env ... [w]
root@WNR2000v4:/tmp# ./fw_printenv
bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ath-nor0:256k(u-boot),64k(u-boot-env),6336k(rootfs),1408k(uImage),64k(mib0),64k(ART)
bootcmd=bootm 0x9f040000
bootdelay=5
baudrate=115200
ethaddr=0x00:0xaa:0xbb:0xcc:0xdd:0xee
ipaddr=192.168.1.1
serverip=192.168.1.10
dir=
lu=tftp 0x80060000 ${dir}u-boot.bin&&erase 0x9f000000 +$filesize;cp.b $fileaddr 0x9f000000 $filesize
lf=tftp 0x80060000 ${dir}db12x${bc}-jffs2&&erase 0x9f050000 +0x630000;cp.b $fileaddr 0x9f050000 $filesize
lk=tftp 0x80060000 ${dir}vmlinux${bc}.lzma.uImage&&erase 0x9f680000 +$filesize;cp.b $fileaddr 0x9f680000 $filesize
# We got an environment. that means we did it ! :D otherwise there was something wrong (??)
# just for fun, I will go over how to use setenv program a variable directly.
# It will work even if your preferences environment does not have a correct CRC32 / hasn't been initialized yet.
# if it complains about bad CRC, it means it's your first entry, which will create the new environment :)
root@WNR2000v4:/tmp# ln -s ./fw_printenv fw_setenv
root@WNR2000v4:/tmp# ./fw_setenv boot_delay 2
root@WNR2000v4:/tmp# ./fw_printenv boot_delay
boot_delay=2
root@WNR2000v4:/tmp# hexdump -C /dev/mtd1
At this point you should transfer your sysupgrade img to the router via TFTP and then flash it.
tftp -g -r sysfsupgrade.bin 192.168.1.10 69
mtd -f -r write sysfsupgrade.bin firmware
Then your router will reboot with the new firmware hopefully, and you can telnet in without needing a telnet-enable. At that point, you customize your router. Have fun : )
Use a pre-made u-boot-env image
This is the easiest method, no work on your part. But since nobody has tried my environment in their router, I can't guarantee you this will work, and it's 100% your own decision to try this method. I am not liable and you agree to that if you try this. You might get bricked (probably not).
We are going to overwrite the u-boot-env partition via the netgear telnet-enable root shell.
you must already be running a TFTP server on the host PC that the router can reach, typically via ethernet. in my example I gave my Host PC a static IP (host setting) of 192.168.1.10 because it's also the pre-programmed IP for the TFTP functions in u-boot.
We will be using my u-boot-env partition to do this. My u-boot-env partition may make the process simple for you, but there is a possibility for error. consider any possible differences that you should account for by comparing the env inside of your u-boot (for my unit it's in mtd0:0x2c7bc) with my u-boot-env. See Appendix A for notes on the analysis process.
If you notice drastic differences, be careful not to brick your unit, especially if you don't have access to JTAG. Report here. Otherwise, should be good to go.
On the Host PC, Download my u-boot-env partition into your TFTP downloads directory (ie. /tftpboot):
Now, from WNR2000V4 root shell, assuming TFTP server at 192.168.1.10:69
cd /tmp
tftp -g -r uboot_env_bootcmd_nocrc.backup 192.168.1.10 69
mtd -f write uboot_env_bootcmd_nocrc.backup u-boot-env
Now upload your new sysupgrade bin file and reboot. Should be golden!
Option 2
Manually modify your u-boot's default environment.
This is like a backup environment when your u-boot-env partition gets messed up. I'm not a big fan of this option, but I did figure out how to do it along the way. So I'll leave this guide here for those wanting to do it.
Note: I don't think there is a checksum on this environment.
Download this modified Netgear WNR2000V4 img to your home computer, and then into the router via the router web interface or tftp Firmware Recovery mode. This image has the u-boot partition writable.
You're likely going to need TFTP server for the rest.. Here's how I did it.
on router root shell [telnet-enable],
dd if=/dev/mtd0 of=/tmp/uboot.backup
tftp -p -r uboot.backup 192.168.1.10 69
On your Host computer
#in the tftp downloads directory (/tftpboot for me)
cp uboot.backup uboot.bootcmd.mod
ghex uboot.bootcmd.mod
# I'm opening the file in a hex editor
# Look for the bootcmd= and then in overlay mode, rewrite the command to be
bootcmd=bootm 0x9f040000
pad the rest of the former command to zero's all the way until the next variable.
You maybe don't have to pad all of the zero's, maybe you could delete them and pull back the environment data, leaving the rest of the image precisely at the addresses they originated from. But that's a hassle and I didn't test it. Use your own judgement.
on the router root shell
tftp -g -r uboot.bootcmd.mod 192.168.1.10 69
mtd -f write uboot.bootcmd.mod u-boot
You may now continue with flashing your firmware.. as per other detailed posts in this thread, but for brevity's sake:
tftp -g -r sysfsupgrade.bin 192.168.1.10 69
mtd -f -r write sysfsupgrade.bin firmware
Appendix A
u-boot analysis
It doesn't matter if your u-boot environment is located at a different address from mine. What we're concerned about is whether you have different variables or variables with different values.
To perform this analysis:
Here's a sample; the forum may have mangled the output, copy paste into fixed-width editor for best results.
0002c7b0 00 02 00 00 00 02 00 00 ff ff ff ff 00 00 00 00 |................|
0002c7c0 62 6f 6f 74 61 72 67 73 3d 63 6f 6e 73 6f 6c 65 |bootargs=console|
0002c7d0 3d 74 74 79 53 30 2c 31 31 35 32 30 30 20 72 6f |=ttyS0,115200 ro|
0002c7e0 6f 74 3d 33 31 3a 30 32 20 72 6f 6f 74 66 73 74 |ot=31:02 rootfst|
0002c7f0 79 70 65 3d 6a 66 66 73 32 20 69 6e 69 74 3d 2f |ype=jffs2 init=/|
0002c800 73 62 69 6e 2f 69 6e 69 74 20 6d 74 64 70 61 72 |sbin/init mtdpar|
0002c810 74 73 3d 61 74 68 2d 6e 6f 72 30 3a 32 35 36 6b |ts=ath-nor0:256k|
0002c820 28 75 2d 62 6f 6f 74 29 2c 36 34 6b 28 75 2d 62 |(u-boot),64k(u-b|
0002c830 6f 6f 74 2d 65 6e 76 29 2c 36 33 33 36 6b 28 72 |oot-env),6336k(r|
0002c840 6f 6f 74 66 73 29 2c 31 34 30 38 6b 28 75 49 6d |ootfs),1408k(uIm|
0002c850 61 67 65 29 2c 36 34 6b 28 6d 69 62 30 29 2c 36 |age),64k(mib0),6|
0002c860 34 6b 28 41 52 54 29 00 62 6f 6f 74 63 6d 64 3d |4k(ART).bootcmd=|
0002c870 73 6c 65 65 70 20 31 3b 20 6e 6d 72 70 3b 20 6e |sleep 1; nmrp; n|
0002c880 6f 72 5f 74 77 6f 5f 70 61 72 74 5f 66 77 5f 69 |or_two_part_fw_i|
0002c890 6e 74 65 67 72 69 74 79 5f 63 68 65 63 6b 20 30 |ntegrity_check 0|
0002c8a0 78 39 66 30 34 30 30 30 30 3b 20 62 6f 6f 74 6d |x9f040000; bootm|
0002c8b0 20 30 78 39 66 30 34 30 30 30 30 00 62 6f 6f 74 | 0x9f040000.boot|
0002c8c0 64 65 6c 61 79 3d 31 00 62 61 75 64 72 61 74 65 |delay=1.baudrate|
0002c8d0 3d 31 31 35 32 30 30 00 65 74 68 61 64 64 72 3d |=115200.ethaddr=|
0002c8e0 30 78 30 30 3a 30 78 61 61 3a 30 78 62 62 3a 30 |0x00:0xaa:0xbb:0|
0002c8f0 78 63 63 3a 30 78 64 64 3a 30 78 65 65 00 69 70 |xcc:0xdd:0xee.ip|
0002c900 61 64 64 72 3d 31 39 32 2e 31 36 38 2e 31 2e 31 |addr=192.168.1.1|
0002c910 00 73 65 72 76 65 72 69 70 3d 31 39 32 2e 31 36 |.serverip=192.16|
0002c920 38 2e 31 2e 31 30 00 64 69 72 3d 00 6c 75 3d 74 |8.1.10.dir=.lu=t|
0002c930 66 74 70 20 30 78 38 30 30 36 30 30 30 30 20 24 |ftp 0x80060000 $|
0002c940 7b 64 69 72 7d 75 2d 62 6f 6f 74 2e 62 69 6e 26 |{dir}u-boot.bin&|
0002c950 26 65 72 61 73 65 20 30 78 39 66 30 30 30 30 30 |&erase 0x9f00000|
0002c960 30 20 2b 24 66 69 6c 65 73 69 7a 65 3b 63 70 2e |0 +$filesize;cp.|
0002c970 62 20 24 66 69 6c 65 61 64 64 72 20 30 78 39 66 |b $fileaddr 0x9f|
0002c980 30 30 30 30 30 30 20 24 66 69 6c 65 73 69 7a 65 |000000 $filesize|
0002c990 00 6c 66 3d 74 66 74 70 20 30 78 38 30 30 36 30 |.lf=tftp 0x80060|
0002c9a0 30 30 30 20 24 7b 64 69 72 7d 64 62 31 32 78 24 |000 ${dir}db12x$|
0002c9b0 7b 62 63 7d 2d 6a 66 66 73 32 26 26 65 72 61 73 |{bc}-jffs2&&eras|
0002c9c0 65 20 30 78 39 66 30 35 30 30 30 30 20 2b 30 78 |e 0x9f050000 +0x|
0002c9d0 36 33 30 30 30 30 3b 63 70 2e 62 20 24 66 69 6c |630000;cp.b $fil|
0002c9e0 65 61 64 64 72 20 30 78 39 66 30 35 30 30 30 30 |eaddr 0x9f050000|
0002c9f0 20 24 66 69 6c 65 73 69 7a 65 00 6c 6b 3d 74 66 | $filesize.lk=tf|
0002ca00 74 70 20 30 78 38 30 30 36 30 30 30 30 20 24 7b |tp 0x80060000 ${|
0002ca10 64 69 72 7d 76 6d 6c 69 6e 75 78 24 7b 62 63 7d |dir}vmlinux${bc}|
0002ca20 2e 6c 7a 6d 61 2e 75 49 6d 61 67 65 26 26 65 72 |.lzma.uImage&&er|
0002ca30 61 73 65 20 30 78 39 66 36 38 30 30 30 30 20 2b |ase 0x9f680000 +|
0002ca40 24 66 69 6c 65 73 69 7a 65 3b 63 70 2e 62 20 24 |$filesize;cp.b $|
0002ca50 66 69 6c 65 61 64 64 72 20 30 78 39 66 36 38 30 |fileaddr 0x9f680|
0002ca60 30 30 30 20 24 66 69 6c 65 73 69 7a 65 00 00 00 |000 $filesize...|
0002ca70 9f 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0002ca80 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 |................|
0002ca90 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 00 |................|
0002caa0 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 01 |................|
0002cab0 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 |................|
0002cac0 00 00 00 02 00 00 00 01 00 00 00 01 00 00 00 00 |................|
0002cad0 00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 01 |................|
0002cae0 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 |................|
0002caf0 00 00 00 04 00 00 00 01 00 00 00 00 00 00 00 01 |................|
0002cb00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 |................|
0002cb10 ff ff ff ff ff ff ff ff ff ff 00 00 c0 a8 01 01 |................|
0002cb20 c0 a8 00 00 00 00 00 01 00 00 00 01 00 00 00 00 |................|
0002cb30 00 00 00 3c 66 69 72 6d 77 61 72 65 00 00 00 00 |...<firmware....|
(Last edited by bazz on 22 Apr 2015, 21:39)