Skip to content

Instantly share code, notes, and snippets.

@jessenich
Created November 3, 2022 19:25
Show Gist options
  • Save jessenich/6ecfb19ce77af3d1ca64707566cd7fe5 to your computer and use it in GitHub Desktop.
Save jessenich/6ecfb19ce77af3d1ca64707566cd7fe5 to your computer and use it in GitHub Desktop.
[Motorola Flashfile SH Generator] Generate a bash script from a given Motorola flash file with all commands needs to send a sparsed image over fastboot #android
#!/usr/bin/env python3
import argparse
import sys
from os import path
from textwrap import indent
from xml.etree import ElementTree
def commentify(x, prefix='# '):
if isinstance(x, (ElementTree.ElementTree, ElementTree.Element)):
x = ElementTree.tostring(x).strip().decode()
return indent(x, prefix)
def parse_args(args=None):
p = argparse.ArgumentParser(
description="Converts Motorola's flashfile.xml format to a [ba]sh script of fastboot commands")
p.add_argument('FLASHFILE_XML')
p.add_argument('-o', '--output', metavar='FLASHFILE_SH', type=argparse.FileType('w'),
help='Script to output (default is flashfile.sh in same directory)')
p.add_argument('-n', '--no-verify', dest='verify', default=True, action='store_false',
help="Don't verify MD5/SHA1 sums")
p.add_argument('-v', '--verbose', action='store_true',
help="Include step-by-step comments in output script")
args = p.parse_args()
if args.output is None:
args.output = sys.stdout
return p, args
def main():
p, args = parse_args()
try:
x = ElementTree.parse(args.FLASHFILE_XML)
except ElementTree.ParseError as e:
p.error('XML parse error: %s' % e.args)
if x.getroot().tag != 'flashing':
p.error('Input does not appear to be a Motorola flashfile.xml (root node is not <flashing>)')
if args.output is not sys.stdout:
args.output.write('#!/bin/sh -x\n\n')
if args.FLASHFILE_XML != sys.stdin:
args.output.write('cd "%s"\n\n' % path.dirname(args.FLASHFILE_XML))
header = x.find('header')
if header:
args.output.write(commentify(header) + '\n\n')
else:
args.output.write('# WARNING: no <header> tag found\n\n')
steps = x.find('steps')
if not steps:
args.output.write('# WARNING: no <steps> found\n')
steps = ()
md5sums = {}
sha1sums = {}
for step in steps:
assert step.tag == 'step'
if 'MD5' in step.keys() and 'filename' in step.keys():
md5sums[step.get('filename')] = step.get('MD5')
elif 'SHA1' in step.keys() and 'filename' in step.keys():
sha1sums[step.get('filename')] = step.get('SHA1')
for checker, checksums in (('md5sum', md5sums), ('sha1sum', sha1sums)):
if checksums:
checksums = checker + ' --check <<EOF || exit 1\n' + ''.join(
'{1} *{0}\n'.format(*p) for p in checksums.items()) + 'EOF'
args.output.write((checksums if args.verify else commentify(checksums)) + '\n\n')
for nn, step in enumerate(steps):
assert step.tag == 'step'
op = step.get('operation')
if op == 'flash':
xml_vars = 'operation', 'partition', 'filename',
elif op == 'erase':
xml_vars = 'operation', 'partition',
elif op in ('getvar', 'oem'):
xml_vars = 'operation', 'var'
else:
args.output.write('\n# %02d: skipping unknown operation %r:\n%s\n\n' % (nn, op, commentify(step)))
op = None
if op:
if args.verbose and args.output is not sys.stdout:
args.output.write(commentify(step, '# %02d: ' % nn) + '\n')
args.output.write('fastboot %s || exit 1\n' % ' '.join(step.get(v) for v in xml_vars))
if args.output is not sys.stdout:
print("Wrote shell script with %d fastboot steps to %s" % (len(steps), args.output.name), file=sys.stderr)
if __name__ == '__main__':
sys.exit(main())
#!/bin/sh -x
cd ""
# <header>
# <phone_model model="guamna_t" />
# <software_version version="guamna_t-user 11 RZAS31.Q2-146-14-11 c426c release-keysHA10_29.11.02.95.01R" />
# <subsidy_lock_config MD5="b8866e8331367acc10903ddf5d89ace6" name="slcf_rev_d_tmo_spr_rsu_qcom_v2.1.nvm" />
# <regulatory_config SHA1="da39a3ee5e6b4b0d3255bfef95601890afd80709" name="regulatory_info_default.png" />
# <sparsing enabled="true" max-sparse-size="268435456" />
# <interfaces>
# <interface name="AP" />
# </interfaces>
# </header>
md5sum --check <<EOF || exit 1
50e6b21815559c92b879aacbb56a5099 *gpt.bin
55225167b30deccb87b6899b45da47d8 *bootloader.img
90234d5b3806cfeee90192b322c81889 *radio.img
0eb3f15609c4673c8b3642e6ec2449bf *BTFM.bin
59d248cb50acb0e7bfab993e30bb40d2 *dspso.bin
468513ad101d711faab8eeb45ed7af10 *logo.bin
b11a41b579d83e2e386144421289a5c8 *vbmeta.img
246938061d57b9376e84ae723fff2118 *boot.img
2be70bb6bde27c1a9d9717360109a3b6 *dtbo.img
e36b2e00472634781ded5cb9a40934d1 *recovery.img
1388000311193182e484352bed946770 *super.img_sparsechunk.0
e2085752e20901cc020e8f666eb03157 *super.img_sparsechunk.1
3e2ffadcc502ff685acec82a44d5a691 *super.img_sparsechunk.2
c8d5d4c690d73022ddfdc0c58325876b *super.img_sparsechunk.3
86154a47871319c002cb5b71b3e349f6 *super.img_sparsechunk.4
1a00958536977fe6768c0308abc7eeda *super.img_sparsechunk.5
216f54d6a42f79a5637395a51dfd1fec *super.img_sparsechunk.6
06cef5c741c09acd666006d70d6d82f9 *super.img_sparsechunk.7
c31f1ffc6583f363ba72d4b6cec1a476 *super.img_sparsechunk.8
24f2800b4cf794013d5972039fe5ef3a *super.img_sparsechunk.9
adbb440e23d985e7c09698f45d3d21a8 *super.img_sparsechunk.10
739cb6e422ba835702e5c8ed1a75a00c *super.img_sparsechunk.11
dc3ef0c026a491e97abe6393fcc02f06 *super.img_sparsechunk.12
459ea8ac58b2e64227741e1487163125 *super.img_sparsechunk.13
e3e6eb48b96587b3e64ce2fcbb517363 *super.img_sparsechunk.14
3be3c59f7af1bcbe19b4fb518065a97e *super.img_sparsechunk.15
9b87ded4470653e187a73163ae37d666 *super.img_sparsechunk.16
eb287a308177d335ed0808b0879d01fa *super.img_sparsechunk.17
6ffc04251f5c7eef13fd07710a32dda3 *super.img_sparsechunk.18
32a94b7a166feb64dd87f27ccd3213da *super.img_sparsechunk.19
EOF
fastboot getvar max-sparse-size || exit 1
fastboot oem fb_mode_set || exit 1
fastboot flash partition gpt.bin || exit 1
fastboot flash bootloader bootloader.img || exit 1
fastboot flash radio radio.img || exit 1
fastboot flash bluetooth BTFM.bin || exit 1
fastboot flash dsp dspso.bin || exit 1
fastboot flash logo logo.bin || exit 1
fastboot flash vbmeta vbmeta.img || exit 1
fastboot flash boot boot.img || exit 1
fastboot flash dtbo dtbo.img || exit 1
fastboot flash recovery recovery.img || exit 1
fastboot flash super super.img_sparsechunk.0 || exit 1
fastboot flash super super.img_sparsechunk.1 || exit 1
fastboot flash super super.img_sparsechunk.2 || exit 1
fastboot flash super super.img_sparsechunk.3 || exit 1
fastboot flash super super.img_sparsechunk.4 || exit 1
fastboot flash super super.img_sparsechunk.5 || exit 1
fastboot flash super super.img_sparsechunk.6 || exit 1
fastboot flash super super.img_sparsechunk.7 || exit 1
fastboot flash super super.img_sparsechunk.8 || exit 1
fastboot flash super super.img_sparsechunk.9 || exit 1
fastboot flash super super.img_sparsechunk.10 || exit 1
fastboot flash super super.img_sparsechunk.11 || exit 1
fastboot flash super super.img_sparsechunk.12 || exit 1
fastboot flash super super.img_sparsechunk.13 || exit 1
fastboot flash super super.img_sparsechunk.14 || exit 1
fastboot flash super super.img_sparsechunk.15 || exit 1
fastboot flash super super.img_sparsechunk.16 || exit 1
fastboot flash super super.img_sparsechunk.17 || exit 1
fastboot flash super super.img_sparsechunk.18 || exit 1
fastboot flash super super.img_sparsechunk.19 || exit 1
fastboot erase carrier || exit 1
fastboot erase ddr || exit 1
fastboot erase userdata || exit 1
fastboot erase metadata || exit 1
fastboot oem fb_mode_clear || exit 1
<?xml version="1.0" ?>
<!-- Flash file from Moto G Play compatible Android 11 image pack -->
<flashing>
<header>
<phone_model model="guamna_t"/>
<software_version version="guamna_t-user 11 RZAS31.Q2-146-14-11 c426c release-keysHA10_29.11.02.95.01R"/>
<subsidy_lock_config MD5="b8866e8331367acc10903ddf5d89ace6" name="slcf_rev_d_tmo_spr_rsu_qcom_v2.1.nvm"/>
<regulatory_config SHA1="da39a3ee5e6b4b0d3255bfef95601890afd80709" name="regulatory_info_default.png"/>
<sparsing enabled="true" max-sparse-size="268435456"/>
<interfaces>
<interface name="AP"/>
</interfaces>
</header>
<steps interface="AP">
<step operation="getvar" var="max-sparse-size"/>
<step operation="oem" var="fb_mode_set"/>
<step MD5="50e6b21815559c92b879aacbb56a5099" filename="gpt.bin" operation="flash" partition="partition"/>
<step MD5="55225167b30deccb87b6899b45da47d8" filename="bootloader.img" operation="flash" partition="bootloader"/>
<step MD5="90234d5b3806cfeee90192b322c81889" filename="radio.img" operation="flash" partition="radio"/>
<step MD5="0eb3f15609c4673c8b3642e6ec2449bf" filename="BTFM.bin" operation="flash" partition="bluetooth"/>
<step MD5="59d248cb50acb0e7bfab993e30bb40d2" filename="dspso.bin" operation="flash" partition="dsp"/>
<step MD5="468513ad101d711faab8eeb45ed7af10" filename="logo.bin" operation="flash" partition="logo"/>
<step MD5="b11a41b579d83e2e386144421289a5c8" filename="vbmeta.img" operation="flash" partition="vbmeta"/>
<step MD5="246938061d57b9376e84ae723fff2118" filename="boot.img" operation="flash" partition="boot"/>
<step MD5="2be70bb6bde27c1a9d9717360109a3b6" filename="dtbo.img" operation="flash" partition="dtbo"/>
<step MD5="e36b2e00472634781ded5cb9a40934d1" filename="recovery.img" operation="flash" partition="recovery"/>
<step MD5="1388000311193182e484352bed946770" filename="super.img_sparsechunk.0" operation="flash" partition="super"/>
<step MD5="e2085752e20901cc020e8f666eb03157" filename="super.img_sparsechunk.1" operation="flash" partition="super"/>
<step MD5="3e2ffadcc502ff685acec82a44d5a691" filename="super.img_sparsechunk.2" operation="flash" partition="super"/>
<step MD5="c8d5d4c690d73022ddfdc0c58325876b" filename="super.img_sparsechunk.3" operation="flash" partition="super"/>
<step MD5="86154a47871319c002cb5b71b3e349f6" filename="super.img_sparsechunk.4" operation="flash" partition="super"/>
<step MD5="1a00958536977fe6768c0308abc7eeda" filename="super.img_sparsechunk.5" operation="flash" partition="super"/>
<step MD5="216f54d6a42f79a5637395a51dfd1fec" filename="super.img_sparsechunk.6" operation="flash" partition="super"/>
<step MD5="06cef5c741c09acd666006d70d6d82f9" filename="super.img_sparsechunk.7" operation="flash" partition="super"/>
<step MD5="c31f1ffc6583f363ba72d4b6cec1a476" filename="super.img_sparsechunk.8" operation="flash" partition="super"/>
<step MD5="24f2800b4cf794013d5972039fe5ef3a" filename="super.img_sparsechunk.9" operation="flash" partition="super"/>
<step MD5="adbb440e23d985e7c09698f45d3d21a8" filename="super.img_sparsechunk.10" operation="flash" partition="super"/>
<step MD5="739cb6e422ba835702e5c8ed1a75a00c" filename="super.img_sparsechunk.11" operation="flash" partition="super"/>
<step MD5="dc3ef0c026a491e97abe6393fcc02f06" filename="super.img_sparsechunk.12" operation="flash" partition="super"/>
<step MD5="459ea8ac58b2e64227741e1487163125" filename="super.img_sparsechunk.13" operation="flash" partition="super"/>
<step MD5="e3e6eb48b96587b3e64ce2fcbb517363" filename="super.img_sparsechunk.14" operation="flash" partition="super"/>
<step MD5="3be3c59f7af1bcbe19b4fb518065a97e" filename="super.img_sparsechunk.15" operation="flash" partition="super"/>
<step MD5="9b87ded4470653e187a73163ae37d666" filename="super.img_sparsechunk.16" operation="flash" partition="super"/>
<step MD5="eb287a308177d335ed0808b0879d01fa" filename="super.img_sparsechunk.17" operation="flash" partition="super"/>
<step MD5="6ffc04251f5c7eef13fd07710a32dda3" filename="super.img_sparsechunk.18" operation="flash" partition="super"/>
<step MD5="32a94b7a166feb64dd87f27ccd3213da" filename="super.img_sparsechunk.19" operation="flash" partition="super"/>
<step operation="erase" partition="carrier"/>
<step operation="erase" partition="ddr"/>
<step operation="erase" partition="userdata"/>
<step operation="erase" partition="metadata"/>
<step operation="oem" var="fb_mode_clear"/>
</steps>
</flashing>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment