♞ Vasu's Journal

Flashing the v25 Screen Firmware on the Minimal Phone MP01

Please note that flashing your phone is a risky affair. Do this at your own risk

0. Introduction and Motivation

The April update for the minimal phone introduced the v36 screen firmware version- which many reported to slow down the screen considerably- even on the fastest refresh rate.

Notably, another older screen firmware version v25 also exists, which has a much quicker refresh rate.

I'll start by providing you with the guide on how to get the v25 screen firmware on your phone, and then the technical details on how this was achieved to those interested.

1. Pre-Requisites

Important Links:

2. Flashing Instructions

2.1 Unlock Your Bootloader

Please note that unlocking your bootloader will completely wipe your phone's data.

  1. Head over to the settings on your phone and open the About section.
  2. Tap the Build Number 7 times to enable developer settings.
  3. Head back now to System -> Developer Options and enable the option for OEM Unlocking
  4. Power down your phone.
  5. With your phone powered down, hold down the Volume Up button and Power buttons simultaneously until the boot menu shows up.
  6. Navigate to the fastboot option with your volume up key and then press the volume down button to boot into fastboot mode.
  7. Connect your phone to your PC.
  8. Open a terminal window and navigate to the directory where you extracted the Android Platform Tools using the command: cd <path_to_platform_tools_in_double_quotes
  9. Type in ./fastboot devices and your device should show up. For Windows: If the device does not show up:
    • Head over to Device Manager, there might be a device with an exclamation mark there.
    • Right click it and click on update driver, click on chose a driver from this PC or whatever it's called
    • Select All Devices, head to Google Inc. and choose Android Bootloader Interface as the driver.
    • Click past all the necessary prompts bla bla and re-run the previous command. Your device should now be detected.
  10. Type in these commands to erase your phone and unlock the bootloader:
fastboot flashing unlock # Press volume up key on phone to confirm this
fastboot flashing unlock_critical # Press volume up key on phone to confirm
fastboot -w
  1. Your bootloader should now be unlocked.

2.2 Flashing the Partitions

  1. With the bootloader now unlocked, download all the files shared on the Google drive and paste them in the same folder as your platform-tools folder (Just so that running the commands is a bit easier)
  2. With that done, in the same terminal windows, execute the following commands in order:
fastboot flash vbmeta_a --disable-verity --disable-verification vbmeta_a.bin
fastboot flash vbmeta_b --disable-verity --disable-verification vbmeta_b.bin
fastboot flash vbmeta_system_a --disable-verity --disable-verification vbmeta_system_a.bin
fastboot flash vbmeta_system_b --disable-verity --disable-verification vbmeta_system_b.bin
fastboot flash vbmeta_vendor_a --disable-verity --disable-verification vbmeta_vendor_a.bin
fastboot flash vbmeta_vendor_b --disable-verity --disable-verification vbmeta_vendor_b.bin
fastboot flash vendor_boot_a new-boot.img
fastboot flash vendor_boot_b new-boot.img
fastboot -w
fastboot reboot
  1. Your phone will now reboot and go through the setup, etc. and head over to Settings -> About and check that your screen firmware. It should be v25 now. Try changing your refresh rate to the quick one and verify that your screen is hella faster now!

2.3 Re-locking the Bootloader (Optional)

Note: Re-locking the bootloader will not upgrade/downgrade the screen firmware. You can safely flash the stock partitions and still enjoy the v25 firmware!

  1. Boot your phone into fastboot mode once again, and with your terminal window, execute the following commands:
fastboot -w
fastboot flash vbmeta_a vbmeta_a.bin
fastboot flash vbmeta_b vbmeta_b.bin
fastboot flash vbmeta_system_a vbmeta_system_a.bin
fastboot flash vbmeta_system_b vbmeta_system_b.bin
fastboot flash vbmeta_vendor_a vbmeta_vendor_a.bin
fastboot flash vbmeta_vendor_b vbmeta_vendor_b.bin
fastboot flash vendor_boot_a vendor_boot_a.bin
fastboot flash vendor_boot_b vendor_boot_b.bin
fastboot flashing lock # Confirm on screen with volume up button
fastboot flashing lock_critical # Confirm on screen with volume up button
fastboot reboot
  1. You should now be back to stock with your bootloader locked. Head over to settings and verify that you still have the v25 screen firmware.

3. How This Was Achieved?

  1. Initially on the March firmware, I intercepted the OTA update for April through the logs, which revealed the download link for it.
  2. I then headed to https://android.github.io/analyseOTA/ to analyse the partitions that were being updated by the incremental OTA update.
  3. One of the partitions being updated was the vendor_boot partition.
  4. Using the magiskboot tool, I unpacked the partition using the command magiskboot unpack vendor_boot.img.
  5. This revealed the vendor_ramdisk folder which contained the ramdisk.cpio file.
  6. Extracted the contents of this file using cpio: cpio -idmv < ramdisk.cpio
  7. This revealed all the files in the ramdisk. Inside the lib/modules folder, the kernel module for controlling the FPGA chip called panel-z10-eink-i2c.ko existed. This is the module we were looking for.
  8. This module contains the screen firmware itself and the logic for updating the screen firmware through the i2c bus.
  9. Opened and analysed this module in ghidra
  10. The analysis revealed 2 functions of interest: check_need_upgrade and pango_PGC_I2C_ProgramSelfLoadBitstreamAndVerify_n10k
  11. Changed the logic for the check_need_upgrade function to always update the screen firmware.
  12. pango_PGC_I2C_ProgramSelfLoadBitstreamAndVerify_n10k function revealed that the screen firmware data was stored in the variable cpld_firmware_data at the address 001030c0 with a size of 146104 bytes.
  13. Selected all these bytes and cleared the registers in Ghidra
  14. Took the v25 firmware shared by the Minimal Company's lead developer Jonathan, padded it to 146104 bytes and converted it into hex bytes with the following code:
cp firmware.bin firmware_padded.bin
truncate -s 146104 firmware_padded.bin
xxd -p firmware_padded.bin | tr -d '\n' | sed 's/../& /g' > firmware.hex.txt
  1. Copied all these bytes and pasted them at the starting address of the firmware.
  2. Saved all the changes in Ghidra and exported as the original file format and replaced the original kernel module in the ramdisk contents with this modified module.
  3. Recreated the cpio file again using: find . | cpio -o -H newc > ../ramdisk_new.cpio
  4. Repack the boot image using: magiskboot repack vendor_boot.img
  5. And there you have it. Flashed the modified vendor_boot.img and got the v25 screen firmware!