blob: 6865f87b2649ab696729b05c9baee1be5a648c0f [file] [log] [blame]
# Copyright 2018 The Hafnium Authors.
#
# 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
#
# https://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.
import("//build/toolchain/embedded.gni")
# Build image, link to an ELF file then convert to plain binary.
template("image_binary") {
assert(defined(invoker.image_name),
"image_binary() must specify an \"image_name\" value")
output_root = ""
if (defined(invoker.output_path)) {
output_root += "${invoker.output_path}/"
}
output_root += invoker.image_name
# Link objects together
executable("${target_name}__elf") {
forward_variables_from(invoker,
[
"cflags",
"cflags_c",
"defines",
"deps",
"include_dirs",
"public_configs",
"public_deps",
"sources",
"testonly",
])
output_name = "${output_root}.elf"
inputs = [
rebase_path("//build/image/image.ld"),
]
ldflags = [
"-T",
rebase_path("//build/image/image.ld"),
]
visibility = [ ":${invoker.target_name}" ]
}
action(target_name) {
forward_variables_from(invoker, [ "testonly" ])
file_root = "${root_out_dir}/${output_root}"
elf_file = "${file_root}.elf"
bin_file = "${file_root}.bin"
script = "//build/image/convert_to_binary.py"
deps = [
":${target_name}__elf",
]
args = [
"--tool_prefix",
tool_prefix,
"--input",
rebase_path(elf_file),
"--output",
rebase_path(bin_file),
]
outputs = [
bin_file,
]
}
}
# Helper to build a hypervisor image
template("hypervisor") {
image_binary(target_name) {
forward_variables_from(invoker,
[
"cflags",
"cflags_c",
"defines",
"deps",
"public_deps",
"sources",
"testonly",
])
image_name = target_name
}
}
# Helper to build a virtual machine kernel
template("vm_kernel") {
image_binary(target_name) {
forward_variables_from(invoker,
[
"cflags",
"cflags_c",
"defines",
"deps",
"include_dirs",
"public_configs",
"public_deps",
"sources",
"testonly",
])
output_path = rebase_path(".", root_out_dir, target_out_dir)
image_name = target_name
}
}
# Build the initial RAM disk for the Linux VM.
template("linux_initrd") {
initrd_base = "${target_out_dir}/${target_name}/initrd"
initrd_file = "${initrd_base}.img"
initrd_staging = "${initrd_base}"
copy("${target_name}__staging") {
forward_variables_from(invoker,
[
"testonly",
"sources",
"deps",
])
outputs = [
"${initrd_staging}/{{source_file_part}}",
]
}
action(target_name) {
forward_variables_from(invoker, [ "testonly" ])
script = "//build/image/generate_linux_initrd.py"
args = [
"--staging",
rebase_path(initrd_staging),
"--output",
rebase_path(initrd_file),
]
deps = [
":${target_name}__staging",
]
outputs = [
initrd_file,
]
}
}
template("device_tree") {
action_foreach(target_name) {
forward_variables_from(invoker,
[
"testonly",
"sources",
"deps",
])
script = "//build/image/dtc.py"
outputs = [
invoker.output_pattern,
]
args = [
"compile",
"-i",
"{{source}}",
"-o",
rebase_path(invoker.output_pattern),
]
}
}
# Build the initial RAM disk for the hypervisor.
template("initrd") {
assert(defined(invoker.primary_vm),
"initrd() must specify a \"primary_vm\" value")
manifest_target = "${target_name}__manifest"
base_out_dir = "${target_out_dir}/${target_name}"
# Generate manifest.dtbo
device_tree(manifest_target) {
sources = [
invoker.manifest,
]
output_pattern = "${base_out_dir}/{{source_name_part}}.dtbo"
}
action(target_name) {
forward_variables_from(invoker, [ "testonly" ])
script = "//build/image/generate_initrd.py"
initrd_file = "${base_out_dir}/initrd.img"
initrd_staging = "${base_out_dir}/initrd"
# Cannot get target outputs here as they are defined in a different file.
primary_vm_image = get_label_info(invoker.primary_vm, "target_out_dir") +
"/" + get_label_info(invoker.primary_vm, "name") + ".bin"
deps = [
":${manifest_target}",
invoker.primary_vm,
]
args = [
"--primary_vm",
rebase_path(primary_vm_image),
"--staging",
rebase_path(initrd_staging),
"--output",
rebase_path(initrd_file),
]
if (defined(invoker.primary_initrd)) {
deps += [ invoker.primary_initrd ]
primary_initrd_outputs = get_target_outputs(invoker.primary_initrd)
args += [
"--primary_vm_initrd",
rebase_path(primary_initrd_outputs[0]),
]
}
# Add the info about the secondary VMs. The information about the VMs is
# encoded in lists with the following elements:
#
# 1. File name for the VM image.
# 2. Build target for the VM.
if (defined(invoker.secondary_vms)) {
foreach(vm, invoker.secondary_vms) {
deps += [ vm[1] ]
args += [
"--secondary_vm",
vm[0],
rebase_path(get_label_info(vm[1], "target_out_dir") + "/" +
get_label_info(vm[1], "name") + ".bin"),
]
}
}
outputs = [
initrd_file,
]
}
}