Following the advice of the people at www.openipcam.com I downloaded the entire contents of flash using Kermit95. Kermit95 is a program developed by Columbia University, but was retired in July of this year. The full source code is available, but as of writing this, there have been no compiled binaries. There exists a command “d” that dumps the data in a specified memory location and Kermit95 was used along with a script found at www.openipcam.com to record every result.
As I’ve mentioned before, the flash chip is split into 5 areas; bootloader, uCLinux, romfs, settings, and webui.99.9% of bootloaders for the Foscam IP camera (and its derivatives, and clones) use the same bootload, and by comparing bootloaders it is possible to see some address and data line problems. My flash chip is a 16bit device, meaning it deals with data in 16bits – and has 16 data lines. The bootloader sits in the bottom 64k, and so uses 12 address lines. If the two bootload sections are identical then you can safely assume that the 16 data lines, and 12 address lines are intact and working correctly.
Moving on to the uCLinux partition, and this is where things got interesting – and we found the fault. We know that the uCLinux is in a ZIP archive, because the Camera tried to unzip “image 7″ (our uCLinux file). Dumping from 0x7f020000 to 0x7F0DF700 gives the *.ZIP file that contains our uCLinux data, as evidenced by the presence of a ZIP header – “50 4B 03 04″ or which includes “PK” in ASCII. PK stands for Phil Katz best known for his work on, you guessed it, ZIP compression algorithms. Part of the header includes the file size, and so we could convert the dump.txt file into a HEX, and onwards to a binary ZIP file, just to check if the unzip functionality of the bootloader was borked. Although I went through the motions, I came to the same conclusion as the bootloader; the file was knackered. As it turns out, memory location 0x7f03000 contained some interesting information.
Upon power up the camera loads the bootloader, and then looks for the BOOT_INFO file at location 0x7f010000. BOOT_INFO contains the camera’s MAC address, IP address, DHCP information, Serial number etc. If the camera can’t find this information, it would query the other hardware, load the values into memory location 0x7f010000 and carry on with its boot sequence. Now image for a second what happens if some damage had happened to the pins responsible for those memory locations. One particular failure mode would be that the ARM would look in the flash at memory location 0x7f010000, but due to an addressing failure, the flash would return the data at location 0x7f030000 (pin A16 being tied with pin A15). Of course 0x7f030000 didn’t contain the BOOT_INFO and so the ARM polled the attached devices for information, and set up a new BOOT_INFO at 0x7f010000. Which would be great, apart from the fact that the flash actually wrote the new data back into 0x7f030000. For those that missed it, the uCLinux partition starts at 0x7f020000 and so NOW has a hole 8k wide. By all accounts, the camera did this to itself
There was no way I would be getting that 8k back, and the only way to move forward was to write to flash a working program. I was 99% certain that I had fixed the hardware fault, and that I would not only write to flash, but the correct location in flash too. But that 1% kept niggling away at me. If for some reason I managed to overwrite the bootloader in flash then I had convinced myself that it would be the end. As it turns out that never happened, and I could always read back the bootloader code and verify it against a previously dumped version – a dodgy address line wouldn’t even matter, as I wrote to the wrong location, so reading from that wrong location is easy. What wouldn’t be easy though is doing anything in Windows7. TeraTerm was supposed to have XMODEM capabilities, but for the life of me I couldn’t get it to work. Fortunately I managed to download an alternative program (ClearTerminal) so all was not lost. Side note: If the developers of RealTerm ever happen to read this, please implement XMODEM.
It took me some time to rationalise my following action; the camera was not usable in its current state – by deleting the current uCLinux there is the possibility that I could find a working version and all would be well with the world. So I started trawling OpenIPCam for a compatible dump. I now knew that my camera was a branded Storage Options, and that it was a clone of a EasyN IP camera which reduced the number of possible candidates. All that is left to do, is find a compatable and appropriate version of software – how hard can that be?