Unlocking the -1 based CPUs of Acer Cloudmobile S500
- 88F3BDF8 aAndroidBoot DCB "ANDROID-BOOT!",0
- 88F3BE06 DCB 0, 0
- 88F3BE08 var_unlocked DCD 0
- 88F3BE0C var_tampered DCD 0
- 88F3BE10 var_reset_cnt DCD 0
Above is the layout of the partition table start; this is a copy from memory. From what I can see this phone has no real fuses. If you compare the CPU-IDs which is a number stored at offset 0xDC from base 0x80000930 you have:
- 00 79 50 E1 CMP R0, R0,LSL#18 "8260a-3"
- 00 79 10 E1 TST R0, R0,LSL#18 "8260a-1"
Now this might be a coincidence but these numbers also decode as the above ARM instructions so my guess is that the processor might just have 2 versions of masked ROM code and they distinguish between them with the comparrison of an instruction from this ROM (the primary boot).
The "unlocked" variable is a plain flash location. So any method which will write a non-zero value at offset 0x10 from the flash partition table will unlock your phone. The "tampered" variable which only has a meaning in RAM is set when the phone is locked and the kernel doesn't have or doesn't pass the X509 certificate check.
Unlocking is performed by using a loophole which allows any phone to boot from an unsigned kernel via the UART_DM protocol. This phone has a booloader based on lk. (L)ittle (K)ernel based Android bootloader and when you issue the command 'fastboot boot some.img' you are actually sending the image via the USB line (UART_DM) and the bootloader happily runs it but sets the tampered variable. Now if one makes an image and copies just the subroutines from the leaked fw which do the "oem unlock" and makes a "kernel" image out of it (with abootimg utility) then runs it with the fastboot command it will mark the partition as unlocked.
If one wants to trace what the phone is doing at early stages the stock bootloader also accepts the "oem debug on/off' command which will toogle logging messages in the misc partition.
This unlock can only happen at the bootloader stage because by the time you have booted the kernel (or the recovery which is also a kernel) you cannot see the partition table anymore, just the partitions. Here is what I've done. I have mimicked a kernel image but only my little ARM code is executed. I have included the sources so you can see I don't do anything sinister.
The bootloader loads the kernel in RAM at address 0x80208000 and passes execution at that address without erasing itself from memory. I'm searching in the bootloader space the partition table copy, a printf function and a write_aboot function which actually writes the copy to flash. Once I've found all these I simply let the bootloader functions do the work and unlock the phone. There are 2 images included: test-only which only searches for functions and if everything is found it prints the addresses and some messages; the unlock-cloudmobile is the real thing.
I have already tried it on my phone and it seems to work but my phone is already unlocked. So just run first 'fastboot boot test-only.img' - this image doesn't change anything in your phone just prints its status. If all the messages are displayed then you can try the unlock code with 'fastboot boot unlock-cloudmobile.img' You will have to take the battery out after this because I haven't bothered to understand how to read buttons or restart the bootloader so I simply halt the processor once I'm done. The function search is very generic so this should work on all CloudMobile phones regardless of CPU or firmware version.
You do not flash anything on your phone, just execute some code. On windows you need the -i 0x0502 switch so:
fastboot -i 0x0502 boot test-only.img
see if all the functions have an address and it says at the end 'Your phone appears to be ready to be unlocked' then take the battery out get back in fastboot then
fastboot -i 0x0502 boot unlock-cloudmobile.img
and then take the battery out again. At this point your phone should be unlocked. You cannot flash individual partitions on JB. Only the bin container is accepted so you should use the merged_acer_fw utility I've made to construct a .bin from just the partition you want to flash. You need to have the correct parameter_list.txt file and the "official" names for partitions (in this case 'recovery.img')
Here are the strings from the leaked unlocked and recent bootloaders.
I've put together a quick C which lists and splits the firmware binary sources and programs here. The first 16 bytes of the merged file: You take the merged file and replace the first 16 bytes with the "[mgfl_k]:t@ac.tw" string. You then perform a md5sum over the whole file. The 16 bytes sum is then overwritten at offset 0.
How to compile your own Android kernel in linux
First you need an original boot.img file. Extract its components with the 'abootimg' program.
$ abootimg -x boot.img
writing boot image config in bootimg.cfg
extracting kernel in zImage
extracting ramdisk in initrd.img
Search for the first "1F 8B 08" bytes in zImage (that's the signature of a gzip file); make a new file starting from there and gunzip it. This will create your Image kernel (decompressed) In the new file search again "1F 8B 08" and make a new file out of that and gunzip it. This will be your kernel config file.
Alternatively you can do
zcat /proc/config.gz
on your runnig phone to achieve the same result. For convinience I've already edited out the CONFIG_ACER_SECURE_MOUNT define and you can grab the file here
Install your ARM cross-compiler and toolchain from your favorite place and grab the kernel sources opensrc_Acer_AV051_S500_RV04RC09_WW_GEN1-20130322.tar.gz or newer; untargz them. Edit the file ./drivers/gpu/msm/adreno.c and change in function adreno_iommu_setstate the
unsigned int link[250];
to 240 otherwise you'll have a frame overflow error.
Also in scripts/Makefile.lib change this line (if you want)
-cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
+cmd_gzip = (cat $(filter-out FORCE,$^) | 7z a $@ -tgzip -mx=9 -si) || \
because the 7z can also make gzip files but with much better compression.
Finally after you've copied the '.config' in the kernel tree
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- zImage
... and wait. After a while you'll have yout new zImage file.
Now the ramdisk: make a 'work' directory and cd to it.
$ zcat ../initrd.img | cpio -i
edit the default.prop file to 'ro.secure=0' and 'ro.debuggable=1' and then convert back to compressed cpio:
$ find . ! -name "." | cpio -o -H newc | 7z a ../initrd.img -tgzip -mx=9 -si
now 'cd ..' and put everything back together
$ abootimg --create boot.img -k zImage -r initrd.img
look at the new size of your boot.img modify in bootimg.cfg the bootsize value (in hex) to reflect this new size and run again with the -f parameter
$ abootimg --create boot.img -f bootimg.cfg -k zImage -r initrd.img
Done. Here is my compiled version.