The (factory) recovery procedure flashes all images from scratch. It is used in case the images are broken.

Ubiquisys provides the images, with some customisation for SFR.

This is the procedure we use to flash the femtocell with our images.


ways to start the recovery process :

  • press the RESET button on the back of the femto while powering up
  • hold the RESET button for 3 sec while powered on
  • use the web interface: diagnostics → Reset → Trigger Factory Recovery → Immediately → submit


the recovery procedure has 3 major steps:

  1. uboot
  2. kernel/initramfs
  3. roofts


  • when the reset button is pressed while booting, uboot invalidates the environment CRC
Factory reset button detected on power-up, invalidating environment CRC
  • when CRC is not valid, uboot used the included environment instead of ubootenvx
Warning - bad CRC, using default environment
  • uboots load the recovery kernel (0x000c0000 in partitions), instead of kernelA (0x00300000)
## Booting image at 200c0000 ...
  • starting kernel, then initramfs (/init) is started


  • get customisation parameters (including public keys)
Parameters read from customisation.ini
  • download recovery rootfs (using the variables in customisation.ini, else use default)
Downloading: ...
  • extract recovery.tar.gz and decrypt rootfs, if file is name rootfs.gz.enc (ignored file name roofts.gz)
ubcrypt `echo $PUBKEY | head -c47 -` rootfs.tgz.enc >rootfs.tgz
  • verify the signature rootfs.sig (also in recovery.tar.gz) using pubkey customisation.ini BootSigning:pubkey
  • switch from initramfs to recovery roofts
echo "Switching to downloaded system (`cat .version` `cat .builddate`)..."
exec switch_root . /sbin/init


the following is based on recovery/etc/init.d/rcS (from the recovery rootfs V2.1.1-DLG1_DLG1):

  • determine the partitions, based on proc/mtd (l.190)
  • initialize variables with default values (l.213)
  • load variables from customisation.ini (l.235)
  • load variables from operation.ini (l.274)
  • determine the partitions, based on recovery/usr/share/recover/env.default (l.349)
  • check if there is a public key and signature at the end of uboot (l.371)
    • not our case
No public key present in bootloader image
  • if it is, verify the signature of uboot and recovery (tail signature), but only as information, without consequences
  • print the version of ubiqfsA (l.397)
Existing ubiqfsA found, version V2.0.17.2, build date 2009-08-21 16:56:41
  • build URL for the inifile, based on customisation.ini (l.408)
  • get the inifile (l.421)
Downloading inifile...
Retrieved customisation.ini and recovery.ini
  • recovery.ini must include URL for : SCF.xml,standard-kernel.bin,rootfs.bin,ubiqfs.bin
  • verify if uboot and recovery (kernel) need to (when starting with “X-”) and can be flashed (URL provided) (l.438)
U-Boot and recovery kernel need reprogramming, but ZDS has not requested it
  • determine what need to be flashed (l.453)
  • send/harvest partitions if needed. this can be used to dump the partitions (l.521)
  • flash customisation.ini. can be merged with operator.ini (l.554)
Programming customisation data
  • flash recovery kernel (l.600)
    • if url provided, and hash different
    • encrypted, signature not checked, only hash
    • flashed into systemB, select for next boot
No factory recovery kernel provided by ZDS
  • create the uboot environment (so to start systemB)
  • flash boot loader uboot (l.661)
  • if url provided, and hash different
  • encrypted, signature not checked, only hash
No bootloader provided by ZDS
  • flash recovery kernel (l.728)
    • in the recovery partition
    • no check done
    • reboot into recovery
  • flash operator (l.765)
    • check existing operator signature
      • signature is the tail of the partition (last 384 bytes)
      • public key is existing customisation.ini::BootSigning
Existing operator data signature check passed
  • check if hash changed, then it will be flashed
Operator data has changed
  • if URL is provided, download and decrypt
  • check signature of the downloaded file
    • signature is the tail of the file, last 384 bytes (the one recovery.ini is not used)
    • public key is new customisation.ini::BootSigning
Programming operator data
  • mount new partition and read public keys
Parameters read from new operator.ini
  • flash calibration. I never seen this happen (l.841)
    • verify if changed, using checksum
    • it is not downloaded, the existing data is used
    • only check file size and checksum, not the signature
No calibration data provided by ZDS
  • get SCF.xml (l.895)
    • download and decrypt. mandatory
    • check signature
      • signature is from recovery.ini
      • public key is operator.ini::SCF
    • read software version and network authorization
SCF file is for software version V2.0.17.2
This ZAP is authorized on any network
  • check hardware compatibility
Prescribed software is compatible with this hardware version G2.3.2
  • create empty database database (l.957)
Created dbfs.bin
  • flash system : standard-kernel.bin, rootfs.bin, ubiqfs.bin, for systemA and systemB
    • read version for existing partition
    • mark for flashing if version not found or signature check failed
      • check if the signature is still verified by the partition
      • use signature from SCF.xml
      • use public key operator.ini::BootSigning
    • flash systemA
      • download and decrypt (mandatory)
      • check signature
        • use signature from SCF.xml
        • use public key operator.ini::BootSigning
    • check systemB
      • leave it as if version found and signature check succeeded
      • invalidate if version found but signature check failed
      • do nothing if version not found
  • flash database dbfs.tgz (never happened) (l.1102)
    • flash the empty database.
    • download and decrypt if url provided
    • only verify the checksum
    • create jffs2 image
No database file system provided by ZDS
  • flash u-boot environment (l.1149)
    • remove recovery and uboot if not in development mode
    • environment based on recovery/usr/share/recover/env.devault, with new info from flashed partitions (including signatures)
  • reboot, if SIM present (l.1178)


recovery rootfs

the recovery rootfs is downloaded over http (with credentials) :

  • normally it's encrypted (rootfs.tgz.enc), but an unencrypted version was available
  • the recovery procedure also accepts the unencrypted recovery rootfs
  • the signatures (rootfs.sig) is also provided in the archive

The URL is in customisation.ini :

  • the pcbid is the crucial part. without it, no rootfs will be returned. Per default, the PCBID is the serial.
  • normal URL. it returns an encrypted recovery rootfs
wget -O recovery.tar.gz --user=sfrfemtocell --password=sfrrecover "<IMEI>&pcbid=<PCBID>&kernel=2.6.18-ubi-fac-V1.2.6"

In the above command you have to replace <IMEI> with the IMEI of your device, and <PCBID> with the PCBID of your device…

  • if only the pcbid is provided, the unencrypted version is returned. this flaw has been fixed by SFR/Ubiquisys ~ Q1 2011. you can also change the pcbid (within the family), but the image is the same.
wget -O recovery.tar.gz --user=sfrfemtocell --password=sfrrecover "<PCBID>"
  • there is a default link, but the rootfs is the same (encrypted)
wget -O recovery.tar.gz "<PCBID>&kernel=2.6.18-ubi-fac-V1.2.6"


the inifile contains customisation.ini and recovery.ini. It is retrieved over HTTPS, with certificates from the recovery rootfs (provided by ubiquisys)

only the pcbid is needed, but here is the complete command used (IMEI and PCBID should be replaced):

wget -O customisation+recovery.ini --no-check-certificate --certificate=tls/certs/client.crt --private-key=tls/private/client.key --ca-certificate=tls/certs/server.crt "<IMEI>&pcbid=<PCBID>&flashid=b6f331453e71bdf54617d5de3965d9ac&keyid=638750569B80CB75A8C1B3A222659ABFB5B6BA992A34912EAF33A4A48FCC147&boot=X-V1.2.6&kernel=X-2.6.18-ubi-fac-V1.2.6&ubiqfs=V2.0.17.2"


this explains how to extract the initramfs from kernels:

  • initramfs is gzip compressed. find the magic number. you should have 2 results. use the second
fgrep -a -b -o $'\x1f\x8b\x08' standard-kernel.bin
  • insert the offset to copy the interesting part. don't care about the size, gzip will ignore trailing data
dd if=standard-kernel.bin bs=1 skip=offset of=initramfs.cpio.gz
  • use a directory (the extraction will be in this folder)
mkdir initramfs
mv initramfs.cpio.gz initramfs/
cd initramfs/
  • extract the initramfs
gzip -d initramfs.cpio.gz
  • extract the file system
cpio -i -d --no-absolute-filenames < initramfs.cpio
recovery.txt · Last modified: 2012/03/23 17:06 by femto
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki