Fw_setenv MTD Erase Error

Hi,

Trying to get a new device up and working (RAVPower rp-wd008). Using U-Boot and hexdump, I have confirmed the correct partition for the environment variables (and have also confirmed the values match, in U-Boot and fw_printenv within OpenWrt). But ... I'm getting an error when trying to use fw_setenv (and I have confirmed, no read-only flag on the partition, in the dts file). If I try to mess with the offset or environment size, I get the error,

Warning: Bad CRC, using default environment

OK, that makes sense. When I use the values as I believe they should be, this issue goes away, but still failing on write, with the error,

MTD erase error on /dev/mtd2: Invalid argument
Error: can't write fw_env to flash

Anyone seen this before? Any suggestions?

Oh, and I am using the format defined here, fw_env.config

Thanks!

Hi! :wave:

Do you have a current / work-in-progress DTS for your new RP-WD008 somewhere?
And a hexdump, to be sure about it's content?

Did you updated the package/boot/uboot-envtools/files/ramips file?

Just locally right now, sorry! I can send it to you if you want. Given my commit fun in the past, wasn't pushing it up quite yet ... LOL!

Sure, here you do. And the variables match to U-Boot (serial port access, checked environment),

00000000  28 76 06 00 00 1c c2 45  c9 6e 00 00 00 00 00 00  |(v.....E.n......|
00000010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000020  00 00 00 00 20 00 00 00  00 1c c2 45 c9 6e 00 1c  |.... ......E.n..|
00000030  c2 45 c9 6f 22 34 00 20  ff ff 00 01 00 00 00 00  |.E.o"4. ........|
00000040  00 00 22 00 00 00 00 00  30 00 00 00 00 00 00 00  |..".....0.......|
00000050  82 00 00 94 40 bc c0 ca  1e 80 c0 c1 40 ca 1e c1  |....@.......@...|
00000060  c1 c0 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000a0  c6 c6 c4 c4 c4 c0 c0 c4  c4 c4 c4 c4 c0 c0 00 00  |................|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000e0  11 1d 11 1d 1c 35 1c 35  1e 35 1e 35 17 19 17 19  |.....5.5.5.5....|
000000f0  02 00 00 00 c8 8d 80 88  00 00 00 00 00 00 00 00  |................|
00000100  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000120  00 00 00 00 00 00 00 00  00 00 00 00 00 00 77 00  |..............w.|
00000130  11 1d 11 1d 15 7f 15 7f  17 7f 17 7f 10 3b 10 3b  |.............;.;|
00000140  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001000  2d 76 1e a3 62 6f 6f 74  63 6d 64 3d 74 66 74 70  |-v..bootcmd=tftp|
00001010  00 62 6f 6f 74 64 65 6c  61 79 3d 32 00 62 61 75  |.bootdelay=2.bau|
00001020  64 72 61 74 65 3d 35 37  36 30 30 00 65 74 68 61  |drate=57600.etha|
00001030  64 64 72 3d 22 30 30 3a  41 41 3a 42 42 3a 43 43  |ddr="00:AA:BB:CC|
00001040  3a 44 44 3a 31 30 22 00  69 70 61 64 64 72 3d 31  |:DD:10".ipaddr=1|
00001050  30 2e 31 30 2e 31 30 2e  31 32 38 00 73 65 72 76  |0.10.10.128.serv|
00001060  65 72 69 70 3d 31 30 2e  31 30 2e 31 30 2e 32 35  |erip=10.10.10.25|
00001070  34 00 67 61 74 65 77 61  79 69 70 3d 31 30 2e 31  |4.gatewayip=10.1|
00001080  30 2e 31 30 2e 31 00 73  74 64 69 6e 3d 73 65 72  |0.10.1.stdin=ser|
00001090  69 61 6c 00 73 74 64 6f  75 74 3d 73 65 72 69 61  |ial.stdout=seria|
000010a0  6c 00 73 74 64 65 72 72  3d 73 65 72 69 61 6c 00  |l.stderr=serial.|
000010b0  00 3d 73 65 72 69 61 6c  00 00 00 00 00 00 00 00  |.=serial........|
000010c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0000e000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00010000

I think so :laughing:. Pulled the latest code upstream, and updated all feeds. Do I need to do more than that?

Thanks!

Including here the partition section from the DTS would be enough now.

:grin:

You could use svn if you don't like git! GitHub do support svn clients! :see_no_evil:

I meant edit when I wrote updated! :wink:
You have to add a few more lines to that file too!

You did it once for HT-TM05 and RP-WD03, you had to do it again!

Sure! Attached,

&spi0 {
        status = "okay";

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

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

                        partition@0 {
                                label = "u-boot";
                                reg = <0x0 0x30000>;
                                read-only;
                        };

                        factory: partition@30000 {
                                label = "factory";
                                reg = <0x30000 0x10000>;
                                read-only;
                        };

                        partition@40000 {
                                label = "u-boot-env";
                                reg = <0x40000 0x10000>;
                        };

                        partition@50000 {
                                compatible = "denx,uimage";
                                label = "firmware";
                                reg = <0x50000 0x7b0000>;
                        };
                };
        };
};

Yes, agreed! I get your point now - and I did, the file (/etc/fw_env.config) is on the router now, just getting that error. I can manually edit it (inside OpenWrt), but still no joy.

Thanks!

Does one the following work, at least (in the file package/boot/uboot-envtools/files/ramips)?

4k 16k sectors:

ubootenv_add_uci_config "/dev/mtd$idx" "0x1000" "0x1000" "0x4000"

64k sectors:

ubootenv_add_uci_config "/dev/mtd$idx" "0x1000" "0x1000" "0x10000"

Nope, same error for both (which makes sense, given the start at 0x1000 ... agreed?),

Environment does not start on (erase) block boundary
Error: environment not initialized

Thanks!

Ohh, I was wrong about 4k sectors :sweat_smile:

4k sector size is 0x1000:

ubootenv_add_uci_config "/dev/mtd$idx" "0x1000" "0x1000" "0x1000"

Btw why does it matter where the enviroment starts in the partition?! :thinking:
Just read the whole block, modify and write back! :upside_down_face:

IF, AND ONLY IF YOU HAVE ALREADY a full flash backup from you device ...
... then you could hack your DTS to work around that 0x1000 offset:

&spi0 {
        status = "okay";

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

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

                        partition@0 {
                                label = "u-boot";
                                reg = <0x0 0x30000>;
                                read-only;
                        };

                        factory: partition@30000 {
                                label = "factory";
                                reg = <0x30000 0x10000>;
                                read-only;
                        };

                        partition@40000 {
                                label = "i-dont-have-a-good-name-for-it";
                                reg = <0x40000 0x01000>;
                        };

                        partition@41000 {
                                label = "u-boot-env";
                                reg = <0x41000 0x0f000>;
                        };

                        partition@50000 {
                                compatible = "denx,uimage";
                                label = "firmware";
                                reg = <0x50000 0x7b0000>;
                        };
                };
        };
};

Please check the addresses and sizes!

That makes sense, completely agree! But ... we are sort of hacking around that 4k at the start, shouldn't fw_setenv allow us to skip it? Is that the "right" place to fix it?

Or, like many of the dts files I see ... just make that partition read-only, only printenv, not write to it?

Thanks!

Yes, this is a decision. Does it worth? :slight_smile:

If it works (reads, writes without destruction) with this DTS workaround, then I'm OK with it.
A nice comment (with a nice partition name :grinning: ) in the DTS around that new partition would help a lot for the reviewer ...

If it doesn't work, then keep the offset in the config and make it read-only! :man_shrugging:

I hoped that too! :confused:
But it doesn't allow, as you saw it:

Environment does not start on (erase) block boundary
Error: environment not initialized

Tried it, and ... no joy :frowning_face:. Hexdump looks good now,

hexdump -C /dev/mtd3
00000000  2d 76 1e a3 62 6f 6f 74  63 6d 64 3d 74 66 74 70  |-v..bootcmd=tftp|
00000010  00 62 6f 6f 74 64 65 6c  61 79 3d 32 00 62 61 75  |.bootdelay=2.bau|
00000020  64 72 61 74 65 3d 35 37  36 30 30 00 65 74 68 61  |drate=57600.etha|
00000030  64 64 72 3d 22 30 30 3a  41 41 3a 42 42 3a 43 43  |ddr="00:AA:BB:CC|
00000040  3a 44 44 3a 31 30 22 00  69 70 61 64 64 72 3d 31  |:DD:10".ipaddr=1|
00000050  30 2e 31 30 2e 31 30 2e  31 32 38 00 73 65 72 76  |0.10.10.128.serv|
00000060  65 72 69 70 3d 31 30 2e  31 30 2e 31 30 2e 32 35  |erip=10.10.10.25|
00000070  34 00 67 61 74 65 77 61  79 69 70 3d 31 30 2e 31  |4.gatewayip=10.1|
00000080  30 2e 31 30 2e 31 00 73  74 64 69 6e 3d 73 65 72  |0.10.1.stdin=ser|
00000090  69 61 6c 00 73 74 64 6f  75 74 3d 73 65 72 69 61  |ial.stdout=seria|
000000a0  6c 00 73 74 64 65 72 72  3d 73 65 72 69 61 6c 00  |l.stderr=serial.|
000000b0  00 3d 73 65 72 69 61 6c  00 00 00 00 00 00 00 00  |.=serial........|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0000d000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
0000f000

Oh, and the partition table :stuck_out_tongue_winking_eye:

cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00030000 00010000 "u-boot"
mtd1: 00010000 00010000 "factory"
mtd2: 00001000 00001000 "skipped"
mtd3: 0000f000 0000f000 "u-boot-env"
mtd4: 007b0000 00010000 "firmware"
mtd5: 001e7c40 00010000 "kernel"
mtd6: 005c83c0 00010000 "rootfs"
mtd7: 00270000 00010000 "rootfs_data"

fw_printenv is clean, but still,

fw_setenv testkey testval
MTD erase error on /dev/mtd3: Invalid argument
Error: can't write fw_env to flash

Just go with read-only it seems?

Thanks!

1 Like

Yeah, for now. :slightly_frowning_face:

hey there guys

I'm thinking that erasesize must be set to 4k for the whole device for this to work
(I cannot tell whether it already is)
that would be in the device definition in the makefile, having this

BLOCKSIZE := 4k

2 Likes

And if BLOCKSIZE is in the house, then pad-to $$$$$$$$$$$$$$$$$$$$$$BLOCKSIZE and friends have to be there too!

(@mpratt14 , how many $ does the recipe need? Four?)

Thanks @mpratt14 - never thought of that :frowning_face:. I did try to add that (to the recipe), but no joy ... so far! Is it really required to pad to a value larger than block size? If so, why? Just to understand.

And when I reflash - do I have to "don't save config", to see if this works?

Thanks again.

If you add BLOCKSIZE := without pad-to then you may have problems with persisting settings through restart / sysupgrade.

If you don't have such problems and dmesg / logread are clean, then that pad-to isn't required.

padding is only necessary to get to an eraseblock start
if your erasesize is 4k then in most cases you only have to pad 4k (pad-to $$$$BLOCKSIZE)

the uboot-env is length 0xd000 which doesn't match any other board's config

you need

ubootenv_add_uci_config "/dev/mtd3" "0x0" "0xd000" "0x1000"

for this change you have to uncheck "keep configuration" when flashing
remember the configuration is only UCI scripts and files in /etc/config
for changes to DTS you can keep configuration

These SunValleyTek devices' u-boot-env partitions are weird. :man_facepalming:
At 0x0 they have some magic Vendor value, and the real u-boot-env starts at 0x1000.

We could see that at HT-TM01, HT-TM02, RP-WD02, HT-TM05, RP-WD03 and here RP-WD008.

maybe that extra partition before uboot-env can be called "vendor" :man_shrugging: