You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.7 KiB
153 lines
4.7 KiB
#!/usr/bin/env python
|
|
#
|
|
# Copyright 2018 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
#
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
"""Helper tool for 'oem at-write-persistent-digest' fastboot command.
|
|
|
|
This tool generates and stages the correct input data format, based on the
|
|
user-provided inputs, for the 'oem at-write-persistent-digest' fastboot command
|
|
for Android Things devices before running the command itself.
|
|
|
|
The input format is defined elsewhere to be the following:
|
|
|
|
- Name length: 4 bytes (little-endian)
|
|
- Name: 'name length' bytes
|
|
- Digest length: 4 bytes (little-endian)
|
|
- Digest: 'digest length' bytes
|
|
|
|
Digest length can be zero, indicating that any existing digest with the given
|
|
name should be deleted. This corresponds to the '--clear_digest' option for this
|
|
tool.
|
|
|
|
Digest names must be prefixed with 'avb.persistent_digest.', and if the
|
|
user-provided name does not include that prefix it is added automatically.
|
|
"""
|
|
|
|
import sys
|
|
|
|
ver = sys.version_info
|
|
if (ver[0] < 2) or (ver[0] == 2 and ver[1] < 7) or (ver[0] == 3 and ver[1] < 2):
|
|
print('This script requires Python 2.7+ or 3.2+')
|
|
sys.exit(1)
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
import struct
|
|
import subprocess
|
|
import tempfile
|
|
|
|
HELP_DESCRIPTION = """Helper script for 'fastboot oem
|
|
at-write-persistent-digest' that generates and stages the required input data
|
|
format."""
|
|
|
|
AVB_PERSISTENT_DIGEST_PREFIX = 'avb.persistent_digest.'
|
|
|
|
|
|
def WritePersistentDigest(name,
|
|
digest=None,
|
|
clear_digest=False,
|
|
serial=None,
|
|
verbose=False):
|
|
if not name.startswith(AVB_PERSISTENT_DIGEST_PREFIX):
|
|
print("Automatically adding '{}' prefix to persistent value name".format(
|
|
AVB_PERSISTENT_DIGEST_PREFIX))
|
|
name = AVB_PERSISTENT_DIGEST_PREFIX + name
|
|
|
|
tempdir = tempfile.mkdtemp()
|
|
try:
|
|
digest_data = os.path.join(tempdir, 'digest_data')
|
|
|
|
with open(digest_data, 'wb') as out:
|
|
out.write(struct.pack('<I', len(name)))
|
|
out.write(name)
|
|
if clear_digest:
|
|
out.write(struct.pack('<I', 0))
|
|
else:
|
|
digest_bytes = bytearray.fromhex(digest)
|
|
out.write(struct.pack('<I', len(digest_bytes)))
|
|
out.write(digest_bytes)
|
|
|
|
def fastboot_cmd(args):
|
|
args = ['fastboot'] + (['-s', serial] if serial else []) + args
|
|
if verbose:
|
|
print('$ ' + ' '.join(args))
|
|
|
|
try:
|
|
out = subprocess.check_output(
|
|
args, stderr=subprocess.STDOUT).decode('utf-8')
|
|
except subprocess.CalledProcessError as e:
|
|
print(e.output.decode('utf-8'))
|
|
print("Command '{}' returned non-zero exit status {}".format(
|
|
' '.join(e.cmd), e.returncode))
|
|
sys.exit(1)
|
|
|
|
if verbose:
|
|
print(out)
|
|
|
|
fastboot_cmd(['stage', digest_data])
|
|
fastboot_cmd(['oem', 'at-write-persistent-digest'])
|
|
|
|
print("Persistent value '{}' {}".format(
|
|
name, 'cleared' if clear_digest else 'written'))
|
|
|
|
finally:
|
|
shutil.rmtree(tempdir)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser(description=HELP_DESCRIPTION)
|
|
|
|
# Optional arguments
|
|
parser.add_argument(
|
|
'-v',
|
|
'--verbose',
|
|
action='store_true',
|
|
help='verbose; prints fastboot commands and their output')
|
|
parser.add_argument(
|
|
'-s',
|
|
'--serial',
|
|
help=
|
|
"specify device to unlock, either by serial or any other valid value for fastboot's -s arg"
|
|
)
|
|
|
|
# Required arguments
|
|
parser.add_argument(
|
|
'--name',
|
|
required=True,
|
|
help=
|
|
"persistent digest name to write, 'avb.persistent_digest.' prefix will be automatically added if not already present"
|
|
)
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
group.add_argument(
|
|
'--clear_digest',
|
|
action='store_true',
|
|
help=
|
|
'clear any existing persistent digest value, rather than writing a new value'
|
|
)
|
|
group.add_argument(
|
|
'--digest',
|
|
help='persistent digest value to write, as a hex encoded string')
|
|
|
|
# Print help if no args given
|
|
args = parser.parse_args(args=None if sys.argv[1:] else ['-h'])
|
|
|
|
WritePersistentDigest(
|
|
name=args.name,
|
|
clear_digest=args.clear_digest,
|
|
digest=args.digest,
|
|
serial=args.serial,
|
|
verbose=args.verbose)
|