FP3 custom rom development based on released source code

well for starters, that aprticular aboot expects a msm-id with 3 entries, while all the ones that come with fairphone kernel only have 2 (which would cause that bootloader to bail

but I looked at the other branches of that same repo, and the aboots differ drastically, even though they are only for a different qualcomm chip series.

so there is no guarantee (quite the contrary, its unlikely) that because the qcom-dima-8x74 aboot does it like this, that ours would do it the same.
btw fastboot getvar all reports:
(bootloader) hw-chip:SDM632
(bootloader) hw-revision:10000

Edit: just found a counter example - another aboot for another qualcomm chip, in this case for the Lumia smartphone with qualcomm msm8227 CPU:

    prop = fdt_getprop(dtb, root_offset, "model", &len);
if (prop && len > 0) {
	model = (char *) malloc(sizeof(char) * len);
	strlcpy(model, prop, len);
} else {
	dprintf(INFO, "model does not exist in device tree\n");
/* Find the pmic-id prop from DTB , if pmic-id is present then
* the DTB is version 3, otherwise find the board-id prop from DTB ,
* if board-id is present then the DTB is version 2 */
pmic_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,pmic-id", &len_pmic_id);
board_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,board-id", &len_board_id);
if (pmic_prop && (len_pmic_id > 0) && board_prop && (len_board_id > 0)) {

the sdm400 and 600 series will likely have yet another bootloader version. It’s really hard to fix this without knowing what our bootloader is looking for and having no debug output :frowning:


has someone already tried the non invasive methods using varing debug cables? https://wiki.postmarketos.org/wiki/Serial_debugging

i might be able to get my hands on a nexus headphone jack debug cable and a suzy-q cable

edit 1: also when you say debug pins have you something paticular in bind or do you just mean that there might be debug pins?

btw for reference ifixit has high-enough res pfotos of the mainboard (but with stuff drawn over it damnit) https://d3nevzfk7ii3be.cloudfront.net/igi/n6YBHoWVNpR6taKK.huge

edit 2: scrolled to fast: there is a picture of the backsite of the mainboard which has some dots that could be debug pins: https://d3nevzfk7ii3be.cloudfront.net/igi/RXVqfOKYw1byuPMu.huge

edit 3: for reference: https://www.ifixit.com/Teardown/Fairphone+3+Teardown/125573 there are some more pictures of the pcb

1 Like

your guess is as good as mine. I marked some pins that are potential candidate, but there are many more. Before connecting anything to them I’d suggest probing them with an oscilloscope during early device boot to see of they show any signal. In my last job we had a lab where I could have easily done so, but right now I’m a bit hardware limited :wink:

I didn’t even think about UART on the headphone jack, I didn’t realise that was a thing. It’s definitely worth finding out.

We DO definitely know there IS a debug UART, because the kernel command line puts a debug console on one :slight_smile:

console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0

So you’d see a 115.2 kHz binary signal on the TX pin during boot.

I would assume it’s likely a 1.8 volt signal, that’s what most modern chips use, but better verify that with a high resistance probe (oscilloscope) before connecting anything and worst case frying the board :slight_smile:

This would be a perfect experiment for one of the gentlemen that already bricked heir phones and cannot boot a kernel anymore :slight_smile:

But if anyone has a cable to test for debugging on the headphone jack, that needs to be tested. How can we find out if the FP3 has that? Ask support? :wink:


The author :

Judging by location, it’s maybe rather R, S, T that exposes an UART?

Edit: I can do some tests if I exactly know what to do. But it won’t help for the dtb not found, my boot breaks before.

1 Like

Breaks before? You can’t even get into fastboot? How did you manage that?

The first step would be to recreate k65onyx test setup - so FP3 opened on a bench, without the back-case, but still as many modules connected as possible (possibly even the screen). Then connect USB (this will get it into fastboot for charging, even if you can’t press the power button). As the pads are now exposed, you can “probe” them with the probe input of an oscilloscope to measure not just the steady voltage but visualize the signal. The UART should be very distinct with its rectangular bit-stream at 115200 Hz. Knowing which pin is the UART (if there is one) would be a great help.
Same possibly with the headphone jack. As a first step I’d just connect a split headphone cable and probe it with the oscilloscope during boot, see if there’s anything there.

I have to admit I don’t really know how a headphone-jack debugging signal looks like and how it might need to be decoded … ?

1 Like

Probing the pads on the mainboard with an oszilloscope during bootup, especially the 1.8V (1.78V) ones and the ones right next to them.
if you get something like this: http://micsig.eu/media/wysiwyg/Micsig_Handheld_oscilloscope_UART_graphic_interface.jpg between 0 and 1,8V it’s propably a uart signal.


No, it breaks before the dtb not found. But I have an access to the bootloader

1 Like

but when you say “fastboot boot <boot.img>” it should ignore what stuff is on the phone and just try to boot it - unless your bootloader thinks its locked or is actually broken.

I found this as a circuit plan for headphone debugging. It’s for a Nexus4, but that’s also msm based. I have no idea if that’s compatible.

Edit: reading more about that, it looks like there needs to be support from the sound circuitry, and the Nexus4 definitely has a different audio solution than FP3, so we have no indication yet if that would work or not

1 Like

The device ignores the boot partition with fastboot boot img, but I’ve changed the vbmeta and system (not boot). The verification chain is probably broken. So I have to wait for a dump of these two partitions.

Why I did that? The device is treble compatible, so :
I think, once we have the original vbmeta, flashing it with the option --disable-verity and/or --disable-verification should be enough to port a gsi (and have a custom ROM or AOSP without gapps)


Weird, after reading
It seems to me that if the bootloader is unlocked, a corrupted or non-matching vbmeta shouldn’t matter as it is supposed to be ignored.

is there any error indication in fastboot? what does it say?

Is there a possibility that your device actually boots further than anyone elses by loading the kernel and only failing because it can’t find the root / /system partition?

1 Like

Some news, since I flashed the vbmeta 1.0, I have a longer boot. Someone as a boot.img to try? (The tests won’t have too many parameters)

1 Like

The sites lists several occurences for hidden serial pins in other ports. The headphone jack is only one of them.
Problem is they all are vendor specific hacks and need some kind of activation, for example sending +3.3V to the right speaker out in case of the nexus headphonejack circutry.
I’m a little afraid to damage my phone tbh xD.
If you want to build that nexus 4 adapter, check if your usb to uart adapter can read 1.8V, because all that cirutry does is to limit the voltage comming from the usb to uart adapter but does not upscale the voltage coming from the phone. Some 3.3V usb to uart have there cutof for low voltage beneath 1.8V they should work, but a lot of them have the cutofvoltage around 1.8V or even 2V, so you wont get output or random garbage.


Quickly reading over suzy-q cable https://wiki.postmarketos.org/wiki/Serial_debugging#Suzy-Q_debug_cable and android debug cable https://wiki.postmarketos.org/wiki/Serial_debugging#Android_Debug_Cable and the usb type-c plug https://www.allaboutcircuits.com/technical-articles/introduction-to-usb-type-c-which-pins-power-delivery-data-transfer/

the interesting pins are cc1, cc2, sbu1 and sbu2
sbu1 and sbu2 are not used in normal operation mode on the usb type-c plug
what google did for the pixel phones was to use these two pins as uart.
For the pixel 1 you had to put specific resistors on cc1 and cc2 to switch them on, on pixel 2 and pixel 3 they seem to be just permanently active.

since the fp3 has a usb type-c port i think it’s most likly that if tx and rx are accessible from the outside they are be accessible over the usb type-c port (short explanation behind this educated guess: somewhere i read the reason the nexus phones used the headphone jack in the first place instead of the usb port was that the micro usb port has only 5 pins and 4 of them are mandatory for adb, so for uart and adb debuging over micro usb you had to permanently switch cables. When the uart is in the headphone jack you can have uart output and an adb shell in parrallel. with the 2 unused pins on the usb type-c connector this isn’t a problem anymore)

Has someone a usb type-c breakout board at hand and can probe these two pins on bootup?
If that doesn’t help, next thing to try would be to put the resistory on cc1 and cc2 like with the suzy-q cable and then test again (the suzy-q cable is nothing more than a usb 2.0 hub + usb-to-uart + these 2 resistors in a small form factor, enabeling uart and adb with just one cable instead of 2 + a breakoutboard + a usb-to-uart adapter)

edit: all this is just wild speculation i haven’t tested anything yet


Another direction. We so far tried - with no luck - to get data out of incremental updates pushed to Fairphones.

The red flag in our faces should be update 39ce8 which coexists with update d1e8 to both get the version to A0096 but from different source versions.

Either of those got offered to users based on their existing system version. So the update process tries to find a matching version. I did some googling, and there are suggestions in other forums (unfortunately without further info) that this process is standardised and automatically selects a FULL UPDATE if no incremental patch is available for the combination. So its entirely possible that someone who never updated their fairphone might eventually get offered a full update.

But that takes too long. Can’t we just re-create this “check update handshake” and request a matching update from A.0000 to A.0105? and get offered free cake in form of a full update?

Which app does the checking? If its the “Settings” app, its part of AOSP:



When you earlier wrote

I already suspected that this could not be the case and that there should be some mechanism to check integrity, or at least current version, before patching, and maybe fail or maybe offer the full image in case the version was not compatible.

I have a brand new FP3, still on the box. I tried switching it on to check it works, but did not make any update. If you fail to recreate the “check update handshake”, I can by tomorrow check the version of my phone and try to get the full update. You must however explain me how to get a link to the update, or the whole update from the phone. I am an experienced Linux user, but I am not familiar at all with smartphone hacking (always had a feature phone till now).

  1. the first thing you should do is enable developer mode on the phone
  2. In Settings -> System -> Advanced -> Developer Options, Turn off “automatic system updates”
  3. In Settings -> System -> Advanced -> Developer Options, Turn on “USB debugging”
  4. Only then enable wifi or cellphone internet
  5. Connect USB on a computer with adb installed and run “adb logcat” - tee that into a file so you don’t miss anything
  6. Manually check for available updates in Settings -> System -> Advanced -> System Update - the URL should show up in logcat if there is any.

it’s possible that you need to let the phone start downloading the update - then interrupt the download (for example by turning wifi off)

see https://www.droidviews.com/ota-update-file-download-link-android/ for info


Perfect, I try this evening when I’m back home and let you know. The possibility exists that the current version on my phone is one for which a diff update is available, in which case it would probably not help much. So going on with hacking the update handshake is probably a good idea anyhow :wink:.


@_tmp your skills could come in helpful. After a bit of searching, I found out that it is indeed the “google play services” that check for availability of updates - it looks like not just the updates themselves are delivered through google, but the process for checking update availability for a phone is also handled by google API and cloud on server side, and the com.google.android.gms app (Google Service Framework) on the client side.
The particular function is called the “Checkin Service” which periodically or when forced to do so through settings menu or through a particular “hack” using the “com.google.android.dialer” app (entering *#*#checkin#*# in the dial pad (no need to confirm that, it responds immediately to the last digit typed)

I think it sends the phones info to https://android.clients.google.com/checkin but what happens beyond that is beyond my expertise. Can we reverse engineer that to request an update URL?

Edit: In googling for info, I came across this automated malware analysis report. Someone uploaded the google service framework apk to an automated malware analysis site - the analysis is both accurate, and amusing :wink:
spolier: it’s classified as spyware :wink:


You can try to set a system proxy to burp (add the burp certificate to the roots cetificates of the phone) to analyse the requests but the certificates are probably pinned to the app.

Try any https website to check the proxy before.

edit :
It seems possible https://habr.com/en/post/446790/

If we re able to install the update app as user.
bypass certif pinning : https://blog.netspi.com/four-ways-bypass-android-ssl-verification-certificate-pinning/


That is one awesome report. A shame he didn’t get the google job, but well… Interview phone calls suck, they always get you on the wrong foot.

I have to say, this doesn’t look promising, if Google put up so much obfuscation in the way of the check-in, too, then to effectively fake the firmware version (short of spending a week or two coding custom bytecode interpreters in Java) you’d need to root the phone and make whatever app is querying it see a different version.

Intercepting doesn’t seem possible, as Android9 certainly DOES use certificate pinning.

Btw, right now when I check for upgrades, the upgrade check fails with an error/timeout! (the phone is currently unlocked, but not flagged as tampered) Although it could be my firewall being responsible, i haven’t turned it off yet.