blob: ce7b1e6b8f5f990ce052836b3b68947faaf2dea6 [file] [log] [blame]
# Copyright 2020 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
import("//build/config/zircon/standard.gni")
import("//build/info/info.gni")
import("//build/toolchain/toolchain_environment.gni")
import("//build/toolchain/zircon/zircon_toolchain_suite.gni")
import("//build/zbi/kernel_cmdline.gni")
import("//build/zircon/zircon_cpu.gni")
import("//zircon/kernel/kernel_package.gni")
import("//zircon/kernel/params.gni")
import("kernel_elf_binary.gni")
import("kernel_elf_interp.gni")
import("zbi_executable.gni")
declare_args() {
# Cause //zircon/kernel/phys:boot_tests to generate the phys boot tests
# for all supported CPUs, not just $target_cpu.
all_cpu_phys_boot_tests = false
}
arch_phys = "//zircon/kernel/arch/$zircon_cpu/phys"
not_needed([ "arch_phys" ]) # Not used in all toolchains.
if (current_toolchain == default_toolchain) {
# Default toolchain (current_cpu == "") just defines the phys environment.
# Note: see //zircon/kernel/arch/x86/phys:kernel.phys32 too.
foreach(cpu, standard_fuchsia_cpus) {
kernel_cpu = cpu
if (kernel_cpu == "x64") {
kernel_cpu = "x86"
}
zircon_toolchain_suite("kernel.phys_$cpu") {
cpu = cpu
os = "fuchsia"
environment = "kernel.phys"
with_shared = false
is_pic_default = true
toolchain_tags = [
"kernel",
"no-floating-point",
]
configs = [ "//zircon/kernel/phys:phys_config" ]
# Always enable frame pointers. This works because frame_pointers
# is added as part of :phys_config below.
remove_common_configs = [ "//build/config:default_frame_pointers" ]
exclude_variant_tags = [
# There is no possibility of fancy runtimes like ASan for phys.
"instrumentation-runtime",
]
# Append the arch-specific lists. The phys/phys.gni file in each arch
# subdirectory defines phys_* lists to append to the parameters. Since
# this is evaluated in the default toolchain where current_cpu is not
# necessarily the same as the cpu we're defining for, import the right
# phys.gni file only into a local scope.
phys = {
import("//zircon/kernel/arch/$kernel_cpu/phys/phys.gni")
}
configs += phys.phys_configs
toolchain_tags += phys.phys_tags
exclude_variant_tags += phys.phys_exclude_variant_tags
}
}
} else if (toolchain_environment == "kernel.phys") {
kernel_cpu = current_cpu
if (current_cpu == "x64") {
kernel_cpu = "x86"
}
config("phys_config") {
configs = [
"//zircon/kernel:standalone",
"//zircon/kernel:warnings",
"//zircon/kernel/arch/$kernel_cpu:abi",
":defines",
"//build/config:no-finite-loops",
# Don't emit extra code making static initializers thread-safe (we don't
# have threads or any of the corresponding library support.)
"//build/config/zircon:no_threadsafe_statics",
# All physmem code is inherently sensitive and in a position for
# any bug to be unusually dangerous. So compile with minimal
# undefined behavior checking in all builds, regardless of variant.
"//build/config/zircon/instrumentation:ubsan-trap",
]
# Always enable frame pointers.
configs += [ "//build/config:frame_pointers" ]
}
group("phys_config_deps") {
deps = [ "//src/lib/trivial-allocator:panic-delete" ]
}
}
if (toolchain_environment == "kernel.phys" ||
toolchain_environment == "kernel.phys32" ||
toolchain_environment == "kernel.efi") {
# All the code gets built here in the phys environment.
source_set("trampoline-boot") {
visibility = [
"./*",
# Required for legacy-boot-shim
"//zircon/kernel/arch/x86/*",
]
sources = [ "trampoline-boot.cc" ]
public = [ "include/phys/trampoline-boot.h" ]
public_deps = [ ":boot-zbi" ]
deps = [
":address-space",
":main",
"//zircon/kernel/lib/arch",
"//zircon/kernel/phys/lib/memalloc",
]
public_configs = [ ":includes" ]
}
config("defines") {
# Always enable tests and asserts in phys code.
defines = [ "LK_DEBUGLEVEL=2" ]
}
config("load-pic") {
# ZBI executables can be loaded anywhere, so they are linked at 0.
ldflags = [ "-Wl,-defsym,PHYS_LOAD_ADDRESS=0" ]
}
static_library("symbolize") {
public = [ "include/phys/symbolize.h" ]
sources = [
"main-symbolize.cc",
"panic.cc",
"stack.cc",
"symbolize.cc",
]
allow_circular_includes_from = [ ":elf-image" ]
deps = [
":elf-image",
"//src/lib/elfldltl",
"//src/lib/symbolizer-markup",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/fbl",
"//zircon/system/ulib/pretty",
]
# This is needed for ArchPanicReset, used by panic.cc; but in EFI, that's
# provided instead by efi:main, which has a circular dependency to here.
if (toolchain_environment != "kernel.efi") {
deps += [ "$arch_phys" ]
}
public_deps = [
# "symbolize.h" has #include <phys/main.h>.
":main",
# <phys/symbolize.h> has #include <lib/symbolizer-markup/writer.h>.
"//src/lib/symbolizer-markup",
# <phys/symbolize.h> has #include <lib/elfldltl/note.h>
"//src/lib/elfldltl",
]
public_configs = [ ":includes" ]
}
# This is used implicitly by phys_executable() targets,
# including zbi_executable() targets.
group("phys_executable.deps") {
deps = [
":symbolize",
"$arch_phys",
]
}
# This is used implicitly by zbi_executable() targets.
source_set("zbi_executable.deps") {
sources = [
"zbi-header.S",
"zbi-main.cc",
]
deps = [
":boot-options",
":exception",
":main",
":stdio",
":uart",
":zbi-memory",
"//src/lib/zbitl",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/crypto:crypto-entropy-src",
"//zircon/system/ulib/uart",
]
}
static_library("exception") {
if (toolchain_environment == "kernel.phys") {
sources = [ "exception.cc" ]
deps = [
":main",
"//zircon/kernel/lib/libc",
]
}
}
static_library("kernel-package") {
public = [ "include/phys/kernel-package.h" ]
public_deps = [
":allocation",
":handoff",
":symbolize",
"//src/lib/zbitl",
"//zircon/kernel/lib/ktl",
]
public_configs = [ ":includes" ]
sources = [ "kernel-package.cc" ]
deps = [
":main",
":stdio",
":zbitl-allocation",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/pretty",
]
}
# Transitive dependencies for the <phys/main.h> header.
static_library("main") {
public = [
"include/phys/exception.h",
"include/phys/main.h",
"include/phys/stack.h",
]
public_deps = [
# "main.h" has #include <lib/arch/ticks.h>.
"//zircon/kernel/lib/arch",
# "main.h" has #include <lib/mempool/range.h>.
"//zircon/kernel/phys/lib/memalloc",
]
public_configs = [ ":includes" ]
if (toolchain_environment != "kernel.efi") {
sources = [ "self-relocation.cc" ]
deps = [ "//src/lib/elfldltl" ]
}
}
source_set("address-space.header") {
visibility = [
":address-space",
":elf-image",
"$arch_phys:address-space",
]
public = [
"$arch_phys/include/phys/arch/address-space.h",
"include/phys/address-space.h",
]
public_configs = [ ":includes" ]
public_deps = [
":allocation",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
# <phys/address-space.h> has #include <lib/arch/paging.h>
# <phys/arch/address-space.h> has #include <lib/arch/${zircon_cpu}/page-table.h>
"//zircon/kernel/lib/arch:headers",
# <phys/address-space.h> has #include <hwreg/array.h>
"//zircon/system/ulib/hwreg:headers",
]
}
static_library("address-space") {
sources = [ "address-space.cc" ]
public_deps = [ ":address-space.header" ]
deps = [
":allocation",
":stdio",
":uart",
"$arch_phys:address-space",
"//zircon/kernel/phys/lib/memalloc",
"//zircon/system/ulib/uart",
]
}
source_set("stdio") {
public = [ "include/phys/stdio.h" ]
public_configs = [ ":includes" ]
public_deps = [
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
deps = [
":log",
"//zircon/kernel/lib/boot-options",
]
sources = [ "stdio.cc" ]
}
source_set("acpi") {
sources = [ "acpi.cc" ]
public = [ "include/phys/acpi.h" ]
public_deps = [
"//zircon/kernel/lib/acpi_lite",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/zx",
]
public_configs = [ ":includes" ]
deps = [
":main",
"//zircon/system/ulib/fbl",
]
}
source_set("uart") {
public = [ "include/phys/uart.h" ]
public_configs = [ ":includes" ]
sources = [ "uart.cc" ]
public_deps = [
"//src/lib/zbitl",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/uart",
]
deps = [
":stdio",
"//zircon/system/ulib/uart",
]
}
source_set("boot-options") {
public = [ "include/phys/boot-options.h" ]
public_configs = [ ":includes" ]
sources = [ "boot-options.cc" ]
public_deps = [ "//zircon/kernel/lib/ktl" ]
deps = [
"//src/lib/zbitl",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/explicit-memory",
]
}
# This is linked into the special-case phys_executable() tests that
# are run directly as QEMU kernels.
source_set("qemu-header") {
deps = [ ":raw-header" ]
public_configs = [ "$arch_phys:qemu.config" ]
}
source_set("raw-header") {
sources = [ "raw-header.S" ]
}
static_library("allocation") {
public = [ "include/phys/allocation.h" ]
if (toolchain_environment != "kernel.efi") {
sources = [ "allocation.cc" ]
deps = [
":main",
"//zircon/kernel/phys/lib/memalloc",
]
}
public_deps = [
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
# allocation.h has #include <lib/memalloc/pool.h>.
# allocation.h has #include <lib/memalloc/range.h>.
"//zircon/kernel/phys/lib/memalloc",
# allocation.h has #include <fbl/alloc_checker.h>.
"//zircon/system/ulib/fbl",
# allocation.h has #include <lib/fit/result.h>.
"//zircon/system/ulib/zx",
# allocation.h has #include <lib/memalloc/range.h>
# allocation.h has #include <lib/memalloc/pool.h>
"//zircon/kernel/phys/lib/memalloc",
]
public_configs = [ ":includes" ]
}
if (toolchain_environment != "kernel.efi") {
# This is only linked into a main phys executable and not into secondary
# modules, which only get the pool set up here handed off. It's not used
# at all for UEFI, where efi:allocation handles everything.
source_set("allocation-init") {
sources = [
"$arch_phys/include/phys/arch/arch-allocation.h",
"allocation-init.cc",
]
public_deps = [ ":allocation" ]
}
}
source_set("new") {
public = [ "include/phys/new.h" ]
public_deps = [
# <phys/new.h> has #include <phys/allocation.h>.
":allocation",
# <phys/new.h> has #include <lib/trivial-allocator/new.h>
"//src/lib/trivial-allocator",
]
}
source_set("zbitl-allocation") {
public = [ "include/phys/zbitl-allocation.h" ]
sources = [ "zbitl-allocation.cc" ]
deps = [
":allocation",
"//zircon/system/ulib/fbl",
]
public_deps = [
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
# zbitl-allocation.h has #include "allocation.h".
":allocation",
# zbitl-allocation.h has #include <lib/zbitl/storage-traits.h>.
"//src/lib/zbitl",
# zbitl-allocation.h has #include <lib/fit/result.h>.
"//zircon/system/ulib/zx",
]
public_configs = [ ":includes" ]
}
# This is a little library instead of a source_set() so it can be included
# implicitly by zbi_executable() without adding bloat to the tiny tests that
# don't use it.
static_library("zbi-memory") {
sources = [
"zbi-init-memory.cc",
"zbi-memory.cc",
]
deps = [
":address-space",
":allocation-init",
":main",
":symbolize",
"//src/lib/zbitl",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/phys/lib/memalloc",
]
public_deps = [
"//sdk/lib/zbi-format",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
# allocation.h has #include <fbl/alloc_checker.h>.
"//zircon/system/ulib/fbl",
]
}
source_set("boot-zbi.deps") {
visibility = [
":boot-zbi",
"$arch_phys:arch-boot-zbi",
]
public = [ "include/phys/boot-zbi.h" ]
public_deps = [
":allocation",
":main",
":stdio",
"//src/lib/zbitl",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/pretty",
"//zircon/system/ulib/zx",
]
}
source_set("boot-zbi") {
sources = [ "boot-zbi.cc" ]
public_deps = [ ":boot-zbi.deps" ]
deps = [ "$arch_phys:arch-boot-zbi" ]
}
source_set("handoff-entropy") {
sources = [ "handoff-entropy.cc" ]
public = [ "handoff-entropy.h" ]
public_deps = [
":stdio",
"//src/lib/zbitl",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/crypto:crypto-entropy-src",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
deps = [ "//zircon/system/ulib/explicit-memory" ]
}
# Split out so that the definition of arch-specific methods can include
# handoff-prep.h without introducing a dependency cycle.
source_set("handoff-prep.h") {
public = [ "handoff-prep.h" ]
public_deps = [
":handoff",
":kernel-package",
":uart",
":zbitl-allocation",
"//sdk/lib/fit",
"//sdk/lib/zbi-format",
"//src/lib/trivial-allocator",
"//src/lib/zbitl",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
}
source_set("handoff-prep") {
sources = [
"handoff-prep-zbi.cc",
"handoff-prep.cc",
]
public_deps = [ ":handoff-prep.h" ]
deps = [
":allocation",
":elf-image",
":handoff",
":handoff-entropy",
":log",
":new",
":physboot.h",
":symbolize",
":zbitl-allocation",
"$arch_phys:arch-handoff-prep",
"//src/lib/llvm-profdata",
"//src/lib/zbitl",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/instrumentation",
"//zircon/kernel/phys/lib/memalloc",
]
}
static_library("elf-image") {
public = [ "include/phys/elf-image.h" ]
sources = [
"elf-image-self-vmos.cc",
"elf-image-vmos.cc",
"elf-image.cc",
]
public_configs = [ ":includes" ]
public_deps = [
":address-space.header",
"//sdk/lib/fit",
"//src/lib/elfldltl",
"//src/lib/zbitl",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/code-patching",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
"//zircon/system/ulib/zx",
]
deps = [
":address-space",
":allocation",
":handoff",
"//src/lib/llvm-profdata",
# Indirect dep via circular :symbolize dep.
"//src/lib/symbolizer-markup",
]
}
source_set("log") {
public = [ "log.h" ]
public_configs = [ ":includes" ]
public_deps = [
":allocation",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
sources = [ "log.cc" ]
deps = [ "//zircon/kernel/lib/boot-options" ]
}
}
config("includes") {
include_dirs = [
"include",
"//zircon/kernel/arch/${zircon_cpu}/phys/include",
]
}
group("tests") {
testonly = true
deps = [
"boot-shim:tests",
"efi:tests",
]
if (build_info_product != "bringup") {
# The following target includes tests that cannot be run on the bringup
# product.
deps += [ "lib:tests" ]
}
}
group("boot_tests") {
testonly = true
deps = [
"boot-shim:boot_tests",
"test",
]
if (target_cpu != "riscv64") { # TODO(mcgrathr): EFI not there yet
deps += [ "efi:boot_tests" ]
}
if (all_cpu_phys_boot_tests) {
foreach(cpu, standard_fuchsia_cpus) {
deps += [ "test:$cpu" ]
if (cpu != "riscv64") { # TODO(mcgrathr): EFI not there yet
deps += [ "efi:boot_tests(//zircon/kernel/phys/efi:kernel.efi_$cpu)" ]
}
}
}
}
group("physboot") {
if (use_elf_kernel) {
public_deps = [ ":physboot-elf-kernel.package" ]
} else {
public_deps = [ ":physboot-zbi-kernel.package" ]
}
}
# The elf-physboot target provides the distribution_entries metadata via
# kernel_elf_binary() for "physboot". This target reifies that to be directly
# in the root of the STORAGE_KERNEL filesystem layout, whereas if another
# kernel_package() took a dependency on the kernel_elf_binary() target, then it
# would wind up under "package_name/physboot" instead.
kernel_package("physboot-zbi-kernel.package") {
visibility = [ ":*" ]
# Just "physboot" at top level is the default for `kernel.phys.next`.
prefix = ""
deps = [ ":elf-physboot(:kernel.phys_$current_cpu)" ]
}
kernel_package("physboot-elf-kernel.package") {
visibility = [ "./*" ]
prefix = ""
deps = [
":physboot-elf-kernel(:kernel.phys_$current_cpu)",
":physboot-elf-kernel.cmdline",
]
}
kernel_cmdline("physboot-elf-kernel.cmdline") {
visibility = [ ":*" ]
args = [ "kernel.phys.next=physboot-elf-kernel" ]
}
zbi_executable("physload") {
sources = [ "physload.cc" ]
deps = [
":address-space",
":allocation",
":elf-image",
":handoff",
":kernel-package",
":log",
":main",
":physload.header",
":stdio",
":symbolize",
"//src/lib/elfldltl",
"//src/lib/zbitl",
"//zircon/kernel/lib/boot-options",
]
}
kernel_elf_interp("physload.interp") {
visibility = [ ":*" ]
deps = [ ":physload" ]
}
if (is_kernel) {
source_set("physload.header") {
visibility = [
":*",
"$arch_phys:arch-on-physload-handoff",
]
public = [ "physload.h" ]
public_deps = [
":handoff",
":kernel-package",
":uart",
]
}
# A physload-compatible module depends on this.
source_set("physload.module") {
visibility = [ "./*" ]
public_deps = [ ":physload.header" ]
public_configs = [ ":physload.module.config" ]
sources = [ "physload-module.cc" ]
deps = [
":address-space",
":allocation",
":elf-image",
":log",
":main",
":physload.interp",
":stdio",
":symbolize",
"$arch_phys:arch-on-physload-handoff",
"//zircon/kernel/lib/boot-options",
]
data_deps = [ ":physload" ]
}
config("physload.module.config") {
visibility = [ ":*" ]
ldflags = [ "-Wl,-e,PhysLoadHandoff" ]
configs = [ ":phys-elf-module.config" ]
}
# The GNU linkers don't do page-aligned segments by default like LLD,
# so a linker script is required.
config("phys-elf-module.config") {
visibility = [ ":*" ]
if (is_gcc) {
inputs = [ "phys-elf-module.ld" ]
ldflags = [
"-Wl,-z,relro",
"-Wl,-T," + rebase_path(inputs[0], root_build_dir),
]
}
}
source_set("handoff") {
public = [
"//zircon/kernel/arch/${zircon_cpu}/phys/include/phys/arch/arch-handoff.h",
"include/phys/handoff-ptr.h",
"include/phys/handoff.h",
]
public_deps = [
# arch-handoff.h has #include <lib/zbi-format/driver-config.h>
"//sdk/lib/zbi-format",
# arm64's arch-handoff.h has #include <lib/boot-options/arm64.h>
"//zircon/kernel/lib/boot-options",
# handoff.h has #include <lib/arch/ticks.h>.
"//zircon/kernel/lib/arch",
# handoff.h has #include <lib/uart/all.h>.
"//zircon/system/ulib/uart",
# handoff.h has #include <lib/crypto/entropy_pool.h>
"//zircon/kernel/lib/crypto:crypto-entropy-src",
]
public_configs = [ ":includes" ]
}
kernel_elf_binary("elf-physboot") {
output_name = "physboot"
target_type = "loadable_module"
has_patches = false
sources = [ "physboot-elf-main.cc" ]
deps = [
":elf-image",
":log",
":physboot-main",
":physload.module",
":stdio",
":symbolize",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
}
source_set("physboot.h") {
visibility = [ ":*" ]
public = [ "physboot.h" ]
}
source_set("physboot-main") {
public_deps = [ ":physboot.h" ]
sources = [ "physboot.cc" ]
deps = [
":allocation",
":boot-zbi",
":handoff",
":handoff-prep",
":kernel-package",
":log",
":main",
":stdio",
":symbolize",
":trampoline-boot",
":uart",
"//src/lib/zbitl",
"//zircon/kernel/arch/$zircon_cpu/code-patches",
"//zircon/kernel/lib/arch",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/code-patching",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
# Used as a bias when patching kernel code.
defines = [ "KERNEL_LINK_ADDRESS=${kernel_base}" ]
}
kernel_elf_binary("physboot-elf-kernel") {
target_type = "loadable_module"
has_patches = false
sources = [ "physboot-elf-kernel.cc" ]
include_dirs = [ "//zircon/kernel/arch/$zircon_cpu/include" ]
deps = [
":allocation",
":boot-zbi",
":elf-image",
":handoff",
":handoff-prep",
":kernel-package",
":log",
":physboot.h",
":physload.module",
":stdio",
":symbolize",
"//sdk/lib/fit",
"//zircon/kernel/arch/$zircon_cpu/code-patches",
"//zircon/kernel/lib/boot-options",
"//zircon/kernel/lib/ktl",
"//zircon/kernel/lib/libc",
]
}
# A physboot-compatible ELF kernel depends on this.
source_set("physboot.kernel") {
public_deps = [ ":handoff" ]
public_configs = [ ":physboot.kernel.config" ]
deps = [ ":physboot.interp" ]
}
config("physboot.kernel.config") {
visibility = [ ":*" ]
ldflags = [ "-Wl,-e,PhysbootHandoff" ]
configs = [ ":phys-elf-module.config" ]
}
source_set("arch-phys-info") {
public_deps = [ "//zircon/kernel/arch/$zircon_cpu/phys:arch-phys-info" ]
}
}
kernel_elf_interp("physboot.interp") {
visibility = [ ":*" ]
deps = [ ":physboot-elf-kernel($phys_toolchain)" ]
}