Sunday, February 12, 2012

Recreating LSPRO fw_env.config

In the process of upgrading my LSPRO to Debian Squeeze I found that I had no fw_env.config. That is, when I attempted to get the boot parameters I only got an error and bogus values:
# fw_printenv
Cannot parse config file: No such file or directory
Bummer...

As it happens, that file only contains the device, offset and length of the parameters in the flash memory. Also, there is a nice example already present in
/usr/share/doc/uboot-envtools/examples/
but I found that one after I made my own fw_env.config by hand.

So, the easy way to fix it:
# cp /usr/share/doc/uboot-envtools/examples/linkstation_pro_live.config /etc/fw_env.config
Here is the hard-ish way I actually used. Find the flash device info according to the kernel:
# cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00001000 "phys_mapped_flash"
With that, we know the device is "/etc/mtd0" and the erase size is 0x1000.

Then we can examine the flash device to figure out where is the actual data. It is probably aligned to the erase size and it is all text (except for a small header) so it should be easy to spot by simple visual inspection:
# hexdump -C /dev/mtd0 | less
Lo and behold, it is there near the end.
00038f70 90 6a f4 00 00 00 00 00 00 00 00 00 ff ff ff ff |.j..............|
00038f80 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
0003f000 48 aa b0 1a 62 6f 6f 74 61 72 67 73 3d 24 28 62 |H...bootargs=$(b|
0003f010 6f 6f 74 61 72 67 73 5f 62 61 73 65 29 20 24 28 |ootargs_base) $(|
0003f020 62 6f 6f 74 61 72 67 73 5f 72 6f 6f 74 29 00 62 |bootargs_root).b|
0003f030 61 75 64 72 61 74 65 3d 31 31 35 32 30 30 00 6c |audrate=115200.l|
... sipped for brevity ... 0003f3e0 6f 64 65 3d 68 6f 73 74 00 00 75 73 62 31 4d 6f |ode=host..usb1Mo|
0003f3f0 64 65 3d 68 6f 73 74 00 00 00 00 00 00 00 00 00 |de=host.........|
0003f400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00040000
It begins at 0x3f000. Given that the erase size is 0x1000, it ends at 0x3ffff. And with that we can reconstruct the file:
/etc/fw_env.conf
#device   start   size   flash block size
/dev/mtd0 0x3f000 0x1000 0x1000