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.
97 lines
2.4 KiB
97 lines
2.4 KiB
4 months ago
|
#!/usr/bin/env python3
|
||
|
|
||
|
# Copyright (C) 2020 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.
|
||
|
|
||
|
"""
|
||
|
Extract boot.img from a GKI APEX.
|
||
|
|
||
|
Usage: extract_img_from_apex [--tool host_tool [--tool ...]] \
|
||
|
input_gki.apex out_dir
|
||
|
"""
|
||
|
|
||
|
import logging
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
import common
|
||
|
|
||
|
APEX_PAYLOAD_FILE = "apex_payload.img"
|
||
|
APEX_PAYLOAD_BIN_PATH = "/etc/ota/payload.bin"
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
OPTIONS = common.OPTIONS
|
||
|
|
||
|
|
||
|
def ExtractImagesFromApex(apex, out_dir):
|
||
|
if not os.path.isdir(out_dir):
|
||
|
os.makedirs(out_dir)
|
||
|
apex_dir = common.UnzipTemp(apex, [APEX_PAYLOAD_FILE])
|
||
|
apex_payload = os.path.join(apex_dir, APEX_PAYLOAD_FILE)
|
||
|
|
||
|
payload_bin = common.MakeTempFile("payload_", ".bin")
|
||
|
debugfs_command = ['debugfs', '-R', "dump {} {}".format(
|
||
|
APEX_PAYLOAD_BIN_PATH, payload_bin), apex_payload]
|
||
|
|
||
|
common.RunAndCheckOutput(debugfs_command)
|
||
|
assert os.path.getsize(payload_bin) > 0, payload_bin + " is an empty file!"
|
||
|
|
||
|
boot_img = os.path.join(out_dir, 'boot.img')
|
||
|
with open(boot_img, 'w') as _:
|
||
|
pass
|
||
|
|
||
|
delta_generator_command = [
|
||
|
'delta_generator',
|
||
|
'--is_partial_update=true',
|
||
|
'--in_file=' + payload_bin,
|
||
|
'--partition_names=boot',
|
||
|
'--new_partitions=' + boot_img
|
||
|
]
|
||
|
common.RunAndCheckOutput(delta_generator_command)
|
||
|
|
||
|
|
||
|
def main(argv):
|
||
|
def option_handler(o, a):
|
||
|
if o == "--tool":
|
||
|
name = os.path.basename(a)
|
||
|
common.SetHostToolLocation(name, a)
|
||
|
else:
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
args = common.ParseOptions(
|
||
|
argv, __doc__,
|
||
|
extra_long_opts=["tool="],
|
||
|
extra_option_handler=option_handler)
|
||
|
|
||
|
if len(args) != 2:
|
||
|
common.Usage(__doc__)
|
||
|
sys.exit(1)
|
||
|
|
||
|
common.InitLogging()
|
||
|
|
||
|
ExtractImagesFromApex(args[0], args[1])
|
||
|
logger.info("done.")
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
try:
|
||
|
common.CloseInheritedPipes()
|
||
|
main(sys.argv[1:])
|
||
|
except common.ExternalError:
|
||
|
logger.exception("\n ERROR:\n")
|
||
|
sys.exit(1)
|
||
|
finally:
|
||
|
common.Cleanup()
|