Support

Blog

Browsing all articles in Technical Mumbo Jumbo

One or two of our servers have been a little bit overloaded recently.

They’re going to be replaced with beefier machines, but due to a number of issues I haven’t been able to replace them yet.

Issue #1 – Pre expo, we weren’t allowed to replace anything.
Issue #2 – Post Expo, I’m no longer allowed in the data center!

We’re working on sorting issue #2 out, but in the interim I need to keep the older machines running.

I was previously using Monit to monitor system load.

Monit would be a good solution – it has a web ui, it can stop services if system load goes too high, and generally works when everything else is failed. This is great when things go poopy, but it has one fatal issue.

It doesn’t know how to restart stuff if load is back to normal.
This typically means that something will put the server load into unusability for a sustained period of time (due to lots of visitors), monit will go ooh, apache has gone awol, and stop it.
Unfortunately if its back to normal, monit doesn’t have a way to start it up again, so I need to manually go to the monit page, and start the service. I do get emailed on things like this, but it leads to complaints from the 2 clients that appear to monitor their particular websites more than monit does.

So, I’ve been looking at other solutions.

One such solution is sysfence

While sysfence is severly underdocumented, the examples provided don’t even work!, and appears to be abandoned, it does do the job.
Sysfence is a no bells and no whistles precursor to monit, but it has that killer feature that monit is missing.

So, how do we use sysfence?

apt-get install sysfence

Will install it, but unfortunately no config is installed.

So, start off by creating a /etc/sysfence folder

mkdir /etc/sysfence
cd /etc/sysfence

We’ll need to create a config file for it, so

pico sysfence.conf

My sample sysfence script is below (explanation underneath script)


rule "ApacheStop" {
la1 >= 10.00 or la5 >= 6.0
}
run '/etc/init.d/apache2 stop;'


rule "ApacheStart" {
la1 <=2 } run once '/etc/init.d/apache2 start;'


rule "warning" { la1 >= 8.00 } run once 'echo "Load High: BACKUP" | mail lawrence@computersolutions.cn'

I'm having issues with apache causing load to rocket, so I've setup some rules as follows:

If load average for 1 minute > 10 (ie server is going bonkers), and load average for the last 5 minutes > 6 then stop apache.
if load average for 1 minute > 8 send me an email.
if load average for 1 minute < 2 then start apache. This will only run one time if load is below 2. The documentation http://sysfence.sourceforge.net/ goes over how to write a rule. Note that the examples are broken;

eg
if {
la1 >= 8.00
} run once 'echo "SHOW FULL PROCESSLIST" | mysql | mail my@email.com'

Issue? All rules need to have a "rule name" specified.

So a corrected working version would be:

if "some rule" {
la1 >= 8.00
} run once 'echo "SHOW FULL PROCESSLIST" | mysql | mail my@email.com'

Back to our setup..

Now we've setup a ruleset, we need to run it. Calling sysfence /etc/sysfence.conf

Will run it as a daemon.

ps -ef shows our rulesets running:

root 7260 1 0 05:51 ? 00:00:01 sffetch
root 7261 7260 0 05:51 ? 00:00:00 sfwatch 'warning'
root 7262 7260 0 05:51 ? 00:00:00 sfwatch 'ApacheStop'
root 7263 7260 0 05:51 ? 00:00:00 sfwatch 'ApacheStart'

sffetch is the daemon, and sfwatch are the rules it runs.

As sysfence is quite rudimentary, you'll need to kill it if you change rules.

You'll also need to add it to your startup scripts or create one. I'll be lazy and not go over that right now. If people are interested, add a comment, and I'll put something up.

Sysfence can be downloaded here - http://sysfence.sourceforge.net/ (or via apt-get if on a Debian based OS)


Man page for sysfence below (note examples require adding "rulename" after if... { or rule ... {):

NAME

sysfence - system resources guard for Linux

SYNOPSIS

sysfence
<configuration file> [<configuration file> ...]

DESCRIPTION

Sysfence is a resource monitoring tool designed for Linux machines.
While running as daemon it checks resource levels and makes desired
action if some values exceed safety limits.

Sysfence can be used for notifying system administrators when something
goes wrong, stopping services when system performance is dropping too
low and starting them when it's going up again, periodically restarting
memory-leaking processes, dumping system statistics in critical situations.

Sysfence can monitor following resource levels: load average, used and
free memory amount, used and free swap space.

USAGE

Sysfence reads it's configuration from file(s) specified in argument
list. Config files may contain one or more rules describing conditions
and actions to be performed.

Rule has syntax like this:

if {
resource1 > limit1
or
{ resource2 < limit2 and resource3 < limit3 }
}
run once 'command-to-be-run'

The block enclosed within {} brackets describes condition. When it's
result is TRUE, following command is invoked.

The once keyword is optional. If present, the command is executed only
once after condition becomes TRUE. Next execution will take place only
if condition becomes FALSE and then TRUE again. Without once keyword,
command is invoked periodically, after every resource check that gives
TRUE, no matter what was the condition result before.

Command specified right after run keyword is passed to /bin/sh, so it
may contain more than one instruction or even whole script. But be
careful - rule checking is suspended unless command execution has been
completed! (Other rules are unaffected.)

As resources, following ones can be given:

la1
- load average during last minute.
la5
- load average during last 5 minutes.
la15
- load average during last 15 minutes.
memfree
- lower limit for free memory amount.
memused

- upper limit for memory used by processes.
swapfree
- lower limit for free swap space.
swapused
- upper limit for swap space in use.

EXAMPLES

Do you have problems with MySQL server choking and freezing whole
system? I do. To find queries that cause problems, you may use:

if {
la1 >= 8.00
} run once 'echo "SHOW FULL PROCESSLIST" | mysql | mail my@email.com'

Of course, that wouldn't prevent your system from being blocked, but
following rule could. MySQL will be restarted if LA for last minute
is over 10.0 or LA for last five minutes is over 6.0.

if { la1 >= 10.00 or la5 >= 6.0 }
run '/etc/rc.d/init.d/mysql stop; sleep 120; /etc/rc.d/init.d/mysql
start'

We may also restart some services that probably have memory leaks and
use lots of swap space if not restarted periodically. Let's assume
that 256MB of used swap is enough to give our Zope server a break.

if {
swapused >= 256M
} run '/etc/rc.d/init.d/zope restart'

We may also alert admins... Notice that you don't have to be r00t:

if {
la15 > 4.0
and
{
swapfree < 64M
or
memfree < 128M
}
} run 'echo "i wish you were here..." | sendsms +48ADMINCELLPHONE'

Using sysfence version 0.7 or later you may give rule a name that will
be used in logs:

rule "high load" { la1 > 3.0 and la15 > 2.0 } log

rule keyword has the same meaning as if. There are also synonymes for
other keywords. Detailed list is included within sysfence package.

You can find an example config file in /usr/share/doc/sysfence/example.conf.

AUTHOR

Sysfence was written by Michal Saban (emes at pld-linux org) and
Mirek Kopertowski (m.kopertowski at post pl)

This manual page was created by Lukasz Jachowicz <honey@debian.org>,
for the Debian project (but may be used by others). It is based on
the http://sysfence.sf.net/ page.

Comment spam is a big load on servers – recently troubleshooting some intermittent load issues on one of our webservers, I discovered that one page was getting hammered by comment spam abuse – the page had already generated over 400,000 comments, which was causing the server to be slightly unhappy loadwise.

After clearing out the comment table for that clients site, I looked into solutions.

mod_security was an obvious one, and the atomic corp rules seem to be better than the default mod_security ones (which break most popular apps, sigh).  However, although the gotroot rules were good at blocking comment spam, they don’t block the ip’s, so persistent spammer bots will still hammer the server.

So, whats a solution?
Blocking the ip’s dynamically for a short period.
Assuming you have a standard setup, the below should be of interest.

I stick my ruleset into /etc/modsecurity2, so amend your url’s accordingly.

My default initialise code is below (pretty much stock except for the end part)

/etc/modsecurity2/modsecurity_crs_10_config.conf

SecRuleEngine On
 SecRequestBodyAccess On
 SecResponseBodyAccess On
 SecResponseBodyMimeType (null) text/html text/plain text/xml
 SecResponseBodyLimit 2621440
 SecServerSignature Apache
 SecComponentSignature 200911012341
 SecUploadDir /var/asl/data/suspicious
 SecUploadKeepFiles Off
 SecAuditEngine RelevantOnly
 SecAuditLogRelevantStatus "^(?:5|4(?!04))"
 SecAuditLogType Concurrent
 SecAuditLog /var/log/apache2/modsec_audit.log
 SecAuditLogParts ABIFHZ
 SecArgumentSeparator "&"
 SecCookieFormat 0
 SecRequestBodyInMemoryLimit 131072
 SecDataDir /var/asl/data/msa
 SecTmpDir /tmp
 SecAuditLogStorageDir /var/asl/data/audit
 SecResponseBodyLimitAction ProcessPartial
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 3
### Ruleset additions for blocking ########################################
# Make sure to clear the default action
SecDefaultAction phase:1,pass
# Initialize collection and deprecate by 3 points per day (86400 seconds)
SecAction phase:1,initcol:IP=%{REMOTE_ADDR},deprecatevar:IP.spam=3/86400,nolog
# If there are already >15 spam points for this IP, then drop
# the connection and add 1 point (instead of 3, as below).
SecRule IP:spam "@gt 15" phase:1,setvar:IP.spam=+1,drop,setenv:spam=spam
# Clear the default action for any mod_security rules later in httpd.conf.
SecDefaultAction phase:1,pass
### End Ruleset additions for blocking ####################################

What does it do?  Basically we keep score of any ip address that visits the site.
Every day any scores depreciate by 3 points per ip.
If any ip scores more than 15 points, we block it.

Now, as it stands, its pretty useless, as we don’t do any scoring.

So, next we’ll need to add some scoring to some of the rules.

In our case, we were getting seriously hammered by pharmacy spam (mostly out of latvia)

So, I went into the default gotroot ruleset that I installed into /etc/modsecurity2

Comment spam is in this file: 30_asl_antispam.conf

I added some scoring there.
In my case, we saw hundreds of thousands of attempts for levitra and tramadol spam, so I went to the pharmacy scoring, and added this:

setvar:IP.spam=+15 in the SecRule check.
This means that any positive lookup for that rule will give the ip a 15 point score.
That will block that attacker ip from the site for 5 days (as we decrement 3 points per day for a given ip).

The setvar needs to go after the “capture,…” part of the rule.

eg

(don’t copy, paste this, you’ll need to add “setvar:IP.spam=+15” into your existing file)
# Rule 300040:
SecRule ARGS|!ARGS:/domain/|!ARGS:description|!ARGS:redirect_to|!ARGS:setting[banemail]|!ARGS:/username/|!ARGS:/user_name/|!ARGS:/page_content/|!ARGS:/search/|!ARGS:/email/!ARGS:Mensaje|!ARGS:/product/|!ARGS:/domain/|!ARGS:description$
"capture,setvar:IP.spam=+15,id:300040,rev:7,severity:2,msg:'Atomicorp.com - FREE UNSUPPORTED DELAYED FEED - WAF Rules: Spam: Pharmacy',logdata:'%{TX.0}'"

I added this to appropriate places, and watched for our first victim^Mspammer in our site logs.
Bingo – here we have a spammer trying to add to a url on one of our sites:

[23/Dec/2010:11:39:45 +0800] [www.chou.cn/sid#bcf3f338][rid#b339b670][/gallery/papratiti/img_5993.jpg.php][1] Access denied with code 403 (phase 2). Pattern match “(?:buy[-_ ]?(cheap)?[-_ ]?(?:adipex|suboxone|pseudovent|topamax|trazodone|prevacid|zyrtec|xenical|toprol|zoloft…” at ARGS:comment. [file “/etc/modsecurity2/30_asl_antispam.conf”] [line “194”] [id “300061”] [rev “10”] [msg “Atomicorp.com – FREE UNSUPPORTED DELAYED FEED – WAF Rules: Spam: Pharmacy”] [data “xanax”] [severity “CRITICAL”]

[23/Dec/2010:11:43:16 +0800] [www.chou.cn/sid#bcf3f338][rid#bfac9d68][/gallery/papratiti/img_5993.jpg.php][1] Access denied with connection close (phase 1). Operator GT matched 15 at IP:spam. [file “/etc/modsecurity2/modsecurity_crs_10_config.conf”] [line “40”]

Bam, that ip is blocked (for 5 days).  Next time around, as its the first rule to run, it will block immediately without processing other rules.

You can amend the block times by decreasing the increments or scoring as per your requirements.

All in all, this is an easy amendment to make to the gotroot rules, and makes for faster experience for users.
Thanks to http://linux.icydog.net/apache/commentspam.php for his implementation, this is pretty much based off that.

Lawrence

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 😉

As I’ve been busy with real life ™, its been a while since I took a trip to the computer mall to see what new goodies I could play with.

A friend is in town from Beijing, so took him down to the Shanzhai hell (or heaven depending on PoV) that is Qiu Jiang lu.

I wasn’t aware that you could buy Keychain video recorders for 80rmb, but you can. Apparently they’re even cheaper in eBay – although I don’t see how its possible, given that the factories here are pricing higher than they sell for in the States. Rejects?

Anyhow, I bought 2 keychain video camera’s, and an MP3 looking one.

(swiped from Chuck Lohr's post)

Dissected one and it contains the Anyka AK3651B as the main chip.

The AK36xx series is an SoC (System on a Chip).

As Anyka appears to be deathly afraid of giving out any useful information about their products, I’ve had to piece together info from what I found online.

Their own product page here – http://www.anyka.com/enProShow.asp?sortFlag=110&sortName=Application%20Processor&id=105
says the following:

32-bit Microprocessor Core
Integrated I/D cache
Memory Management Unit (MMU)

Video Coprocessor
MPEG4.SP codec
H.263 codec
Motion JPEG codec

Audio Coprocessor
MP3 decoder
WMA decoder
AAC/AAC+ decoder
AMR codec
Real-time audio stream in PCM/ADPCM format

Image Coprocessor
JPEG HW codec

Glueless Dual LCD Displays
Supporting MPU LCD
Supporting RGB LCD
Programmable LCD size and refreshing rate

Connectivity
USB 2.0 HS OTG
I2S master/slave
UART
SPI
MMC/SD

Embedded ADCs and DACs
SAR ADC for touch panel and voltage detect
Sigma-Delta ADC for microphone
Sigma-Delta DACs for stereo

Built-in Power Amplifier/Headphone Driver

External Memory Support
Supporting SDRAM
Supporting Nand Flash (SLC/MLC, with hardware ECC)

Package
LQFP 128-pin/144-pin,FBGA 100-pin/144-pin

Appears that they’re mostly used in MP3/MP4 players, which is why most of my googling on specs was ruined by whiny users asking for someone to please help them with their foobar’d player.

The first useful links on these are at Chuck’s pages here – http://www.chucklohr.com/808/

He’s done a lot of useful work collating information, although some of his deductions are a little strange, so take some things with a pinch of salt. Lots of good info though.

The main source of info on the hardware side is at http://www.readerme.com, they have a most excellent section of downloads which provide more information on the chips than anything else out there!

We gave them a call and had a chat (one of the benefits of being located in China, is that we obviously speak Chinese in the office!).
They don’t speak great Mandarin though – so it was bad cantonesedarin or Mandonese? Hmm, have to come up with a word for that! (similar to Chinglish but mixing Cantonese and Mandarin).

Both sides were laughing but we could at least talk to each other. “Mo man tai, dui ma?”

They actually don’t sell products, they only do design work for others, but, thats good to know.
They did point us in the direction of a few trading companies that could do FOB export, but shipping quantities are in the x,000’s so not so useful yet.

I’ll see if I can find the actual factories making these tomorrow. (Although when I say we, I mean the staff).
They did prove to be an excellent source of data on the chips though if one takes a look at the PDF’s on their site.

The golden data trove is here – http://www.readerme.com/html/html/%E7%9B%B8%E5%85%B3%E4%BA%A7%E5%93%81%E5%8E%9F%E7%90%86%E5%9B%BE%EF%BC%8C%E8%B4%B4%E7%89%87%E5%9B%BE.html

According to Anyka (安凯 in Chinese) the 36xx chips are a series, so they should have similar functionality.

While I don’t have data sheets, or a BSP, I can read the PDF’s at least to get an idea of where things are laid out.

AK3631B

AK3651B

They do look similar, so probably only minor differences in functionality (probably the newer ones are cheaper?).
Again, hard to check, as Anyka datasheets appear to be hens teeth.

I may give them a call also, and see if they’ll be willing to give us some info about their products, but I’m not holding my breath on that one.

I’ve also poked around a bit in the firmware files using strings, and taking a look at headers, and have come up with some preliminary conclusions.

I’m guessing their SoC is ARM5 based, given what i have found (haven’t decompiled yet, but looks like that).

Some common strings in the firmware’s from start:

00000 06 00 00 EA FE FF FF EA

Googling “06 00 00 EA FE FF FF EA” comes up with some other people talking about firmware for pxa312 devices, which have exactly that in their boot loader, so, seems likely.

The PXA312 is ARMv5TE…

I’m guessing some playing around with radare (http://radare.nopcode.org/get/radare.pdf.html) should get some more info about whats going on.

Running strings on the firmware files available shows interesting info:

strings /Documents/Keychain\ Camera/cx311V2.04/Spiboot_36XX.bin
ANYKA362
6KA49
start read cfg
file cnt:%d
file name:%s
Cannot find BIOS
read file info fail
load bios ……
map:%d
file len:%d
ld addr:0x%x
Load bios from spiflash successfuly!
read BIOS fail
spi boot start
system clock: %d
BIOS

Thats our 4k bootloader, which obviously loads our 1M bios image from SPI flash memory (SPI = Serial Peripheral Interface)
More on SPI here.
http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

Hmm, more reasons for me to get a Bus Pirate now…

We have a flasher also, although its Windows based.
I’m guessing some USB sniffing will lead to some magic byte handshake sequence to get into the bootloader via USB, as the BIOS strings point to that.

eg:

“The setup packet is not 8 byte!”

Also amusing is that its fairly easy to find the FAT32 code embedded in at least one of the firmwares

EB xx 90 … -> 55 AA (in Sprint1M.bin)

The flasher tool is also nice enough to give us an idea of layout in the 1M flash chip.

You’ll need to install the Anyka M3 USB driver to talk to the chip, which appears to have the following attributes via USB:
Vendor ID: 0471
Product ID: 0666 (the product of the beast? hehe)

This is a bit naughty, as 0471 is in theory already taken by Philips (or NXP) according to http://www.linux-usb.org/usb.ids

Its also astoundingly obvious that they used driverworks to make the driver. (From the oh so copied in China vid/pid, and the strings left in the driver). An example of this here http://www.baiheee.com/OpenSource/Easy%20USB%2051%20Programer/Easy%20USB%2051%20Programer_DriveOurBoard.htm

Want to bet someone read those instructions and its been repeated ad nauseum?
Sadly, its so easy to see the minimal effort that’s gone into things.

Back to our flasher, it says that our 1M chip is laid out as follows:

###Project Name
project name = chaoxian

###Devie Number
device channel = 8

###COM
com bOpen = 0
com base = 1
com count = 1
com baud rate = 38400

path producer sundance2 = producer_sundance2.bin
path producer sundance2A uboot = producer_sundance2A_uboot.bin
path producer sundance2A umass = producer_sundance2A_umass.bin
path nandboot sundance2= Spiboot_36XX.bin
path nandboot sundance2A= Spiboot_36XX.bin

bios run addr = 0x30500000
bios start addr = 0xc0000
bios end addr = 0x1c0000
bios backup start addr = 0x1c0000
bios backup end addr = 0x2c0000

chip type = AK_3225
chip uboot = 1
chip power off gpio = 255
chip usb2 = 0
chip get aid = 0
chip update = 0
chip select loop = 1
chip select nand0 = 1
chip select nand1 = 1
chip select nand2 = 1
chip select nand3 = 1
chip gpio_ce2 = 255
chip gpio_ce3 = 255

ram size = 8
ram row = 12
ram column = 8
ram bank = 4

moduleburn DownloadMode = 2
moduleburn bDownloadFLS = 1
moduleburn bDownloadEEP = 1
moduleburn baudrate = 921600
moduleburn gpio_dtr = 85
moduleburn gpio_module_igt = 109
moduleburn gpio_module_reset = 87
moduleburn path_fls = LCG2.fls
moduleburn path_eep = LCG2.eep

fs start addr = 0x6c0000
fs reserver block = 64
fs nonfs reserve size = 4

partition count = 0

download_to_udisk count = 0

download_to_nand count = 3
download_to_nand1 = 0, Spring1M_bios.bin, 0x30500000, BIOS
download_to_nand2 = 0, Spring.bin, 0x30000000, MMI
download_to_nand3 = 0, AkResData.Bin, 0x0, RES

download_to_mtd count = 0

nand supported count = 0

If we take a look at that, our Spring1M_bios.bin starts off at C000
(bios start addr = 0xc0000)
(Deduct a 0 as we’re not offset by 0x300000000)

A look in a hex editor at that position shows:

Note the 32bit word value – 0xE1A0C00D

Thats classic ARM, so we _know_ its arm based…

romStart [0xe1a0c00d] mov r12,r13

Our next line of code is exactly the same as listed here http://code.google.com/p/milestone-overclock/wiki/Disassembly

e1a0c00d mov ip, sp
e92dd8f0 push {r4, r5, r6, r7, fp, ip, lr, pc}

So its looking like we can basically disassemble the code using arm-none-linux-gnueabi-objdump

I’ll leave that for another day, but with a bit more work we could compile our own code for this as we now have a good idea of the target cpu.

The next step would be to get into the bootloader or debug mode via USB, and see what can be seen.

Tools used:

0xED – http://www.suavetech.com/0xed/0xed.html
A nice fast and compact hex viewer for OSX.

strings – built into most *nix based systems.

Grey matter – Available to all, unused by many 😉

Now hopefully I can get back to the Webcam firmware stuff as I’ve been promising to do.

As someone I know was interested in getting a new (old) laptop, I did some trawling of the intertubes, and saw that there were quite a few IBM Thinkpad’s in nice condition available on Taobao.

After checking away the requirements (one of which was not to go down in resolution to the crap they sell nowadays), I decided on a T6x series.

A T60 with a 1400×1050 screen was about RMB2500 on Taobao with fairly decent spec’s – DVD Writer, Bluetooth, Fingerprint Reader, SATA, Extended Battery. 3 month warranty, with a replacement 7 day swap for another unit. I sent my staff to go take a look at the shop, they liked, and I was soon the owner of an ex-corporate laptop that looked like it came from Singapore originally (according to the model / software licence sticker on the laptop). It even came with a legitimate licenced copy of Windows.

As I had ordered one for test purposes to see what the quality was like, I was pleasantly suprised. The one I received is pretty much in mint condition. In fact its in such good condition, that I decided I would keep it for myself!

Read more »

Spent a while checking out the different binaries available for the different OEM versions.
Some interesting things I’ve found.

If I take a look at a sample kernel – eg
lr_cmos_11_14_1_46.bin

ls -al lr_cmos_11_14_1_46.bin
-rw-r--r-- 1 lawrence staff 1350539 Mar 15 13:47 lr_cmos_11_14_1_46.bin

Our file size for the file i have is 1350539 bytes.

A hexdump of the header shows:

00000000 42 4e 45 47 01 00 00 00 01 00 00 00 77 cb 0b 00 |BNEG……..w…|
00000010 00 d0 08 00 50 4b 03 04 14 00 00 00 08 00 3a 2e |….PK……..:.|
00000020 87 3b 3b e7 b8 16 03 cb 0b 00 bc d9 18 00 09 00 |.;;………….|

PK is the standard file header for Zip compression (as Zip was invented by Phil Katz)
Zip fingerprint in hex is – 0x04034b50, which matches nicely in our second line – 50 4b 03 04

On the offchance it contained a zip file, I tried unzipping from the start of the PK.

We can totally misuse dd to write from an offset of 20 bytes to a test.zip file as follows:


lawrence$ dd if=lr_cmos_11_14_1_46.bin of=test.zip skip=0x14 bs=1

(check I actually did that right)
lawrence$ hexdump -C test.zip |more
00000000 50 4b 03 04 14 00 00 00 08 00 3a 2e 87 3b 3b e7 |PK........:..;;.|
00000010 b8 16 03 cb 0b 00 bc d9 18 00 09 00 00 00 6c 69 |..............li|

Unfortunately this didn’t unzip.

However…

zipinfo test.zip
Archive: test.zip 1350519 bytes 1 file
-rw------- 2.0 fat 1628604 b- defN 7-Dec-09 05:49 linux.bin
1 file, 1628604 bytes uncompressed, 772867 bytes compressed: 52.5%

Says there is a valid zip file there, so we’re getting somewhere. It should be something like 772867 bytes + whatever Zip header / footer file bits in size.

If we take a look at the Zip file format, it says that the end of directory (aka end of zip file) marker is 0x06054b50

ZIP end of central directory record

Offset Bytes Description[4]
 0 4 End of central directory signature = 0x06054b50
 4 2 Number of this disk
 6 2 Disk where central directory starts
 8 2 Number of central directory records on this disk
10 2 Total number of central directory records
12 4 Size of central directory (bytes)
16 4 Offset of start of central directory, relative to start of archive
20 2 ZIP file comment length (n)
22 n ZIP file comment

If we search the file for that, we get:
000bcb70 78 2e 62 69 6e 50 4b 05 06 00 00 00 00 01 00 01 |x.binPK………|

So, from our Start PK 03 04 through to PK 05 06 we’re at position 0x14 through 0x0bcb79

If we write that out now –
dd if=lr_cmos_11_14_1_46.bin of=test.zip skip=0x14 bs=1 count=0x0bcb79

Then try unzip test.zip – we have a winner!

lawrence$ unzip test.zip
Archive: test.zip
inflating: linux.bin
lawrence$ ls -al test.zip
-rw-r--r-- 1 lawrence staff 772985 Apr 30 03:28 test.zip
lawrence$ ls -al linux.bin
-rw-------@ 1 lawrence staff 1628604 Dec 7 05:49 linux.bin

So, we know that the file has a header, then a zip file (which uncompresses to linux.bin, and has our linux binary), then more data.

If we take a look at what follows – ie the rest of the data in the original file after the end of the zip, it doesn’t look compressed

000bcb79 00 00 00 00 01 00 01 00 37 00 00 00 2a cb 0b 00 |……..7…*…|
000bcb89 00 00 2d 72 6f 6d 31 66 73 2d 00 08 cf a0 98 16 |..-rom1fs-……|
000bcb99 76 dd 72 6f 6d 20 34 62 31 63 62 36 38 66 00 00 |v.rom 4b1cb68f..|
000bcba9 00 00 00 00 00 49 00 00 00 20 00 00 00 00 d1 ff |…..I… ……|
000bcbb9 ff 97 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
000bcbc9 00 00 00 00 00 60 00 00 00 20 00 00 00 00 d1 d1 |…..`… ……|
000bcbd9 ff 80 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
000bcbe9 00 00 00 00 00 c9 00 00 00 80 00 00 00 00 8c 88 |…………….|
000bcbf9 9d 47 73 77 61 70 00 00 00 00 00 00 00 00 00 00 |.Gswap……….|

000bd969 50 7d 64 68 63 70 63 00 00 00 00 00 00 00 00 00 |P}dhcpc………|
000bd979 00 00 62 46 4c 54 00 00 00 04 00 00 00 40 00 01 |..bFLT…….@..|
000bd989 11 70 00 01 37 60 00 01 50 e8 00 00 28 00 00 01 |.p..7`..P…(…|
000bd999 37 60 00 00 02 b5 00 00 00 05 00 00 00 00 00 00 |7`…………..|
000bd9a9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….|
000bd9b9 00 00 1f 8b 08 00 f4 6b 45 3f 02 03 dc 5b 0f 70 |…….kE?…[.p|
000bd9c9 14 d7 79 7f bb 77 a7 bf 07 9c fe f0 c7 48 a0 95 |..y..w…….H..|
000bd9d9 50 88 5c 23 b3 02 19 64 23 e0 84 30 76 72 b8 9c |P.\#…d#..0vr..|
000bd9e9 31 50 6c 2b 58 06 d7 25 84 d6 ea 80 6d 02 8c 7d |1Pl+X..%….m..}|
000bd9f9 48 02 64 17 b0 00 91 12 17 fb b6 29 ed 60 86 c6 |H.d……..).`..|
000bda09 4c aa 74 34 0e 71 0e 90 03 d3 d2 54 fc 51 87 30 |L.t4.q…..T.Q.0|

In fact it looks like more files…

bFLT is our flat ELF header…, and the other bits in-between look suspiciously like more files, and folders.
So, we probably have a filesystem in there.

Its late, and thats all for today, but it looks like we might even get to play around with both the linux image and the web UI image.

Just had another thought though – if you recall, our romfs size was 0x0008D000

Image: 6 name:romfs.img base:0x7F0E0000 size:0x0008D000 exec:0x7F0E0000 -a

What do we see here – in our header? 00000010 00 d0 08 00


00000000 42 4e 45 47 01 00 00 00 01 00 00 00 77 cb 0b 00 |BNEG……..w…|
00000010 00 d0 08 00 50 4b 03 04 14 00 00 00 08 00 3a 2e |….PK……..:.|

Seem to have a match, no? 0x 08 d0 00
I’m going to bet that our 0x 00 0b cb 77 also has some meaning too in our header 20 bytes, especially as the linux.bin zip file size is close to that at 0x00 0b cb 79.

Its highly probable I’ve miscounted something with the offset, and thats going to turn out to be the zip file size.

Now I’ve gotten this far, I’m too excited to go to sleep (its 4am here now!)

Lets try the filesystem from where we left off (aka from 0x0bcb79)
dd if=lr_cmos_11_14_1_46.bin of=unsure_what_filesystem.img skip=0x0bcb79 bs=1

mount -r unsure_what_filesystem.img
mount: unsure_what_filesystem.img: unknown special file or file system.

Nope.

Kyle’s blog comment has this gem in

however the ‘-romfs-’ tag is offset by 0×14

so I used the line

fx 6 romfs.img 0x7f0a0000 0x7f0a0014 -a

the system then rebooted correctly…”

Lets use that as the start.

hexdump -C unsure_what_filesystem.img |more
00000000 00 00 00 00 01 00 01 00 37 00 00 00 2a cb 0b 00 |……..7…*…|
00000010 00 00 2d 72 6f 6d 31 66 73 2d 00 08 cf a0 98 16 |..-rom1fs-……|
00000020 76 dd 72 6f 6d 20 34 62 31 63 62 36 38 66 00 00 |v.rom 4b1cb68f..|

-rom1fs- starts at position 0x12 [which is another indicator that I’m off by 2 bytes somewhere – as they mention 0x14 bytes, and the 12bytes prefix I have prior to the -rom1fs- are going to be from our second file header, I’ll bet…
0x0bcb79 – 2 = 0x0bcb77, which is what the previous header said, so that really makes me think thats the filesize now!

Our ROMFS works out to be 577 536 bytes, which is 0x8D000, which is also what the boot loader said, so getting a lot of good confirmation on these figures!]

Write that out to another file:
dd if=unsure_what_filesystem.img of=still_unsure.img skip=0x12 bs=1

Still doesn’t mount on my Mac, however, some more googling for rom1fs uclinux got me here

http://romfs.sourceforge.net/

Which specifically mentions –

Embedded projects using romfs

uClinux, the microcontroller Linux, is a port of the kernel, and selected user-space programs to capable, embedded processors, like some “smaller” Motorola m68k, and ARM systems.

ROMFS looks like:

offset content
+—+—+—+—+
0 | – | r | o | m | \
+—+—+—+—+ The ASCII representation of those bytes
4 | 1 | f | s | – | / (i.e. “-rom1fs-“)
+—+—+—+—+
8 | full size | The number of accessible bytes in this fs.
+—+—+—+—+
12 | checksum | The checksum of the FIRST 512 BYTES.
+—+—+—+—+
16 | volume name | The zero terminated name of the volume,
: : padded to 16 byte boundary.
+—+—+—+—+
xx | file |
: headers :

struct romfs_super_block
{

__u32 word0;

__u32 word1;

__u32 size;

__u32 checksum;

char name[0]; /* volume name */

};

Which looks to be a *very* good match for what that header has!
So, its in ROMFS format from the -rom1fs- start header.

(Mostly from here – http://zhwen.org/?p=articles/romfs)

Unfortunately my OSX box appears to be missing romfs support, so I can’t check it without going back to the office.

mount -o loop -t romfs still_unsure.img /mnt
mount: exec /System/Library/Filesystems/romfs.fs/Contents/Resources/mount_romfs for /mnt: No such file or directory

Booted up my Debian VM, and tried again.

debian:/mnt/hgfs/FI8908,FI8908W# mount -o loop -t romfs still_unsure.img /mnt/test -r
debian:/mnt/hgfs/FI8908,FI8908W# cd /mnt/test/
debian:/mnt/test# ls -al
total 4
drwxr-xr-x 1 root root 32 1969-12-31 18:00 .
drwxr-xr-x 4 root root 4096 2010-04-29 16:19 ..
drwxr-xr-x 1 root root 32 1969-12-31 18:00 bin
drwxr-xr-x 1 root root 32 1969-12-31 18:00 dev
drwxr-xr-x 1 root root 32 1969-12-31 18:00 etc
drwxr-xr-x 1 root root 32 1969-12-31 18:00 flash
drwxr-xr-x 1 root root 32 1969-12-31 18:00 home
drwxr-xr-x 1 root root 32 1969-12-31 18:00 proc
drwxr-xr-x 1 root root 32 1969-12-31 18:00 swap
drwxr-xr-x 1 root root 32 1969-12-31 18:00 usr

We have a winner!

Full file listing below:

.
|-- bin
| |-- camera
| |-- dhcpc
| |-- ifconfig
| |-- init
| |-- iwconfig
| |-- iwpriv
| |-- mypppd
| | |-- chap-secrets
| | |-- options
| | |-- pap-secrets
| | `-- pppd
| |-- route
| |-- rt73.bin
| |-- sh
| |-- wetctl
| `-- wpa_supplicant
|-- dev
| |-- console
| |-- display
| |-- dsp -> dsp1
| |-- dsp0
| |-- dsp1
| |-- fb0
| |-- hda
| |-- hda1
| |-- hda2
| |-- hdb
| |-- i2c0
| |-- i2c1
| |-- key
| |-- keypad
| |-- lp0
| |-- mixer -> mixer1
| |-- mixer0
| |-- mixer1
| |-- mouse
| |-- mtd0
| |-- mtd1
| |-- mtdblock0
| |-- mtdblock1
| |-- nftlA1
| |-- nftla
| |-- null
| |-- ppp
| |-- ppp1
| |-- ptmx
| |-- pts
| |-- ptyp0
| |-- ptyp1
| |-- ptyp2
| |-- ptyp3
| |-- ptyp4
| |-- ptyp5
| |-- ptyp6
| |-- ptyp7
| |-- ptyp8
| |-- ptyp9
| |-- ptz0
| |-- rom0
| |-- rom1
| |-- rom2
| |-- sda
| |-- sda1
| |-- sda2
| |-- sdb
| |-- sdb1
| |-- sdb2
| |-- smartcard0
| |-- smartcard1
| |-- tty
| |-- tty1
| |-- ttyS0
| |-- ttyS1
| |-- ttyS2
| |-- ttyS3
| |-- ttyp0
| |-- ttyp1
| |-- ttyp2
| |-- ttyp3
| |-- ttyp4
| |-- ttyp5
| |-- ttyp6
| |-- ttyp7
| |-- ttyp8
| |-- ttyp9
| |-- urandom
| |-- usb
| | |-- lp.sh
| | |-- lp0
| | |-- lp1
| | |-- lp2
| | |-- lp3
| | |-- lp4
| | |-- lp5
| | |-- lp6
| | |-- lp7
| | |-- lp8
| | `-- lp9
| |-- usi
| |-- video0
| `-- video1
|-- etc
|-- flash
|-- home
|-- proc
|-- swap
|-- usr
`-- var
`-- run

13 directories, 97 files

While I obviously can’t run any binaries locally, I can look at the text files to confirm that the ROMFS hasn’t just gotten the filesystem correct.

debian:/mnt/test/bin# cat init
mount -t proc none /proc
mount -t ramfs none /usr
mount -t ramfs none /swap
mount -t ramfs none /var/run
mount -t ramfs none /etc
mount -t ramfs none /flash
mount -t ramfs none /home
camera&
sh

debian:/mnt/test/bin# file camera
camera: BFLT executable - version 4 ram gzip

Looking *very* good.

Thats all for tonight, but it looks like we can easily add bits to the firmware using genromfs, dd, and a hex editor, or just genromfs, and someone willing to test a rebuilt user rom with an extra binary. Probably going to be telnetd as ssh requires a kernel recompile 🙁

Next step, actually doing that, and testing.

I’m definitely going to bed now – its 5:30am.

Tomorrow is a holiday though (in China), so happy May holidays!

I’ve finally received my 2nd camera, so I can now start working properly on it (assuming I get some free time too!)

High resolution photos of the board are below:

Main parts used are:

RAM – Winbond W9812G61H-6 (2M)
According to the data sheet, that 2M X 4 BANKS X 16 BITS SDRAM @ 3.3V / 166MHz/CL3
Data sheet is here – http://jp.ic-on-line.cn/IOL/datasheet/w9812g6ih_4223255.pdf

Flash – Spansion S29AL016D (2M)
Other boards are populated with different providers – some people have Samsung flash…
Mine has the Spansion onboard both units. Its programmable onboard (via the uBoot)
Data sheet here – http://www.datasheetpro.com/259722_view_S29AL016D_datasheet.html

Sound Card – ALC203
This is obviously used as the BSP for the Novotel provides sample code for that card, making their life easier…
Data sheet here – http://realtek.info/pdf/alc203.pdf

Wired Ethernet – Davicom DM9161AEP (10/100 Ethernet)
Data sheet here –
http://www.davicom.com.tw/userfile/24247/DM9161AEPProductBrief_v1.0.pdf

8 Port Relay Driver (for the motors etc) – ULN2803
Data sheet here – http://www.rentron.com/Files/uln2803.pdf
More info / explanation here – http://wiki.answers.com/Q/What_is_Relay_driver_ULN2803

Wifi – RALINK 2571 (on daughterboard). Wireless G
This is a USB based chipset, so we’re using 4 usb connector pins for this one.
No datasheet, as Ralink are dicks.

CPU – ARM7 N745CDG (Arm 7 by Nuvoton)
Lot of info for chip available at Nuvoton.

W90N745 makes use of the ARM7TDMI microprocessor core of ARMR and 0.18um production to achieve standard operation at 80MHz. 128-Pin LQPF packing is also used to save electricity and lower costs. The built-in 4KBytes I-Cache and 4KBytes D-Cache of W90N745 can also be set as On-Chip RAM according to the needs of product developers. With regards to system integration, W90N745 is suitable for network-related applications such as management switch, IP cameras, VoIP and printer servers.
Features
* One Ethernet MAC
* One USB 2.0 full speed Host controller
* One USB 2.0 full speed Host/Device controller
* AC97/I2S
* 4 UARTs
* I²C Master
* 31 GPIOs
* Power Management

Data sheets – http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller/NUC745A.htm
The uclinux sample distribution and files can be downloaded here – http://www.metavert.com/public/NO-SUPPORT/NUC700%20Series%20MCU%20uCLinux%20BSP.zip

I’m just waiting on a JLINK USB adaptor, then I’m ready to roll.

[Updates]

David M from comments at http://irishjesus.wordpress.com/2010/03/30/hacking-the-foscam-fi8908w/#comments provided his rom sizing from his device, I’ve got some notes on that here.

MAC Address : 00:30:10:C1:D0:39
IP Address : 0.0.0.0
DHCP Client : Enabled
CACHE : Enabled
BL buffer base : 0×00300000
BL buffer size : 0×00100000
Baud Rate : -1
USB Interface : Disabled
Serial Number : 0xFFFFFFFF

For help on the available commands type ‘h’

Press ESC to enter debug mode …

bootloader > ls
Image: 0 name:BOOT INFO base:0x7F010000 size:0×00000038 exec:0x7F010000 -af
Image: 7 name:linux.bin base:0x7F020000 size:0x000BB334 exec:0×00008000 -acxz
Image: 6 name:romfs.img base:0x7F0E0000 size:0x0008D000 exec:0x7F0E0000 -a

My notes:

Image: 0 name:BOOT INFO base:0x7F010000 size:0×00000038 exec:0x7F010000 -af

[Image 0 is 38 bytes (small!).
Boot info is not the bootloader – 38bytes is way too small for that.
It actually stores our bootloader config settings.
eg ip address, cache setting, boot loader buffer address etc.
Our initial settings are below:

MAC Address : 00:30:10:C1:D0:39 (should be changed, this Mac range belongs to Cisco!)
IP Address : 0.0.0.0 (unset)
DHCP Client : Enabled (pulls ip from dhcp..)
CACHE : Enabled (onboard chip cache)
BL buffer base : 0×00300000
BL buffer size : 0×00100000
Baud Rate : -1 (unset / so defaults to 115,200,8,n,1)
USB Interface : Disabled (NC745 has no USB for bootloader)
Serial Number : 0xFFFFFFFF (unset)

-af indicates Active (a) , and is a Filesystem image (f)]

Image: 7 name:linux.bin base:0x7F020000 size:0x000BB334 exec:0×00008000 -acxz
[Image 7 is our OS – Linux 2.4.20 ucLinux Not sure why Maverick didn’t build on 2.6, there is more hardware support. Probably time dependant – 2.6 may not have been available, plus the Nuvoton sample code is also 2.4 based…

-axcz says active (a) executable (x) copied to ram (c) compressed (z) ]

Image: 6 name:romfs.img base:0x7F0E0000 size:0x0008D000 exec:0x7F0E0000 -a

[Our rom image – aka userland stuff. This is where we’ll be putting our own code. Looks like its stuck quite high up in the flash, although doesn’t need to be given size of the Linux rom. We have plenty of room available.

We’ll need to make appropriate changes to Image 6 size on flashing

-a says active partition.]

Finally got a chance to play around with the second ipcam I bought.

This one is a little bit smarter than the previous one – its running off an ARM5ARM7 CPU (Nuvoton NUC745ADN), so has a bit more oomph. 16M ram is a whole lot more to play with for a start! The last device only had 16KB, so this puppy can be taught to do some tricks!

Serial was a little bit trickier to solder on this time – my initial connectors were too small, so had to resolder with larger ones, and I managed to mess up a tad. Never said my soldering was any good 😉
Getting it to talk to the computer was a bit painful too – eventually I settled on 115,200 8,n,1, xon/xoff which should have worked the first time around, but I was getting garbage.

Probably flow control (xon/xoff), as fiddling with the connections got it going eventually.

First output from the board is below – this is from a clean boot (with no ethernet or wifi).


W90P745 Boot Loader [ Version 1.1 $Revision: 1 $ ] Rebuilt on Dec 10 2009
Memory Size is 0x1000000 Bytes, Flash Size is 0x200000 Bytes
Board designed by Winbond
Hardware support provided at Winbond
Copyright (c) Winbond Limited 2001 - 2006. All rights reserved.
Boot Loader Configuration:

MAC Address : 0E:F2:B3:DC:08:05
IP Address : 0.0.0.0
DHCP Client : Enabled
CACHE : Enabled
BL buffer base : 0x00300000
BL buffer size : 0x00100000
Baud Rate : -1
USB Interface : Disabled
Serial Number : 0xFFFFFFFF

For help on the available commands type 'h'

Press ESC to enter debug mode ......
Cache enabled!
Processing image 1 ...
Processing image 2 ...
Processing image 3 ...
Processing image 4 ...
Processing image 5 ...
Processing image 6 ...
Processing image 7 ...
Unzip image 7 ...
Executing image 7 ...
Linux version 2.4.20-uc0 (root@maverick-linux) (gcc version 3.0) #1013 Èý 12ÔÂ 2 13:17:32 CST 2009
Processor: Winbond W90N745 revision 1
Architecture: W90N745
On node 0 totalpages: 4096
zone(0): 0 pages.
zone(1): 4096 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0 rw
Calibrating delay loop... 39.83 BogoMIPS
Memory: 16MB = 16MB total
Memory: 14376KB available (1435K code, 288K data, 40K init)
Dentry cache hash table entries: 2048 (order: 2, 16384 bytes)
Inode cache hash table entries: 1024 (order: 1, 8192 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
Winbond W90N745 Serial driver version 1.0 (2005-08-15) with no serial options enabled
ttyS00 at 0xfff80000 (irq = 9) is a W90N745
Winbond W90N7451 Serial driver version 1.0 (2005-08-15) with no serial options enabled
ttyS00 at 0xfff80100 (irq = 10) is a W90N7451
I2C Bus Driver has been installed successfully.
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: 7F0E0000-7F16D3FF [VIRTUAL 7F0E0000-7F16D3FF] (RO)
AM29LV160DB Flash Detected
01 eth0 initial ok!
which:0
PPP generic driver version 2.4.2
Linux video capture interface: v1.00
Winbond Audio Driver v1.0 Initialization successfully.
usb.c: registered new driver hub
add a static ohci host controller device
: USB OHCI at membase 0xfff05000, IRQ 15
hc_alloc_ohci
usb-ohci.c: AMD756 erratum 4 workaround
hc_reset
usb.c: new USB bus registered, assigned bus number 1
hub.c: USB hub found
hub.c: 2 ports detected
usb.c: registered new driver audio
audio.c: v1.0.0:USB Audio Class driver
usb.c: registered new driver serial
usbserial.c: USB Serial Driver core v1.4

_____ ____ _ ____
|__ / _| _ \ / \ / ___|
/ / | | | | | |/ _ \ \___ \
/ /| |_| | |_| / ___ \ ___) |
/____\__, |____/_/ \_\____/
|___/
ZD1211B - version 2.24.0.0
usb.c: registered new driver zd1211b
main_usb.c: VIA Networking Wireless LAN USB Driver 1.13
usb.c: registered new driver vntwusb
usb.c: registered new driver rt73
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
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 2048)
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 40K
BINFMT_FLAT: bad magic/rev (0x74202d74, need 0x4)
BINFMT_FLAT: bad magic/rev (0x74202d74, need 0x4)
Shell invoked to run file: /bin/init
Command: mount -t proc none /proc
Command: mount -t ramfs none /usr
Command: mount -t ramfs none /swap
Command: mount -t ramfs none /var/run
Command: mount -t ramfs none /etc
Command: mount -t ramfs none /flash
Command: mount -t ramfs none /home
Command: camera&
[8]
Command: sh
no support

Sash command shell (version 1.1.1)
/> hub.c: connect-debounce failed, port 1 disabled
new USB device :80fd7e04-fed640
hub.c: new USB device 1, assigned address 2
dvm cmos successfully initialized
dvm camera registered as video0
new USB device :80fb0204-fed640
hub.c: new USB device 2, assigned address 3
idVendor = 0x148f, idProduct = 0x2573

Wait for auto-negotiation complete...ResetPhyChip Failed
video0 opened
1
1
1
1
1
1
set resolution 5
set brightness 144
set contrast 3
set sharpness 3
set mode 2
__pthread_initial_thread_bos:34c000
manage pid:16
audio_dev.state not AU_STATE_RECORDING
wb_audio_start_record
=> usb_rtusb_open
retide_ddns.c: can not get server dns.camcctv.com ip
ntpc.c: can not resolve ntpserver(time.nist.gov)'s ip
get oray info
upnp get ip error
inet_sr.c INET_rinput 321
action===1
options==33
inet_sr.c INET_setroute 75
*args===255.255.255.255
*args===netmask
*args===eth1
inet_sr.c INET_rinput 321
action===1
options==33
inet_sr.c INET_setroute 75
*args===default
*args===gw
*args===eth1
MlmeAssocReqAction(): WPA2/WPA2PSK fill the ReqVarIEs with CipherTmp!
3
3
3
3
3
3

Initially I had the board setup on its own without the camera attached, but the boot scripts require it connected, otherwise they reboot..
Ostensibly, this is the same hardware as the fi8908w (who are just reselling the OEM version with marginally different firmware as far as I can tell).

Next step is to setup a cross compiler for uclinux so I can make some binaries, and test.
Luckily all the available tools are open source / free. Yay!

I’m in contact with the factory, and they’ll be sending an SDK over at some point soonish, although its only in Chinese.
Luckily for me, that shouldn’t be a problem, as i’m reasonably capable at groking both code, and simplified chinese 🙂

ucLinux should be easy enough to build a rom image for though – tons of examples, and I already have a few firmware files to compare.

It shouldn’t be too hard for me to roll another firmware with ssh installed, so that we can get in without serial, that would be more useful for others too.

I’ve had a quick look inside the folders in the device from the device itself – fairly minimal, pretty much the only binaries are the necessary ones.
My initial aim is to redo the UI to a nicer one, and fix some of the more glaring bugs. The factory people are at a trade show in Taiwan this week, so hopefully next week I’ll get some dev tools (otherwise its reverse engineering, bleh…).

Some more people are playing with these as well (links below):

http://irishjesus.wordpress.com/2010/03/30/hacking-the-foscam-fi8908w/


http://www.gadgetvictims.com/2009/12/bring-your-fi8908w-paperweight-back-to.html

Unfortuanately for me, both are variably accessible. WordPress is available this week woohoo, but its an on / off dealio with the GFW…, so I might have to stop commenting there once the government decides if WordPress is “teh evil” again.

The irishjesus blog guy has done some of the harder bits like file extraction already (although not strictly necessary, as there are existing tools for that kind of thing).

Updates

Have some docs from the factory now, see attached file for the CGI spec.

IP Camera CGI 应用指南-1.11

I have others, but not so relevant especially for those than don’t read Chinese!

Data sheet for the Chip and build instructions here –

http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller/NUC745A.htm

When I was younger, I used to like taking things apart.  I still do that, but they tend to work better these days, hehe

This last few weeks I’ve been playing with IP Camera’s for a pet project that started off as a request over Skype for info about surveillance.
As the ever useful Taobao is full of vendors selling the same 4 or 5 camera’s for reasonable prices I ordered a couple to take a peek at.

I’ve only taken one apart so far – the really really cheap one that I installed in the office so I can get a look at who comes up the stairs without having to move my fat ass out of the chair.  A quick shortcut in FF, and it works quite nicely as a separate browser window in the corner of the desktop.

Onto the discovery phase 🙂

I had a quick spin with NMAP, but other than discovering that they rather naughtily misuse a Mac Address assigned to the evil Cisco, not much help.
Also nothing appeared to be running on any other ports than the web port 🙁
nmap -A 192.168.0.88

Starting Nmap 5.00 ( http://nmap.org ) at 2010-04-13 19:27 CST
Interesting ports on 192.168.0.88:
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http?
|_ html-title: IPCamera
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port80-TCP:V=5.00%I=7%D=4/13%Time=4BC45529%P=i686-pc-linux-gnu%r(GetReq
SF:uest,2E1,"HTTP/1\.1\x20200\x20OK\r\nExpires:\x200\r\nConnection:\x20clo
SF:se\r\ncache-control:\x20no-cache\r\n\r\n\r\n
SF:IPCamera\r\n\r
SF:\n\r\n\r\n\r\n\r\n
SF:\r\n\r\n\r\n\r\n\r\n\r\n\r\n<BODY\x20onLoad=\" SF:doPop\(\);\">\xb6\xd4\xb2\xbb\xc6\xf0\xa3\xac\xc4\xfa\xb5\xc4\xe4\xaf\x
SF:c0\xc0\xc6\xf7\xb2\xbb\xd6\xa7\xb3\xd6\xbf\xf2\xbc\xdc\xa3\xa1</BODY></ SF:NOFRAMES>\r\n</FRAMESET>\r\n\r\n</HTML>\r\n")%r(FourOhFourRequest,1DF,"
SF:HTTP/1\.1\x20200\x20OK\r\nConnection:\x20close\r\ncache-control:\x20no-
SF:cache\r\n\r\n<HTML>\r\n<HEAD>\r\n<TITLE></TITLE>\r\n<meta\x20http-equiv SF:=\"Content-Type\"\x20content=\"text/html;\x20charset=gb2312\"></HEAD>\r
SF:\n<BODY\x20BGCOLOR=\"#C4CEEF\"\x20onLoad=\"window\.status='\xbb\xb6\xd3 SF:\xad\xca\xb9\xd3\xc3\xcd\xf8\xc2\xe7\xc9\xe3\xcf\xf1\xbb\xfa!';return\x SF:20true;\">\r\n\r\n
<TABLE\x20WIDTH=140\x20BORDER=0\x20CELLSPACING=0\x20C SF:ELLPADDING=0>\r\n
<TR>\r\n\t
<TD\x20HEIGHT=80\x20ALIGN=center\x20BGCOLOR= SF:\"#C4CEEF\"><FONT\x20color=\"#FF6633\"\x20size=\"\+2\"\x20FACE=\"Arial\ SF:"><B>IP\x20Camera</B></FONT></TD>

\r\n</TR>

\r\n</TABLE>

\r\n\r\n</BODY>\r
SF:\n</HTML>\r\n");
MAC Address: 00:0A:42:33:66:54 (Cisco Systems)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 1 hop

Next up is the usual dissection. I had done some minor googling on the device I bought, which is basically this below:

As its an OEM product, this is available under a whole bunch of different names – mostly with IP-510 or similar in the title, eg LTI-510 etc.

For a cheap OEM product, it actually seems to be reasonably well made though – the Case is an nice and solid aluminium sheath that looks like its been repurposed from something else, and the board itself is suprisingly well diagrammed. Its almost made for hacking!

Chips onboard are as follows:

25.0618mhz crystal from TXC – bonus points for why its 25mhz. Reply in the comments 🙂
Davicom DM9008AEP, TRC9016NLE (both for Ethernet. imho Davicom is a second-rate Realtek)
ViMicro VC0528BRVC (Camera processor / CCD Controller)
And last, but not least, our CPU, which is an 8051, although not from ATMEL.
Part number on that is C8051F340. My first guess is that it incorporates some integrated flash on there for firmware. Unfortunately its likely to be all C and Assembler, and the last time I did embedded 8051 stuff was in the early 90’s.

Google confirms it – basically its an all in one controller with 32 or 64KB onboard, and roughly 4k ram. Woohoo!

Datasheet here – http://www.alldatasheet.com/datasheet-pdf/pdf/182721/SILABS/C8051F340.html

Good news is that the board has serial out clearly labeled on the top left side. Better news is that the chip has an onboard debug mode, so I don’t even need any ICE (In Circuit Emulation) tools should I want to take a look. Bad news is that I’m probably going to be too lazy to do it, as its more work and less fun than the second one I bought, which has Linux running on it.

That said, this one is cheap. Real cheap. Cheap enough that its probably worth knocking out a decent firmware, and reselling it with a better UI, and more features.
Might be possible, although anything more than whats there is probably stretching it given the ram / storage constraints. Looks like its all offboard processing/streaming for this model!

There are also some unpopulated spots on the board, which I strongly suspect would be for audio, given the board has a MIC input and no Mic, and the main controller is a ViMicro, which supports MP3 output also…

I’ll see if I can find a firmware file, and do a disassembly, or more probably see what I get out of the serial port connection in the near future.

Photos below. [Excuse the pasty white hands, its still winter for some reason in Shanghai, despite being April… Oh global warming. Where art thou, when I needest thee!]:

Some further files for the curious here –

http://kuklin.ru/ip400cam

I’ve been seeing a bunch of failed Apple Time Capsules recently.
The issue is that the PSU’s are dying, as opposed to the HDD’s.

I took one apart to take a look, and the issue is the oh too familiar someone bought cheap capacitors that use the wrong formula. Tsk tsk Apple!

Here are some photos of a faulty power supply from a Time Capsule I’ve taken apart to demonstrate –

Read more »

Archives

Categories

Tags

PHOTOSTREAM