Once upon a time I was cleaning up the jffs2 filesystem of my OpenWrt Backfire 10.03.1 based Fonera by removing "unused" packages and I thought... what is this hotplug2 package doing here, the fonera doesn't have anything hotplugable, so I can safely remove it...
WRONG!Never remove your hotplug2 package from your OpenWrt router, it won't complain, but once you reboot... at least on a Fonera with Backfire you are f*cked!
Hotplug2 is so needed that today, after finishing my definitive cable for La Fonera (I'll write about this later) when I saw it booting on the serial console, I watched my Fonera say on boot...
VFS: Mounted root (jffs2 filesystem) readonly on device 31:1.
Freeing unused kernel memory: 136k freed
Please be patient, while OpenWrt loads ...
Kernel panic - not syncing: Attempted to kill init!
and that was before getting to failsafe mode or anything, so... how could I gain access to the files I had inside if it was not booting?
It seems I went through the hard way, cause it resulted on a long way, that's why I'm writing it here...
I had access to the console and it has redboot on it (/me doesn't know anything about redboot), so I stopped redboot (I did this on the serial console but I have just realised that this can be done over telnet as well) and typed help, and then looking at my previous notes on how to flash OpenWrt I tried to enable capture on minicom (if you do this on telnet try to pipe it to tee) and dump the contents of the jffs2 filesystem using:
RedBoot> baudrate -b 115200
Baud rate will be changed to 115200 - update your settings
Baud rate changed to 115200 - continue (y/n)? y
Update RedBoot non-volatile configuration - continue (y/n)? n
RedBoot> fis list
Name FLASH addr Mem addr Length Entry point
RedBoot 0xA8000000 0xA8000000 0x00030000 0x00000000
rootfs 0xA8030000 0xA8030000 0x006D0000 0x00000000
vmlinux.bin.l7 0xA8700000 0x80041000 0x000E0000 0x80041000
FIS directory 0xA87E0000 0xA87E0000 0x0000F000 0x00000000
RedBoot config 0xA87EF000 0xA87EF000 0x00001000 0x00000000
RedBoot> fis load -b 0x80041000 rootfs
** Warning - checksum failure. stored: 0x136086ec, computed: 0x5571b53b
RedBoot> dump -b 0x80041000 -l 0x006D0000
80041000: 19 85 20 03 00 00 00 0C F0 60 DC 98 19 85 E0 01 |.. ......`......|
...
So, after some minutes I had all this hexa dump of the memory on my HD.
Deavid kindly contributed this 90 secs python script to extract the hexa into binary (many thanks to him):
#! /usr/bin/python
from binascii import unhexlify
import sys
for line in sys.stdin:
colon = line.find(":")
end = line.find("|")
if colon < 0 or end <0:
sys.stderr.write(line)
else:
newline = line[colon+1:end].replace(" ","")
sys.stdout.write(unhexlify(newline))
And I had my jffs2 filesystem dumped on a file, yeah, so I thought I could simple mount -o loop it but... nope, jffs2 isn't that easy. Looking on the net I found that I should:
modprobe mtdram total_size=24576 erase_size=128
modprobe mtdblock
dd if=jffs2.img of=/dev/mtdblock0
mount -t jffs2 /dev/mtdblock0 /mnt
But that resulted on a mount: /dev/mtdblock0: can't read superblock error.
At that time I thought it could be an endianness problem, as I also wasn't able to mount an OpenWrt original jffs2 filesystem. So... a little more search on the net confirmed this and showed that:
apt-get install mtd-utils
jffs2dump -b -c -e dest_file.little src_file.big
should fix it, and so it did, after doing that and copying the new data converted from big endian to little endian to the mtdblock0 I was able to mount it and finally access all that I had on my Fonera.
That's it!