blob: 71d76dfd41993393460a6f4af4ba2f355e573921 [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.
import("//build/bazel/bazel_inputs.gni")
import("//build/board.gni")
import("//build/images/custom_signing.gni")
import("//build/images/flash/parts.gni")
import("//build/images/vboot/vboot.gni")
import("//build/sdk/config.gni")
import("//build/sdk/physical_device.gni")
import("//build/sdk/product_metadata.gni")
import("//build/sdk/virtual_device.gni")
assert(current_toolchain == default_toolchain,
"//build/images/* are only valid in the Fuchsia toolchain")
# Deps that are added to the //build/images:default_image_deps target.
flash_image_deps = []
# Track some firmware information locally so we can flash it without
# re-calculating all the names and paths.
firmware_info = []
# EFI ESP images.
group("esp") {
public_deps = [ "//src/firmware/gigaboot/cpp:fuchsia" ]
}
bazel_input_resource("esp.bazel_input") {
sources = [ "${root_build_dir}/fuchsia.esp.blk" ]
outputs = [ "fuchsia.esp.blk" ]
deps = [ ":esp" ]
}
if (use_gigaboot) {
flash_image_deps += [ ":esp" ]
firmware_info += [
{
name = "esp"
partition = "fuchsia-esp"
out_path = rebase_path(files.esp, root_build_dir)
},
]
}
foreach(firmware, firmware_prebuilts) {
if (firmware.type == "") {
# Don't add a trailing delimiter if firmware.type is empty.
name = "firmware"
bootserver_arg = "--firmware"
} else {
name = "firmware_${firmware.type}"
bootserver_arg = "--firmware-${firmware.type}"
}
copy(name) {
testonly = true
sources = [ "${firmware.path}${firmware_prebuilts_path_suffix}" ]
outputs = [ "$root_out_dir/$name.img" ]
metadata = {
images = [
{
label = get_label_info(":$name", "label_with_toolchain")
archive = true
bootserver_pave = [ bootserver_arg ]
bootserver_pave_zedboot = [ bootserver_arg ]
name = name
path = "$name.img"
type = "img"
if (defined(firmware.partition)) {
fastboot_flash = [ firmware.partition ]
}
},
]
}
}
flash_image_deps += [ ":$name" ]
if (defined(firmware.partition)) {
firmware_info += [
{
name = name
partition = firmware.partition
# Both the output dir and the build archive put the image at this path.
out_path = "$name.img"
},
]
}
}
# Stores bootstrap partition information to assemble the flashing manifest.
bootstrap_parts = []
archive_bootstrap_parts = []
flash_script_deps = [ "//build/images/tools:fastboot($host_toolchain)" ]
foreach(file, bootstrap_files) {
file_name = get_path_info(file.path, "file")
out_path = "${root_out_dir}/${file_name}"
copy(file_name) {
sources = [ file.path ]
outputs = [ out_path ]
metadata = {
images = [
{
label = get_label_info(":${file_name}", "label_with_toolchain")
archive = true
name = get_path_info(file.path, "name")
path = rebase_path(out_path, root_build_dir)
type = get_path_info(file.path, "extension")
fastboot_flash = []
},
]
}
}
flash_image_deps += [ ":${file_name}" ]
flash_script_deps += [ ":${file_name}" ]
if (defined(file.partition)) {
part = {
}
archive_part = {
}
# The only difference here is the path. For the normal partition map it
# should be the path relative to the build dir, whereas the archive needs it
# to be just the file name.
part.name = file.partition
part.path = rebase_path(out_path, root_build_dir)
archive_part.name = file.partition
archive_part.path = file_name
if (defined(file.condition)) {
part.condition = file.condition
archive_part.condition = file.condition
}
bootstrap_parts += [ part ]
archive_bootstrap_parts += [ archive_part ]
}
}
###
### Paver and flash scripts, and archives using those images and zedboot's images.
###
# TODO(fxbug.dev/82862): Move the construction of the flash archive/manifest
# into a separate BUILD.gn file.
flash_script_outputs = [ "$root_out_dir/flash.sh" ]
host_out_dir = get_label_info(":anything($host_toolchain)", "root_out_dir")
flash_script_args = [
"--image=" + rebase_path(files.final_zbi, root_build_dir),
"--vbmeta=" + rebase_path(files.final_vbmeta, root_build_dir),
"--recovery-image=" + rebase_path(files.final_recovery_zbi, root_build_dir),
"--recovery-vbmeta=" +
rebase_path(files.final_recovery_vbmeta, root_build_dir),
"--output=" + rebase_path(flash_script_outputs[0], root_build_dir),
"--zircon-a=${zircon_a_partition}",
"--zircon-b=${zircon_b_partition}",
"--zircon-r=${zircon_r_partition}",
"--vbmeta-a=${vbmeta_a_partition}",
"--vbmeta-b=${vbmeta_b_partition}",
"--vbmeta-r=${vbmeta_r_partition}",
"--active=${active_partition}",
"--product=${fastboot_product}",
"--pre-erase-flash=${pre_erase_flash}",
"--fastboot-path=" + rebase_path("$host_out_dir/fastboot", root_build_dir),
]
if (sign_zbi) {
flash_script_args += [ "--signed=true" ]
}
bootloader_parts = []
foreach(info, firmware_info) {
flash_script_args += [ "--firmware=${info.partition}:${info.out_path}" ]
flash_script_deps += [ ":${info.name}" ]
bootloader_parts += [
{
name = info.partition
path = rebase_path("$root_out_dir/${info.out_path}", root_build_dir)
},
]
}
if (supports_flashing_fxfs) {
flash_script_args += [
"--fvm-image=" + rebase_path(files.fxfs, root_build_dir),
"--fvm=${fxfs_partition}",
]
flash_script_deps += [ labels.images ]
parts += [
{
name = fxfs_partition
path = rebase_path(files.fxfs, root_build_dir)
},
]
} else if (supports_fastboot_fvm) {
flash_script_args += [
"--fvm-image=" + rebase_path(files.fvm_fastboot, root_build_dir),
"--fvm=${fvm_partition}",
]
flash_script_deps += [ labels.images ]
parts += [
{
name = fvm_partition
path = rebase_path(files.fvm_fastboot, root_build_dir)
},
]
}
action("flash_script") {
# Required for dependency on testonly firmware image targets.
testonly = true
script = "generate_flash_script.sh"
outputs = flash_script_outputs
args = flash_script_args
deps = flash_script_deps
metadata = {
images = [
{
label = get_label_info(":$target_name", "label_with_toolchain")
name = "flash-script"
path = "flash.sh"
type = "script"
},
]
}
}
fastboot_credential_deps = []
fastboot_credential_paths = []
fastboot_credential_archive_paths = []
foreach(cred_path, board_fastboot_unlock_credentials) {
name = get_path_info(cred_path, "name")
ext = get_path_info(cred_path, "extension")
target_name = "unlock_creds_${name}"
out_path = "unlock_creds/${name}.${ext}"
copy(target_name) {
sources = [ cred_path ]
outputs = [ "${root_out_dir}/${out_path}" ]
metadata = {
images = [
{
label = get_label_info(":${target_name}", "label_with_toolchain")
archive = true
name = name
path = out_path
type = ext
fastboot_flash = []
},
]
}
}
fastboot_credential_deps += [ ":${target_name}" ]
fastboot_credential_paths += [ out_path ]
fastboot_credential_archive_paths += [ get_path_info(out_path, "file") ]
}
group("fastboot_credentials") {
deps = fastboot_credential_deps
}
flash_image_deps += [ ":fastboot_credentials" ]
# Bootstrap partitions are the lowest-level images and must come first.
fuchsia_bootloader_partitions = bootstrap_parts + bootloader_parts
fuchsia_requires_unlock = false
if (bootstrap_parts != []) {
fuchsia_requires_unlock = true
}
flash_manifest_products = []
recovery_product = {
name = "recovery"
requires_unlock = false
}
fuchsia_only_product = {
name = "fuchsia_only"
requires_unlock = false
}
fuchsia_product = {
name = "fuchsia"
requires_unlock = fuchsia_requires_unlock
}
if (bootloader_parts != []) {
recovery_product.bootloader_partitions = bootloader_parts
fuchsia_only_product.bootloader_partitions = bootloader_parts
}
if (fuchsia_bootloader_partitions != []) {
fuchsia_product.bootloader_partitions = fuchsia_bootloader_partitions
}
if (recovery_parts != []) {
recovery_product.partitions = recovery_parts
}
if (parts != []) {
fuchsia_only_product.partitions = parts
fuchsia_product.partitions = parts
}
flash_manifest_products += [
recovery_product,
fuchsia_only_product,
fuchsia_product,
]
if (bootstrap_parts != []) {
# "bootstrap" product is only responsible for flashing any bootstrap
# files and the bootloader itself, at which point the device is
# ready to be flashed using the standard means.
flash_manifest_products += [
{
name = "bootstrap"
requires_unlock = true
# Bootstrap partitions are the lowest-level images and must come first.
bootloader_partitions = bootstrap_parts + bootloader_parts
},
]
}
flash_manifest_content = {
hw_revision = "${board_name}"
}
if (fastboot_credential_paths != []) {
flash_manifest_content.credentials = fastboot_credential_paths
}
if (flash_manifest_products != []) {
flash_manifest_content.products = flash_manifest_products
}
fastboot_manifest_file = "$root_build_dir/flash.json"
generated_file("fastboot_manifest") {
testonly = true
outputs = [ fastboot_manifest_file ]
output_conversion = "json"
deps = [
":fastboot_credentials",
"//build/images/tools:board_tools",
]
contents = {
version = flash_manifest_version
manifest = flash_manifest_content
}
metadata = {
images = [
{
label = get_label_info(":$target_name", "label_with_toolchain")
name = "flash-manifest"
path = "flash.json"
type = "manifest"
},
]
}
}
##### BUILD ARCHIVE
archive_outputs = [ "$root_out_dir/flash-archive.sh" ]
archive_args = [
"--image=${archive_image}",
"--vbmeta=${archive_vbmeta}",
"--recovery-image=${archive_recovery_image}",
"--recovery-vbmeta=${archive_recovery_vbmeta}",
"--output=" + rebase_path(archive_outputs[0], root_build_dir),
"--zircon-a=${zircon_a_partition}",
"--zircon-b=${zircon_b_partition}",
"--zircon-r=${zircon_r_partition}",
"--vbmeta-a=${vbmeta_a_partition}",
"--vbmeta-b=${vbmeta_b_partition}",
"--vbmeta-r=${vbmeta_r_partition}",
"--active=${active_partition}",
"--product=${fastboot_product}",
"--pre-erase-flash=${pre_erase_flash}",
"--fastboot-path=fastboot.exe.$host_platform",
]
archive_deps = [ "//build/images/tools:fastboot($host_toolchain)" ]
# A list of partitions for the flash json manifest that will be
# generated. The first item should be the partition name and the
# second should be the path to the image for the partition. These
# are the images flashed for the firmware/bootloader.
archive_bootloader_parts = []
foreach(info, firmware_info) {
archive_args += [ "--firmware=${info.partition}:${info.out_path}" ]
archive_deps += [ ":${info.name}" ]
archive_bootloader_parts += [
{
name = info.partition
path = info.out_path
},
]
}
if (supports_fastboot_fvm) {
archive_deps += [ "//build/images/fuchsia" ]
archive_args += [
"--fvm-image=" + get_path_info(files.fvm_fastboot, "file"),
"--fvm=${fvm_partition}",
]
archive_parts += [
{
name = fvm_partition
path = get_path_info(files.fvm_fastboot, "file")
},
]
}
action("flash_script_archive") {
testonly = true
script = "generate_flash_script.sh"
outputs = archive_outputs
args = archive_args
deps = archive_deps
metadata = {
images = [
{
label = get_label_info(":$target_name", "label_with_toolchain")
archive = true
name = "flash"
type = "sh"
path = "flash-archive.sh"
},
]
}
}
fastboot_manifest_archive_file = "$root_build_dir/flash_archive.json"
# Bootstrap partitions are the lowest-level images and must come first.
archive_fuchsia_bootloader_partitions =
archive_bootstrap_parts + archive_bootloader_parts
archive_fuchsia_requires_unlock = false
if (archive_bootstrap_parts != []) {
archive_fuchsia_requires_unlock = true
}
archive_flash_manifest_products = [
{
name = "recovery"
bootloader_partitions = archive_bootloader_parts
partitions = archive_recovery_parts
},
{
name = "fuchsia_only"
bootloader_partitions = archive_bootloader_parts
partitions = archive_parts
},
{
name = "fuchsia"
requires_unlock = archive_fuchsia_requires_unlock
bootloader_partitions = archive_fuchsia_bootloader_partitions
partitions = archive_parts
},
]
if (archive_bootstrap_parts != []) {
# "bootstrap" product is only responsible for flashing any bootstrap
# files and the bootloader itself, at which point the device is
# ready to be flashed using the standard means.
archive_flash_manifest_products += [
{
name = "bootstrap"
requires_unlock = true
# Bootstrap partitions are the lowest-level images and must come first.
bootloader_partitions = archive_bootstrap_parts + archive_bootloader_parts
partitions = []
},
]
}
archive_flash_manifest_content = {
hw_revision = "${board_name}"
credentials = fastboot_credential_archive_paths
products = archive_flash_manifest_products
}
generated_file("fastboot_manifest_archive") {
testonly = true
outputs = [ fastboot_manifest_archive_file ]
output_conversion = "json"
deps = [ ":flash_script_archive" ]
contents = [
{
version = flash_manifest_version
manifest = archive_flash_manifest_content
},
]
metadata = {
images = [
{
label = get_label_info(":$target_name", "label_with_toolchain")
archive = true
name = "flash-manifest"
path = "flash_archive.json"
type = "manifest"
},
]
}
}
## Product Bundle
## TODO: Move this to it's own BUILD.gn file once the template are taught to
## read a flash.json rather than taking the GN object.
compatible_devices = []
# Virtual device manifest should only be generated for emu compatible boards.
if (board_is_emu) {
if (!defined(virtual_device_labels)) {
virtual_device_labels = []
}
# Append '-emu' to the end of the device_name in order to make it unique for
# cases where the board is compatible with a physical and virtual device.
device_name = "${board_name}-emu"
if (virtual_device_name_prefix != "") {
device_name = "${virtual_device_name_prefix}-${device_name}"
}
# Add the recommended configuration first. This is the default
# used unless a specific device is requested.
virtual_device_labels += [ ":virtual_device_specification_recommended" ]
virtual_device_specification("virtual_device_specification_recommended") {
testonly = true
name = "${device_name}-recommended"
description = "Recommended configuration for running this product"
output = "$root_build_dir/virtual_device_recommended.json"
}
compatible_devices += [ "${device_name}-recommended" ]
# Add the Minimum configuration
virtual_device_labels += [ ":virtual_device_specification_min" ]
virtual_device_specification("virtual_device_specification_min") {
testonly = true
name = "${device_name}-min"
description = "Minimum configuration for running this product"
output = "$root_build_dir/virtual_device_min.json"
memory = {
quantity = 2048
units = "megabytes"
}
}
compatible_devices += [ "${device_name}-min" ]
# Add a Large configuration
virtual_device_labels += [ ":virtual_device_specification_large" ]
virtual_device_specification("virtual_device_specification_large") {
testonly = true
name = "${device_name}-large"
description =
"Larger configuration for running this product with extra storage"
output = "$root_build_dir/virtual_device_large.json"
storage = {
quantity = 10
units = "gigabytes"
}
}
compatible_devices += [ "${device_name}-large" ]
}
# Physical device manifest should only be generated for physical boards.
if (board_is_phys) {
device_name = board_name
physical_device_manifest("physical_device_manifest") {
testonly = true
name = device_name
output = "$root_build_dir/physical_device.json"
}
compatible_devices += [ device_name ]
}
if (build_pb_v1) {
product_metadata("product_metadata") {
testonly = true
devices = compatible_devices
output = "$root_build_dir/product_bundle.json"
deps = []
if (board_is_emu) {
deps += virtual_device_labels
emu_manifest = {
initial_ramdisk = rebase_path(files.final_zbi, root_out_dir)
kernel = rebase_path(files.qemu_kernel, root_out_dir)
disk_images = []
if (defined(files.fvm)) {
disk_images = [ rebase_path(files.fvm, root_build_dir) ]
} else if (defined(files.fxfs)) {
disk_images = [ rebase_path(files.fxfs, root_build_dir) ]
}
}
}
if (board_is_phys) {
flash_manifest = flash_manifest_content
deps += [ ":physical_device_manifest" ]
}
}
}
group("flash") {
testonly = true
public_deps = flash_image_deps
}