blob: a703fa18a25864fdf49df102df168fc97ab3e60e [file] [log] [blame]
# Copyright 2019 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("$zx/public/gn/config/standard.gni")
import("$zx/public/gn/toolchain/c_utils.gni")
import("$zx/public/gn/toolchain/environment.gni")
import("params.gni")
if (current_toolchain == default_toolchain) {
# In the default toolchain, just define the kernel toolchains.
foreach(cpu, standard_fuchsia_cpus) {
define_environment("kernel") {
globals = {
is_kernel = true
}
configs += standard_fuchsia_configs
configs += [
":kernel_config",
"lib/libc:headers",
# <kernel/spinlock.h> has #include <lockdep/lock_policy.h>.
"$zx/system/ulib/lockdep:headers",
# <kernel/thread.h> has #include <vm/kstack.h>.
"vm:headers",
# <lib/ktrace.h> has #include <lib/zircon-internal/ktrace.h>.
"$zx/system/ulib/zircon-internal:headers",
]
}
}
} else {
assert(is_kernel)
# These are needed both in kernel sources (pervasively) and in the linker
# scripts.
kernel_defines = [
# TODO: should not be needed in C, but is in one place now.
"KERNEL_BASE=$kernel_base",
"SMP_MAX_CPUS=$smp_max_cpus",
]
# This is the top config for all kernel code.
config("kernel_config") {
public_deps = [
":headers",
":lock_dep",
":standalone",
":warnings",
"arch/$zircon_cpu:kernel",
# include/lib/counters.h and kernel.ld depend on -fdata-sections.
"$zx/public/gn/config:data_sections",
]
defines = kernel_defines + kernel_extra_defines
defines += [
"_KERNEL",
"LK",
"ENABLE_PANIC_SHELL",
"WITH_DEBUG_LINEBUFFER",
"ZIRCON_TOOLCHAIN",
]
if (!enable_user_pci) {
defines += [ "WITH_KERNEL_PCIE" ]
}
cflags = [ "-fpie" ]
}
config("headers") {
include_dirs = [ "include" ]
}
# For any standalone static binary.
config("standalone") {
ldflags = [ "-nostdlib" ]
cflags = [
"-ffreestanding",
"-include",
rebase_path("include/hidden.h", root_build_dir),
# We want `.debug_frame` for the kernel (ZX-62). And we still want
# asynchronous unwind tables. Alas there's (currently) no way to
# achieve this with our GCC. At the moment we compile with
# `-fno-omit-frame-pointer`, which is good because we link with
# `--gc-sections`, which means `.eh_frame` gets discarded so GCC-built
# kernels don't have any unwind info (except for assembly)! Assembler
# code has its own way of requesting `.debug_frame` vs `.eh_frame` with
# the `.cfi_sections` directive.
"-fno-unwind-tables",
]
if (!is_gcc && current_os == "fuchsia") {
# In the Fuchsia-target toolchains there's no way to prevent the
# compiler driver from passing -pie, so negate it. BFD ld doesn't
# have --no-pie, but arm64-elf-gcc doesn't pass -pie either.
ldflags += [ "-Wl,--no-pie" ]
}
public_deps = [
"$zx/public/gn/config:no_exceptions",
]
}
config("warnings") {
cflags = [
"-Wformat=2",
"-Wvla",
]
# GCC supports `-Wformat-signedness` but Clang currently does not.
if (is_gcc) {
cflags += [ "-Wformat-signedness" ]
}
cflags_c = [ "-Wmissing-prototypes" ]
}
config("lock_dep") {
visibility = [ ":*" ]
defines = []
if (enable_lock_dep) {
defines += [
"WITH_LOCK_DEP=1",
"LOCK_DEP_ENABLE_VALIDATION=1",
]
}
if (enable_lock_dep_tests) {
defines += [ "WITH_LOCK_DEP_TESTS=1" ]
}
}
# This is the kernel proper, an ELF executable with full symbols.
# It's the file to use with a debugger, for example.
executable("zircon") {
visibility = [ ":*" ]
# $zx/scripts/zircon.elf-gdb.py expects kernel symbols in "zircon.elf".
output_extension = "elf"
ldflags = [
"-Wl,-T," + rebase_path("kernel.ld", root_build_dir),
"-Wl,--emit-relocs",
]
inputs = [
"kernel.ld",
]
configs += [ ":kernel_defsym" ]
deps = [
":test", # TODO: make optional, add testonly taint
"top",
]
if (current_cpu == "arm64") {
deps += [ "platform/generic-arm" ]
} else if (current_cpu == "x64") {
deps += [ "target/pc" ]
}
}
# Output file of that target.
zircon_elf = "$target_out_dir/zircon.elf"
# These are needed only in image.S and in the linker scripts.
image_defines = [ "BOOT_HEADER_SIZE=0x50" ]
# This supplies those variables for use in linker scripts.
config("kernel_defsym") {
visibility = [ ":*" ]
ldflags = []
foreach(assignment, kernel_defines + image_defines) {
ldflags += [ "-Wl,-defsym,$assignment" ]
}
}
# TODO: From project/virtual/test.mk
group("test") {
#TODO: testonly = true
visibility = [ ":*" ]
deps = [
"lib/debugcommands",
"tests",
]
}
zircon_raw = "$target_out_dir/zircon.bin"
image_binary("raw") {
visibility = [ ":*" ]
deps = [
":zircon",
]
sources = [
zircon_elf,
]
outputs = [
zircon_raw,
]
}
# Use the --emit-relocs records to extract the fixups needed to relocate
# the kernel at boot. This generates the "kernel-fixups.inc" file that's
# #include'd by "arch/$zircon_cpu/image.S".
toolchain_utils_action("fixups") {
visibility = [ ":*" ]
deps = [
":zircon",
]
sources = [
zircon_elf,
]
outputs = [
"$target_gen_dir/kernel-fixups.inc",
]
# TODO(mcgrathr): Move the script to this dir as it's private to this use.
script = "$zx/scripts/gen-kaslr-fixups.sh"
utils = [
"readelf",
"objdump",
]
args = [
rebase_path(sources[0], root_build_dir),
rebase_path(outputs[0], root_build_dir),
]
}
executable("image") {
visibility = [ ":*" ]
configs += [ ":kernel_defsym" ]
deps = [
":fixups",
":raw",
":zircon",
]
include_dirs = [ target_gen_dir ]
raw_path = rebase_path(zircon_raw, root_build_dir)
defines = image_defines + [ "KERNEL_IMAGE=\"${raw_path}\"" ]
sources = [
"arch/$zircon_cpu/image.S",
]
ldflags = [
"-Wl,--build-id=none",
"-Wl,-T," + rebase_path("image.ld", root_build_dir),
"-Wl,--just-symbols," + rebase_path(zircon_elf, root_build_dir),
]
inputs = [
"image.ld",
zircon_elf,
zircon_raw,
]
}
image_binary("kernel") {
deps = [
":image",
]
outputs = [
"$root_out_dir/kernel.zbi",
]
sources = [
"$target_out_dir/image",
]
metadata = {
images = [
{
type = "zbi"
name = "kernel"
path = rebase_path(outputs[0], root_build_dir)
},
]
# This metadata makes the kernel act as a zbi_input() target so it can
# be a dependency of a zbi() target to get into the image.
zbi_input_args = [
"--type=container",
rebase_path(outputs[0], root_build_dir),
]
}
}
}