Support

Blog

Browsing all articles in Firmware

Flattr this!

Had a client come into the office today with a locked iPhone.

Normally this isn’t really a big deal (assuming that there is a hack for it), but in this case, it was a little more complex, as he didn’t have working wifi.

PwnageTool has a great feature where you can add Cydia Packages to a custom firmware, so that you can prepackage the firmware already to go.

So, I opened up PwnageTool, added the http://repo666.ultrasn0w.com/ site to the Cydia sources section in advanced, and tried to load in Ultrasn0w.

Life isn’t easy, and it didn’t work.

But why didn’t it work?

I took a look at a working site, and checked out the differences between their package section and Ultrasn0w’s.

Ultrasn0w is hosted on repo666.ultrasn0w.com
While their website doesn’t really tell you much useful information, a bit of googling lead to some info.

The .deb file (debian package file) on their site is at http://repo666.ultrasn0w.com/ultrasn0w.deb

Cydia usually needs stuff in a particular format, so I next checked out how one makes a repository.
This is documented at Saurik’s site here – http://www.saurik.com/id/7

Basically, you throw files into a folder and make a Packages file.

The example given on Saurik’s site is this:

/web/apt/xmpl]# dpkg-scanpackages -m . /dev/null >Packages
** Packages in archive but missing from override file: **
com.saurik.myprogram

Wrote 1 entries to output Packages file.
[root@desktop:/web/apt/xmpl]# bzip2 Packages
[root@desktop:/web/apt/xmpl]# ls -la *
-rw-r--r-- 1 root root 906 2008-07-01 07:48 MyProgram.deb
-rw-r--r-- 1 root root 380 2008-07-01 08:00 Packages.bz2
[root@desktop:/web/apt/xmpl]#

So, it appears we need a Packages.bz2 file.

Being adventurous, I decided to setup my own repo, and stuck the .deb file for Ultrasn0w in there.
Followed the instructions and created the Packages.bz2 file.

Tried again in PwnageTool, and… No go.

Hmm.

Does http://repo666.ultrasn0w.com have a Packages.bz2 file?
Why yes it does.

Take another look at the working one – ahah says my brain.

They point the folder to the _uncompressed_ Packages file.
I guess PwnageTool doesn’t support compressed Package list files.

So, I try that out using an uncompressed file.
Created the Packages file with

dpkg-scanpackages -m . /dev/null >Packages

and try again.

Better – I’m getting a result now with my repo when I click refresh.
However, I can’t seem to be able to download any files…

So, lets take a look at whats happening in my apache logs.


58.37.213.199 - - [07/Mar/2011:20:50:52 +0800] "GET /dists/Packages HTTP/1.1" 200 1643 "-" "PwnageTool/4.2 CFNetwork/454.11.5 Darwin/10.6.0 (i386) (iMac9%2C1)"
58.37.213.199 - - [07/Mar/2011:20:51:06 +0800] "GET /./mobilesubstrate_0.9.3228-1_iphoneos-arm.deb HTTP/1.1" 404 1184 "-" "PwnageTool/4.2 CFNetwork/454.11.5 Darwin/10.6.0 (i386) (iMac9%2C1)"
58.37.213.199 - - [07/Mar/2011:20:51:42 +0800] "GET /./ultrasn0w.deb HTTP/1.1" 404 1164 "-" "PwnageTool/4.2 CFNetwork/454.11.5 Darwin/10.6.0 (i386) (iMac9%2C1)"

Aha! While its successfully found the repo now, its looking for the files in the wrong folder – my repo is in /dists, and its looking in the root folder.

Seems the Saurik instructions are a bit mangled, or the Package generator is a bit silly.
Quick look at the helpfile shows it needs the folder via -m

So I went up a level, and regenerated my file.


cd ..
dpkg-scanpackages -m dists > dists/Packages

Yes, it works!

Now PwnageTool can download my file finally. Yay!

I just need to select it in PwnageTool / Packages as below, and build my ipsw to test.

Now I can finally make my own Ultrasn0w firmware woohoo!
Not as hard as it seems, but not as easy either!

I’ll leave my UltraSn0w repo at http://www.sheed.com/dists/ for now, but will probably move it elsewhere at some point, and update this post. So, if you need it, get it while you can.

Lawrence.

Flattr this!

Its been a while since I did any IPCam stuff, but I’ve now got most of the bits I needed together again, as well as a new laptop for dev work (curse the thieves that stole my last one!)

As we recall from previous work, the main binary for the IPCam runs off a file called “camera”.

As some people have discovered, it likes to reboot the equipment when its not happy (eg when the camera is unplugged, it has issues talking to hardware, or when someone has flashed the wrong firmware).

So, lets take a look at the executable to see what interesting bits we can find out from it.

#file camera tells us – BINFLT file format. Fileflags: RAM GZIP.
So we know its a compressed bflt elf – bflt stands for binary flat file, and it uses gzip compression. It also sits in ram.

A hex dump of camera shows this for the first few bytes:

62 46 4C 54 00 00 00 04 | bFLT . . . .

[Note – I had about 4 pages of #$%# work done on this, and WordPress decided to flake once finished due to an errant pasted 0x0 null byte above, cutting off the rest of my post, so this is going to be shorter and angrier than it was originally written.
Lesson learned, always save stuff elsewhere before posting.
]

bFLT headers consist of 4 bytes identifier, then 4 bytes for the version number.
In this case, its a version 4 bFLT file.

If we take a look at the header file source for bflt at the uclinux site we see the below layout.


struct flat_hdr {
char magic[4];
unsigned long rev; /* version */
unsigned long entry; /* Offset of first executable instruction with text segment from beginning of file */
unsigned long data_start; /* Offset of data segment from beginning of file */
unsigned long data_end; /* Offset of end of data segment from beginning of file */
unsigned long bss_end; /* Offset of end of bss segment from beginning of file */
/* (It is assumed that data_end through bss_end forms the bss segment.) */
unsigned long stack_size; /* Size of stack, in bytes */
unsigned long reloc_start; /* Offset of relocation records from beginning of file */
unsigned long reloc_count; /* Number of relocation records */
unsigned long flags;
unsigned long filler[6]; /* Reserved, set to zero */
};

It doesn’t match up properly, as the sizes or code don’t make sense (yet).

If we take a closer look, the header file has this to say:


#define FLAT_FLAG_RAM 0x0001 /* load program entirely into RAM */
#define FLAT_FLAG_GOTPIC 0x0002 /* program is PIC with GOT */
#define FLAT_FLAG_GZIP 0x0004 /* all but the header is compressed */

Ahah!

So, all but the header is compressed for a version 4 file.

Lets check this out, and see if its correct.
Excluding the initial file identifier (bFLT), our header consists of 10 longs. Thats 40 bytes long.
Lets jump to offset 40 in the file, and see what we have there.

1F 8B 08

Those of you familiar with gzipped files will recognize that – its the gzip header identifier. So, so far, so good.
Compressed files aren’t very useful to us, as they don’t show much text content.
So, we could unzip the file to take a look at whats inside.

There are a number of ways we can unzip this (zcat, gzip -d etc), but I’m going to be lazy, and use someone elses premade code.

See below for some perl to safely uncompress our binary , taken from here – http://www.openwiz.org/wiki/BWFWTools_Release


#!/usr/bin/perl

=pod

=head1 NAME

gunzip_bflt - convert gzip-compressed bFLT executable files into uncompressed bFLT

=head1 SYNOPSIS

gunzip_bflt zipped_blflt_files...

=head1 DESCRIPTION

Convert gzipped bFLT files into an uncompressed bFLT files.
The unzipped bFLT files have B<.unz> added to their file names.
If the file is already ungzipped bFLT, it isn't converted,
but a warning is printed.

=head1 PREREQUSITES

Uses packages C and C.

=cut

use strict;
use warnings;

# gunzip_bflt zipped_blflt_files...

use IO::Uncompress::Gunzip qw/gunzip $GunzipError/;
use POSIX;

# Read and return the BFLT header
# prints a warning and returns undef on error.
# $bfltZfh is the BFLT file handle,
# $bfltZ is the BFLT file name (for error messages)

sub get_bflt_hdr($$) {
my ($bfltZfh, $bfltZ) = @_;
my $buf;
my $res = sysread $bfltZfh, $buf, 64;
if(!defined($res)) {
warn "$bfltZ: $!\n";
return undef;
}
if($res < 64) { warn "$bfltZ: Too short!\n"; return undef; } # Align the buffered file handle with the unbuffered seek $bfltZfh, sysseek($bfltZfh, 0, SEEK_CUR), SEEK_SET; return $buf; } # Expand a gzipped BFLT intoi an ungziped BFLT sub expand_blftZ($) { my ($bfltZ) = @_; my $bflt = $bfltZ . '.unz'; if(!open BFLTZ, '<' . $bfltZ) { warn "$bfltZ: $!\n"; return; } my $hdr = get_bflt_hdr(\*BFLTZ, $bfltZ); if(!defined $hdr) { return; } if(substr($hdr, 0, 4) eq 'bFLT') { # Pack/unpack template for the BFLT header, 4 bytes ACSII, # 15 little-endian words my $hdrFmt = 'a4 N15'; my @unpHdr = unpack $hdrFmt, $hdr; # Test the header flags 'gzipped' bit if($unpHdr[9] & 4) { # Unset the header flags 'gzipped' bit, and make a new header $unpHdr[9] &= ~4; $hdr = pack $hdrFmt, @unpHdr; if(open BFLT, '>' . $bflt) {

# Write the header
syswrite BFLT, $hdr;

# Align the buffered file handle with the unbuffered
seek BFLT, sysseek(BFLT, 0, SEEK_CUR), SEEK_SET;

# Ungzip from the compressed file into the uncompressed
# file
gunzip \*BFLTZ => \*BFLT
or die "gunzip failed: $GunzipError\n";

close BFLTZ;
} else {
warn "$bflt: $!\n";
return;
}
} else {
warn "$bfltZ: Not a compressed bFLT file, not gunzipped\n";
return;
}
} else {
warn "$bfltZ: Not a bFLT file\n";
}
close BFLT;
}

# Expand the arguments...

foreach my $bfltZ (@ARGV) {
expand_blftZ($bfltZ)
}

If we run that on our ‘camera’ executable, we should have an uncompressed bFLT file as output ‘camera.unz’.
Lets run strings on ‘camera.unz’, to see what interesting text content is in there.

Some interesting things of note:

From the variables list below, looks like there is a way to turn off the LED…

led_mode
ptz_center_onstart
ptz_auto_patrol_interval
ptz_auto_patrol_type
ptz_patrol_h_rounds
ptz_patrol_v_rounds
ptz_patrol_rate
ptz_patrol_up_rate
ptz_patrol_down_rate
ptz_patrol_left_rate
ptz_patrol_right_rate

We also have a full list of the internal cgi functions now, which might prove useful…

snapshot.cgi
get_status.cgi
get_camera_params.cgi
decoder_control.cgi
camera_control.cgi
reboot.cgi
restore_factory.cgi
upgrade_firmware.cgi
upgrade_htmls.cgi
get_params.cgi
set_alias.cgi
set_datetime.cgi
set_users.cgi
set_devices.cgi
set_network.cgi
set_wifi.cgi
set_pppoe.cgi
set_upnp.cgi
set_ddns.cgi
set_ftp.cgi
set_mail.cgi
set_alarm.cgi
videostream.cgi
video.cgi
test_ftp.cgi
test_mail.cgi
set_misc.cgi
get_misc.cgi
set_p2p.cgi
get_p2p.cgi
set_forbidden.cgi
get_forbidden.cgi
set_decoder.cgi
comm_write.cgi
wifi_scan.cgi
get_wifi_scan_result.cgi
get_log.cgi
check_user.cgi
check_user2.cgi
backup_params.cgi
restore_params.cgi
erase_allparams.cgi
set_mac.cgi
do_cgi: unknown cgi

You can see that Maverick decided to fake the X-Mailer smtp header (Foxmail is a commonly used Mail Program in China).

MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary=”smtp_msg_boundary”
X-Mailer: Foxmail
–smtp_msg_boundary
Content-Type: image/jpeg;
name=”%s(%s)_%c%s.jpg”
Content-Transfer-Encoding: base64
–smtp_msg_boundary–

I’m interested in why the firmware reboots on some firmwares though, so lets take a deeper look at the code.

To do so, we’ll need to decompile it.
The better equipped than me will probably use something like the nice ARM decompiler plugin for IDA-Pro called Hex-Ray. Unfortunately that costs $$$, and I’m just a hobbyist.

Luckily there is a free windows decompiler called arm2html available here.
arm2html doesn’t handle compressed bFLT files though, so you’ll need to point it at the freshly ungzipped code you got from the perl script above.

As we know that the camera executable reboots after issuing i2c errors, the first piece of decompiled code I wanted to look at was the first piece of code related to i2c:

(excerpted piece below)
02588: e1a0c00d mov ip, sp
00258c: e92dd810 stmdb sp!, {r4, fp, ip, lr, pc}
002590: e24cb004 sub fp, ip, #4 ; 0x4
002594: e24dd00c sub sp, sp, #12 ; 0xc
002598: e59f023c ldr r0, [pc, #572] ; [0027dc] "/dev/i2c0"
00259c: e3a01002 mov r1, #2 ; 0x2
0025a0: eb00c9b8 bl 034c88(c9b8)
0025a4: e1a04000 mov r4, r0
0025a8: e3540000 cmp r4, #0 ; 0x0
0025ac: aa000003 bge 0025c0(3) ; jump
0025b0: e59f0228 ldr r0, [pc, #552] ; [0027e0] "%s: can not open i2c device"
0025b4: e59f1228 ldr r1, [pc, #552] ; [0027e4] "zoom_test"
0025b8: eb00bc86 bl 0317d8(bc86)
0025bc: e91ba810 ldmdb fp, {r4, fp, sp, pc} ; return

The full piece of code essentially loops 7 times trying to open the i2c sensor to call the zoom_test code. If it fails, it calls for a reboot.
Success proceeds to setting up the camera.

We know from our boot log that my camera in this model is a Sonix288.

dvm usb cam driver 0.0.0.0 by Maverick Gao in 2006-8-12
usb.c: registered new driver dvm
dvm usb cam driver 0.1 for sonix288 by Maverick Gao in 2009-4-20
usb.c: registered new driver dvm usb cam driver for sonix288

The Sonix288 is a chipset SoC that will talk to an attached image sensor via i2c. I think that the Sonix288 is probably a standard USB 1.1/2.0 compatible UVC (USB Video Class) chipset from a bit of googling about it.

We don’t have the source for our particular camera though (its secret, much like the data sheets, grrr…).
What to do?
Linux generally uses spcaxxx (and UVC) drivers for talking to camera’s, so lets start taking a look there.

http://read.pudn.com/downloads127/sourcecode/unix_linux/539050/zc030x/zc030x_cameras.c__.htm

http://www.hackchina.com/r/54654/zc030x_i2c.c__html

Taking a look at some spcaxxx driver header files and code shows that i2c is setup by first getting the USB VID, USB PID of the hardware, then talking to the i2c device on that hardware.

So, we need to know what our USB VID and PID’s are.

Generally all devices from a given manufacturer will have a single VID as issued by the USB Forum.

If we search through the code for Sonix, it appears that Sonix’s VID is 0x0c45

{USB_DEVICE(0x0c45, 0x607c)}, /* Sonix sn9c102p Hv7131R */
(from http://linux.downloadatoz.com/linux-kernel-webcams-driver-gspca-spca5xx/ )

The Linux UVC page confirms this http://www.ideasonboard.org/uvc/.

(Listings of webcams excerpted – note the VID of 0c45)

0c45:6310 USB 2.0 Camera (Trust Chat Webcam) Sonix Technology
0c45:63e0 Sonix Integrated Webcam (Dell notebooks) Sonix Technology
0c45:63ea Laptop Integrated Webcam 2M (Dell Studio 1555 notebooks) Sonix Technology
0c45:6409 USB 2.0 Camera (Nokia Booklet 3G netbooks) Sonix Technology
0c45:6415 Laptop Integrated Webcam 1.3M (Dell Inspiron 13z notebooks) Sonix Technology

Ideally at this point, I’d have a data sheet for the Sonix288 chip, but the #$%#$ people at Sonix don’t seem to publish one for us mere mortals.

So, we’ll use the next best thing, and use one for their other chipsets.

SN9C1xx PC Camera Controllers –
http://ww2.cs.fsu.edu/~rosentha/linux/2.6.26.5/docs/video4linux/sn9c102.txt

There is a lot of good useful info in that particular file. We don’t know how much is useful yet, but generally chipsets are quite similar for a given range.

Image sensor / SN9C1xx bridge | SN9C10[12] SN9C103 SN9C105 SN9C120
——————————————————————————-
HV7131D Hynix Semiconductor | Yes No No No
HV7131R Hynix Semiconductor | No Yes Yes Yes
MI-0343 Micron Technology | Yes No No No
MI-0360 Micron Technology | No Yes Yes Yes
OV7630 OmniVision Technologies | Yes Yes Yes Yes
OV7660 OmniVision Technologies | No No Yes Yes
PAS106B PixArt Imaging | Yes No No No
PAS202B PixArt Imaging | Yes Yes No No
TAS5110C1B Taiwan Advanced Sensor | Yes No No No
TAS5110D Taiwan Advanced Sensor | Yes No No No
TAS5130D1B Taiwan Advanced Sensor | Yes No No No

Interesting… Hmm, so it seems that Sonix uses a SN9Cxxx for its product names.
Lets google for SN9C288 instead, and see if we get any results.

Bingo.

From here – www.lh-invest.com/en/showpro.asp?id=308&proid=3

* MCU: SONIX SN9C288
* Sensor: MICRON K14 1,300,000 pixels CMOS
* 5-glass lens,can reach 30 frames/sec. under 640*480
resolutions,software insertion value 1,300,000 pixels
* Focus range: 3CM to infinitude farness
* Dynamic video resolutions: 1280*960 pixels(max.)
* Support microsoft UVC driver-free function
* Support RGB24 and YUY2 two kinds of image formats
* USB 2.0 port,support plug and play
* Human face tracking function

Seems our chipset is finally getting some details.
Max resolution, video modes, face tracking capability, etc
We also know that it can be paired with a Micron K14 image sensor.

Further googling reveals it can also be paired with the MI-0360 (which is listed above).

SN9C288+MI0360

This page also gives us a possible pid:

http://forums.lenovo.com/t5/SL-Series-ThinkPad-Laptops/camera-problem-in-all-windows-Creation-of-the-Video-preview/m-p/163019/highlight/true

“Device Name: ?USB Video Device

PnP Device ID: VID = 0C45 PID = 62C0
Serial Number: 6&&2BCAFCF3&&0&&0000
Revision: (Information not returned)

Device Type: Standard USB device – USB2.0 High-Speed

Chip Vendor: SONiX
Chip Part-Number: SN9C288PFG

In Microsoft parlance, this looks like this USB\VID_0C45&PID_62C0

Googling that gives us a product with windows drivers (HP) and more.

http://www.downloadwindowsdrivers.info/usb/vid_0c45/pid_62c0/mi_00/

Also says that these product drivers also work.
USB\VID_0C45&PID_62C0 ;SN9C211/213/230

That means we can take a look at their inf file and see if anything useful in there. Unfortunately I did, and there isn’t much 🙁

Sonix has datasheets for some of their other products available though (SN9C2028AF).

First, a quick overview of UVC devices (snarfed from elsewhere).

USB devices are required by the USB specification to respond to the Host device (the computer) with a stream of data describing the device and the interface to the device. This “Device Descriptor” includes vendor, product, and version IDs specific to the manufacturer, the product, and the version of the product. In addition to the device information, the descriptor also includes information on how to talk to the device through a series of “Interface Descriptors”.

The device descriptor for Video is 13.

#define USB_DEVICE_CLASS_VIDEO 0x0E

In addition to the end points described in the interface descriptors, all USB devices support a control pipe to end point 0. This is used to manipulate some of the low level functions of the device such as power, and error status queries.

The USB Video specification describes two interfaces, a control interface to manage the camera, and a stream interface to send or receive video information from the camera.

The control interface is used to manipulate the camera parameters such as brightness and contrast as well as to negotiate a valid set of the video format, frame size, frame rate, and compression rates parameters that describe a video stream. In addition, the control interface can ask the camera for still frame.

In the datasheet for the 2028, it basically states that they use end point 0 for STD Commands, with a maximum packet size of 64 bytes.

Further googling reveals that there is no special driver for it, its a plain UVC 1.0 device.

usb 1-2: New USB device strings: Mfr=2, Product=1, SerialNumber=0
usb 1-2: Product: USB 2.0 Camera
usb 1-2: Manufacturer: Sonix Technology Co., Ltd.
Linux video capture interface: v2.00
uvcvideo: Found UVC 1.00 device USB 2.0 Camera

Further heavy baidu’ing in Chinese sites finds that the SN9C213 and SN9C288 are the same pretty much.

其内部编号是SN9C213,功能完全和SN9C288一样。From http://ep.cbifamily.com/2007/04/44/87819.html

David McCullough very nicely also compiled in usb debug support on his kernel and ran some tests too:

> > > T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
> > > D: Ver= 2.00 Cls=ef(unk. ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1
> > > P: Vendor=0c45 ProdID=62f1 Rev= 1.00
> > > S: Manufacturer=Sonix Technology Co., Ltd.
> > > S: Product=USB 2.0 Camera
> > > C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=500mA
> > > I: If#= 0 Alt= 0 #EPs= 1 Cls=0e(unk. ) Sub=01 Prot=00 Driver=(none)
> > > E: Ad=83(I) Atr=03(Int.) MxPS= 16 Ivl=6ms
> > > I: If#= 1 Alt= 0 #EPs= 0 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > I: If#= 1 Alt= 1 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 128 Ivl=1ms
> > > I: If#= 1 Alt= 2 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 256 Ivl=1ms
> > > I: If#= 1 Alt= 3 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 512 Ivl=1ms
> > > I: If#= 1 Alt= 4 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 600 Ivl=1ms
> > > I: If#= 1 Alt= 5 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 800 Ivl=1ms
> > > I: If#= 1 Alt= 6 #EPs= 1 Cls=0e(unk. ) Sub=02 Prot=00 Driver=(none)
> > > E: Ad=81(I) Atr=05(Isoc) MxPS= 956 Ivl=1ms

The uvc driver status is obviously an issue as we’re on a 2.4 Kernel. No uvc support on 2.4.
So…, we either compile 2.6 with UVC support, and reflash, or we continue to use Mavericks driver in lieu of any source.

With that, you have some background on things..
Now, why does this cause a reboot on some machines?

Well, the hardware is different, so the hardware isn’t seen by the driver.
From looking at a few different boards I have seen a few devices id’s used.

So far I have seen these:
vid_0c45/pid_62f1 – (The Sonix Chipset allows you to write pid’s into the device, so this can be changed, or alternately change the driver from 62c0 to 62f1 on these models)

vid_0c45/pid_62c0 – (Our driver is compiled for this)

For those of you with rebooting machines, remove ‘camera &’ from the boot sequence, recompile the kernel with USB verbose debug message logging, and start posting your vid/pid’s here so we can compare, and add to the list.

If someone twisted my arm I could probably oblige…

References:
http://www.beyondlogic.org/uClinux/bflt.htm – bFLT file format details.
http://www.garykessler.net/library/file_sigs.html – Common file format headers
http://www.openwiz.org/wiki/BWFWTools_Release – bFLT unzip and other tools
http://www.hex-rays.com – IDA Pro and Hex-Ray ARM Decompiler
http://www.sigmaplayer.com/filebase.php?d=1&id=13&c_old=5&what=c&page=1 – Arm Decompiler
http://www.ideasonboard.org/uvc/
http://read.pudn.com/downloads127/sourcecode/unix_linux/539050/zc030x/zc030x_cameras.c__.htm
http://www.hackchina.com/r/54654/zc030x_i2c.c__html
http://linux.downloadatoz.com/linux-kernel-webcams-driver-gspca-spca5xx/
http://ww2.cs.fsu.edu/~rosentha/linux/2.6.26.5/docs/video4linux/sn9c102.txt

Files from this post:
(arm2html.exe, bFLT gunzip perl script, original camera bFLT, uncompressed camera bFLT, and camera asm source )
Camera Disassembly, unpacked bFLT and Tools

Flattr this!

As I’ve been reasonably successful in the past at figuring out file systems from flat files, I thought I’d have a go at the Dell Mini 3i 1.5 Firmware that surfaced at damipan (http://www.namipan.com/d/DELL_MINI3I_OMS1.5.rar/a5ba3b06ab0bfc9baeb2f09b44f54aa40bac3457ee8ebc04)

The rar file unzips to a MFF file.

This I’m probably guessing is probably named after Marvell File Format or Marvell Flasher File.
Here’s my initial work on the file system of MFF format, based on DELL_Mini3i_OMS1.5.mff

Initial 80 bytes [0x0 – 0x080] (MFF HEADER)

0x00 – 0x03 : 3 Bytes Header MFF
0x03 – 0x07 : Still to figure out, probably file length or crc.
Have to grab another firmware file to check though..

0x08 : Number of files? 9 listed, so quite probably…
Rest of header padded out with zero’s to end of 80 bytes.

[0x80 – 0x180] File Allocation Table
0x80 – our first file. Looks like 0x100 / 256 bytes per file listed, padded with 0x0’s

File listing looks like this:

File header (for each file)
8 bytes, then filename, padded with 0’s to fill 256 bytes length

First 4 bytes – offset in MFF of start of file.
Second 4 bytes – length of file.

Remaining files repeat from next 256 byte intervals.

eg
0x180 – 0x280
0x280 – 0x380

[0x80 + 9 files x 0x100 bytes = 0x980] Start of Data.

How did I work this out?

HEADER | Filename (not in hex below as easier to read)
80 09 00 00 34 BB 00 00 | Tavor Flasher_Samsung_ONENAND_h.bin

0x0980 is the start of our first file data, so the first 2 bytes are definitely File Start.
0xBB34 looks quite possibly like File Length.

We can check this easily with one of the plain text files.

Flash_Protection_table.ini is prefixed with 63 EA AD 09 4B 00 00 00

So it should start at 0x09 AD – hmm, readable text starts at offset 9AD D564.
Not quite right. Start offset looks close though.

Lets look at another one.

Tavor_saar_onenand.ini – prefix says
64 d5 ad 09 6f 01 00 00

Ah, 0x9 AD D5 64 is actually our Tavor_saar_onenand.ini content. Cool, a match. So, the first 4 bytes are definitely our location pointer.

Lets look at the Flash protection table again Flash_Protection_table.ini

63 EA AD 09 | 4B 00 00 00
Should start at 09 AD EA 63, and go for 4B length. Bingo, it does 🙂

Our file contents for that area are:

[PROTECTED_REGION_0]
Block_Offset=0x100000
Length=0x20000
Mode=SKIP_BLOCKS

So, now we can start to split the files apart into their associated parts.

factory_BENZ2GWIFI.fbf is probably going to be the most interesting, as its the largest.

That starts at 0xC564, length of 0x09AD1000 and starts with “Marvell_FBF”
Basic math says that 0x9ADD564 (0x09AD1000 + 0xC564) should be our end of file.
Well, it is, as we know flash protection table.ini starts at 9add564.

So, should be fairly easy with that info to write an unpacker tool to rip out the first interior files from the MFF file format.
Some of the files inside are also “packed”, but those appear to be fairly easy to rip apart also 🙂

I’m guessing with a bit more work I’ll be able to replace parts of the firmware with different versions quite soonish.

The file I’m using off of namipan has the following files inside:

TavorFlasher_SAMSUNG_ONENAND_h.bin
TavorFlasher_SAMSUNG_ONENAND_TIM.bin
factory_BENZ2GWIFI.fbf
Tavor_SAAR_OneNAND.ini
factory_BENZ2GWIFI.mff.mlt
magic_fbf.ini
magic_fbf_inner.ini
NTIM_fbw.ini
Flash_Protection_Table.ini

I’m guessing that our fbf file will probably be able to be split into parts as per our ntim_fbw.ini data.
FBF = Flash Binary Format?

some interesting files listed
ntim.bin – non trusted image module?
blob_full.bin – from the borq’s blob gz?
Tavor_M05_Poleg_AI_B0_Flash.bin – tavor = our product chip, as we’re running on a Marvel PXA935 (aka Tavor-P65)

Interesting thing of note – our OEM UniqueID: 0xF00F00 in Unicode is what glyph?
Hint – its not an orange, or a pear 😉

NTIM_fbw.ini

Version: 0x030102
Trusted: 0

Issue Date: 0x08142006
OEM UniqueID: 0xf00f00
Boot Flash Signature: 0x4e414e02
Number of Images: 10
Size of Reserved in bytes: 0x40

Image ID: 0x54494D48
Next Image ID: 0x4F424D49
Flash Entry Address: 0x0
Load Address: 0x5c008000
Image Size To CRC in bytes: 0x0
Image Filename: NTIM.bin

Image ID: 0x4F424D49
Next Image ID: 0x4F534C4F
Flash Entry Address: 0x20000
Load Address: 0x5c013000
Image Size To CRC in bytes: 0x0
Image Filename: obm_full.bin

Image ID: 0x4F534C4F
Next Image ID: 0x5349474E
Flash Entry Address: 0x80000
Load Address: 0x83000000
Image Size To CRC in bytes: 0x0
Image Filename: blob_full.bin

Image ID: 0x5349474E
Next Image ID: 0x494D4549
Flash Entry Address: 0x00120000
Load Address: 0x84000000
Image Size To CRC in bytes: 0x0
Image Filename: signature_full.bin

Image ID: 0x494D4549
Next Image ID: 0x4152424C
Flash Entry Address: 0x00100000
Load Address: 0xBFEE0000
Image Size To CRC in bytes: 0x0
Image Filename: reliable_full.bin

Image ID: 0x4152424C
Next Image ID: 0x47524249
Flash Entry Address: 0x00140000
Load Address: 0xBF600000
Image Size To CRC in bytes: 0x0
Image Filename: arbel_full.bin

Image ID: 0x47524249
Next Image ID: 0x62746C67
Flash Entry Address: 0x00840000
Load Address: 0xBFF00000
Image Size To CRC in bytes: 0x0
Image Filename: tavor_full.bin

Image ID: 0x62746C67
Next Image ID: 0x70636C67
Flash Entry Address: 0x00A00000
Load Address: 0xBF300000
Image Size To CRC in bytes: 0x0
Image Filename: bootlogo_full.bin

Image ID: 0x70636C67
Next Image ID: 0x464F5441
Flash Entry Address: 0x00A20000
Load Address: 0x8F300000
Image Size To CRC in bytes: 0x0
Image Filename: prechangelogo_full.bin

Image ID: 0x464F5441
Next Image ID: 0xFFFFFFFF
Flash Entry Address: 0x0EA40000
Load Address: 0x80100000
Image Size To CRC in bytes: 0x0
Image Filename: fota_full.bin

Reserved Data:
0x4F505448
0x00000002
0x55415254
0x00000010
0x00004646
0x00000001
0x50524F49
0x00000020
0x00000002
0x00000000
0x00000000
0x00000000
0x00000001
0x00000000
0x5465726D
0x00000008

Flash_Protection_Table.ini

[PROTECTED_REGION_0]
Block_Offset=0x100000
Length=0x20000
Mode=SKIP_BLOCKS

magic_fbf_inner.ini

[INTEL_FLASH_DEVICE_INPUT_FILE]
Number_of_Images=20

[IMAGE_HEADER_0]
Start_Address=0xfa00000
Image_Length=0x80000
EraseBlocks=1
WriteImage=0
VerifyWrite=0

[IMAGE_HEADER_1]
Start_Address=0xdd40000
Image_Length=0x800000
EraseBlocks=1
WriteImage=0
VerifyWrite=0

[IMAGE_HEADER_2]
Start_Address=0xeb40000
Image_Length=0x8c0000
EraseBlocks=1
WriteImage=0
VerifyWrite=0

[IMAGE_HEADER_3]
Filename=NTIM.bin
Start_Address=0x00000000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_4]
Filename=Arbel_NVM_SAC_NOCOMMRTC.bin
Start_Address=0x00140000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_5]
Filename=blob
Start_Address=0x00080000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_6]
Start_Address=0x0bd40000
Image_Length=0x02000000
EraseBlocks=1
WriteImage=0
VerifyWrite=0
[IMAGE_HEADER_7]
Filename=opl.img.yaffs
Start_Address=0x0bd40000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_8]
Filename=ramdisk_len.img
Start_Address=0x00c40000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_9]
Filename=ramdisk-recovery_len.img
Start_Address=0x00cc0000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_10]
Start_Address=0x00d40000
Image_Length=0x08000000
EraseBlocks=1
WriteImage=0
VerifyWrite=0
[IMAGE_HEADER_11]
Filename=system.img.yaffs
Start_Address=0x00d40000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_12]
Filename=TAVOR_LINUX_NTOBM.bin
Start_Address=0x00020000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_13]
Filename=Tavor_M05_Poleg_AI_B0_Flash.bin
Start_Address=0x00840000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_14]
Start_Address=0x08d40000
Image_Length=0x03000000
EraseBlocks=1
WriteImage=0
VerifyWrite=0
[IMAGE_HEADER_15]
Filename=userdata.img.yaffs
Start_Address=0x08d40000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_16]
Filename=zImage
Start_Address=0x00a40000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_17]
Filename=prdcfg.bin
Start_Address=0x00940000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_18]
Filename=precharge_logo.out
Start_Address=0x00a20000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

[IMAGE_HEADER_19]
Filename=logo_pic.gz.out
Start_Address=0x00a00000
EraseBlocks=1
WriteImage=1
VerifyWrite=0

Lastly, hi to the people at http://www.allphone.com.cn 😉

Archives

Categories

Tags

PHOTOSTREAM