• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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