Skip to content

Porting MultiROM

Luca Weiss edited this page Sep 19, 2016 · 11 revisions

Notes

MultiROM is not as flexible as TWRP by far. It has only been ported to Nexus or close-to-nexus devices, so here's (rough) list of the limitations:

  • It only supports devices with storage in /data/media/. Physical SD cards are not supported because of how slow and generally awful they are, but some devices have "fake" /sdcard on separate partition, which is not supported as of yet.
  • MultiROM currently only handles devices which don't mount /data, /system or /cache in *.rc files but use fstab instead. This can be workaround by using a hook callback during the boot preparation steps in MultiROM, more on that later.
  • MultiROM is currently tested only on devices which use ext4 for their partitions. It is very likely that the code will require modifications to support other types of filesystems.
  • Framebuffer code is not as flexible as TWRP's, though it support some of its flags.
  • Touchscreen input code might not support your touchscreen, as OEMs like to use non-standard protocols. This can be easily fixed by writing your own handler, see input_type_a.c and input_type_b.c as examples.

To wrap it up, it is very likely you're gonna need at least some idea about programming in C to port MultiROM.

Prerequisites

Downloading sources

Just clone TWRP, MultiROM and libbootimg repos into your Android Tree, the commands would look something like this:

rm -r bootable/recovery  
git clone https://github.com/Tasssadar/Team-Win-Recovery-Project.git bootable/recovery  
git clone https://github.com/Tasssadar/multirom.git system/extras/multirom  
git clone https://github.com/Tasssadar/libbootimg.git system/extras/libbootimg
cd system/extras/multirom
git submodule update --init

Setting-up the device folder

This is assuming you have device folder already set-up for building TWRP. If not, go do that, guides are elsewhere.
Now, you'll be adding options to BoardConfig.mk and also adding some files into the device folder. Let's look at how MultiROM options look in mako's BoardConfig.mk and then describe them individualy:

#MultiROM config. MultiROM also uses parts of TWRP config
MR_INPUT_TYPE := type_b
MR_INIT_DEVICES := device/lge/mako/mr_init_devices.c
MR_RD_ADDR := 0x82500000
MR_DPI := hdpi
MR_DPI_FONT := 216
MR_FSTAB := device/lge/mako/twrp.fstab
MR_KEXEC_MEM_MIN := 0x85000000
MR_INFOS := device/lge/mako/mrom_infos

MR_INPUT_TYPE

Specifies what input handler to use - the handler used will be ..multirom/input_$(MR_INPUT_TYPE).c Touchscreen input events can come in different formats, MultiROM currently only supports types A and B from the kernel documentation. You can find out which type is your device using with evtest, or just by trying both and using the one which works.

MR_INIT_DEVICES

Specifies path to .c file containing string array with paths to uevents which are needed to initialize MultiROM. While normal uevent daemon initializes every uevent file in /sys, MultiROM does not need that and some devices don't like being initialized twice (once by MultiROM and once by ROM's init). Here's how the file should look like:

#include <stdlib.h>

const char *mr_init_devices[] =
{
    "/sys/path/to/folder/with/uevent/without/last/slash",
    "/sys/you/can/use/star/to/add/path/recursively*",
    ...
    NULL // must be NULL-terminated
}

MultiROM needs to initialize MMC blocks, framebuffer, inputs and some things for ADB. Take a look at mako's mr_init_devices.c for inspiration. find /sys | grep uevent | grep *the_thingIwantToInit* is your friend.

MR_RD_ADDR

This option might not be needed for your device. It sets address in boot.img to unpack ramdisk into, and most devices can handle MultiROM changes even without this option. But, some devices (Nexus 7 and Nexus 4) will panic on boot when the ramdisk is bigger than expected. As to what value to set, well, it's more about guessing than anything else. Look at default ramdisk address in your boot.img and try to use a bit higher address.

MR_DPI

DPI category of the device. Font size and DPI_MUL are set according to this value. Only hdpi and xhdpi are implemented at this time, but it is easy to add another one - here is setting of MR_DPI and here is the font size.

MR_DPI_MUL

This value specifies a coefficient to all pixel lenghts in MultiROM UI. The theme was initially made for 1280x800, so grouper and mako both have MR_DPI_MUL := 1 and flo has MR_DPI_MUL := 1.5. If not speicified otherwise, MR_DPI sets MR_DPI_MUL to 1 for hdpi and to 1.5 for xhdpi.

MR_DPI_FONT

DPI value passed to libfreetype font rendering. Doesn't really correspond to real dpi of the display for some reason, so just try different values and see what looks good. For example mako with 4.5' at 768x1280 has 216 and hammerhead with 4.95' at 1080x1920 has 340.

MR_DISABLE_ALPHA

If set to true, alpha background for the "message boxes" is disabled. Use this if it takes a long time to render this background on your device.

MR_FSTAB

Path to some kind of fstab in device tree, TWRP's fstab is prefered. It is used to get paths to boot and recovery devices.

MR_USE_MROM_FSTAB

If set to true, fstab specified in MR_FSTAB is used when running MultiROM instead of device's default fstab. This is usefull when the device's fstab is borked in some way, but chances are your fstab is okay.

MR_KEXEC_MEM_MIN

Value passed as --mem-min to kexec call. More on that later.

MR_INFOS

Path to folder with rom_infos for the recovery. Recovery enables/disables installation options according to present info files. Currently supported are:

  • ubuntu.txt - for Ubuntu Desktop, currently only on grouper.
  • ubuntu_touch.txt - for Ubuntu Touch
  • sailfishos.txt - for SailfishOS

Look at grouper's mrom_infos folder or hammerhead's mrom_infos folder for inspiration.

MR_DEVICE_HOOKS and MR_DEVICE_HOOKS_VER

If needed, specifies path to .c file with device-specific hooks and it's version. Only MR_DEVICE_HOOKS_VER := 1 with one hook is available at this time, and the file should look like this:

#if MR_DEVICE_HOOKS >= 1
int mrom_hook_after_android_mounts(const char *busybox_path, const char *base_path, int type)
{
    // base_path - absolute path to rom root, e.g. /data/media/0/multirom/roms/stock/
    // type - ROM type as in multirom.h

    // return negative value to abort boot, return >= 0 to continue boot.
    return 0;
}
#endif /* MR_DEVICE_HOOKS >= 1 */

This hook is called just afer MultiROM mounts Android directories to /system, /data and /cache - here.

Building MultiROM

make recoveryimage # builds the recovery image
make multirom # builds multirom binary
make trampoline # builds trampoline - MultiROM's init daemon
make multirom_zip # builds multirom and trampoline and installation ZIP file
make multirom_uninstaller # builds uninstaller ZIP

You'll probably use multirom_zip and recoveryimage targets. Once it's done, flash the recovery and the ZIP file and see how's it working. Remember, MultiROM logs into kmsg.

Porting kexec-hardboot patch

Info about kexec-hardboot patch is on a separate page.

Further support

Chances are you can find me on IRC - irc.freenode.net, channels #multirom or #twrp, nick Tassadar. Webchat.

You can’t perform that action at this time.