1#!/usr/bin/env python3 2 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17""" 18Extract boot.img from a GKI APEX. 19 20Usage: extract_img_from_apex [--tool host_tool [--tool ...]] \ 21 input_gki.apex out_dir 22""" 23 24import logging 25import os 26import sys 27 28import common 29 30APEX_PAYLOAD_FILE = "apex_payload.img" 31APEX_PAYLOAD_BIN_PATH = "/etc/ota/payload.bin" 32 33logger = logging.getLogger(__name__) 34OPTIONS = common.OPTIONS 35 36 37def ExtractImagesFromApex(apex, out_dir): 38 if not os.path.isdir(out_dir): 39 os.makedirs(out_dir) 40 apex_dir = common.UnzipTemp(apex, [APEX_PAYLOAD_FILE]) 41 apex_payload = os.path.join(apex_dir, APEX_PAYLOAD_FILE) 42 43 payload_bin = common.MakeTempFile("payload_", ".bin") 44 debugfs_command = ['debugfs', '-R', "dump {} {}".format( 45 APEX_PAYLOAD_BIN_PATH, payload_bin), apex_payload] 46 47 common.RunAndCheckOutput(debugfs_command) 48 assert os.path.getsize(payload_bin) > 0, payload_bin + " is an empty file!" 49 50 boot_img = os.path.join(out_dir, 'boot.img') 51 with open(boot_img, 'w') as _: 52 pass 53 54 delta_generator_command = [ 55 'delta_generator', 56 '--is_partial_update=true', 57 '--in_file=' + payload_bin, 58 '--partition_names=boot', 59 '--new_partitions=' + boot_img 60 ] 61 common.RunAndCheckOutput(delta_generator_command) 62 63 64def main(argv): 65 def option_handler(o, a): 66 if o == "--tool": 67 name = os.path.basename(a) 68 common.SetHostToolLocation(name, a) 69 else: 70 return False 71 return True 72 73 args = common.ParseOptions( 74 argv, __doc__, 75 extra_long_opts=["tool="], 76 extra_option_handler=option_handler) 77 78 if len(args) != 2: 79 common.Usage(__doc__) 80 sys.exit(1) 81 82 common.InitLogging() 83 84 ExtractImagesFromApex(args[0], args[1]) 85 logger.info("done.") 86 87 88if __name__ == '__main__': 89 try: 90 common.CloseInheritedPipes() 91 main(sys.argv[1:]) 92 except common.ExternalError: 93 logger.exception("\n ERROR:\n") 94 sys.exit(1) 95 finally: 96 common.Cleanup() 97