#!/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()