view doc/Compal-unlock @ 889:1b1683cda154

fc-shell: implemented poweroff and tgtreset commands
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sun, 28 Jun 2015 16:52:06 +0000
parents 2d8ab1b0df8d
children 3f67d5bf96ef
line wrap: on
line source

Using FreeCalypso tools to unlock Motorola C1xx phones
======================================================

The ultimate goal of the FreeCalypso project is to produce our own complete GSM
dumbphone firmware which We the People fully own, control and compile from
source ourselves, running at first on some selected pre-existing hardware
targets, and then ultimately on our own Free Dumb Phone hardware.  While that
goal is still far past the visible horizon, what can we do in the meantime to
make our current forced use of existing proprietary dumbphone firmwares a
little more tolerable?  This article presents one such hack: using FreeCalypso
loadtools to dump the flash content of Compal phones for analysis, including
TIFFS, and to replace one existing proprietary fw version with another, e.g.,
to remove carrier branding and the associated SIM restriction.

Serial access

Mot C1xx (Compal) phones have a 2.5 mm headset jack that dual-functions as a
debug/programming serial port.  In hardware terms, there is an electrically
controlled switch (MUX) inside that switches the external jack between the
analog headset signals and the digital serial ones; this switch is controlled
by a GPIO signal from the Calypso.  The hardware power-up state of this switch
is serial; Mot/Compal's standard fw switches it to headset upon boot, but the
serial setting persists long enough to use it to break into the bootloader.

Bootloader

The Calypso DBB (digital baseband) chip used in these phones has an on-chip
boot ROM, but it also has a hardware pin that enables or disables this boot
ROM, and unfortunately these phones have it disabled.  If the boot ROM were
enabled in hardware, it would provide an unstoppable and unbrickable way to
take control of the device through the externally-accessible serial port like
we have on Openmoko and Pirelli phones, but unfortunately the hardware we have
available is not wired that way.

However, Mot/Compal's standard firmware on these phones includes a bootloader,
a part that executes before any of the rest of the fw image is allowed to
execute or is made use of in any way, and this Compal-specific bootloader has a
provision for interrupting the boot process and diverting it to an externally-
supplied piece of code loaded over the serial line.  Older fw versions have
this feature enabled unconditionally, but some of the newer versions have a
malfeature whereby the serial boot interrupt and code download possibility may
be disabled.  Some C1xx phones out in the wild, particularly all North American
C139s with TracFone branding, have such maliciously-locked firmware in them.

Fortunately though, these maliciously-locked firmwares (or at least the most
common TFC139 one) have been found to have another hole through which we can
break in, as described here:

http://lists.osmocom.org/pipermail/baseband-devel/2014-May/004451.html
http://lists.osmocom.org/pipermail/baseband-devel/2014-May/004455.html

We can exploit this hole in the TFC139 firmware to gain code execution access
to the Calypso, and then use the latter to reprogram the flash, replacing the
ultra-malicious firmware with some other version that, although still
proprietary, is a little less evil.

Making first contact
====================

If you have a C1xx phone which you are seeking to free, your first step should
be to try breaking in with fc-loadtool, using the Compal bootloader method.
With the phone powered off, but containing a charged battery (SIM present or
absent, doesn't matter), proceed as follows:

1. Connect the serial or USB-serial cable between your PC or other host and the
   target phone's headset jack.

2. On the host end, run fc-loadtool like this:

C11x/123: fc-loadtool -h compal /dev/ttyXXX
C139/140: fc-loadtool -h compal -c 1003 /dev/ttyXXX
C155/156: fc-loadtool -h c155 /dev/ttyXXX

3. Press the power button on the phone.  A momentary press is sufficient and
   recommended: the hardware powers up and causes the boot code to run exactly
   the same whether the power button is pressed momentarily or held down.

   Normal phone power-up requires the button to be held down because the
   standard firmware does a check fairly late in the boot process to see if the
   power button is still held down, and commands the hardware (the ABB) to
   power off if it is not - it is a standard feature to prevent phones from
   turning themselves on inadvertently from accidental momentary presses of
   that button.  But if the goal is to cause the boot code to run, but not to
   boot the regular fw all the way, a momentary press is ideal.

If your phone has a bootloader without the malicious lock in it, the above
procedure should result in fc-loadtool gaining full access to the target and
landing you at a loadtool> prompt.  You can dump the flash content and analyse
it, etc.  If you would like to change to a different fw version (to remove the
SIM lock / carrier branding or for any other reason), see the corresponding
later section of this article.

Alternative method
==================

If the above procedure fails to gain access to the Calypso because the boot
code in the phone never offers a serial download opportunity, the alternate
break-in method should be tried, going through the full running firmware
instead of just the bootloader part thereof.  Proceed as follows:

1. Remove the SIM (if there was one to begin with) and put the charged battery
   back in.  Charge the battery if necessary, using the standard charging
   function of the existing fw.

2. Power the phone up for normal boot: hold the power button down like a
   regular user would, without fc-loadtool or other serial break-in tools.
   The fw will boot up, notice the lack of a SIM, and the display will read
   "SIM card absent" or something to that effect, depending on the fw version.

3. Key in this magic sequence: **16379#.  A hidden "Trace Switch" menu should
   appear, with the choices being "Trace On" and "Earphone".  Select "Trace On".
   The electrically controlled hardware switch mentioned earlier in this article
   should now be set back to the UART, bringing the latter out to the headset
   jack.  Because Mot/Compal's firmware is based on TI's reference architecture,
   the interface presented by the running fw on this serial port is TI's RVTMUX,
   albeit at 57600 baud instead of TI's default of 115200.

4. Connect the headset jack serial cable if it wasn't already connected, and
   run this FreeCalypso hack-utility:

   tfc139 /dev/ttyXXX

Compal's firmware has some non-standard commands of their own invention added
to TI's RVT/ETM interface, and one of these commands is a raw memory write.
Our tfc139 hack-utility will try to break into the phone (gain code execution
access) by using this Compal ETM command to write a little payload into a
particular RAM location (beginning of IRAM), and then doing more memory writes
by the same method, seeking to smash the stack and cause control to be
transferred to the sent payload by overwriting a function return address on the
stack.

If the stack smashing hack succeeds, the code injected by tfc139 will send a
message out the serial port indicating this success, and then re-enable the
Calypso boot ROM and jump to it.  Once the boot ROM code gains control, it will
wait forever for a serial code download following its standard protocol.  If
tfc139 gets the success indication from the target, it will announce this
success and direct you to run:

fc-loadtool -h compal -c none /dev/ttyXXX

Do as it says.  The -c none option tells fc-loadtool to skip compalstage and
proceed directly to feeding loadagent to the Calypso boot ROM.  You should now
be in full control of the phone via fc-loadtool.

There is one additional quirk worth mentioning.  It appears that Mot/Compal's
main fw (at least TF's version 8.8.17, which is the version we break into with
tfc139; other versions are anyone's guess) keeps resetting the RTC alarm
registers in the Calypso DBB as it runs, always keeping the alarm time in the
near future relative to the current time.  When one breaks into this firmware
with tfc139 and takes over the control of the device with fc-loadtool, this
alarm time will almost certainly be reached, and the RTC alarm will go off.
This alarm has no effect on loadtool operation (i.e., it cannot reset the CPU
or otherwise wrestle control away from loadtool, so it doesn't add any bricking
risk), but it has one quite surprising effect upon exit, i.e., when you are
done with your loadtool session and give it the exit command.

Loadtool's configured default exit action for this target is to send a power-off
command to the Iota ABB, leaving the device cleanly powered off.  However, if
the RTC alarm has gone off previously during the session, the ABB will instantly
power the phone back on, and put it through a new boot cycle.  The firmware
(again, the only version this stuff can be tested on is the one that works with
tfc139) handles this special form of boot rather oddly: it proceeds to the same
end state it would have reached via a normal power button hold-down boot
(powered on with the "Insert SIM" message on the LCD), but it reaches this state
almost instantly, without going through the power-on LCD logo and buzz phase.
Odd, but harmless.  This explanation has been included to save other hackers
the hours of bewildered head-scratching I spent chasing this quirk down.

Dumping and reloading flash
===========================

Once you break in with fc-loadtool (either through the bootloader or through
tfc139), the first step you should do is make a dump (backup) of the flash:

loadtool> flash dump2bin flashdump.bin

Before you do any flash write (erase or program) operations, please realise
that these phones are brickable.  Because the Calypso boot ROM is disabled at
the board level (Calypso DBB's nIBOOT configuration input is tied high directly
underneath the BGA package!), when the phone powers up, the ARM7 core starts
executing instructions directly out of the flash, from address 0.  Therefore,
flash sector 0 must contain good working boot code (one that allows serial code
download access for recovery) at all times.  If you erase this sector or fill
it with some garbage (anything other than good working boot code) and then power
the phone off or otherwise lose control of it, the phone will be unrecoverably
bricked!

On most C1xx models there seems to be no way to access the Calypso's JTAG
signals, hence no possibility of using JTAG to unbrick a bricked phone.  And
because the flash chip is a micro-BGA, it is quite unlikely that one could
successfully desolder it, program it in a standalone flash chip programmer,
and then put it back on the board.  Thus if you brick your C1xx phone, then
most likely it is truly toast.  You've been warned!

That being said, if your phone came with a maliciously locked bootloader, such
that you had to use tfc139 to break in, then replacing that bootloader with a
non-malware version is pretty much a necessity, and taking the chance of
bricking the phone becomes a necessary risk.  Even if the bootloader version in
your C1xx is free of the locking malfeature, if you need to reflash the main fw
to a different version, one still needs to erase and reprogram the dangerous
sector: on C11x/123 and C139/140 the main fw image starts at 0x2000, but the
erase block boundary doesn't come until 0x10000.

The good news, however, is that fc-loadtool has special support for rewriting
the boot sector on Compal phones with minimal risk of bricking.  The command is:

flash erase-program-boot binfile [length]

The first argument is the name of the file (in straight binary format)
containing the new boot code; the second argument (always interpreted as hex)
is the number of bytes to program, always starting at 0.  If only one argument
is given, the length of the file is used instead, which must not exceed the
length of flash sector 0: 64 KiB on C11x/123 and C139/140, or 8 KiB on C155/156.

This special command minimizes the bricking vulnerability window by loading the
entirety of the new boot code to be programmed into a scratchpad RAM buffer on
the target first (no problem because it's 64 KiB max), then commanding loadagent
(the code that actually runs on the Calypso when you use fc-loadtool) to perform
the "atomic" operation of erasing flash sector 0, then immediately reprogramming
it with the bits that are already in scratchpad RAM on the phone.

With this approach the phone will only be bricked if the battery dies or is
physically yanked out of the phone in the time window between the beginning of
the erase operation and the last critical bit of the new boot code being
programmed - on the order of a second or two, or if the flash operations fail
for some reason.  However, the phone will *not* be bricked with this approach
if the serial connection between fc-loadtool or the target gets broken during
the window in question, or if the host machine running fc-loadtool crashes: no
flash operations start until loadtool gives the go-ahead command to loadagent,
and once loadagent receives the latter command, it will proceed till completion
without caring if loadtool is still there or not.

Of course the conventional flash erase and flash program-bin commands will be
happy to operate on flash sector 0 just like any other sector, but doing so is
NOT recommended, as the window of vulnerability for bricking would then be
considerably greater.

Unlocked firmware for C139
==========================

If your phone is a North American (1900+850 MHz) C139, and you are reading this
article because it came with Cingular or TracFone branding, whereas you would
like to use it with SIMs and networks of your own choosing instead, you've come
to the right place.  We have an unlocked and non-carrier-branded (Mot branding
only) version of the fw that runs on these phones, and you can use FreeCalypso
loadtools to flash this version into your C139 whether it came with Cingular or
TF branding originally.  Download this file:

ftp.ifctf.org:/pub/GSM/Compal/c139-unlocked-fw.zip

Unzip it, and you'll get c139-unlocked-fw.bin - that is the image you'll need
to flash into your phone.  Get in with fc-loadtool (using tfc139 if necessary
for locked-down Tracfones) and make a backup of the original flash content.
Then reflash the firmware as follows:

flash erase-program-boot c139-unlocked-fw.bin 2000
flash erase 10000 360000
flash program-bin 2000 c139-unlocked-fw.bin 2000

The 3 commands given above will reflash the phone as follows:

* The first 0x2000 bytes of the firmware image in c139-unlocked-fw.bin comprise
  the boot code.  This fw version features the "good" boot code *without* the
  access locking malfeature.  The erase-program-boot command will erase flash
  sector 0 (the entire 64 KiB sector, as the physics of the flash chip dictates)
  and then immediately reprogram its first 8 KiB with the "good" boot code from
  the unlocked fw image file.  The remaining 56 KiB of this sector will be blank
  after this step.

* The following "regular" flash erase command is to erase the following 54
  sectors (also of 64 KiB each) in preparation for programming the main fw
  image in there.

* The last command programs the bulk of the fw image into blank flash that has
  been erased by the first two commands.

I also recommend erasing the old FFS that was maintained by the old fw version,
so that the new fw will automatically format a "virgin" FFS the first time it
boots:

flash erase 370000 50000

After this procedure the phone should retain its original IMEI and factory RF
calibration values, as these are stored in the 8 KiB sector at 0x3FC000 which
is not touched per the above procedure - not in the FFS.

The same procedure should be followed for flashing all firmwares for C11x/123
and C139/140 phones.  In the case of C11x/123, adjust the length for the "main"
erase and program operations appropriately for the flash configuration in your
phone.

One last word of caution: if you are going to flash some fw version other than
the unlocked North American C139 one discussed above, please check to see what
boot code version it includes, and whether or not that version has the
malfeature of checking the flash word at 0x2060 for the serial access control
flag.  If the fw version you are seeking to play with has boot code with that
malfeature present, the bricking vulnerability window extends until you not
only program the new boot code into flash, but also program 0xDDDDDDDD into
that 0x2060 word.  You've been warned.

C155/156 differences
====================

C155/156 phones are nicer than the others in that they use a flash chip with a
"bottom boot" configuration.  C11x/123 and C139/140 use "top boot" flash chips,
which is why the boot code and the first 56 KiB of the main fw image live in
the same erase block on those phones.  The boot code and the control hand-off
interface between it and the main fw have also been revamped in C155/156 fw,
and the new structure is:

8 KiB sector at 0: contains the boot code
7 more 8 KiB sectors starting at 0x2000: blank and unused
64 KiB sector at 0x10000: also blank and unused
64 KiB sector at 0x20000: beginning of main fw image

With this new flash layout, it is now possible to erase and program the main fw
region starting at 0x20000 without ever erasing the boot code sector or doing
any writes to it, so there is no bricking vulnerability window at all.  (The
phone can still be bricked though if one types the wrong command and erases the
boot sector inadvertently, so be careful.)

So far the only phones in this family that I laid my hacking hands on have been
North American C156 units, all from the same seller and batch (hence identical),
so I don't know if there exist any maliciously-locked boot code versions in
this family - the boot code in my C156 is free of any malfeatures.  But if "bad"
versions of C155/156 boot code do exist, and if you can break into the phone
somehow, you can use the flash erase-program-boot command to rewrite the boot
code with minimal risk of bricking just like on the other Compal families.