blob: a2cd1cffbc3e84c20f107782946c5b7733e1f033 [file] [log] [blame]
# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Generates an Images Config. See the specification here:
# https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/developer/ffx/plugins/assembly/#images-config
#
# Parameters:
#
# output_path (optional)
# [string] Where to write the images config to.
# Defaults to $target_out_dir/$target_name.json
#
# zbi (required)
# [struct] Arguments for generating a ZBI.
# {
# name (required)
# [string] The name to give the ZBI in the out directory.
# Typically: fuchsia, recovery, etc.
# compression (optional; default = "zstd")
# [string] The compression format to use for the ZBI.
# Example: "zstd.max".
# signing_script (optional)
# [path] Location of script to use to sign the ZBI.
# signing_args (optional)
# [list of strings] Arguments to pass to the signing script.
# }
#
# vbmeta (optional)
# [scope] Arguments for generating an optional VBMeta.
# {
# key (required)
# [path] Path on host to the key for signing VBMeta.
# key_metadata (required)
# [path] Path on host to the key metadata to add to the VBMeta.
# extra_descriptors (optional)
# [list] Optional descriptors to add to the VBMeta image.
# Each descriptor has the format:
# {
# size (required)
# [int] Size of the partitions in bytes.
# flags (required)
# [int] Custom VBMeta flags to add.
# min_avb_version (required)
# [string] Minimum AVB version to add.
# }
# }
#
# fvm (optional)
# [struct] Arguments for generating optional FVMs.
# {
#
# ### Parameters
# slice_size (optional)
# [int] The slice size of the FVM.
# truncate_to_length (optional)
# [int] After the optional resize for standard FVMs, truncate the file
# to this length.
# max_disk_size (optional)
# [int] The maximum size the FVM can expand to at runtime.
# This sets the amount of slice metadata to allocate duringx
# construction, which cannot be modified at runtime.
# empty_account_partition (optional)
# [bool] Include an empty account partition.
#
# ### Filesystems
# blobfs
# {
# compress (optional)
# [bool] Whether the blobs added to the blobfs image should be compressed.
# layout (optional)
# [string] The format blobfs should store blobs in. The valid values are
# "deprecated_padded" and "compact". The deprecated padded format is
# supported only for Astro devices and will be removed in the future (it
# wastes space).
# minimum_inodes, minimum_data_bytes, maximum_bytes (optional)
# [int] Size options for blobfs to pass to the fvm tool.
# maximum_contents_size (optional)
# [int] The maximum bytes the blobfs can contain. This is used by
# size checker.
# }
#
# reserved
# {
# slices (required)
# [int] The number of slices to reserve in the FVM.
# }
#
# ### Optional Outputs
# (standard, sparse, and blob-sparse are generated by default)
#
# nand
# {
# compress (required)
# [string] Whether to compress the FVM.
# max_disk_size (optional)
# [int] The maximum size the FVM can expand to at runtime.
# This sets the amount of slice metadata to allocate duringx
# construction, which cannot be modified at runtime.
# block_count (required)
# oob_size (required)
# page_size (required)
# pages_per_block (required)
# }
#
# emmc
# {
# compress (required)
# [string] Whether to compress the FVM.
# truncate_to_length (optional)
# [int] After the optional resize, truncate the file to this length.
# }
# }
#
# fxfs (optional)
# [struct] Arguments for generating optional Fxfs images containing a nested Blobfs instance.
# {
#
# ### Parameters
# reserved_space_bytes
# [int] How many extra bytes to allocate in Fxfs.
#
# }
#
template("generated_images_config") {
output_path = "$target_out_dir/$target_name.json"
if (defined(invoker.output_path)) {
output_path = invoker.output_path
}
# ZBI
assert(defined(invoker.zbi), "Need to define zbi")
invoker_zbi = invoker.zbi
assert(defined(invoker_zbi.name), "Need to define zbi.name")
zbi_compression = "zstd"
if (defined(invoker_zbi.compression)) {
zbi_compression = invoker_zbi.compression
}
zbi = {
type = "zbi"
name = invoker_zbi.name
compression = zbi_compression
if (defined(invoker_zbi.signing_script)) {
postprocessing_script = {
path = rebase_path(invoker_zbi.signing_script, root_build_dir)
if (defined(invoker_zbi.signing_args)) {
args = invoker_zbi.signing_args
}
}
}
}
# VBMeta
if (defined(invoker.vbmeta)) {
invoker_vbmeta = invoker.vbmeta
assert(defined(invoker_vbmeta.key), "Need to define vbmeta.key")
assert(defined(invoker_vbmeta.key_metadata),
"Need to define vbmeta.key_metadata")
vbmeta = {
type = "vbmeta"
name = invoker_zbi.name
key = rebase_path(invoker_vbmeta.key, root_build_dir)
key_metadata = rebase_path(invoker_vbmeta.key_metadata, root_build_dir)
if (defined(invoker_vbmeta.extra_descriptors)) {
additional_descriptors = invoker_vbmeta.extra_descriptors
}
}
}
# FVMs.
if (defined(invoker.fvm)) {
invoker_fvm = invoker.fvm
# Collect all the filesystems that can be put in FVMs.
blobfs = {
type = "blobfs"
name = "blob"
if (defined(invoker_fvm.blobfs)) {
forward_variables_from(invoker_fvm.blobfs, "*")
}
}
empty_data = {
type = "empty-data"
name = "empty-data"
}
fvm_filesystems = [
blobfs,
empty_data,
]
# Optionally, reserve some slices in the FVM.
if (defined(invoker_fvm.reserved)) {
invoker_reserved = invoker_fvm.reserved
reserved = {
type = "reserved"
name = "internal"
slices = invoker_reserved.slices
}
fvm_filesystems += [ reserved ]
}
standard_fvm = {
type = "standard"
name = "fvm"
filesystems = [
"empty-data",
"blob",
]
if (defined(reserved)) {
filesystems += [ "internal" ]
}
if (defined(invoker_fvm.truncate_to_length)) {
truncate_to_length = invoker_fvm.truncate_to_length
}
}
sparse_fvm = {
type = "sparse"
name = "fvm.sparse"
filesystems = [
"empty-data",
"blob",
]
if (defined(reserved)) {
filesystems += [ "internal" ]
}
if (defined(invoker_fvm.max_disk_size)) {
max_disk_size = invoker_fvm.max_disk_size
}
}
blob_sparse_fvm = {
type = "sparse"
name = "fvm.blob.sparse"
filesystems = [
"empty-data",
"blob",
]
if (defined(reserved)) {
filesystems += [ "internal" ]
}
if (defined(invoker_fvm.max_disk_size)) {
max_disk_size = invoker_fvm.max_disk_size
}
}
if (defined(invoker_fvm.emmc)) {
invoker_emmc = invoker_fvm.emmc
assert(defined(invoker_emmc.compress), "Need to define fvm.emmc.compress")
emmc_fvm = {
type = "standard"
name = "fvm.fastboot"
compress = invoker_emmc.compress
resize_image_file_to_fit = true
filesystems = [
"empty-data",
"blob",
]
if (defined(reserved)) {
filesystems += [ "internal" ]
}
if (defined(invoker_fvm.max_disk_size)) {
max_disk_size = invoker_fvm.max_disk_size
}
if (defined(invoker_emmc.truncate_to_length)) {
truncate_to_length = invoker_emmc.truncate_to_length
}
}
} else if (defined(invoker_fvm.nand)) {
invoker_nand = invoker_fvm.nand
assert(defined(invoker_nand.compress), "Need to define fvm.nand.compress")
assert(defined(invoker_nand.block_count),
"Need to define fvm.nand.block_count")
assert(defined(invoker_nand.oob_size), "Need to define fvm.nand.oob_size")
assert(defined(invoker_nand.page_size),
"Need to define fvm.nand.page_size")
assert(defined(invoker_nand.pages_per_block),
"Need to define fvm.nand.pages_per_block")
nand_fvm = {
type = "nand"
name = "fvm.fastboot"
compress = invoker_nand.compress
block_count = invoker_nand.block_count
oob_size = invoker_nand.oob_size
page_size = invoker_nand.page_size
pages_per_block = invoker_nand.pages_per_block
filesystems = [
"empty-data",
"blob",
]
if (defined(reserved)) {
filesystems += [ "internal" ]
}
if (defined(invoker_fvm.max_disk_size)) {
max_disk_size = invoker_fvm.max_disk_size
}
}
}
# Collect the fvms to generate.
fvm_outputs = [
standard_fvm,
sparse_fvm,
blob_sparse_fvm,
]
# Optionally, include a fastboot fvm.
if (defined(emmc_fvm)) {
fvm_outputs += [ emmc_fvm ]
not_needed([ "nand_fvm" ])
} else if (defined(nand_fvm)) {
fvm_outputs += [ nand_fvm ]
not_needed([ "emmc_fvm" ])
} else {
not_needed([
"nand_fvm",
"emmc_fvm",
])
}
# Define an optional fvm
fvm = {
type = "fvm"
# The size of a slice within the FVM.
if (defined(invoker_fvm.slice_size)) {
slice_size = invoker_fvm.slice_size
}
# The list of filesystems to generate that can be added to the outputs.
filesystems = fvm_filesystems
# The FVM images to generate.
outputs = fvm_outputs
}
}
# Fxfs.
if (defined(invoker.fxfs)) {
invoker_fxfs = invoker.fxfs
fxfs = {
type = "fxfs"
if (defined(invoker_fxfs.reserved_space_bytes)) {
reserved_space_bytes = invoker_fxfs.reserved_space_bytes
} else {
not_needed([ "invoker_fxfs" ])
}
}
}
generated_file(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
"deps",
])
outputs = [ output_path ]
output_conversion = "json"
# Construct the list of images to assemble.
_images = [ zbi ]
if (defined(vbmeta)) {
_images += [ vbmeta ]
}
if (defined(fvm)) {
_images += [ fvm ]
}
if (defined(fxfs)) {
_images += [ fxfs ]
}
contents = {
images = _images
}
}
}