• If you are experiencing issues logging in, we moved to a new and more secure software and older account passwords were not able to be migrated. We recommend trying to reset your password, then contacting us if there are issues.
  • Nearly done! Migration cleanup is mostly done. There are a small number of issues left that we continue to work on, but all the heavy lifting is done. We still would love to hear feedback over at this thread and also check out the new XDA app! Thanks and we hope you enjoy the new forums, and thanks for your support of XDA <3

[GUIDE] Creating TWRP Flashbale Stock roms

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
This project is inspired by the thread here by Q9Nap
TWRP Flashable Stock Builds

In that thread, Q9Nap (and later me, although in an unofficial capacity) has created TWRP Flashable builds of the stock rom. These would have been based upon the full fastboot flashable stock images, and then OTA patches from those roms.

Although the tools used have been provided in that thread, there isn't a guide saying how to use them. (I originally posted parts of this guide in that thread, but this is to consolidate it all into one project.) So in the below posts, I'll go through the actual process of generating the TWRP flashable builds themselves.

This project is divided into the following posts:
  1. Tools required
  2. Creating a TWRP flashable build from an existing TWRP flashable build + OTA patch
  3. Creating a TWRP flashable build from the fastboot iamges

Here is the link to the builds that I have created. Other older ones are in the thread mentioned at the top of this post.
https://www.androidfilehost.com/?w=files&flid=273039

Finally, this guide could also be used in principle for other devices, however there may be some device or vendor-specific differences.

XDA:DevDB Information
[GUIDE] Creating TWRP Flashbale Stock roms, ROM for the Moto G5 Plus

Contributors
NZedPred
ROM OS Version: 7.x Nougat

Version Information
Status: Stable

Created 2018-06-16
Last Updated 2018-06-16
 
Last edited:

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Tools and other pre-requisites

Pre-requisites

This has been done entirely on Linux, Debian Stretch to be precise. Other 64 bit modern distros should work fine.

In all cases, it is assumed that you have extract or copy the relevant files into somewhere in your PATH.

1) IMG Patch Tools

The link to the IMG Patch Tools is here:
https://forum.xda-developers.com/an...ev-img-patch-tools-sdat2img-ota-zips-t3640308 - credits to @erfanoabdi

Repo is here:
https://github.com/erfanoabdi/imgpatchtools

The first post is a description of what the tool does. The second explains usage. The third contains download links.

Download the Release version from the first link in the third post. Note that the tools are only available for Linux_x64 and MacOS.

In my case I needed to compile them on my system. Follow the instructions as per the second post. I needed to install the development libraries for zlib and libbz2, and openssl:
sudo apt-get install libbz2-dev zlib1g-dev openssl

2) IMG Repack Tools

The link to the Android img Repack Tools is here:
https://forum.xda-developers.com/android/general/tool-android-rom-repack-tools-t3763986 - credits to @rkhat

Releases:
https://github.com/rkhat2/android-rom-repacker/releases

Source:
https://github.com/rkhat2/android-rom-repacker/tree/android-7

Download and extract the android-7 / nougat version

3) IMG to SDAT and SDAT to IMG tools

The link to the img2sdat and sdat2img tools is here:
https://forum.xda-developers.com/an.../how-to-conver-lollipop-dat-files-to-t2978952 - credits to @expirt

Repos are here:
https://github.com/xpirt/img2sdat
https://github.com/xpirt/sdat2img

4) Boot image tools

Get the mkbootimg tools available here:
https://github.com/xiaolu/mkbootimg_tools

Don't know of any XDA thread or developer for these.

5) SparseConverter
SparseConverter is needed to convert the Fastboot sparse chunks into an image file. This is only required for creating a TWRP flashable build from the Fastboot image files. It is not needed for an existing TWRP flashable build.

The link to SparseConverter, both the binary and source code, is here:
https://forum.xda-developers.com/showthread.php?t=2749797 - credits to @tal.aloni

In my case, I downloaded the source code and compiled it using MonoDevelop. You can open the Visual Studio Solution file (.sln) in MonoDevelop and compile. It may also be possible to download the binary and execute it using mono. If you choose this route, adjust commands below to suit. I haven't tried this myself, so if it doesn't work try compiling it from source.

6) TWRP Flashable Template zip
Another requirement for building a TWRP flashable zip from the Fastboot images is to have a suitable template zip. I have created one and placed it here:
https://www.androidfilehost.com/?fid=5862345805528045057

7) Brotli
Brotli is a loss-less compression format that is now being used in the Oreo OTAs. Its file extension is br. You can get the latest release/source code from here:
https://github.com/google/brotli/releases

8) lz4
In some cases, device tree images are compressed using lz4. This is a standard part of many linux distributions. Use the following on Debian/Ubuntu:
Code:
sudo apt install liblz4-tool
9) A hex editor
Editing the device tree binary/blob needs a hex editor. I have used dhex because it can be used over the command line. Use the following on Debian/Ubuntu:
Code:
sudo apt install dhex
Any other hex editor will suffice.

Change log of this post
  • 2018-06-17 - add in SparseConverter details, TWRP template zip.
  • 2018-07-10 - change link to TWRP Flashable template - new one is edited to NOT erase modemst1 and modemst2.
  • 2018-08-19 - add in Brotli, required for new Oreo OTAs.
  • 2018-09-09 - add in lz4 and hex editor requirements.
  • 2018-10-14 - add in link to sdat2img repo. Properly tag the authors of the different tools that I use (where available).
 
Last edited:

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Create TWRP Flashable from existing TWRP Flashable

Create TWRP Flashable zip from Existing TWRP Flashable

1) Get an existing TWRP flashable

You can download the latest TWRP Nougat flashables for Potter from here:
[Nougat][Stock][Rom] TWRP Flashable Stock Builds

The latest TWRP Oreo flashables for Potter are here:
[Oreo][Stock][Rom] TWRP Flashable Stock Builds

I also put together some TWRP flashables for other devices, such as Cedric (G5) and Sanders (G5S Plus). Have a search under my profile at Android File Host:
Downloads for Android Devices by nzedpred

Extract it to a folder, e.g. "next", that represents the next version that you will be creating. Enter the folder.

All commands are run from within this folder. If a folder is created as part of the instructions, I assume that the folder is not entered.

2) Convert sparse data images to img

With the sdat2img tool, convert the system, oem, and modem images to raw images:
Code:
sdat2img.py system.transfer.list system.new.dat system.img
sdat2img.py oem.transfer.list oem.new.dat oem.img
sdat2img.py modem.transfer.list modem.new.dat modem.img
3) Analyse the OTA and apply patching and updates

Unzip the ota upgrade files into a sub-folder ota.
Code:
unzip path/to/ota/Blur_Version.x.y.z.zip -d ota
In the OTA extract, open up the updater-script in a text editor
Code:
ota/META-INF/com/google/android/updater-script
The first parts of the script are to check for valid OEM, Recovery and System partitions from the previous version. The parts we're interested in start below the line:
Code:
# ---- start making changes here ----
New in Oreo
In Nougat, many of the files below are named e.g. system.new.dat. Oreo may have these files named e.g. system.new.dat.br. These "br" files are Brotli compressed files. Look for any files that are named as such, e.g.
Code:
ls ota/*.br
ota/dsp.new.dat.br  ota/system.new.dat.br
In the example above, I get two files that are Brotli compressed. Decompress these using the following:
Code:
brotli --decompress --input ota/dsp.new.dat.br --output ota/dsp.new.dat
brotli --decompress --input ota/system.new.dat.br --output ota/system.new.dat
** System **
The first line that makes updates to the system image is this one for Nougat:
Code:
block_image_update("/dev/block/bootdevice/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat")
or Oreo:
Code:
block_image_update("/dev/block/bootdevice/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat.br", "system.patch.dat")
The only difference between Nougat and Oreo is the "br" in system.new.dat.br. As we have decompressed the Brotli files in the previous steps, we only need to use sytem.new.dat.

The equivalent command to imitate this command is the following:
Code:
BlockImageUpdate system.img ota/system.transfer.list ota/system.new.dat ota/system.patch.dat
Check that the error code returned is 0.

** Boot **
The next line that makes updates to the boot image is this one:
Code:
apply_patch("EMMC:/dev/block/bootdevice/by-name/boot:16777216:f6ee50c0900378319080912820b5c20f4bb7051c:16777216:19b3ba799fd8f57588ff3736f1a1c0070417f4c2",
            "-", 19b3ba799fd8f57588ff3736f1a1c0070417f4c2, 16777216,
            f6ee50c0900378319080912820b5c20f4bb7051c,
            package_extract_file("patch/boot.img.p"))
The equivalent command to imitate this is the following:
Code:
ApplyPatch boot.img - 19b3ba799fd8f57588ff3736f1a1c0070417f4c2 16777216 f6ee50c0900378319080912820b5c20f4bb7051c ota/patch/boot.img.p
NOTE: You will need to update the strings above to match what is in the OTA update script, which will differ from OTA to OTA.

NOTE: This will fail if we use the version straight from the previous flashable zip, as that version may have already been patched to disable dm-verity and disable forced encryption. We need to get a version from the stock image.

Also note, that as part of creating these zips, I leave the original unmodified boot.img file as a copy, boot-stock.img or similar. When patching, simply rename it to boot.img before doing the ApplyPatch command
Code:
mv boot-stock.img boot.img -fv
Check that the error code returned is 0.

** Bootloader **
The bootloader also gets updated quite often. Note that as part of making these zips safer, we don't update the bootloader, so skip right past them. These lines look something like this:
Code:
ui_print("updating sbl1 ...");
assert(package_extract_file("sbl1.mbn", "/tmp/sbl1.mbn"),
	   apply_raw_image("/tmp/sbl1.mbn", "sbl1"),
	   delete("/tmp/sbl1.mbn"));
Refer to post #13 to see details of how to work out which partitions are bootloader-related. In brief, the following are bootloader-related:
  • aboot
  • rpm
  • tz
  • devcfg
  • cmnlib
  • cmnlib64
  • keymaster
  • prov
  • sbl1

** MODEM **
When the modem is updated, it tends to be done using a few different techniques. Sometimes it uses one of the approaches above, other times it is untouched, and finally it can have a combination of deleting, patching and copying new files.

To apply changes that are done by deleting, patching and copying, first set up a mount point, mount the image, and make sure you have any of the tools in the path of the root user, as these need to be run as root.
Code:
mkdir modem
sudo su
mount modem.img modem
export PATH=$PATH:/path/to/tools
An example of deleting:
Code:
ui_print("Removing unneeded files from modem...");
delete("/modem/image/Ver_Info.txt", "/modem/image/cmnlib.b04",
       "/modem/image/fpctzappfingerprint.b04",
       "/modem/image/fpctzappfingerprint.b05", "/modem/image/modem.b17",
       "/modem/image/qdsp6m.qdb", "/modem/image/dhsecapp.b00",
etc...
The equivalent of these are:
Code:
rm modem/image/Ver_Info.txt
rm modem/image/cmnlib.b04
rm modem/image/fpctzappfingerprint.b04
etc...
Take very special care to remove the leading slash before modem. You don't want to risk deleting files on your PC's filesystem.

An example of patching:
Code:
ui_print("Patching modem files...");
apply_patch("/modem/image/adsp.b00", "-",
            42ae9e4a8a04b70938c6fda6bef2ad7063ccba15, 532,
            6df377596db8273c268691fb87380c416128502c,
            package_extract_file("patch/modem/image/adsp.b00.p")) ||
    abort("E3008: Failed to apply patch to /modem/image/adsp.b00");
apply_patch("/modem/image/adsp.b01", "-",
            13500067ce0564e2d45780d5511271f8d195a598, 6920,
            3ee7f84d3e81a44725554ac24d001cff21a636ab,
            package_extract_file("patch/modem/image/adsp.b01.p")) ||
    abort("E3008: Failed to apply patch to /modem/image/adsp.b01");
etc...
The equivalent of these are:
Code:
ApplyPatch modem/image/adsp.b00 - 42ae9e4a8a04b70938c6fda6bef2ad7063ccba15 532 6df377596db8273c268691fb87380c416128502c ota/patch/modem/image/adsp.b00.p
ApplyPatch modem/image/adsp.b01 - 13500067ce0564e2d45780d5511271f8d195a598 6920 3ee7f84d3e81a44725554ac24d001cff21a636ab ota/patch/modem/image/adsp.b01.p
etc...
An example of copying:
Code:
ui_print("Unpacking new files in modem ...");
assert(package_extract_dir("modem", "/modem"));
The equivalent of this is:
Code:
cp -rv ota/modem/* modem/
You will probably also see something like:
Code:
ui_print("Symlinks and permissions in modem ...");
set_metadata_recursive("/modem/", "uid", 0, "gid", 0, "dmode", 0755, "fmode", 0644, "capabilities", 0x0);
That sets permissions of folders and files to 0755 and 0644 respectively. This can be achieved by:
Code:
find modem/ -type d -exec chmod 0755 {} \;
find modem/ -type f -exec chmod 0644 {} \;
When finished, unmount modem.img, exit the root shell, and remove the mount folder:
Code:
umount modem
exit
rmdir modem
** OEM **
The line that updates the oem image is this one:
Code:
block_image_update("/dev/block/bootdevice/by-name/oem", package_extract_file("oem.transfer.list"), "oem.new.dat", "oem.patch.dat")
The equivalent command to imitate this is the following:
Code:
BlockImageUpdate oem.img ota/oem.transfer.list ota/oem.new.dat ota/oem.patch.dat
Check that the error code returned is 0.

** DSP **
Occasionally the dsp partition is also updated. It will use one of the techniques above, e.g.
Code:
block_image_update("/dev/block/bootdevice/by-name/dsp", package_extract_file("dsp.transfer.list"), "dsp.new.dat.br", "dsp.patch.dat")
Has the equivalent command:
Code:
BlockImageUpdate adspso.bin ota/dsp.transfer.list ota/dsp.new.dat ota/dsp.patch.dat
Note that the equivalent of the dsp partition is the adspso.bin file.

** FSG **
If FSG is updated, you will often see something like this:
Code:
assert(package_extract_file("fsg.mbn", "/tmp/fsg.mbn"),
	   apply_raw_image("/tmp/fsg.mbn", "fsg"),
	   delete("/tmp/fsg.mbn"));
This doesn't represent a patch being applied. Instead the file would just be copied from the OTA folder into the base folder. This applies to any other file that hasn't been patched in one of the ways above (except the bootloader).

** Others **
At this point, check if there are other (non-bootloader) partitions in the updater-script. This should have covered off all, but a future device may have other partitions that follow this (or a new) technique.

One that is present that I haven't used here, is logo.bin being copied over the logo partition. I tend to leave this as-is, as I prefer/recommend that people flash the logo as a one-off, and preferably grab a "Hidden N/A" from the themes forum.

4) Disable dm-verity and forced encryption

There are two different techniques to disabling dm-verity and forced encryption, one for Nougat and one for Oreo. Refer to the appropriate section below.

4a) Nougat - Disable dm-verity and forced encryption in boot

Nougat has the flags for enabling/disabling dm-verity and forced encryption in the boot image. These instructions are based upon looking at the scripts in the files here:
https://build.nethunter.com/android-tools/no-verity-opt-encrypt/

Make a copy of the boot.img file, so that we have the original for the next ota. This is important, as without the original, the next time we try to apply the patch, it will fail.
Code:
cp boot.img boot-stock.img
Extract the boot image:
Code:
mkboot boot.img bootimg
Modify the fstab file in a text editor:
Code:
bootimg/ramdisk/fstab.qcom
Remove any instances of verify. For example, the below line:
Code:
/dev/block/bootdevice/by-name/system         /system      ext4    ro,barrier=1,discard                                wait[U],verify[/U]
Can be changed to:
Code:
/dev/block/bootdevice/by-name/system         /system      ext4    ro,barrier=1,discard                                wait
If the section "wait,verify" was in fact just "verify", we would need to replace it with "defaults"

Replace any instances of forceencrypt or forcefdeorfbe with encryptable

E.g. the below line:
Code:
/dev/block/bootdevice/by-name/userdata       /data        f2fs    rw,discard,nosuid,nodev,noatime,nodiratime,nobarrier,inline_xattr,inline_data    wait,check,formattable,[U]forceencrypt[/U]=/dev/block/bootdevice/by-name/metadata
Can be changed to:
Code:
/dev/block/bootdevice/by-name/userdata       /data        f2fs    rw,discard,nosuid,nodev,noatime,nodiratime,nobarrier,inline_xattr,inline_data    wait,check,formattable,[U]encryptable[/U]=/dev/block/bootdevice/by-name/metadata
Save and close the file.

Repack the boot image:
Code:
mkboot bootimg boot.img
Note the above line will replace your previous boot.img file, but that's OK because we made the copy to boot-stock.img.

4b) Oreo - Disable dm-verity and forced encryption

Oreo is different to Nougat with respect to these flags. Oreo uses a "device tree" in the boot image to mount the vendor partition. In the case of potter, and presumably the other recent Moto devices, vendor is actually a symlink to a folder in system. So, we need to make a change to the boot image, and the system partition.

4b) i) Oreo - Disable dm-verity

The process in broad terms is this:
  • Backup the boot image
  • Unpack the boot image
  • Decompress the dt.img file (if applicable), to get the underlying dtb file (device tree blob)
  • Hexedit the device tree blob, removing instances of verify
  • Compress the dtb file
  • Pack the boot image

To assist with the next OTA, make a copy of the boot image. Then use mkboot to extract the boot image to its component parts:
Code:
cp -v boot.img boot-stock.img
mkboot boot.img bootimg
Look at the extracted boot image:
Code:
ls -l bootimg/
-rw-r--r--  1 user user  418560 Sep  9 09:12 dt.img
-rw-r--r--  1 user user     466 Sep  9 09:12 img_info
-rw-r--r--  1 user user 9211208 Sep  9 09:12 kernel
drwxr-xr-x 21 user user    4096 Sep  9 09:12 ramdisk
-rw-r--r--  1 user user 1273390 Sep  9 09:12 ramdisk.packed
The dt.img is the device tree, which holds the mount information that we need to edit. Note that dt.img may be compressed - for Potter it is lz4 compressed, for Cedric for example, it is not compressed - it is raw data. To find out whether or not it is compressed, use the following command and check the output

Code:
file bootimg/dt.img
The output could be one of the following:
Code:
bootimg/dt.img: LZ4 compressed data (v1.4+)
bootimg/dt.img: data
If the output says that it is LZ4 compressed, use the following to decompress - we will call the decompressed file dtb.img:
Code:
lz4 -d bootimg/dt.img bootimg/dtb.img
Now we need to use a hex editor to view and manipulate the dtb.img (or dt.img if not compressed) file. Note that the dtc command (device tree compiler) should be able to convert these dtb files into source files. However I have had no success even with the latest versions. In future it may be possible (and preferable) to convert to source, and edit the source text and recompile to dtb.

Code:
dhex bootimg/dtb.img
or
Code:
dhex bootimg/dt.img
Now, search for instances of ",verify" (without the quotes). When they are found, you can also scroll up to see what the previous lines were, to make sure they are editing instances of "fstab", for example:
Code:
   32E44     00 00 00 01 61 6e 64 72  6f 69 64 00 00 00 00 03  00 00 00 11 00 00 00 21      ....android............!
   32E5C     61 6e 64 72 6f 69 64 2c  66 69 72 6d 77 61 72 65  00 00 00 00 00 00 00 01      android,firmware........
[COLOR="red"]   32E74     66 73 74 61 62 00 00 00  00 00 00 03 00 00 00 0e  00 00 00 21 61 6e 64 72      fstab..............!andr[/COLOR]
   32E8C     6f 69 64 2c 66 73 74 61  62 00 00 00 00 00 00 01  73 79 73 74 65 6d 00 00      oid,fstab.......system..
   32EA4     00 00 00 03 00 00 00 0f  00 00 00 21 61 6e 64 72  6f 69 64 2c 73 79 73 74      ...........!android,syst
   32EBC     65 6d 00 00 00 00 00 03  00 00 00 35 00 00 03 72  2f 64 65 76 2f 62 6c 6f      em.........5...r/dev/blo
   32ED4     63 6b 2f 70 6c 61 74 66  6f 72 6d 2f 73 6f 63 2f  37 38 32 34 39 30 30 2e      ck/platform/soc/7824900.
   32EEC     73 64 68 63 69 2f 62 79  2d 6e 61 6d 65 2f 73 79  73 74 65 6d 00 00 00 00      sdhci/by-name/system....
   32F04     00 00 00 03 00 00 00 05  00 00 00 71 65 78 74 34  00 00 00 00 00 00 00 03      ...........qext4........
   32F1C     00 00 00 15 00 00 69 bc  72 6f 2c 62 61 72 72 69  65 72 3d 31 2c 64 69 73      ......i.ro,barrier=1,dis
   32F34     63 61 72 64 00 00 00 00  00 00 00 03 00 00 00 0c  00 00 69 c6 77 61 69 74      card..............i.wait
[COLOR="Red"]   32F4C     2c 76 65 72 69 66 79 00  00 00 00 03 00 00 00 03  00 00 02 b4 6f 6b 00 00      ,verify.............ok..[/COLOR]
There will be several instances of this. In all cases, we want to overwrite the ",verify" with zeroes. So the last line above would become:
Code:
   32F4C     00 00 00 00 00 00 00 00  00 00 00 03 00 00 00 03  00 00 02 b4 6f 6b 00 00      ....................ok..
Make sure to repeat for all, then save and exit the hex editor.

Now complete the last few steps - the first set of commands if the dt.img file was compressed:
Code:
rm -v bootimg/dt.img
lz4 -9 bootimg/dtb.img bootimg/dt.img
rm -v bootimg/dtb.img
mkboot bootimg boot.img
Or the following if dt.img was not compressed:
Code:
mkboot bootimg boot.img
The boot image has now been recreated with dm-verity disabled.

4b) ii) Oreo - Disable forced encryption
The process here is similar to what is done in Nougat, just that we need to mount system.img first, and then apply to a file at system/vendor/etc/fstab.qcom.

It is important to know that merely mounting system.img will result in changes to the file. This could cause a future OTA to not work. The approach below will work, however it is now recommended that system.img is mounted read-only, the fstab.qcom file is copied and edited, and a script is used to replace the fstab.qcom file at install time. This way system.img is kept intact, there is no need to keep a > 1 GB file as a backup, and there will be no issues with future OTAs. This is the approach taken by the latest flashable zips with the Aroma installer.

In the below, I use vim to edit, but you can use any other text editor. I also create a backup of system.img, just in case I make a mistake. Note that it is a large file so you wouldn't want to keep it in the final zip.

Another thing to note is that this change appears to have no effect if dm-verity is not disabled.

Code:
cp -v system.img /path/to/keep/system.img.backup
mkdir system
sudo su
mount system.img system
vim system/vendor/etc/fstab.qcom
Here, apply the same approach as Nougat - replace "forceencrypt" with "encryptable". Close and save, then unmount system.img, and exit the root shell. Then remove the system folder.
Code:
umount system
exit
rmdir -v system
Installing Magisk immediately after flashing the rom, and before rebooting, will also disable dm-verity and forced encryption.

5) Convert images to sparse images, then to sparse data

Make a temporary folder for the spasre image files that we will create:
Code:
mkdir tmp
img2simg system.img tmp/system.img
img2simg oem.img tmp/oem.img
img2simg modem.img tmp/modem.img
Create the sparse data files from the sparse images:
Code:
img2sdat.py tmp/system.img -v 4 -p system
img2sdat.py tmp/oem.img -v 4 -p oem
img2sdat.py tmp/modem.img -v 4 -p modem
6) Update the actual updater-script

Use your text editor to update the updater-script file:
Code:
vim META-INF/com/google/android/updater-script
Update any lines that refer to the version being installed. It's good to have these lines in there, but are optional. They could be removed entirely if so desired...
Code:
ui_print("Target: motorola/potter/potter:7.0/NPNS25.137-93-8/10:user/release-keys");
As it is information only, it isn't necessary to get the values exactly right. You can get the correct values from the ota updater script here:
Code:
ota/META-INF/com/google/android/updater-script
Update - remove format of modemst1 and modemst2
The builds that I have provided to date erase the modemst1 and modemst2 partitions. Whilst that is fine for devices normally as they get recreated on boot, in cases where users have flashed a custom Oreo rom and then reverted to stock, there have been reports of losing IMEI and other capabilities. Whilst this is caused by Oreo roms changing ownership of the /persist/rfs folder, the fact that these partitions are erased can leave people without IMEI, relying upon a backup to get back. So, if the previous flashable zip has lines to format the modemst1/2 partitions, remove them. The lines look like the following, with the format commands being the ones that do the erase:
Code:
ui_print("Erasing modemst1 ...");
format("raw", "EMMC", "/dev/block/bootdevice/by-name/modemst1", "0", "/modemst1");
ui_print(" ");

ui_print("Erasing modemst2 ...");
format("raw", "EMMC", "/dev/block/bootdevice/by-name/modemst2", "0", "/modemst2");
ui_print(" ");
7) Remove working files and folders and zip

The folders we created in previous steps can now be removed:
Code:
rm -rf ota tmp bootimg
The temporary img files can now be removed:
Code:
rm system.img oem.img modem.img
Zip up the remaining files into the parent folder (I like to keep the update tree clean) - replace version_info with an appropriate string, e.g. NPNS25.137-93-14, OPS28.85-13:
Code:
zip ../twrp-flashable-potter-[i]version_info[/i].zip -r *
Note - this will also include the boot-stock.img file. Best to keep it there so we can use it for the next patch!

8) Prepare for flashing

Copy the newly created zip into your phone's SD card

BACKUP BACKUP BACKUP!!! Do a TWRP backup of course! NO EXCUSES!

Flash the zip file.

Voila!

Edit log
  • 2018-07-07 - Added reference to post #10, as it details how to do a modem update for the NPNS25.137-93-14 OTA
  • 2018-07-10 - Added recommendation to remove lines from OTA updater-script that erase modemst1 and modemst2
  • 2018-08-19 - Updated for Oreo.
  • 2018-09-09 - Tidied up the steps to disable dm-verity for Oreo, other tidying up. Catered for dt.img being either compressed (e.g. Potter) or not (e.g. Cedric).
 
Last edited:

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Create TWRP from full fastboot image

Create TWRP Flashable from Fastboot Image

First off, make sure you have the SparseConverter and TWRP template zip from the second post. These weren't needed for building from an existing TWRP flashable zip, but are necessary for this.

1) Get an appropriate starting firmware
At the time of writing this, the April 2018 security patches are available for the Indian variant (NPNS25.137-92-10) and US variant (NPNS25.137-93-10). Note that these firmwares are used on other regions as well (e.g. the US firmware can be used on retapac). Refer to other threads in the forum if you aren't sure. Ideally you should stick with the firmware for your region, as e.g. there may be differences in the modems, etc.

Indian (NPNS25.137-92-10) https://mirrors.lolinet.com/firmware/moto/potter/official/RETAIL/POTTER_RETAIL_7.0_NPNS25.137-92-10_cid50_subsidy-DEFAULT_regulatory-DEFAULT_CFC.xml.zip

US (NPNS25.137-93-10) - refer to this thread https://forum.xda-developers.com/g5-plus/development/april-security-patch-xt1687-npns25-137-t3796797

Extract the zip file and enter the folder (rename it if you want for convenience).

2a) Convert the sparse chunk files into a (Motorola) image file

Use SparseConverter to convert the sparse chunks into an image file:
Code:
SparseConverter.exe /decompress system.img_sparsechunk.0 system.img.moto
The first parameter says that we are decompressing (obvious). The second is the name of the very first sparse chunk file - we only need to specify the first. The third and last parameter is the destination file to be created.

The reason for naming it system.img.moto (i.e. with moto on the end) is because Motorola have added a 128KB header and 4KB trailer. These will need to be removed later.

2b) Convert oem.img from sparse image to raw image
Confusingly, sparse image files and raw image files typically have the same extension - img. oem.img is a sparse image file, and must be converted to raw image. Similarly to the system image, it has a 128KB header and 4KB trailer.

Code:
mv oem.img oem.simg.moto
simg2img oem.simg.moto oem.img.moto
2c) Convert the modem (NON-HLOS.bin) to raw image
The modem file, although it has a .bin extension, is in sparse image format.
Code:
simg2img NON-HLOS.bin modem.img
This particular file does not have a header or trailer.

3) Remove header and trailer from image files
We will use dd and truncate to remove the header and trailer respectively from the system and oem image files:

Code:
dd if=system.img.moto of=system.img bs=131072 skip=1
truncate -s -4096 system.img

dd if=oem.img.moto of=oem.img bs=131072 skip=1
truncate -s -4096 oem.img
4) Extract template and copy files
In a separate folder, extract the TWRP Template zip file into a folder, and rename the folder to something more reasonable, e.g. twrp-flashable-NPNS.25.137-xx-xx.

Copy each of the following files into the template folder:
  • system.img
  • oem.img
  • modem.img
  • boot.img
  • fsg.mbn
  • adspso.bin
  • logo.bin

E.g. use a command like the following, adjusting the paths as necessary (the last parameter is the location of the template folder that I renamed in this case):
Code:
cp -fv adspso.bin boot.img fsg.mbn logo.bin modem.img oem.img system.img ../twrp-flashable-NPNS25.137-92-10/
Note that of those above, the first three were created in our previous steps, the others (boot.img etc) were already there with the other fastboot files.

The updater-script, located at META-INF/com/google/android/updater-script is already set up to take the steps that are done in the fastboot images, except it does not update the bootloader-related files.

At this stage, you could just go and zip up all of the files and flash. However, there are a few things you may want to do first. Ensure you are in the template folder before doing any of the following.

5) Disable dm-verity and forced encryption in boot
To do this, follow the same instructions as the previous post - step 4. Note the two different methods, one for Nougat, one for Oreo.

6) Change the logo image
Note that the logo.bin file is from stock, and therefore it will have the unlocked bootloader warning. You could replace it with the logo.bin from the other TWRP flashables, or you may want to grab one from the Themes forum, and (as I did) pick a nice one that hides the N/A.

7) Convert images to sparse images, then to sparse data
This step is the same as the previous post, step 5. It is repeated here for convenience.

Make a temporary folder for the sparse image files that we will create:
Code:
mkdir tmp
img2simg system.img tmp/system.img
img2simg oem.img tmp/oem.img
img2simg modem.img tmp/modem.img
Create the sparse data files from the sparse images:
Code:
img2sdat.py tmp/system.img -v 4 -p system
img2sdat.py tmp/oem.img -v 4 -p oem
img2sdat.py tmp/modem.img -v 4 -p modem
8) Remove working files and folders and zip
The folders we created in previous steps can now be removed:
Code:
rm -rf tmp bootimg
The temporary img files can now be removed:
Code:
rm -fv system.img oem.img modem.img
9) Create the zip file
Ensuring that you are in the template folder, execute the following command to create the zip:
Code:
zip twrp-flashable-NPNS25.137-92-10.zip -r *
Make sure to change the zip filename as appropriate.

10) Flash
Copy to your phone's SD Card

BACKUP BACKUP BACKUP Yes, the same warning as per usual!

Flash the zip file as usual.

Edit log
2018-06-29 - fixed references to logo.img, as they are actually logo.bin. Added -fv to remove temporary files.
 
Last edited:

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Hi all - the Fastboot to TWRP Flashable guide in post #4 is now complete.
I'd be really interested if anyone has tried following the guide and had success.
All the best.
 

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Modem update via OTA

The update I did of NPNS25.137-93-14 (from NPNS25.137-93-10) had something I hadn't seen in previous updates. The modem was updated, but rather than the partition as a whole being patched, individual files within the partition were patched. The relevant parts of the updater-script from the OTA were as follows:
Code:
ui_print("Patching modem files...");
apply_patch("/modem/image/cmnlib.b01", "-",
            6fa3c6b7659a838aba82f079794a9ac46b74651b, 6632,
            720b36038ee0c7152dac051d7f4bb13dfdd3fb15,
            package_extract_file("patch/modem/image/cmnlib.b01.p")) ||
    abort("E3008: Failed to apply patch to /modem/image/cmnlib.b01");
apply_patch("/modem/image/cmnlib.b02", "-",
            155983f129c89d1c8fb96df20e069e388a23c2c2, 178690,
            6e0951d9fab22276dd772cb96ae91eff850b5bf1,
            package_extract_file("patch/modem/image/cmnlib.b02.p")) ||
    abort("E3008: Failed to apply patch to /modem/image/cmnlib.b02");
apply_patch("/modem/image/cmnlib.mdt", "-",
            41fdff0863ac1215135802499433644f2b030b92, 6876,
            1e7c7b75c2aec4cecfea538b93350975160ce0b5,
            package_extract_file("patch/modem/image/cmnlib.mdt.p")) ||
    abort("E3008: Failed to apply patch to /modem/image/cmnlib.mdt");

etc - there were a total of 51 patches applied
The other images have been patched directly, rather than individual files within the image. So the approach had to be slightly different:
  • Create a folder and mount the modem.img file into it
  • Use ApplyPatch on each of the folders
  • Unmount the image
  • Remove the folder

The resulting code to apply the changes looked like this:
Code:
# Make a folder to mount the image in
mkdir modem

# Change to a root shell
sudo su

# Mount the modem image to the modem sub-folder
mount modem.img modem

# ensure the ApplyPatch executable is in the path
export PATH=$PATH:"path to ApplyPatch"

ApplyPatch modem/image/cmnlib.b01 - 6fa3c6b7659a838aba82f079794a9ac46b74651b 6632 720b36038ee0c7152dac051d7f4bb13dfdd3fb15 ota/patch/modem/image/cmnlib.b01.p
ApplyPatch modem/image/cmnlib.b02 - 155983f129c89d1c8fb96df20e069e388a23c2c2 178690 6e0951d9fab22276dd772cb96ae91eff850b5bf1 ota/patch/modem/image/cmnlib.b02.p
ApplyPatch modem/image/cmnlib.mdt - 41fdff0863ac1215135802499433644f2b030b92 6876 1e7c7b75c2aec4cecfea538b93350975160ce0b5 ota/patch/modem/image/cmnlib.mdt.p

etc... for the remainder of the patches

# Unmount the modem image
umount modem

# Exit the root shell
exit

# Remove the modem folder
rmdir modem
Because the updater-script was consistently formatted, after doing the first 20 manually to make sure I was doing it right, I used a spreadsheet to extract the relevant hashes and filenames, and turned them into the commands above. This could have been done using a script or similar, but I'm a master of spreadsheets so chose to do it that way :)
 

Tech_Savvy

Elite Member
May 8, 2014
1,493
679
0
watertown
@NZedPred is it possible to make a flashable zip to update only the firmware? I'm on custom rom and only would like the upgrade my firmware....would i only have to delete system boot and recovery from the zip?
 

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
@NZedPred is it possible to make a flashable zip to update only the firmware? I'm on custom rom and only would like the upgrade my firmware....would i only have to delete system boot and recovery from the zip?
Hi - yes it's possible. Not 100% sure what you mean by "only the firmware" (modem/network related?), but you can alter the update the zip to only update the partitions that you want. These are the current steps in the updater-script (META-INF/com/google/android/updater-script):
  • modem
  • fsg
  • Erase modemst1 and modemst2
  • dsp
  • logo
  • boot
  • system
  • oem
  • Erase ddr

I've read that the modem and fsg are relating to the network. See the thread here for more information: Motorola Moto G Partitions Explained.

Not sure if custom roms would use oem. I know that Treble roms use oem in place of vendor, so if you're using a treble rom you wouldn't want to update that.

So all you need to do is remove the commands you don't want in the updater-script.

Hope this helps a bit.
 
Last edited:

NZedPred

Senior Member
Mar 16, 2016
857
1,632
93
Wellington
Bootloader partitions

This is a quick guide on determining which partitions are related to the bootloader.

Using a full fastboot firmware, extract the bootloader.img file. Although it is a binary file, it has sections that are text, e.g. the following is using the less command
Code:
SINGLE_N_LONELY^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@index.xml^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@<82>^@^@^@^@^@^@^@<?xml version="1.0"?>
<index>
  <package compatible="cpu.name:MSM8953 protocol:fastboot" filename="bootloader.pkg.xml"/>
</index>
Scrolling down a few pages, you'll find the following:
Code:
<?xml version="1.0" ?>
<recipe>
  <flash partition="aboot"     filename="emmc_appsboot.mbn"/>
  <flash partition="rpm"       filename="rpm.mbn"/>
  <flash partition="tz"        filename="tz.mbn"/>
  <flash partition="devcfg"    filename="devcfg.mbn"/>
  <flash partition="cmnlib"    filename="cmnlib.mbn"/>
  <flash partition="cmnlib64"  filename="cmnlib64.mbn"/>
  <flash partition="keymaster" filename="keymaster.mbn"/>
  <flash partition="prov"      filename="prov.mbn"/>
  <flash partition="sbl1"      filename="sbl1.mbn"/>
</recipe>
So, that tells us exactly which partitions are updated when we update the bootloader. The filenames and partitions are the same as those that we would see in an OTA, e.g. when we see commands like this:
Code:
ui_print("updating rpm ...");
assert(package_extract_file("rpm.mbn", "/tmp/rpm.mbn"),
	   apply_raw_image("/tmp/rpm.mbn", "rpm"),
	   delete("/tmp/rpm.mbn"));
show_progress(0.100000,0);
assert(set_backup_flag());
ui_print("updating tz ...");
assert(package_extract_file("tz.mbn", "/tmp/tz.mbn"),
	   apply_raw_image("/tmp/tz.mbn", "tz"),
	   delete("/tmp/tz.mbn"));
show_progress(0.050000,0);
ui_print("updating devcfg ...");
assert(package_extract_file("devcfg.mbn", "/tmp/devcfg.mbn"),
	   apply_raw_image("/tmp/devcfg.mbn", "devcfg"),
	   delete("/tmp/devcfg.mbn"));
show_progress(0.050000,0);

etc...
 

romuloxiii

Senior Member
Apr 8, 2011
216
49
28
Wow, great thread. Thank you so much for providing all of this info. I have been curious about how this works for quite some time. I can't wait to give it a try this coming weekend.

Thanks again mate!!
 
  • Like
Reactions: NZedPred