I have a u-boot (version 1.6.1) enabled board, I have dumped the partition that contains the environment variables to a binary file using dd and now am stumped at finding out how to translate the location of ascii values found into an OFFSET and SIZE parameter for fw_env.config. (Any other method at finding and trying numbers failed as well).
I'm hoping to find someone here who has already done this on any kind of system, who can tell me what to add or subtract or shift, as plain copy-paste of address of first ascii parameter doesn't work.
Full History (Most relevant info to expand on TLDR; is after the "most relevant" header, the long preamble is "proof of prior effort" and completeness):
I am faced with a daunting problem, after a full weekend of searching and trying I have not yet come towards a solution.
I have "inherited" a Linux Embedded System, Samsung ARM based, which runs a modified version of U-boot-1.6.1. I have accepted the task of fixing a few errors, one of these errors requires me to update an environment variable to u-boot.
The system in question is an EmbedSky board, TQ2440 to be specific, this doesn't help matters as it isn't a very well known type, originating from China/HongKong as it seems to me.
I have succesfully compiled fw_printenv/fw_setenv using guides like this one and have got source files to what should be the u-boot that has been used.
To be specific, for future reference, after some poking and prodding the complete call for this tool, from a PC based build environment, turned out to be (inside the u-boot root folder):
make env ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- HOSTCC=arm-none-linux-gnueabi-gcc
The last token seems to be an error, or at least something about which back in 2012 was still some contention, but it is required, as the makefile compiles for HOSTCC for the env tools. Whether this is still true in 2014/2015 releases I don't know, as an attempt to modify a 2015 version for EmbedSky went horribly, horribly wrong (all kinds of missing stuff), so I gave up on that.
Now, my problem is, in the EmbedSky.h the following defines occur (didn't find any CONFIG_, only CFG_):
#define CFG_ENV_SIZE 0x020000 #define CFG_ENV_OFFSET 0x1F0000
While the /proc/mtd shows that mtd0 is named "uboot", mtd1 is named "kernel" and mtd2 is named "root", no other mtd-sectors present.
Where the mtd0 with "uboot" is only
0x40000 long, has a block size of
0x20000 and an erase size of
0x20000 So that wouldn't fit the
The one thing that does match is that the mtd0 "uboot" device is in NAND flash and the configured parameters all over the EmbedSky.h file are for NAND flash.
Of course, being a stubborn little worker I tried setting my fw_env.config file to every combination of the known numbers on all three mtd partitions. Calling fw_printenv on any combination with an offset
0x1F0000 gave errors like "Invallid Instruction", where anything I tried below that only ever gave "CRC error: Using default Environment".
(I did notice the link above still includes the HOSTCC= directive :-) )
Every combination here means: OFFSET=0x00000; OFFSET=0x1F0000; Offset halfway, offset one 0x20000-sized sector in and two sectors in, with sizes 0x01000, 0x02000; 0x04000; 0x04200; 0x10000 and 0x20000 and spanning 1, 2 or 3 sectors. So not really every, but especially for the size those are all the numbers I came across in the tutorials I found as well as in the header file.
At this point I considered that the sources I have may not actually be what's in the board, since this fits the rest of the state of the project. So I looked for other ways.
At about 3AM tonight I did come across a blog post that spoke of "dumping the mtd containing u-boot env" and then it would be "extremely obvious what those OFFSET and SIZE parameters would be, by looking at the 0x00 bytes between primary and redundant block". I have just re-googled, as in my addled midnight state I closed the page before bookmarking, but I seem to be unable to re-find the blog.
So being hopeful I ran
sudo dd if=/dev/mtd0 of=/home/ActiveMtd0.bin bs=128k count=2 to fit the information in my /proc/mtd list. Result: Copied 256kbyte.
This gave me a binary file, and lo and behold, it contains in plain ascii the u-boot environment variables. Hurray! But, elas, this whole "obvious" seems to fail me. First of all, this dump contains only one block, not also a redundant block, so that trick is out. Second of all, it looks like the block starts at
0x367F8 (with 4 bytes of what could be CRC, followed by the first ascii parameter) which in any architecture I could dream of would be nowhere near a convenient cell boundary. It runs over 488 bytes with zero-padding, with the first non-zero byte after the env being at
0x369B8, which also isn't a nice spot. Both spots are aligned to 8 bytes, so that is at least something. Whether that's a relevant something, I can only guess at.
Optimistically I did try OFFSET =
0x367F8 on mtd0 in the config file, with a size of
0x01C0 (= 488 decimal), but that also gave invalid instruction, possibly because of the block size, going out of the boundary of mtd0, or some such, but that's much more detail than I know about the inner u-boot fw_printenv process. I then also tried OFFSET =
0x367FC and SIZE =
0x01BC to set it right at the first character of the first variable, skipping what I thought might be the CRC, but this also failed. To note, the ascii values in what seems to be the env is much less than the 488 bytes, approximately the last half is 0-padding, no idea if that's relevant to the process.
I am now fully and truly stumped.
Is there anyone who can point me to a general "subtract 12 bytes from" or "divide by 4 from this point" in the binary mtd0 dump? I would strongly prefer using fw_printenv and fw_setenv, as it needs to be automated for hundreds of devices in the field, and this is safer than meddling with NAND flash directly from script files.
Even if it is "One of the addresses you tried should be right", because now I only feel like I'm shooting in the dark with seemingly random numbers, although most of them have some reason behind them.