FP3 custom rom development based on released source code

i think the trick is to do an adb logdump when you get the update offered - before you install it, and you get the URL/identifier

there is some information useful:
aboot.img: no update ever touched the area between 0x0000 and 0x10a8 - the kernel image probably starts at 0x800
0x3000 start a lot of (true) zeroes - there is nothing there up until
0x8000 starts anothe area that remained untouched by all patches, up to
0x77000 start another batch of true zeroes up to
0x78000 (that means something was there but is no longer) untouched area
0x8714e there are some bytes changed - something must be there

i only see dtb data fragments between
0x192010 and
0x1926d8

that’s an incredibly small range. if that is all, then the boot image holds only a fraction of the dtb’s, maybe only a single one

there might be a ramdisk present but with no changes to it whatsoever between updates

forget that. aboot.img is too small to include a kernel, its only 1.6 MB
so boot.img must be “it” but it has not a single human readable string. unfortunately I cannot apply “unpackbootimg” since I’m missing the headers.

1 Like

The aboot.img is the partition with the fastboot commands. It can also be usefull ^^

2 Likes

if aboot.img is the bootloader, then why is it full of device tree information. it shouldn’t be there, this looks pretty non-standard.
and why does the bootloader say "“dtb not found” when the dtb’s are in fact within the bootloader config partition?
does that mean you have to reflash aboot if you need to change the device tree? that could brick the bootloader, wouldn’t it?

edit:
found this:

http://newandroidbook.com/Articles/aboot.html

critical info to keep in mind:
aboot.img IS the bootloader. The boot sequence is as follows:

  1. ROM bootloader (hardwired into CPU) checks checksum of SBL and executes it if correct (CPU’s can be in debug mode so they won’t check it and you can in fact update it to try a new SBL, but that’s usually a “fuse” register. you can only blow it but not re-enable it. once its blown, it will only load the SBL with the set checksum - point of no return.

  2. SBL (secondary bootloader) loaded from a partition. it includes a cryptographic public key. with it, it checks if the actual “bootloader” in the aboot partition is correctly signed, it reads out the aboot header to see how to load that bootloader

  3. aboot - has a user interface and vendor specific apps. can be updated (which ROM and SBL can NOT) but the update needs to be signed with the same key!

aboot can include any number of “apps” (read - vendor specific extensions that do all sorts of things - including charging the phone and displaying charge state when in bootloader mode, talk fastboot protocol via USB, …, …, … oem specific commands, too - some allow unlocking and/or changes to aboots configuration - this configuration is stored in other partitions, since aboot needs to be signed again if changed)

because of this, seeing .dtb -ish data in the aboot partition is worrysome. this could mean, kernels that do not use the same symbols can not be loaded without a matching (and vendor signed) bootloader!

1 Like

Actually, it misses 2 things : the kernel size and the ramdisk size. But even if we had them, they are gunzip compressed. So they’ll be corrupted.
I had a few guess for the end of the kernel part but it is useless. :frowning:

1 Like

You may find some answers here

https://www.xda-developers.com/how-to-discover-hidden-fastboot-commands/

I hope not ^^

1 Like

list of partitions (block devices) on FP3:

lrwxrwxrwx 1 root root 21 1970-01-07 09:59 DDR -> /dev/block/mmcblk0p17
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 aboot_a -> /dev/block/mmcblk0p21
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 aboot_b -> /dev/block/mmcblk0p22
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 apdp -> /dev/block/mmcblk0p55
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 boot_a -> /dev/block/mmcblk0p27
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 boot_b -> /dev/block/mmcblk0p28
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 cmnlib64_a -> /dev/block/mmcblk0p51
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 cmnlib64_b -> /dev/block/mmcblk0p52
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 cmnlib_a -> /dev/block/mmcblk0p49
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 cmnlib_b -> /dev/block/mmcblk0p50
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 config -> /dev/block/mmcblk0p38
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 devcfg_a -> /dev/block/mmcblk0p11
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 devcfg_b -> /dev/block/mmcblk0p12
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 devinfo -> /dev/block/mmcblk0p29
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dip -> /dev/block/mmcblk0p42
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dpo -> /dev/block/mmcblk0p57
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dsp_a -> /dev/block/mmcblk0p13
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dsp_b -> /dev/block/mmcblk0p14
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dtbo_a -> /dev/block/mmcblk0p23
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 dtbo_b -> /dev/block/mmcblk0p24
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 frp -> /dev/block/mmcblk0p59
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 fsc -> /dev/block/mmcblk0p3
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 fsg -> /dev/block/mmcblk0p18
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 keymaster_a -> /dev/block/mmcblk0p53
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 keymaster_b -> /dev/block/mmcblk0p54
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 keystore -> /dev/block/mmcblk0p36
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 limits -> /dev/block/mmcblk0p40
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 lksecapp_a -> /dev/block/mmcblk0p47
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 lksecapp_b -> /dev/block/mmcblk0p48
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 logdump -> /dev/block/mmcblk0p58
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 mcfg -> /dev/block/mmcblk0p46
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 mdtp_a -> /dev/block/mmcblk0p43
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 mdtp_b -> /dev/block/mmcblk0p44
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 misc -> /dev/block/mmcblk0p35
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 modem_a -> /dev/block/mmcblk0p1
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 modem_b -> /dev/block/mmcblk0p2
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 modemst1 -> /dev/block/mmcblk0p15
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 modemst2 -> /dev/block/mmcblk0p16
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 mota -> /dev/block/mmcblk0p41
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 msadp -> /dev/block/mmcblk0p56
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 oem -> /dev/block/mmcblk0p39
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 persist -> /dev/block/mmcblk0p34
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 prodinfo -> /dev/block/mmcblk0p37
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 product_a -> /dev/block/mmcblk0p60
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 product_b -> /dev/block/mmcblk0p61
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 rpm_a -> /dev/block/mmcblk0p7
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 rpm_b -> /dev/block/mmcblk0p8
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 sbl1_a -> /dev/block/mmcblk0p5
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 sbl1_b -> /dev/block/mmcblk0p6
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 sec -> /dev/block/mmcblk0p19
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 splash -> /dev/block/mmcblk0p20
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 ssd -> /dev/block/mmcblk0p4
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 syscfg -> /dev/block/mmcblk0p45
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 system_a -> /dev/block/mmcblk0p30
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 system_b -> /dev/block/mmcblk0p31
lrwxrwxrwx 1 root root 20 1970-01-07 09:59 tz_a -> /dev/block/mmcblk0p9
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 tz_b -> /dev/block/mmcblk0p10
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 userdata -> /dev/block/mmcblk0p62
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 vbmeta_a -> /dev/block/mmcblk0p25
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 vbmeta_b -> /dev/block/mmcblk0p26
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 vendor_a -> /dev/block/mmcblk0p32
lrwxrwxrwx 1 root root 21 1970-01-07 09:59 vendor_b -> /dev/block/mmcblk0p33

2 Likes

https://android.googlesource.com/kernel/lk/+/qcom-dima-8x74-fixes/app/aboot/aboot.c

if (!dtb_copied) {
	void *dtb;
	dtb = dev_tree_appended((void *)hdr->kernel_addr, kernel_actual,
				(void *)hdr->tags_addr);
	if (!dtb) {
		fastboot_fail("dtb not found");
		return;
	}
}

The bootloader just don’t look in its partitions, and don’t find the dtb its looking for in our boot image. So it gives up ^^

3 Likes

that code is <3 <3 <3

it looks like aboot decides based on the size of “tags” in the boot image if there’s a device tree database, or a “appended device tree”
tags must be 0 for appended device tree.
imgonnabuildabootimagerioghtnowandtestthat

where did you find that? i googled for that exact string and found Nothing at All

2 Likes

Haha! I felt the same.

I looked exact strings aroung “aboot”. inurl:source intext:"dtb not found" did the trick too !

I think it’s the same :
https://source.codeaurora.org/quic/la/kernel/lk/plain/app/aboot/aboot.c?h=master

1 Like

its too bad we don’t get the debug prints.
no matter what the error, if there is no dtb, no dtb database, or simply no matching entry in it, the fastboot error message is always the same.
maybe someone needs to open a phone and probe the debug pins. I bet one of them is a serial UART and those aboot debug prints get printed on it. the code to do exactly that is there!

Edit: from:
https://android.googlesource.com/kernel/lk/+/refs/heads/qcom-dima-8x74-fixes/platform/msm_shared/dev_tree.c

prop = fdt_getprop(dtb, root_offset, "qcom,msm-id", &len);
if (!prop || len <= 0) {
        dprintf(INFO, "qcom,msm-id entry not found\n");
        return false;
} else if (len < (int)sizeof(struct msm_id)) {
        dprintf(INFO, "qcom,msm-id entry size mismatch (%d != %d)\n",
                len, sizeof(struct msm_id));
        return false;
}
msm_id.platform_id = fdt32_to_cpu(((const struct msm_id *)prop)->platform_id);
msm_id.hardware_id = fdt32_to_cpu(((const struct msm_id *)prop)->hardware_id);
msm_id.soc_rev = fdt32_to_cpu(((const struct msm_id *)prop)->soc_rev);

dprintf(INFO, "Found an appended flattened device tree (%s - %d %d 0x%x)\n",
        *model ? model : "unknown",
        msm_id.platform_id, msm_id.hardware_id, msm_id.soc_rev);

if (msm_id.platform_id != board_platform_id() ||
    msm_id.hardware_id != board_hardware_id() ||
    msm_id.soc_rev != board_soc_version()) {
        dprintf(INFO, "Device tree's msm_id doesn't match the board: <%d %d 0x%x> != <%d %d 0x%x>\n",
1 Like

What was your config?

We now have some information about the device, maybe we’ll have to dig the bugreports.

There is no way to have any log of the boot error I guess…

1 Like

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);
	ASSERT(model);
	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:

2 Likes

has someone already tried the non invasive methods using varing debug cables? Serial debugging - postmarketOS

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: Fairphone 3 Teardown - iFixit 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:

3 Likes

https://forum.xda-developers.com/fairphone/general/fairphone-3-internals-t4005103
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.

4 Likes

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 :
https://source.android.com/setup/build/gsi
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)

2 Likes