blob: e91edda845bdc6b095698e009f41d0252eb675e2 [file] [log] [blame]
# Copyright 2021 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.
import("//build/board.gni")
import("//build/images/args.gni")
import("//build/images/custom_signing.gni")
import("//build/images/fvm.gni")
import("//build/images/vbmeta.gni")
import("//build/images/vboot/vboot.gni")
import("//build/info/info.gni")
import("//build/product.gni")
import("//build/zbi/zbi.gni")
# Generates a board config to be consumed by the Image Assembler.
#
# Arguments
# board_name (required)
# [string] The name of the board.
#
# output_path (required)
# [path] Board config output location.
#
# salt_file (optional)
# [path] Pre-defined salt to use in VBMeta.
#
# recovery (optional)
# [label] Recovery label to include in the update package.
#
# use_esp (optional)
# [bool] Whether to include ESP bootloaders in the update package.
#
# MinFS arguments
# minfs (optional)
# [path] Path to prebuilt MinFS block file.
#
# minfs_minimum_inodes, minfs_minimum_data_bytes, minfs_maximum_bytes (optional)
# [int] Size options for minfs to pass to the fvm tool.
#
# BlobFS arguments
# blob_layout_format (required)
# [string] Layout of the blobs (compact or padded).
#
# compress_blobs (optional)
# [bool] Whether the blobs in BlobFS should be compressed.
#
# blobfs_minimum_inodes, blobfs_minimum_data_bytes, blobfs_maximum_bytes (optional)
# [int] Size options for blobfs to pass to the fvm tool.
#
# FVM arguments
# embed_fvm_in_zbi (optional)
# [bool] Whether the FVM should be embedded into the ZBI as a ramdisk.
#
# fvm_slice_size (required)
# [int] The slice size of the FVM.
#
# ZBI arguments
# zbi_signing_script (optional)
# [path] Location of script to use to sign the ZBI.
#
# zbi_signing_args (optional)
# [list of strings] Arguments to pass to the signing script.
#
template("generated_board_config") {
assert(defined(invoker.board_name), "Need to define board_name")
assert(defined(invoker.output_path), "Need to define output_path")
assert(defined(invoker.blob_layout_format), "Need to define blob_layout_form")
assert(defined(invoker.fvm_slice_size), "Need to define fvm_slice_size")
use_esp = false
if (defined(invoker.use_esp)) {
use_esp = invoker.use_esp
}
generated_file(target_name) {
forward_variables_from(invoker,
[
"salt_file",
"testonly",
])
deps = []
if (defined(invoker.deps)) {
deps += invoker.deps
}
if (use_esp) {
deps += [ "//build/images:esp" ]
}
if (defined(invoker.recovery)) {
deps += [ invoker.recovery ]
}
outputs = [ invoker.output_path ]
output_conversion = "json"
if (fvm_partition != "" && !bootfs_only) {
if (fvm_fastboot_compression != "default") {
fastboot_fvm_compression = fvm_fastboot_compression
}
if (fvm_emmc_partition_size != false) {
fastboot_fvm_type = "emmc"
} else if (fvm_ftl_nand_block_count != false) {
fastboot_fvm_type = "nand"
} else {
assert(
false,
"|fvm_partition| is specified. But failed to determine the target format.")
}
}
if (!bootfs_only) {
if (defined(invoker.minfs)) {
minfs_parameters = {
MinFS = {
path = invoker.minfs
name = "data"
if (defined(invoker.minfs_minimum_inodes)) {
minimum_inodes = invoker.minfs_minimum_inodes
}
if (defined(invoker.minfs_minimum_data_bytes)) {
minimum_data_bytes = invoker.minfs_minimum_data_bytes
}
if (defined(invoker.minfs_maximum_bytes)) {
maximum_bytes = invoker.minfs_maximum_bytes
}
}
}
}
blobfs_parameters = {
BlobFS = {
name = "blob"
if (defined(invoker.blobfs_minimum_inodes)) {
minimum_inodes = invoker.blobfs_minimum_inodes
}
if (defined(invoker.blobfs_minimum_data_bytes)) {
minimum_data_bytes = invoker.blobfs_minimum_data_bytes
}
if (defined(invoker.blobfs_maximum_bytes)) {
maximum_bytes = invoker.blobfs_maximum_bytes
}
}
}
}
contents = {
board_name = invoker.board_name
arch = target_cpu
zbi = {
partition = zircon_a_partition
if (custom_signing_script != "" || use_vboot) {
name = "zbi.signed"
} else {
name = "zbi"
}
max_size = 0
if (defined(invoker.embed_fvm_in_zbi)) {
embed_fvm_in_zbi = invoker.embed_fvm_in_zbi
}
compression = zbi_compression
if (defined(invoker.zbi_signing_script)) {
# Set up the vboot script and its arguments.
# Assembly always passes the -z and -o switches too.
signing_script = {
tool = rebase_path(invoker.zbi_signing_script, root_build_dir)
if (defined(invoker.zbi_signing_args)) {
extra_arguments = invoker.zbi_signing_args
}
}
}
backstop_file =
rebase_path(build_info_files.minimum_utc_stamp, root_build_dir)
}
if (use_vbmeta) {
vbmeta = {
partition = vbmeta_a_partition
kernel_partition = "zircon"
key = rebase_path(avb_key, root_build_dir)
key_metadata = rebase_path(avb_atx_metadata, root_build_dir)
additional_descriptor_files =
rebase_path(board_extra_vbmeta_descriptors, root_build_dir)
# TODO(aaronwood) - Remove when no longer matching against other impl.
if (defined(salt_file)) {
salt = salt_file
}
}
}
blobfs = {
layout = invoker.blob_layout_format
if (defined(invoker.compress_blobs)) {
compress = invoker.compress_blobs
}
}
if (!bootfs_only) {
fvm = {
partition = fvm_partition
slice_size = invoker.fvm_slice_size
reserved_slices = fvm_reserved_slices
if (fvm_max_disk_size != false) {
max_disk_size = fvm_max_disk_size
}
# Generated a fastboot-supported FVM if needed.
if (defined(fastboot_fvm_type)) {
fastboot = {
if (fastboot_fvm_type == "emmc") {
# Format for EMMC.
Emmc = {
if (defined(fastboot_fvm_compression)) {
compression = fastboot_fvm_compression
}
length = fvm_emmc_partition_size
}
} else if (fastboot_fvm_type == "nand") {
# Format for NAND.
Nand = {
if (defined(fastboot_fvm_compression)) {
compression = fastboot_fvm_compression
}
page_size = fvm_ftl_nand_page_size
oob_size = fvm_ftl_nand_oob_size
pages_per_block = fvm_ftl_nand_pages_per_block
block_count = fvm_ftl_nand_block_count
}
}
}
}
if (defined(invoker.minfs)) {
filesystems = [
minfs_parameters,
blobfs_parameters,
]
} else {
filesystems = [ blobfs_parameters ]
}
}
}
# For each firmware item we have as a bootloader, add the correct entry
# for it into the board config.
bootloaders = []
foreach(firmware, firmware_prebuilts) {
bootloaders += [
{
# These can be used unchanged.
forward_variables_from(firmware,
[
"partition",
"type",
])
if (defined(type) && type != "") {
name = "firmware_${firmware.type}"
} else {
name = "firmware"
}
# The source has an optional suffix, which we need to add if present.
source =
rebase_path("${firmware.path}${firmware_prebuilts_path_suffix}",
root_build_dir)
},
]
}
# This is copied from //build/images/BUILD.gn, and should be moved to board
# config files, and not generated.
if (use_esp) {
bootloaders += [
{
type = "esp"
name = "bootloader"
partition = "bootloader"
source =
rebase_path("${root_build_dir}/fuchsia.esp.blk", root_build_dir)
},
]
}
# Recovery varies by product, and needs to be moved out of board config and
# into its own configuration item for `ffx assembly image`
#
# TODO(fxbug.dev/77535)
#
if (defined(invoker.recovery)) {
recovery = {
# Inspect the recovery label's name, as the in-tree recovery and zedboot
# builds have different naming behavior.
#
# This different naming behavior is an artifact of the current build
# process and GN logic, and can all go away after `ffx assembly` is the
# only implementation used in-tree.
#
# At that time, these are always:
# name = "recovery"
# zbi = <path to ZBI that contains recovery>
# Use the `name` variable for this, because all vars that we use in this
# scope will end up in the generated JSON, so let's not use any temporary
# vars and just mutate the fields we need to have in the final until they
# have the right values.
#
# Get the 'name' field of the recovery implementation's GN target.
# e.g. "zedboot" for "//build/images:zedboot"
name = get_label_info(invoker.recovery, "name")
if (name == "zedboot") {
# Zedboot's name is different depending on if, and how, it's post-
# processed for booting by the board's bootloaders.
if (custom_signing_script != "") {
name = "zedboot.signed"
zbi = "zedboot.zbi.signed"
} else if (use_vboot) {
name = "zedboot.signed"
zbi = "zedboot.vboot"
} else {
zbi = "zedboot.zbi"
}
if (use_vbmeta) {
vbmeta = "zedboot.vbmeta"
}
} else {
# All recovery options result in a "recovery.zbi", not the default of
# "${name}.zbi", and need to be named "recovery" in the update package.
name = "recovery"
zbi = "recovery.zbi"
if (use_vbmeta) {
vbmeta = "recovery.vbmeta"
}
}
}
}
}
}
}