Camcorder Firmware Disassembly

Pure Digital's Camcorder for CVS

[camcorder pic]


Overview
The camera's firmware is a stored near the beginning of FLASH memory. Unlike the PV2, it is not a unique file, so no bootloader is needed to traverse the file system and load the correct firmware into memory.

The firmware is about 1255 kB in size. So far, I have disassembled and roughly traced approximately 54% of the code - I still haven't commented individual lines (I managed to interface with the camera before doing that), but the disassembler I wrote does a good job of automatically adding some meaningful comments.

ELF Header
The firmware's ELF header yields this general information:

firmware.o: ELF 32-bit LSB executable, MIPS, version 1 (SYSV), statically linked, stripped

The camera uses a MIPS-I compatible processor. A simulator and a good set of resources is available here. Being statically linked makes it easier to disassemble (and also easier for the camera to execute). "Stripped" means that the complier has removed all variable and function names that would make debugging very easy. Doing this also makes the program smaller and faster.

The standard unix utility objdump provides information on the structure of the file:

architecture: mips:isa32, flags 0x00000002: EXEC_P
start address 0x80000600

Program Header:
    LOAD off    0x000000d4 vaddr 0x80000180 paddr 0x80000180 align 2**0
         filesz 0x0000013c memsz 0x0000013c flags r-x
    LOAD off    0x00000220 vaddr 0x80000600 paddr 0x80000600 align 2**5
         filesz 0x0012e19c memsz 0x0012e19c flags r-x
    LOAD off    0x0012e3c0 vaddr 0x8012e7a0 paddr 0x8012e7a0 align 2**4
         filesz 0x0000a820 memsz 0x000173c0 flags rw-
    LOAD off    0x00138bec vaddr 0x90009800 paddr 0x90009800 align 2**2
         filesz 0x00000400 memsz 0x00000400 flags rw-
    LOAD off    0x00138fec vaddr 0xbfc08000 paddr 0xbfc08000 align 2**2
         filesz 0x00000210 memsz 0x00000210 flags rwx
private flags = 50000001: [no abi set] [mips32] [not 32bitmode]

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .spc0         00000210  bfc08000  bfc08000  00138fec  2**2  CONTENTS, ALLOC, LOAD, CODE
  1 .spc1         00000000  bfc09000  bfc09000  001391fc  2**0  CONTENTS
  2 .spc2         00000000  bfc09400  bfc09400  001391fc  2**0  CONTENTS
  3 .spc3         00000000  bfc09800  bfc09800  001391fc  2**0  CONTENTS
  4 .spd0         00000000  90008000  90008000  001391fc  2**0  CONTENTS
  5 .spd1         00000000  90009000  90009000  001391fc  2**0  CONTENTS
  6 .spd2         00000000  90009400  90009400  001391fc  2**0  CONTENTS
  7 .spd3         00000400  90009800  90009800  00138bec  2**2  CONTENTS, ALLOC, LOAD, DATA
  8 .exception    0000013c  80000180  80000180  000000d4  2**0  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .boot         00000040  80000600  80000600  00000220  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .text         0012dfc0  80000640  80000640  00000260  2**5  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 __ex_table    00000010  8012e600  8012e600  0012e220  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .scratch      0000011c  8012e610  8012e610  0012e230  2**2  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .scratchpad3  00000070  8012e72c  8012e72c  0012e34c  2**0  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .data         0000a808  8012e7a0  8012e7a0  0012e3c0  2**3  CONTENTS, ALLOC, LOAD, DATA
 15 .data1        00000018  80138fa8  80138fa8  00138bc8  2**2  CONTENTS, ALLOC, LOAD, DATA
 16 .sbss         000005c4  80138fc0  80138fc0  00138be0  2**2  ALLOC
 17 .bss          0000c5d0  80139590  80139590  00138bec  2**4  ALLOC

SYMBOL TABLE:
no symbols

Although there are no symbols ("stripped"), there are plenty of debugging strings that are printed either for general reference (in case a serial monitor is connected) or when an error occurs. The original source filenames have also been preserved. Between the two of these sources, there is a lot more information with this camera than the PV2.

Two Part Disassembly

In the past, I've written a complete disassembler. (examples: disv8 for the pv2 and Dis8051 for the original Dakota). This worked well for 8-bit processors since their instruction sets were fairly simple. But, the MIPS instruction set is a lot more complicated. There is already a good open-source disassembler for the MIPS, but it doesn't perform well when symbols are not present. (It assumes you are debugging your own program and can tell the compiler to leave the symbols in). I also did not want to make another ELF decoder.

The solution was a two-part disassembly: First, the .o file is converted to a very boring and uncommented text file disassembly. Then, my program takes in that output and adds all the mojo needed to make it easy to read.

OBJDUMP: A Rough Draft

Objdump is a standard GNU utility to display information in an object file. It is part of the Binutils library that is included with every Linux and Macintosh installation.  Unfortunately, though, support for the MIPS processor probably wasn't enabled unless you have an old Silicon Graphics (SGI) computer.

1. Make sure you compile it with support for MIPS
[to do: better description here]

2. Run this command to convert the firmware file into a raw disassembled file:

objdump-mips -h -D -M reg-names=r3000 firmware.o > firmware.hd

This specifies the R3000 register names. I guess MIPS I/II/etc is automatic if they are backwards compatible.

I used the suffix ".hd" because the the "-h" and "-D" flags were enabled.

DISMIPPER: A Big Improvement

Dismipper adds a lot of features that are missing from objdump. The big difference is that Dismipper uses a file to provide extra information to guide disassembly.

The new (& powerful!) features are:
First, download Dismipper version 0.9.  This includes the file firmware.comments, which is the main fruit of my labors (do you detect a little pride in my offspring?). This contains:
The program is an Xcode project for the mac, but it should be simple to make a makefile to allow compiling it under Linux or another operating system (Xcode uses gcc).  Sorry I don't have that file (I'm lazy) -- if you make one, could you send it to me so that I can include it in future distributions?

Assuming that firmware.hd is in your current directory, invoke the program with this command:

dismipper > firmware.lst

... and there you go! Look at firmware.lst in your favorite editor.



Known bugs:





back to my analysis of the firmware

My main CVS Camcorder analysis page
Info on the PV2 still disposable digital camera (also with LCD screen)
other systems I've played with
visit my homepage