| # 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, |
| ] |
| } |
| } |
| |
| # Build the initial RAM disk for the hypervisor. |
| template("initrd") { |
| assert( |
| defined(invoker.primary_vm) || defined(invoker.primary_vm_prebuilt), |
| "initrd() must specify a \"primary_vm\" or \"primary_vm_prebuilt\" value") |
| |
| action(target_name) { |
| forward_variables_from(invoker, [ "testonly" ]) |
| script = "//build/image/generate_initrd.py" |
| |
| initrd_base = "${target_out_dir}/${target_name}/initrd" |
| initrd_file = "${initrd_base}.img" |
| initrd_staging = "${initrd_base}" |
| |
| deps = [] |
| |
| if (defined(invoker.primary_vm_prebuilt)) { |
| primary_vm_output = invoker.primary_vm_prebuilt |
| } else { |
| primary_vm_output = |
| get_label_info(invoker.primary_vm, "target_out_dir") + "/" + |
| get_label_info(invoker.primary_vm, "name") + ".bin" |
| deps += [ invoker.primary_vm ] |
| } |
| args = [ |
| "--primary_vm", |
| rebase_path(primary_vm_output), |
| "--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. Memory in bytes. |
| # 2. Number of cores. |
| # 3. File name for the VM image. |
| # 4. Build target for the VM. |
| if (defined(invoker.secondary_vms)) { |
| foreach(vm, invoker.secondary_vms) { |
| deps += [ vm[3] ] |
| args += [ |
| "--secondary_vm", |
| vm[0], |
| vm[1], |
| vm[2], |
| rebase_path(get_label_info(vm[3], "target_out_dir") + "/" + |
| get_label_info(vm[3], "name") + ".bin"), |
| ] |
| } |
| } |
| |
| outputs = [ |
| initrd_file, |
| "${initrd_staging}/vms.txt", |
| ] |
| } |
| } |