English

FP3 custom rom development based on released source code

I contacted support, but its still holidays, so no reply yet.
What I wanted to try - without flashing anything yet - was just to override kernel, dtb and kernel commandline for a single boot using a fastboot command.

If you managed to compile the kernel, as above, can you try if you can boot into it at all with something like

fastboot boot arch/arm64/boot/Image.gz --dtb arch/arm64/boot/dts/qcom/sdm632-ext-codec-mtp-s4.dtb

note, NO flash command, it’d be a smart idea not to flash anything to the phone’s partitions before testing it in one-shot mode

this should - if it works - boot the phone up into the default android system, but using the self compiled kernel.

if that works, as a next step I’d try

fastboot boot arch/arm64/boot/Image.gz --dtb arch/arm64/boot/dts/qcom/sdm632-ext-codec-mtp-s4.dtb --cmdline “init=/bin/sh”
to try to just run a shell instead of android.

this likely will result in a blank screen (but if you’re really lucky, the kernel has a working framebuffer console. then you could connect a keyboard via a USB-C OTG cable and browse the file-system)

if there was no framebuffer console, maybe the kernel can be recompiled with one enabled, (make menuconfig) but its possible additional cmdline options need to be supplied to setup the screen correctly

once you have a shell, the next step would be to compile a ramdisk image with busybox or similar and an ssh server, wifi support (wpa-supplicant) etc, to have a working linux to play.

from there its a very small step to a working ubuntu image or similar.

3 Likes

ok, the --dtb commandline option doesn’t work, fastboot complains about the option not being valid for “version 0” boot images… - back to square 1 :wink:
the fact the sourcecode had to be patched to allow compiling dtb’s the phone isn’t using suggests that for the real thing, only the correct dtb gets compiled, so I still think only one dtb is to be included in the image. I’ll play around with that a bit.

big shoutout to @_tmp for supplying the script to generate the bootloader unlock code in Oem unlock "input verify code" :smiley:

5 Likes

I remembered now another thing so your extra warning patch isn’t needed (I’m guessing gcc-wrapper.py complained about disallowed warnings):

make -j9 CC=aarch64-linux-gnu-gcc

If you look into the Makefile you can see CC being set to CC = $(srctree)/scripts/gcc-wrapper.py $(REAL_CC) but you can override that by giving make the real gcc directly through make. I’ll adjust my post from before for that

3 Likes

I couldn’t get past the “dtb” not found. I am wondering if this could help:


apparently there is a particular boot image layout used by some bootloaders on qualcomm chipset devices using a separate header describing the dtb’s available and the supported chipsets.
i found that by following links from here:

1 Like

that “dtbtool” can be compiled simply with “gcc dtbtool.c -o dtbtool”
it can be run succesfully with
export PATH=$PATH:[path-to-kernel]/scripts/dtc
./dtbtool -o dtbtreeimage [path-to-kernel]/arch/arm64/boot/dts/

if dtc is not in the PATH, it will fail to parse the dtb’s and extract the relevant qualcomm chip ids.

now I have the dtb table, but I don’t have a complete boot image yet (nor a way to load it without flashing, does anyone know if a boot image instead of just a kernel is even an option with fastboot? the forum entries suggest fastboot boot might work too)

1 Like

To compile the kernel, I had to disable some warnings.

diff --git a/Makefile b/Makefile
index a12cc2722114..777d421cfdc3 100644
--- a/Makefile
+++ b/Makefile
@@ -654,6 +654,20 @@ KBUILD_CFLAGS      += $(call cc-disable-warning,frame-address,)
 KBUILD_CFLAGS  += $(call cc-disable-warning, format-truncation)
 KBUILD_CFLAGS  += $(call cc-disable-warning, format-overflow)
 KBUILD_CFLAGS  += $(call cc-disable-warning, int-in-bool-context)
+KBUILD_CFLAGS   += $(call cc-disable-warning, attribute-alias)
+KBUILD_CFLAGS   += $(call cc-disable-warning, sizeof-pointer-memaccess)
+KBUILD_CFLAGS   += $(call cc-disable-warning, stringop-truncation)
+KBUILD_CFLAGS   += $(call cc-disable-warning, stringop-overflow)
+KBUILD_CFLAGS   += $(call cc-disable-warning, array-bounds)
+KBUILD_CFLAGS   += $(call cc-disable-warning, address-of-packed-member)
+KBUILD_CFLAGS   += $(call cc-disable-warning, packed-not-aligned)
+KBUILD_CFLAGS   += $(call cc-disable-warning, missing-attributes)
+KBUILD_CFLAGS   += $(call cc-disable-warning, misleading-indentation)
+KBUILD_CFLAGS   += $(call cc-disable-warning, bool-operation)
+KBUILD_CFLAGS   += $(call cc-disable-warning, bool-compare)
+KBUILD_CFLAGS   += $(call cc-disable-warning, maybe-uninitialized)
+KBUILD_CFLAGS   += $(call cc-disable-warning, parentheses)
+KBUILD_CFLAGS   += $(call cc-disable-warning, memset-elt-size)

It seems we can change the boot image header version created with mkbootimg
(https://source.android.com/devices/bootloader/recovery-image - and another interesting link: https://source.android.com/devices/bootloader/boot-image-header).

Note : I have bricked my phone trying to deal with the treble function (I have only access to bootloader). I can help to test things if needed. I hope I’ll have some images soon ^^.
Strangely, my boot image header version changed (without touching it) :

Argument dtb not supported for boot image header version 0

2 Likes

as far as i understand it, that “boot image header” is the header of the “bootimage” that the fastboot executable compiles on the fly when you use the “fastboot boot” command in this way.

(fastboot runs mkbootimg internally and compiles a header and a boot image from kernel, ramdisk, dtd and commandline, then sends the entire image to the phones bootloader which takes it apart again)

you can tell it to create a header version 2 with

fastboot boot --header-version 2

but I have’t been able to get around the dtb error that way either

1 Like

Actually, it was an answer to this error :

2 Likes

fastboot can do both, it can “create” a boot-image on the fly from specified kernel, ramdisk, dtd (if using header-version>=2) and commandline in this case output will look like this:

fastboot boot arch/arm64/boot/Image.gz --dtb dtimage --header-version 2

creating boot image…
creating boot image - 27367424 bytes
Sending ‘boot.img’ (26726 KB) OKAY [ 0.835s]
Booting FAILED (remote: ‘dtb not found’)
fastboot: error: Command failed

or one can create one’s own boot image using mkbootimage

mkbootimg --kernel ~/src/android_kernel_fairphone_sdm632/arch/arm64/boot/Image.gz --dt ~/src/android_kernel_fairphone_sdm632/dtimage -o boot.img
fastboot boot boot.img

Sending ‘boot.img’ (26726 KB) OKAY [ 0.878s]
Booting FAILED (remote: ‘dtb not found’)
fastboot: error: Command failed

I tried that both using individual dtb’s and compiled dtb’s using dtbtool, both with v2 and v3 dtb image version (I assume v1 is a flat single dtb) I also tried a flat concatenation of all dtb’s like the kernel make file creates.
So far I haven’t gotten past “dtb not found” – but if we had a working boot or recovery image from Fairphone (or offloaded from a phone somehow) we could analyze that to at least figure out which format the bootloader expects - and then figure out which dtb version we need

1 Like

lacking any working images for FP3, I looked at the TWRP image for FP2.
This boot image uses a combined dtb image using dtbtool in version 2
trying to boot from it kinda unsurprisingly results in a “dtb not found” error
@z3ntu , where did you get the parameters for fp3 as in:
--base 0x80000000 --second_offset 0x00f00000 --kernel_offset 0x00008000 --ramdisk_offset 0x01000000 --tags_offset 0x00000100 --pagesize 2048

the TWRP fp2 image uses different offsets. I have no clue how important/critical those are.

1 Like

You should rather compare images for other sdm632 devices (asus X01AD, motorola river, etc) than FP2 images

1 Like

These are the addresses on moto G7 (same chipset)

2 Likes

interestingly the twrp image for the moto G7 has the device tree concatenated old school to the kernel image (using a single device tree file) but this might be depending on the bootloader used
the descriptor info says:

model = "Qualcomm Technologies, Inc. SDM632 + PMI632 MTP S3";
compatible = "qcom,sdm632-mtp", "qcom,sdm632", "qcom,mtp";
qcom,msm-id = <0x15d 0x0>;
qcom,msm-name = "SDM632";
interrupt-parent = <0x1>;
qcom,board-id = <0x8 0x3>;
qcom,pmic-id = <0x10016 0x25 0x0 0x0>;
channel-id-map = [00];

that matches the entries in fairphones sdm632-mtp-s3.dtb

however trying to load that (twrp) image results in (you guessed it) “‘dtb not found’”

1 Like

just for fun I looked at (the TWRP image for) that one as well. It uses the same addresses as the motorola g7, but it has a whole bunch of dtb’s concatenated to the kernel image in binary, for a whole lot of chipsets (including the SDM632 with msm-id 0x15d and pmic-id = <0x10016 0x25 0x0 0x0> but without specifying and board-id)

so now we do indeed have all 3 variants seen in the wild :wink:

Edit: and of course: “dtb not found” :wink:

1 Like

I had a closer look at
https://source.android.com/devices/architecture/dto/multiple
and
https://source.android.com/devices/architecture/dto/partitions

its possible that fastboot ignores the device tree information in the boot image and instead looks for the images in the dtbo partition

fastboot getvar all

lists among others:

(bootloader) has-slot:dtbo: Yes
(bootloader) partition-type:dtbo_b:raw
(bootloader) partition-size:dtbo_b: 0x800000
(bootloader) partition-type:dtbo_a:raw
(bootloader) partition-size:dtbo_a: 0x800000

this could be a problem. Although the installed device trees would always fit the hardware, they might not fit the built kernel

the sources we have are for linux 4.9.112

but with the latest updates on the phone (2019-12-17) the stock android image is running linux 4.9.119 - incorrect - still on 4.9.112, must have been my eyes!

how hard is it to upgrade the kernel (assuming/hoping none of the fairphone specific patches got changed) ?

1 Like

I’m still on 4.9.112 for 2019-12-17…?

Linux localhost 4.9.112-perf+ #2 SMP PREEMPT Tue Dec 17 14:35:21 CST 2019 aarch64

But anyways, I don’t think the dtb has changed and it would definitely be “compatible”. And I think dtb != dtbo but that might be completely wrong, I don’t know what the dtbo partition is really used for.

1 Like

my bad, I could have sworn I saw a larger number. I just verified that, it is 4.9.112 on mine, too

this gets more and more annoying.

https://source.android.com/devices/architecture/dto/compile.html#verifying-DTO-in-p

Apparently Android9 bootloaders must use a device tree overlay partition and overlay the contents to the regular device tree.

the rules are pretty elaborate. It’s thinkable that - even though we are supplying a correct and valid device tree with the kernel, the existing overlay in the overlay partition doesn’t find a symbol it wants and as such invalidates the dtb in question - leading to the error.

@z3ntu
in a nutshell the overlay modifies a device tree. So qcom could provide a standard device tree for their SOC - and then Fairphone could put all their stuff in the overlays - enabling or disabling features as needed or changing some wiring. its basically an “override” - all described here: https://source.android.com/devices/architecture/dto/compile.html#verifying-DTO-in-p

now the thing is, as we saw fairphone patched all their changes into the original dts files, so I don’t know what exactly is going on here. Is everything in the overlays and the dtb is effectively unused? or are the overlays empty and everything is in the dtb? or is it some weird mix.

another thing is, when flashing an image into boot slot a or b, the bootloader would use the respective a or b overlay partition. but I have no clue what happens when you make a “try-run” with
fastboot boot
would it load no overlays? or the one from a? or from b? or is that simply no longer supported and simply always fails?

from the android docu:>

Figure 5. Typical runtime implementation for device tree overlay in bootloader.

  1. Load .dtb from storage into memory.
  2. Load .dtbo from storage into memory.
  3. Overlay .dtb with .dtbo to be a merged DT.
  4. Start kernel given the memory address of the merged DT.

so the bootloader does all this magic crap, and its up to the vendor how its implemented exactly.

edit: more interesting bg reading. apparently recovery images are not supposed to rely on the dtbo partition but include dtb and dtbo in the boot image (to prevent bricking if the device crashes after dtbo got written but before the image got updated)

edit: related kernel config flag:
CONFIG_BUILD_ARM64_DT_OVERLAY
if enabled, it adds a parameter to dtc adding a symbol needed for overlays to work. I’m trying if that helps

3 Likes

When you do a “fastboot boot” the image is loaded in memory then it boots on it. It’s not written anywhere (nor boot_a, nor boot_b, that’s done with “fastboot flash”)
It seems possible to flash only the kernel (https://source.android.com/devices/bootloader/partitions-images), but I don’t know if it uses the ramdisk and cmdline from the partition when we do a “fastboot boot Image.gz”

@corvuscorax : for the moto g7 play, it seems they had to deal with the dtbo partition.
(https://forum.xda-developers.com/g7-play/development/recovery-moto-g7-play-kernel-source-code-t3933680 , I didn’t look further)

1 Like

good links. some scary things there regarding the qcom bootloader. we’re going to have to be careful to not brick our phones :wink:

what I meant is:
with a regular boot sequence from slot A, the bootloader

  1. loads the boot image from boot partition A
  2. extracts the kernel, ramdisk, and dtb from that boot image (basically reads it all into RAM and reads the header where what sits)
  3. reads the dtbo from the dtbo partition A
  4. patches the dtb in memory to apply the changes to dtb described in the overlay
  5. extracts the kernel and starts it - feeding it the address of ramdisk and the (now patched) device tree inc. overlay.

now if you say "boot <myimage.img>

  1. fastboot will push a boot image to the phone into RAM
  2. bootloader reads out header for addresses of image, ramdisk, dtb
  3. <<< this is the question - does the bootloader read out a dtbo? if so which one? dtbo A, dtbo B, whichever is the current one?
  4. bootloader might or might not try to patch the bootimg supplied dtb device tree with whatever overlay info it got from the partition or not
  5. bootloader aborts with “error: no dtb found”
  6. instead of starting the kernel as in step 5 above :wink:
3 Likes

Too late :grin: (waiting for stock rom or a rooted phone)

If the bootloader read the dtbo partition, it is on the active slot (pretty sure, from the test I did, which bricked my phone…). You can know which one is active with “getvar all”, or change it with “–set-active=b”

Maybe we should contact one of the devs who’ve ported twrp to moto g7

2 Likes