#!/usr/bin/env python3
#
# Copyright 2015, 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.

"""Creates the boot image."""

from argparse import (ArgumentParser, ArgumentTypeError,
                      FileType, RawDescriptionHelpFormatter)
from hashlib import sha1
from os import fstat
from struct import pack

import array
import collections
import os
import re
import subprocess
import tempfile

# Constant and structure definition is in
# system/tools/mkbootimg/include/bootimg/bootimg.h
BOOT_MAGIC = 'ANDROID!'
BOOT_MAGIC_SIZE = 8
BOOT_NAME_SIZE = 16
BOOT_ARGS_SIZE = 512
BOOT_EXTRA_ARGS_SIZE = 1024
BOOT_IMAGE_HEADER_V1_SIZE = 1648
BOOT_IMAGE_HEADER_V2_SIZE = 1660
BOOT_IMAGE_HEADER_V3_SIZE = 1580
BOOT_IMAGE_HEADER_V3_PAGESIZE = 4096
BOOT_IMAGE_HEADER_V4_SIZE = 1584
BOOT_IMAGE_V4_SIGNATURE_SIZE = 4096

VENDOR_BOOT_MAGIC = 'VNDRBOOT'
VENDOR_BOOT_MAGIC_SIZE = 8
VENDOR_BOOT_NAME_SIZE = BOOT_NAME_SIZE
VENDOR_BOOT_ARGS_SIZE = 2048
VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
VENDOR_BOOT_IMAGE_HEADER_V4_SIZE = 2128

VENDOR_RAMDISK_TYPE_NONE = 0
VENDOR_RAMDISK_TYPE_PLATFORM = 1
VENDOR_RAMDISK_TYPE_RECOVERY = 2
VENDOR_RAMDISK_TYPE_DLKM = 3
VENDOR_RAMDISK_NAME_SIZE = 32
VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE = 16
VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE = 108

# Names with special meaning, mustn't be specified in --ramdisk_name.
VENDOR_RAMDISK_NAME_BLOCKLIST = {b'default'}

PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT = '--vendor_ramdisk_fragment'


def filesize(f):
    if f is None:
        return 0
    try:
        return fstat(f.fileno()).st_size
    except OSError:
        return 0


def update_sha(sha, f):
    if f:
        sha.update(f.read())
        f.seek(0)
        sha.update(pack('I', filesize(f)))
    else:
        sha.update(pack('I', 0))


def pad_file(f, padding):
    pad = (padding - (f.tell() & (padding - 1))) & (padding - 1)
    f.write(pack(str(pad) + 'x'))


def get_number_of_pages(image_size, page_size):
    """calculates the number of pages required for the image"""
    return (image_size + page_size - 1) // page_size


def get_recovery_dtbo_offset(args):
    """calculates the offset of recovery_dtbo image in the boot image"""
    num_header_pages = 1 # header occupies a page
    num_kernel_pages = get_number_of_pages(filesize(args.kernel), args.pagesize)
    num_ramdisk_pages = get_number_of_pages(filesize(args.ramdisk),
                                            args.pagesize)
    num_second_pages = get_number_of_pages(filesize(args.second), args.pagesize)
    dtbo_offset = args.pagesize * (num_header_pages + num_kernel_pages +
                                   num_ramdisk_pages + num_second_pages)
    return dtbo_offset


def write_header_v3_and_above(args):
    if args.header_version > 3:
        boot_header_size = BOOT_IMAGE_HEADER_V4_SIZE
    else:
        boot_header_size = BOOT_IMAGE_HEADER_V3_SIZE

    args.output.write(pack(f'{BOOT_MAGIC_SIZE}s', BOOT_MAGIC.encode()))
    # kernel size in bytes
    args.output.write(pack('I', filesize(args.kernel)))
    # ramdisk size in bytes
    args.output.write(pack('I', filesize(args.ramdisk)))
    # os version and patch level
    args.output.write(pack('I', (args.os_version << 11) | args.os_patch_level))
    args.output.write(pack('I', boot_header_size))
    # reserved
    args.output.write(pack('4I', 0, 0, 0, 0))
    # version of boot image header
    args.output.write(pack('I', args.header_version))
    args.output.write(pack(f'{BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE}s',
                           args.cmdline))
    if args.header_version >= 4:
        # The signature used to verify boot image v4.
        args.output.write(pack('I', BOOT_IMAGE_V4_SIGNATURE_SIZE))
    pad_file(args.output, BOOT_IMAGE_HEADER_V3_PAGESIZE)


def write_vendor_boot_header(args):
    if filesize(args.dtb) == 0:
        raise ValueError('DTB image must not be empty.')

    if args.header_version > 3:
        vendor_ramdisk_size = args.vendor_ramdisk_total_size
        vendor_boot_header_size = VENDOR_BOOT_IMAGE_HEADER_V4_SIZE
    else:
        vendor_ramdisk_size = filesize(args.vendor_ramdisk)
        vendor_boot_header_size = VENDOR_BOOT_IMAGE_HEADER_V3_SIZE

    args.vendor_boot.write(pack(f'{VENDOR_BOOT_MAGIC_SIZE}s',
                                VENDOR_BOOT_MAGIC.encode()))
    # version of boot image header
    args.vendor_boot.write(pack('I', args.header_version))
    # flash page size
    args.vendor_boot.write(pack('I', args.pagesize))
    # kernel physical load address
    args.vendor_boot.write(pack('I', args.base + args.kernel_offset))
    # ramdisk physical load address
    args.vendor_boot.write(pack('I', args.base + args.ramdisk_offset))
    # ramdisk size in bytes
    args.vendor_boot.write(pack('I', vendor_ramdisk_size))
    args.vendor_boot.write(pack(f'{VENDOR_BOOT_ARGS_SIZE}s',
                                args.vendor_cmdline))
    # kernel tags physical load address
    args.vendor_boot.write(pack('I', args.base + args.tags_offset))
    # asciiz product name
    args.vendor_boot.write(pack(f'{VENDOR_BOOT_NAME_SIZE}s', args.board))

    # header size in bytes
    args.vendor_boot.write(pack('I', vendor_boot_header_size))

    # dtb size in bytes
    args.vendor_boot.write(pack('I', filesize(args.dtb)))
    # dtb physical load address
    args.vendor_boot.write(pack('Q', args.base + args.dtb_offset))

    if args.header_version > 3:
        vendor_ramdisk_table_size = (args.vendor_ramdisk_table_entry_num *
                                     VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE)
        # vendor ramdisk table size in bytes
        args.vendor_boot.write(pack('I', vendor_ramdisk_table_size))
        # number of vendor ramdisk table entries
        args.vendor_boot.write(pack('I', args.vendor_ramdisk_table_entry_num))
        # vendor ramdisk table entry size in bytes
        args.vendor_boot.write(pack('I', VENDOR_RAMDISK_TABLE_ENTRY_V4_SIZE))
        # bootconfig section size in bytes
        args.vendor_boot.write(pack('I', filesize(args.vendor_bootconfig)))
    pad_file(args.vendor_boot, args.pagesize)


def write_header(args):
    if args.header_version > 4:
        raise ValueError(
            f'Boot header version {args.header_version} not supported')
    if args.header_version in {3, 4}:
        return write_header_v3_and_above(args)

    ramdisk_load_address = ((args.base + args.ramdisk_offset)
                            if filesize(args.ramdisk) > 0 else 0)
    second_load_address = ((args.base + args.second_offset)
                           if filesize(args.second) > 0 else 0)

    args.output.write(pack(f'{BOOT_MAGIC_SIZE}s', BOOT_MAGIC.encode()))
    # kernel size in bytes
    args.output.write(pack('I', filesize(args.kernel)))
    # kernel physical load address
    args.output.write(pack('I', args.base + args.kernel_offset))
    # ramdisk size in bytes
    args.output.write(pack('I', filesize(args.ramdisk)))
    # ramdisk physical load address
    args.output.write(pack('I', ramdisk_load_address))
    # second bootloader size in bytes
    args.output.write(pack('I', filesize(args.second)))
    # second bootloader physical load address
    args.output.write(pack('I', second_load_address))
    # kernel tags physical load address
    args.output.write(pack('I', args.base + args.tags_offset))
    # flash page size
    args.output.write(pack('I', args.pagesize))
    # version of boot image header
    args.output.write(pack('I', args.header_version))
    # os version and patch level
    args.output.write(pack('I', (args.os_version << 11) | args.os_patch_level))
    # asciiz product name
    args.output.write(pack(f'{BOOT_NAME_SIZE}s', args.board))
    args.output.write(pack(f'{BOOT_ARGS_SIZE}s', args.cmdline))

    sha = sha1()
    update_sha(sha, args.kernel)
    update_sha(sha, args.ramdisk)
    update_sha(sha, args.second)

    if args.header_version > 0:
        update_sha(sha, args.recovery_dtbo)
    if args.header_version > 1:
        update_sha(sha, args.dtb)

    img_id = pack('32s', sha.digest())

    args.output.write(img_id)
    args.output.write(pack(f'{BOOT_EXTRA_ARGS_SIZE}s', args.extra_cmdline))

    if args.header_version > 0:
        if args.recovery_dtbo:
            # recovery dtbo size in bytes
            args.output.write(pack('I', filesize(args.recovery_dtbo)))
            # recovert dtbo offset in the boot image
            args.output.write(pack('Q', get_recovery_dtbo_offset(args)))
        else:
            # Set to zero if no recovery dtbo
            args.output.write(pack('I', 0))
            args.output.write(pack('Q', 0))

    # Populate boot image header size for header versions 1 and 2.
    if args.header_version == 1:
        args.output.write(pack('I', BOOT_IMAGE_HEADER_V1_SIZE))
    elif args.header_version == 2:
        args.output.write(pack('I', BOOT_IMAGE_HEADER_V2_SIZE))

    if args.header_version > 1:
        if filesize(args.dtb) == 0:
            raise ValueError('DTB image must not be empty.')

        # dtb size in bytes
        args.output.write(pack('I', filesize(args.dtb)))
        # dtb physical load address
        args.output.write(pack('Q', args.base + args.dtb_offset))

    pad_file(args.output, args.pagesize)
    return img_id


class AsciizBytes:
    """Parses a string and encodes it as an asciiz bytes object.

    >>> AsciizBytes(bufsize=4)('foo')
    b'foo\\x00'
    >>> AsciizBytes(bufsize=4)('foob')
    Traceback (most recent call last):
        ...
    argparse.ArgumentTypeError: Encoded asciiz length exceeded: max 4, got 5
    """

    def __init__(self, bufsize):
        self.bufsize = bufsize

    def __call__(self, arg):
        arg_bytes = arg.encode() + b'\x00'
        if len(arg_bytes) > self.bufsize:
            raise ArgumentTypeError(
                'Encoded asciiz length exceeded: '
                f'max {self.bufsize}, got {len(arg_bytes)}')
        return arg_bytes


class VendorRamdiskTableBuilder:
    """Vendor ramdisk table builder.

    Attributes:
        entries: A list of VendorRamdiskTableEntry namedtuple.
        ramdisk_total_size: Total size in bytes of all ramdisks in the table.
    """

    VendorRamdiskTableEntry = collections.namedtuple(  # pylint: disable=invalid-name
        'VendorRamdiskTableEntry',
        ['ramdisk_path', 'ramdisk_size', 'ramdisk_offset', 'ramdisk_type',
         'ramdisk_name', 'board_id'])

    def __init__(self):
        self.entries = []
        self.ramdisk_total_size = 0
        self.ramdisk_names = set()

    def add_entry(self, ramdisk_path, ramdisk_type, ramdisk_name, board_id):
        # Strip any trailing null for simple comparison.
        stripped_ramdisk_name = ramdisk_name.rstrip(b'\x00')
        if stripped_ramdisk_name in VENDOR_RAMDISK_NAME_BLOCKLIST:
            raise ValueError(
                f'Banned vendor ramdisk name: {stripped_ramdisk_name}')
        if stripped_ramdisk_name in self.ramdisk_names:
            raise ValueError(
                f'Duplicated vendor ramdisk name: {stripped_ramdisk_name}')
        self.ramdisk_names.add(stripped_ramdisk_name)

        if board_id is None:
            board_id = array.array(
                'I', [0] * VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE)
        else:
            board_id = array.array('I', board_id)
        if len(board_id) != VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE:
            raise ValueError('board_id size must be '
                             f'{VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE}')

        with open(ramdisk_path, 'rb') as f:
            ramdisk_size = filesize(f)
        self.entries.append(self.VendorRamdiskTableEntry(
            ramdisk_path, ramdisk_size, self.ramdisk_total_size, ramdisk_type,
            ramdisk_name, board_id))
        self.ramdisk_total_size += ramdisk_size

    def write_ramdisks_padded(self, fout, alignment):
        for entry in self.entries:
            with open(entry.ramdisk_path, 'rb') as f:
                fout.write(f.read())
        pad_file(fout, alignment)

    def write_entries_padded(self, fout, alignment):
        for entry in self.entries:
            fout.write(pack('I', entry.ramdisk_size))
            fout.write(pack('I', entry.ramdisk_offset))
            fout.write(pack('I', entry.ramdisk_type))
            fout.write(pack(f'{VENDOR_RAMDISK_NAME_SIZE}s',
                            entry.ramdisk_name))
            fout.write(entry.board_id)
        pad_file(fout, alignment)


def write_padded_file(f_out, f_in, padding):
    if f_in is None:
        return
    f_out.write(f_in.read())
    pad_file(f_out, padding)


def parse_int(x):
    return int(x, 0)


def parse_os_version(x):
    match = re.search(r'^(\d{1,3})(?:\.(\d{1,3})(?:\.(\d{1,3}))?)?', x)
    if match:
        a = int(match.group(1))
        b = c = 0
        if match.lastindex >= 2:
            b = int(match.group(2))
        if match.lastindex == 3:
            c = int(match.group(3))
        # 7 bits allocated for each field
        assert a < 128
        assert b < 128
        assert c < 128
        return (a << 14) | (b << 7) | c
    return 0


def parse_os_patch_level(x):
    match = re.search(r'^(\d{4})-(\d{2})(?:-(\d{2}))?', x)
    if match:
        y = int(match.group(1)) - 2000
        m = int(match.group(2))
        # 7 bits allocated for the year, 4 bits for the month
        assert 0 <= y < 128
        assert 0 < m <= 12
        return (y << 4) | m
    return 0


def parse_vendor_ramdisk_type(x):
    type_dict = {
        'none': VENDOR_RAMDISK_TYPE_NONE,
        'platform': VENDOR_RAMDISK_TYPE_PLATFORM,
        'recovery': VENDOR_RAMDISK_TYPE_RECOVERY,
        'dlkm': VENDOR_RAMDISK_TYPE_DLKM,
    }
    if x.lower() in type_dict:
        return type_dict[x.lower()]
    return parse_int(x)


def get_vendor_boot_v4_usage():
    return """vendor boot version 4 arguments:
  --ramdisk_type {none,platform,recovery,dlkm}
                        specify the type of the ramdisk
  --ramdisk_name NAME
                        specify the name of the ramdisk
  --board_id{0..15} NUMBER
                        specify the value of the board_id vector, defaults to 0
  --vendor_ramdisk_fragment VENDOR_RAMDISK_FILE
                        path to the vendor ramdisk file

  These options can be specified multiple times, where each vendor ramdisk
  option group ends with a --vendor_ramdisk_fragment option.
  Each option group appends an additional ramdisk to the vendor boot image.
"""


def parse_vendor_ramdisk_args(args, args_list):
    """Parses vendor ramdisk specific arguments.

    Args:
        args: An argparse.Namespace object. Parsed results are stored into this
            object.
        args_list: A list of argument strings to be parsed.

    Returns:
        A list argument strings that are not parsed by this method.
    """
    parser = ArgumentParser(add_help=False)
    parser.add_argument('--ramdisk_type', type=parse_vendor_ramdisk_type,
                        default=VENDOR_RAMDISK_TYPE_NONE)
    parser.add_argument('--ramdisk_name',
                        type=AsciizBytes(bufsize=VENDOR_RAMDISK_NAME_SIZE),
                        required=True)
    for i in range(VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE):
        parser.add_argument(f'--board_id{i}', type=parse_int, default=0)
    parser.add_argument(PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT, required=True)

    unknown_args = []

    vendor_ramdisk_table_builder = VendorRamdiskTableBuilder()
    if args.vendor_ramdisk is not None:
        vendor_ramdisk_table_builder.add_entry(
            args.vendor_ramdisk.name, VENDOR_RAMDISK_TYPE_PLATFORM, b'', None)

    while PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT in args_list:
        idx = args_list.index(PARSER_ARGUMENT_VENDOR_RAMDISK_FRAGMENT) + 2
        vendor_ramdisk_args = args_list[:idx]
        args_list = args_list[idx:]

        ramdisk_args, extra_args = parser.parse_known_args(vendor_ramdisk_args)
        ramdisk_args_dict = vars(ramdisk_args)
        unknown_args.extend(extra_args)

        ramdisk_path = ramdisk_args.vendor_ramdisk_fragment
        ramdisk_type = ramdisk_args.ramdisk_type
        ramdisk_name = ramdisk_args.ramdisk_name
        board_id = [ramdisk_args_dict[f'board_id{i}']
                    for i in range(VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE)]
        vendor_ramdisk_table_builder.add_entry(ramdisk_path, ramdisk_type,
                                               ramdisk_name, board_id)

    if len(args_list) > 0:
        unknown_args.extend(args_list)

    args.vendor_ramdisk_total_size = (vendor_ramdisk_table_builder
                                      .ramdisk_total_size)
    args.vendor_ramdisk_table_entry_num = len(vendor_ramdisk_table_builder
                                              .entries)
    args.vendor_ramdisk_table_builder = vendor_ramdisk_table_builder
    return unknown_args


def parse_cmdline():
    version_parser = ArgumentParser(add_help=False)
    version_parser.add_argument('--header_version', type=parse_int, default=0)
    if version_parser.parse_known_args()[0].header_version < 3:
        # For boot header v0 to v2, the kernel commandline field is split into
        # two fields, cmdline and extra_cmdline. Both fields are asciiz strings,
        # so we minus one here to ensure the encoded string plus the
        # null-terminator can fit in the buffer size.
        cmdline_size = BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE - 1
    else:
        cmdline_size = BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE

    parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter,
                            epilog=get_vendor_boot_v4_usage())
    parser.add_argument('--kernel', type=FileType('rb'),
                        help='path to the kernel')
    parser.add_argument('--ramdisk', type=FileType('rb'),
                        help='path to the ramdisk')
    parser.add_argument('--second', type=FileType('rb'),
                        help='path to the second bootloader')
    parser.add_argument('--dtb', type=FileType('rb'), help='path to the dtb')
    dtbo_group = parser.add_mutually_exclusive_group()
    dtbo_group.add_argument('--recovery_dtbo', type=FileType('rb'),
                            help='path to the recovery DTBO')
    dtbo_group.add_argument('--recovery_acpio', type=FileType('rb'),
                            metavar='RECOVERY_ACPIO', dest='recovery_dtbo',
                            help='path to the recovery ACPIO')
    parser.add_argument('--cmdline', type=AsciizBytes(bufsize=cmdline_size),
                        default='', help='kernel command line arguments')
    parser.add_argument('--vendor_cmdline',
                        type=AsciizBytes(bufsize=VENDOR_BOOT_ARGS_SIZE),
                        default='',
                        help='vendor boot kernel command line arguments')
    parser.add_argument('--base', type=parse_int, default=0x10000000,
                        help='base address')
    parser.add_argument('--kernel_offset', type=parse_int, default=0x00008000,
                        help='kernel offset')
    parser.add_argument('--ramdisk_offset', type=parse_int, default=0x01000000,
                        help='ramdisk offset')
    parser.add_argument('--second_offset', type=parse_int, default=0x00f00000,
                        help='second bootloader offset')
    parser.add_argument('--dtb_offset', type=parse_int, default=0x01f00000,
                        help='dtb offset')

    parser.add_argument('--os_version', type=parse_os_version, default=0,
                        help='operating system version')
    parser.add_argument('--os_patch_level', type=parse_os_patch_level,
                        default=0, help='operating system patch level')
    parser.add_argument('--tags_offset', type=parse_int, default=0x00000100,
                        help='tags offset')
    parser.add_argument('--board', type=AsciizBytes(bufsize=BOOT_NAME_SIZE),
                        default='', help='board name')
    parser.add_argument('--pagesize', type=parse_int,
                        choices=[2**i for i in range(11, 15)], default=2048,
                        help='page size')
    parser.add_argument('--id', action='store_true',
                        help='print the image ID on standard output')
    parser.add_argument('--header_version', type=parse_int, default=0,
                        help='boot image header version')
    parser.add_argument('-o', '--output', type=FileType('wb'),
                        help='output file name')
    parser.add_argument('--gki_signing_algorithm',
                        help='GKI signing algorithm to use')
    parser.add_argument('--gki_signing_key',
                        help='path to RSA private key file')
    parser.add_argument('--gki_signing_signature_args',
                        help='other hash arguments passed to avbtool')
    parser.add_argument('--gki_signing_avbtool_path',
                        help='path to avbtool for boot signature generation')
    parser.add_argument('--vendor_boot', type=FileType('wb'),
                        help='vendor boot output file name')
    parser.add_argument('--vendor_ramdisk', type=FileType('rb'),
                        help='path to the vendor ramdisk')
    parser.add_argument('--vendor_bootconfig', type=FileType('rb'),
                        help='path to the vendor bootconfig file')

    args, extra_args = parser.parse_known_args()
    if args.vendor_boot is not None and args.header_version > 3:
        extra_args = parse_vendor_ramdisk_args(args, extra_args)
    if len(extra_args) > 0:
        raise ValueError(f'Unrecognized arguments: {extra_args}')

    if args.header_version < 3:
        args.extra_cmdline = args.cmdline[BOOT_ARGS_SIZE-1:]
        args.cmdline = args.cmdline[:BOOT_ARGS_SIZE-1] + b'\x00'
        assert len(args.cmdline) <= BOOT_ARGS_SIZE
        assert len(args.extra_cmdline) <= BOOT_EXTRA_ARGS_SIZE

    return args


def add_boot_image_signature(args, pagesize):
    """Adds the boot image signature.

    Note that the signature will only be verified in VTS to ensure a
    generic boot.img is used. It will not be used by the device
    bootloader at boot time. The bootloader should only verify
    the boot vbmeta at the end of the boot partition (or in the top-level
    vbmeta partition) via the Android Verified Boot process, when the
    device boots.
    """
    args.output.flush()  # Flush the buffer for signature calculation.

    # Appends zeros if the signing key is not specified.
    if not args.gki_signing_key or not args.gki_signing_algorithm:
        zeros = b'\x00' * BOOT_IMAGE_V4_SIGNATURE_SIZE
        args.output.write(zeros)
        pad_file(args.output, pagesize)
        return

    avbtool = 'avbtool'  # Used from otatools.zip or Android build env.

    # We need to specify the path of avbtool in build/core/Makefile.
    # Because avbtool is not guaranteed to be in $PATH there.
    if args.gki_signing_avbtool_path:
        avbtool = args.gki_signing_avbtool_path

    # Need to specify a value of --partition_size for avbtool to work.
    # We use 64 MB below, but avbtool will not resize the boot image to
    # this size because --do_not_append_vbmeta_image is also specified.
    avbtool_cmd = [
        avbtool, 'add_hash_footer',
        '--partition_name', 'boot',
        '--partition_size', str(64 * 1024 * 1024),
        '--image', args.output.name,
        '--algorithm', args.gki_signing_algorithm,
        '--key', args.gki_signing_key,
        '--salt', 'd00df00d']  # TODO: use a hash of kernel/ramdisk as the salt.

    # Additional arguments passed to avbtool.
    if args.gki_signing_signature_args:
        avbtool_cmd += args.gki_signing_signature_args.split()

    # Outputs the signed vbmeta to a separate file, then append to boot.img
    # as the boot signature.
    with tempfile.TemporaryDirectory() as temp_out_dir:
        boot_signature_output = os.path.join(temp_out_dir, 'boot_signature')
        avbtool_cmd += ['--do_not_append_vbmeta_image',
                        '--output_vbmeta_image', boot_signature_output]
        subprocess.check_call(avbtool_cmd)
        with open(boot_signature_output, 'rb') as boot_signature:
            if filesize(boot_signature) > BOOT_IMAGE_V4_SIGNATURE_SIZE:
                raise ValueError(
                    f'boot sigature size is > {BOOT_IMAGE_V4_SIGNATURE_SIZE}')
            write_padded_file(args.output, boot_signature, pagesize)


def write_data(args, pagesize):
    write_padded_file(args.output, args.kernel, pagesize)
    write_padded_file(args.output, args.ramdisk, pagesize)
    write_padded_file(args.output, args.second, pagesize)

    if args.header_version > 0 and args.header_version < 3:
        write_padded_file(args.output, args.recovery_dtbo, pagesize)
    if args.header_version == 2:
        write_padded_file(args.output, args.dtb, pagesize)
    if args.header_version >= 4:
        add_boot_image_signature(args, pagesize)


def write_vendor_boot_data(args):
    if args.header_version > 3:
        builder = args.vendor_ramdisk_table_builder
        builder.write_ramdisks_padded(args.vendor_boot, args.pagesize)
        write_padded_file(args.vendor_boot, args.dtb, args.pagesize)
        builder.write_entries_padded(args.vendor_boot, args.pagesize)
        write_padded_file(args.vendor_boot, args.vendor_bootconfig,
            args.pagesize)
    else:
        write_padded_file(args.vendor_boot, args.vendor_ramdisk, args.pagesize)
        write_padded_file(args.vendor_boot, args.dtb, args.pagesize)


def main():
    args = parse_cmdline()
    if args.vendor_boot is not None:
        if args.header_version not in {3, 4}:
            raise ValueError(
                '--vendor_boot not compatible with given header version')
        if args.header_version == 3 and args.vendor_ramdisk is None:
            raise ValueError('--vendor_ramdisk missing or invalid')
        write_vendor_boot_header(args)
        write_vendor_boot_data(args)
    if args.output is not None:
        if args.second is not None and args.header_version > 2:
            raise ValueError(
                '--second not compatible with given header version')
        img_id = write_header(args)
        if args.header_version > 2:
            write_data(args, BOOT_IMAGE_HEADER_V3_PAGESIZE)
        else:
            write_data(args, args.pagesize)
        if args.id and img_id is not None:
            print('0x' + ''.join(f'{octet:02x}' for octet in img_id))


if __name__ == '__main__':
    main()
