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:
- Android Platform Tools: Contains the fastboot tool which will be used to flash the vendor_boot partition. Download this and extract to a directory.
- Google USB Driver: To allow the phone to be detected in the fastboot mode. Since a lot of people have Windows as their OS, this would be useful to them. Simply download the zip, extract the contents, right click on the
android_winusb.inf
file, and select install and follow the prompts to install the driver. - Modified vendor_boot partition and Stock Partitions: This contains the modified vendor_boot partition image that contains the logic to flash the screen firmware in a kernel module. Also contains stock vbmeta and vendor_boot partitions to go back to the stock firmware once the screen firmware has been updated.
2. Flashing Instructions
2.1 Unlock Your Bootloader
Please note that unlocking your bootloader will completely wipe your phone's data.
- Head over to the settings on your phone and open the About section.
- Tap the Build Number 7 times to enable developer settings.
- Head back now to System -> Developer Options and enable the option for OEM Unlocking
- Power down your phone.
- With your phone powered down, hold down the Volume Up button and Power buttons simultaneously until the boot menu shows up.
- Navigate to the fastboot option with your volume up key and then press the volume down button to boot into fastboot mode.
- Connect your phone to your PC.
- 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
- 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.
- 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
- Your bootloader should now be unlocked.
2.2 Flashing the Partitions
- 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)
- 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
- 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!
- 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
- 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?
- Initially on the March firmware, I intercepted the OTA update for April through the logs, which revealed the download link for it.
- I then headed to https://android.github.io/analyseOTA/ to analyse the partitions that were being updated by the incremental OTA update.
- One of the partitions being updated was the vendor_boot partition.
- Using the magiskboot tool, I unpacked the partition using the command
magiskboot unpack vendor_boot.img
. - This revealed the
vendor_ramdisk
folder which contained theramdisk.cpio
file. - Extracted the contents of this file using cpio:
cpio -idmv < ramdisk.cpio
- This revealed all the files in the ramdisk. Inside the
lib/modules
folder, the kernel module for controlling the FPGA chip calledpanel-z10-eink-i2c.ko
existed. This is the module we were looking for. - This module contains the screen firmware itself and the logic for updating the screen firmware through the i2c bus.
- Opened and analysed this module in ghidra
- The analysis revealed 2 functions of interest:
check_need_upgrade
andpango_PGC_I2C_ProgramSelfLoadBitstreamAndVerify_n10k
- Changed the logic for the
check_need_upgrade
function to always update the screen firmware. pango_PGC_I2C_ProgramSelfLoadBitstreamAndVerify_n10k
function revealed that the screen firmware data was stored in the variablecpld_firmware_data
at the address001030c0
with a size of 146104 bytes.- Selected all these bytes and cleared the registers in Ghidra
- 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
- Copied all these bytes and pasted them at the starting address of the firmware.
- 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.
- Recreated the cpio file again using:
find . | cpio -o -H newc > ../ramdisk_new.cpio
- Repack the boot image using:
magiskboot repack vendor_boot.img
- And there you have it. Flashed the modified vendor_boot.img and got the v25 screen firmware!