This post talk about a cheap Heden clone outdoor camera but should work on most Linux embedded systems.
Here the little story : A friend ask me to repair his bricked Heden cam copy (no-name). So let’s open it, find a serial port and look what’s going on. I used the bus-pirate of course. I discovered that only the bootloader is working, the whole flash seems empty.I searched a long time, and tried severals stuffs, but I was unable to find the right firmware (in the right format) for his no-name camera.
So my friend sent the camera back (warranty), and receive a new one. Now, he ask me to backup the flash memory, to fix the problem if this occurs in a few months again.
The main issue is : The camera has no backup web interface, no MTD dump shell binary (nor ftp, scp..), and it’s not really easy to compile the mtd tools because the system has no library installed (only a few static binary files). I’m unable to backup the firmware throught the OS. Let’s try see the bootloader.
The bootloader has no backup firmware features, but it can dump the memory content (flash included), and it has a builtin “ls” like command that display base memory segments. With the simple “d 0xAAAA”, you can dump the memory at 0xAAAA address. Fine, I decided to write a little script that walk the memory, dump the content and rebuild the binary file.
#!/usr/bin/env python2 import serial,sys,string log_file = None def ser_open(): ser = serial.Serial("/dev/ttyUSB0", 115200, timeout = 0.1) return ser def log(line): l=string.split(line,' ') data='%s%s%s%s' % (l[1],l[2],l[4],l[5]) for i in range(0,32,2): octet = int(data[i:i+2],16) log_file.write('%s' % chr(octet)) def dump(ser,addr): s = "d -s 0x%x\n" % addr ser.write(s) l=[] i = 0 while 1: data = ser.read() if not data:break l.append(data) if (data=='\r'): s = string.join(l,'') if (s[0] == '['): log(s) l=[] d = ser_open() log_file = open('log.raw','a') img_start = 0x7F0E0000 img_size = 0xC3C00 for i in range(img_start,img_start+img_size+0x100,0x100): dump(d,i) print "0x%x"% i
As you can see, this code isn’t really clean and well written, but it give me a nice binary file for a given offset and size. Simply dump the memory through serial port, do a little parsing, and store the result in binary file named log.raw.
I used this to backup the camera linux.bin file, and the romfs.img. Of course you can use this to dump the whole memory too. To check if the files are Ok, you can try to g-unzip the Linux Kernel, and mount the romfs.
To check the romfs, I simply mount it with : mount -t roomfs -o loop log.raw ./log
So now, I have a backup for this no-name camera, and next time the whole memory will drop, I will try to restore it ;).
This method seems really crude (and dirty), but it work without too much trouble, and can be tweaked for a lot of systems. It should work on every Linux embedded system with an dump memory feature in the bootloader (quite every one).
Enjoy memory ;)