[zircon] [gn] Build kernel

Bug: BLD-325
Test: gn gen && ninja
Change-Id: Iab61d39049adbccbf8d5e6984bc0fca81070dd2e
diff --git a/zircon/BUILD.gn b/zircon/BUILD.gn
index 35e6731..10dde62 100644
--- a/zircon/BUILD.gn
+++ b/zircon/BUILD.gn
@@ -94,8 +94,8 @@
     cpu = cpu
     deps = [
       # TODO: This indirectly reaches everything that builds so far.
+      "$zx/kernel",
       "$zx/system/core",
-      "$zx/system/core/userboot",
       "$zx/system/dev",
       "$zx/system/uapp",
       "$zx/system/utest",
diff --git a/zircon/kernel/BUILD.gn b/zircon/kernel/BUILD.gn
new file mode 100644
index 0000000..6bfd7a8
--- /dev/null
+++ b/zircon/kernel/BUILD.gn
@@ -0,0 +1,359 @@
+# Copyright 2019 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("$zx/public/gn/config/standard.gni")
+import("$zx/public/gn/toolchain/c_utils.gni")
+import("$zx/public/gn/toolchain/environment.gni")
+import("$zx/public/gn/toolchain/environment_redirect.gni")
+import("params.gni")
+
+if (current_toolchain == default_toolchain) {
+  # In the default toolchain, just define the kernel toolchains.
+  foreach(cpu, standard_fuchsia_cpus) {
+    environment("kernel") {
+      globals = {
+        is_kernel = true
+      }
+      configs += standard_fuchsia_configs
+      configs += [
+        ":kernel_config",
+
+        # <stdio.h> has #include <lib/io.h>.
+        "$zx/kernel/lib/io:headers.config",
+
+        # <malloc.h> has #include <lib/heap.h>.
+        "$zx/kernel/lib/heap:headers.config",
+
+        # <kernel/spinlock.h> has #include <lockdep/lock_policy.h>.
+        "$zx/system/ulib/lockdep:headers.config",
+
+        # <kernel/thread.h> has #include <vm/kstack.h>.
+        "vm:headers.config",
+
+        # <lib/ktrace.h> has #include <lib/zircon-internal/ktrace.h>.
+        "$zx/system/ulib/zircon-internal:headers.config",
+
+        # <kernel/thread.h> has #include <fbl/macros.h>
+        "$zx/system/ulib/fbl:headers.config",
+
+        # <dev/iommu.h> has #include <fbl/name.h>
+        "lib/fbl:headers.config",
+
+        # <lib/mtrace.h> has #include <lib/user_copy/user_ptr.h>
+        "lib/user_copy:headers.config",
+      ]
+    }
+  }
+} else if (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") {
+    configs = [
+      ":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",
+      "lib/libc/include",
+    ]
+  }
+
+  # For any standalone static binary.
+  config("standalone") {
+    ldflags = [
+      "-nostdlib",
+      "-static",
+    ]
+
+    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" ]
+    }
+
+    configs = [ "$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" ]
+    }
+  }
+
+  zircon_elf_rspfile = "$target_gen_dir/zircon.elf.rsp"
+  link_output_rspfile("zircon.elf.rsp") {
+    visibility = [ ":*" ]
+    deps = [
+      ":zircon",
+    ]
+    outputs = [
+      zircon_elf_rspfile,
+    ]
+  }
+
+  # 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" ]
+    }
+  }
+
+  group("test") {
+    #TODO: testonly = true
+    visibility = [ ":*" ]
+    deps = [
+      "lib/debugcommands",
+      "tests",
+    ]
+  }
+
+  # Extract the raw binary image (no ELF headers) of the kernel proper.
+  image_binary("raw") {
+    visibility = [ ":*" ]
+    deps = [
+      ":zircon",
+    ]
+    output_name = "zircon"
+    output_path =
+        rebase_path("$target_out_dir/$output_name.bin", root_build_dir)
+    metadata = {
+      image_path_defines = [ "#define KERNEL_IMAGE \"${output_path}\"" ]
+      image_path_barrier = []
+    }
+
+    # Use the same variant for the extraction that will have built the kernel.
+    variant_target = {
+      match = "executable"
+      label = ":zircon"
+      output_name = "zircon"
+    }
+  }
+
+  # Use metadata to embed that file name in case it's a variant redirect.
+  kernel_image_h = "$target_gen_dir/kernel_image.h"
+  generated_file("kernel_image.h") {
+    visibility = [ ":*" ]
+    deps = [
+      ":raw",
+    ]
+    outputs = [
+      kernel_image_h,
+    ]
+    data_keys = [ "image_path_defines" ]
+    walk_keys = [ "image_path_barrier" ]
+    output_conversion = "list lines"
+  }
+
+  # 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",
+      ":zircon.elf.rsp",
+    ]
+    sources = [
+      zircon_elf_rspfile,
+    ]
+    outputs = [
+      "$target_gen_dir/kernel-fixups.inc",
+    ]
+    depfile = "${outputs[0]}.d"
+
+    # 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(zircon_elf_rspfile, root_build_dir),
+      rebase_path(outputs[0], root_build_dir),
+      rebase_path(depfile, root_build_dir),
+    ]
+
+    # Use the same variant for the extraction that will have built the kernel.
+    variant_target = {
+      match = "executable"
+      label = ":zircon"
+      output_name = "zircon"
+    }
+  }
+
+  # Link the final kernel image layout including the extracted raw binary
+  # and the generated fixups.
+  executable("image") {
+    visibility = [ ":*" ]
+    configs += [ ":kernel_defsym" ]
+    deps = [
+      ":fixups",
+      ":kernel_image.h",
+      ":raw",
+      ":zircon",
+      ":zircon.elf.rsp",
+    ]
+    include_dirs = [ target_gen_dir ]
+    defines = image_defines
+    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_rspfile, root_build_dir),
+    ]
+    inputs = [
+      "image.ld",
+      zircon_elf_rspfile,
+    ]
+  }
+
+  # Finally, extract the raw image (no ELF headers), which includes its own
+  # embedded headers to make it a ZBI.
+  image_binary("kernel") {
+    output_dir = root_out_dir
+    output_extension = "zbi"
+    output_path = rebase_path("$output_dir/$target_name.$output_extension",
+                              root_build_dir)
+    deps = [
+      ":image",
+    ]
+    metadata = {
+      images = [
+        {
+          type = "zbi"
+          name = "kernel"
+          path = output_path
+        },
+      ]
+
+      # 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",
+        output_path,
+      ]
+    }
+
+    # Use the same variant for the extraction that will have built the kernel.
+    variant_target = {
+      match = "executable"
+      label = ":zircon"
+      output_name = "zircon"
+    }
+  }
+} else {
+  # Redirect to the kernel toolchain.
+  environment_redirect("kernel") {
+    environment_label = ":kernel"
+    deps = [
+      ":kernel",
+    ]
+  }
+}
diff --git a/zircon/kernel/arch/arm64/BUILD.gn b/zircon/kernel/arch/arm64/BUILD.gn
new file mode 100644
index 0000000..c011d93
--- /dev/null
+++ b/zircon/kernel/arch/arm64/BUILD.gn
@@ -0,0 +1,110 @@
+# Copyright 2019 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("$zx/kernel/params.gni")
+import("$zx/public/gn/toolchain/environment.gni")
+
+if (current_toolchain == default_toolchain) {
+  # Define a special environment for building code that runs in physical
+  # memory with the MMU disabled, at early boot.
+  environment("physmem") {
+    cpu = "arm64"
+    globals = {
+      is_kernel = true
+    }
+    configs += standard_fuchsia_configs + [ ":physmem_config" ]
+  }
+} else {
+  # This is the top config for the physmem environment.
+  config("physmem_config") {
+    configs = [
+      "$zx/kernel:headers",
+      "$zx/kernel:standalone",
+      "$zx/kernel:warnings",
+      "$zx/kernel/lib/libc:headers.config",
+      "$zx/public/gn/config:no_sanitizers",
+    ]
+
+    cflags = [
+      "-fpie",
+
+      "-mgeneral-regs-only",
+
+      # With the MMU disabled, alignment checking is always enabled.  So make
+      # sure the compiler doesn't use any unaligned memory accesses.
+      "-mstrict-align",
+    ]
+
+    if (!is_gcc) {
+      # TODO(TC-237): cflags += [ "-mcmodel=tiny" ]
+    }
+
+    include_dirs = [ "include" ]
+  }
+
+  # This is used pervasively throughout the kernel on arm64.
+  config("kernel") {
+    # The kernel does not use FP or vector registers.
+    cflags = [ "-mgeneral-regs-only" ]
+
+    if (!is_gcc) {
+      # Clang needs -mcmodel=kernel to tell it to use the right safe-stack
+      # ABI for the kernel.
+      cflags += [ "-mcmodel=kernel" ]
+    }
+
+    defines = [
+      "ARCH_ARM64",
+      "KERNEL_ASPACE_BASE=$kernel_aspace_base",
+      "KERNEL_ASPACE_SIZE=0x0001000000000000",
+      "USER_ASPACE_BASE=0x0000000001000000",
+      "USER_ASPACE_SIZE=0x0000fffffe000000",
+    ]
+
+    # For #include <arch/foo.h>.
+    include_dirs = [ "include" ]
+  }
+
+  library("arm64") {
+    kernel = true
+    defines = [
+      "SMP_CPU_MAX_CLUSTER_CPUS=$smp_max_cpus",
+      "SMP_CPU_MAX_CLUSTERS=$smp_max_clusters",
+    ]
+    sources = [
+      "arch.cpp",
+      "asm.S",
+      "boot-mmu.cpp",
+      "cache-ops.S",
+      "debugger.cpp",
+      "exceptions.S",
+      "exceptions_c.cpp",
+      "feature.cpp",
+      "fpu.cpp",
+      "mexec.S",
+      "mmu.cpp",
+      "mp.cpp",
+      "periphmap.cpp",
+      "registers.cpp",
+      "smccc.S",
+      "spinlock.cpp",
+      "start.S",
+      "sysreg.cpp",
+      "thread.cpp",
+      "user_copy.S",
+      "user_copy_c.cpp",
+      "uspace_entry.S",
+    ]
+    deps = [
+      "$zx/kernel/dev/iommu/dummy",
+      "$zx/kernel/lib/console",
+      "$zx/kernel/lib/counters",
+      "$zx/kernel/lib/crashlog",
+      "$zx/kernel/object",
+      "$zx/kernel/syscalls:syscall-abi",
+      "$zx/kernel/vm",
+      "$zx/system/ulib/bitmap",
+    ]
+  }
+}
diff --git a/zircon/kernel/arch/arm64/hypervisor/BUILD.gn b/zircon/kernel/arch/arm64/hypervisor/BUILD.gn
new file mode 100644
index 0000000..9c24d65
--- /dev/null
+++ b/zircon/kernel/arch/arm64/hypervisor/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2019 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.
+
+source_set("hypervisor") {
+  sources = [
+    "el2.S",
+    "el2_cpu_state.cpp",
+    "gic/el2.S",
+    "gic/gicv2.cpp",
+    "gic/gicv3.cpp",
+    "guest.cpp",
+    "vcpu.cpp",
+    "vmexit.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt/arm_gic/common",
+    "$zx/kernel/dev/interrupt/arm_gic/v2",
+    "$zx/kernel/dev/interrupt/arm_gic/v3",
+    "$zx/kernel/dev/psci",
+    "$zx/kernel/dev/timer/arm_generic",
+    "$zx/kernel/lib/hypervisor:headers",
+  ]
+}
diff --git a/zircon/kernel/arch/arm64/image.S b/zircon/kernel/arch/arm64/image.S
index 4d88938..d6882fb 100644
--- a/zircon/kernel/arch/arm64/image.S
+++ b/zircon/kernel/arch/arm64/image.S
@@ -58,6 +58,7 @@
 
 // Include the kernel image itself, skipping the padding left for the headers.
 DATA(kernel_image)
+#include "kernel_image.h"
 .incbin KERNEL_IMAGE, BOOT_HEADER_SIZE
 DATA(kernel_image_end)
 END_DATA(kernel_image)
diff --git a/zircon/kernel/arch/x86/BUILD.gn b/zircon/kernel/arch/x86/BUILD.gn
new file mode 100644
index 0000000..0adfd27
--- /dev/null
+++ b/zircon/kernel/arch/x86/BUILD.gn
@@ -0,0 +1,165 @@
+# Copyright 2019 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("$zx/kernel/params.gni")
+
+# This is used pervasively throughout the kernel on x86.
+config("kernel") {
+  cflags = [
+    "-mno-red-zone",
+
+    # Hard disable floating point in the kernel.
+    "-msoft-float",
+    "-mno-mmx",
+    "-mno-sse",
+    "-mno-sse2",
+    "-mno-3dnow",
+    "-mno-avx",
+    "-mno-avx2",
+  ]
+
+  if (is_gcc) {
+    cflags += [
+      "-falign-jumps=1",
+      "-falign-loops=1",
+      "-falign-functions=4",
+
+      # Optimization: Since FPU is disabled, do not pass flag in %rax to
+      # varargs routines that floating point args are in use.
+      "-mskip-rax-setup",
+    ]
+  } else {
+    # Clang needs -mcmodel=kernel to tell it to use the right safe-stack
+    # ABI for the kernel.
+    cflags += [ "-mcmodel=kernel" ]
+  }
+
+  defines = [
+    "ARCH_X86",
+    "KERNEL_ASPACE_BASE=$kernel_aspace_base",
+    "KERNEL_ASPACE_SIZE=0x0000008000000000UL",
+
+    "USER_ASPACE_BASE=0x0000000001000000UL",  # 16MB
+
+    # We set the top of user address space to be (1 << 47) - 4k.  See
+    # docs/sysret_problem.md for why we subtract 4k here.  Subtracting
+    # USER_ASPACE_BASE from that value gives the value for USER_ASPACE_SIZE
+    # below.
+    "USER_ASPACE_SIZE=0x00007ffffefff000UL",
+
+    "KERNEL_LOAD_OFFSET=0x00100000",  # 1MB
+  ]
+
+  # For #include <arch/foo.h>.
+  include_dirs = [ "include" ]
+
+  configs = [
+    # <arch/aspace.h> has #include <bitmap/rle-bitmap.h>
+    "$zx/system/ulib/bitmap:headers.config",
+
+    # <arch/aspace.h> has #include <arch/x86/page_tables/constants.h>.
+    "page_tables:headers.config",
+
+    # <arch/x86/page_tables/page_tables.h> has #include <hwreg/bitfields.h>.
+    "$zx/system/ulib/hwreg:headers.config",
+  ]
+}
+
+library("x86") {
+  kernel = true
+  sources = [
+    "acpi.S",
+    "arch.cpp",
+    "asm.S",
+    "bootstrap16.cpp",
+    "cache.cpp",
+    "cpu_topology.cpp",
+    "debugger.cpp",
+    "descriptor.cpp",
+    "exceptions.S",
+    "faults.cpp",
+    "feature.cpp",
+    "gdt.S",
+    "hwp.cpp",
+    "idt.cpp",
+    "ioapic.cpp",
+    "ioport.cpp",
+    "lapic.cpp",
+    "mexec.S",
+    "mmu.cpp",
+    "mmu_mem_types.cpp",
+    "mp.cpp",
+    "ops.S",
+    "perf_mon.cpp",
+    "proc_trace.cpp",
+    "pvclock.cpp",
+    "registers.cpp",
+    "smp.cpp",
+    "start.S",
+    "start16.S",
+    "thread.cpp",
+    "timer_freq.cpp",
+    "tsc.cpp",
+    "user_copy.S",
+    "user_copy.cpp",
+    "uspace_entry.S",
+  ]
+  deps = [
+    ":syscall",
+    ":tests",
+    "$zx/kernel/dev/hw_rng",
+    "$zx/kernel/dev/iommu/dummy",
+    "$zx/kernel/dev/iommu/intel",
+    "$zx/kernel/lib/code_patching",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/counters",
+    "$zx/kernel/lib/crashlog",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/pci",
+    "$zx/kernel/object",
+    "$zx/system/ulib/bitmap",
+    "cpuid",
+  ]
+  public_deps = [
+    # arch/x86/apic.h has #include <dev/interrupt.h>.
+    "$zx/kernel/dev/interrupt:headers",
+
+    # arch/x86/hypervisor.h has #include <hypervisor/guest_physical_address_space.h>.
+    "$zx/kernel/lib/hypervisor:headers",
+
+    # <arch/aspace.h> has #include <bitmap/rle-bitmap.h>.
+    "$zx/system/ulib/bitmap:headers",
+
+    # <arch/aspace.h> has #include <fbl/unique_ptr.h>.
+    "$zx/system/ulib/fbl:headers",
+
+    # <arch/x86/acpi.h> has #include <acpica/acpi.h>.
+    "$zx/third_party/lib/acpica:headers",
+
+    # <arch/x86/ioport.h> has #include <bitmap/rle-bitmap.h>.
+    "$zx/system/ulib/bitmap:headers",
+
+    # <arch/x86/apic.h> has #include <dev/interrupt.h>.
+    "$zx/kernel/dev/interrupt:headers",
+  ]
+}
+
+source_set("syscall") {
+  sources = [
+    "syscall.S",
+  ]
+  deps = [
+    "$zx/kernel/syscalls:syscall-abi",
+  ]
+}
+
+source_set("tests") {
+  sources = [
+    "mmu_tests.cpp",
+  ]
+  deps = [
+    ":headers",
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/arch/x86/cpuid/BUILD.gn b/zircon/kernel/arch/x86/cpuid/BUILD.gn
new file mode 100644
index 0000000..e200761
--- /dev/null
+++ b/zircon/kernel/arch/x86/cpuid/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2019 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.
+
+library("cpuid") {
+  kernel = true
+  sources = [
+    "cpuid.cpp",
+  ]
+
+  # TODO: testonly
+  deps = [
+    ":test",
+  ]
+}
+
+source_set("test") {
+  # TODO: testonly = true
+  sources = [
+    "cpuid_test.cpp",
+  ]
+  deps = [
+    ":cpuid.headers",
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/arch/x86/hypervisor/BUILD.gn b/zircon/kernel/arch/x86/hypervisor/BUILD.gn
new file mode 100644
index 0000000..facdd69
--- /dev/null
+++ b/zircon/kernel/arch/x86/hypervisor/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2019 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.
+
+source_set("hypervisor") {
+  sources = [
+    "guest.cpp",
+    "pvclock.cpp",
+    "vcpu.cpp",
+    "vmexit.cpp",
+    "vmx.S",
+    "vmx_cpu_state.cpp",
+  ]
+  deps = [
+    "$zx/kernel/arch/x86:headers",
+    "$zx/kernel/lib/hypervisor:headers",
+    "$zx/kernel/platform/pc",
+    "$zx/system/ulib/explicit-memory",
+  ]
+}
diff --git a/zircon/kernel/arch/x86/image.S b/zircon/kernel/arch/x86/image.S
index c9a199f..fab8c33 100644
--- a/zircon/kernel/arch/x86/image.S
+++ b/zircon/kernel/arch/x86/image.S
@@ -74,6 +74,7 @@
 
 // Include the kernel image itself, skipping the padding left for the headers.
 DATA(kernel_image)
+#include "kernel_image.h"
 .incbin KERNEL_IMAGE, BOOT_HEADER_SIZE
 DATA(kernel_image_end)
 END_DATA(kernel_image)
diff --git a/zircon/kernel/arch/x86/page_tables/BUILD.gn b/zircon/kernel/arch/x86/page_tables/BUILD.gn
new file mode 100644
index 0000000..aa0ef47
--- /dev/null
+++ b/zircon/kernel/arch/x86/page_tables/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2019 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.
+
+library("page_tables") {
+  kernel = true
+  sources = [
+    "page_tables.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/fbl",
+  ]
+  public_deps = [
+    # <arch/x86/page_tables/page_tables.h> has #include <hwreg/bitfields.h>.
+    "$zx/system/ulib/hwreg:headers",
+  ]
+}
diff --git a/zircon/kernel/dev/hdcp/amlogic_s912/BUILD.gn b/zircon/kernel/dev/hdcp/amlogic_s912/BUILD.gn
new file mode 100644
index 0000000..0a0d600
--- /dev/null
+++ b/zircon/kernel/dev/hdcp/amlogic_s912/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+source_set("amlogic_s912") {
+  sources = [
+    "hdcp.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/lib/cbuf",
+  ]
+}
diff --git a/zircon/kernel/dev/hw_rng/BUILD.gn b/zircon/kernel/dev/hw_rng/BUILD.gn
new file mode 100644
index 0000000..c8aa46ae
--- /dev/null
+++ b/zircon/kernel/dev/hw_rng/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("hw_rng") {
+  kernel = true
+  sources = [
+    "debug.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+  ]
+}
diff --git a/zircon/kernel/dev/intel_rng/BUILD.gn b/zircon/kernel/dev/intel_rng/BUILD.gn
new file mode 100644
index 0000000..672103f
--- /dev/null
+++ b/zircon/kernel/dev/intel_rng/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+source_set("intel_rng") {
+  sources = [
+    "intel-rng.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/hw_rng",
+  ]
+}
diff --git a/zircon/kernel/dev/interrupt/BUILD.gn b/zircon/kernel/dev/interrupt/BUILD.gn
new file mode 100644
index 0000000..42ee3dc
--- /dev/null
+++ b/zircon/kernel/dev/interrupt/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("interrupt") {
+  kernel = true
+  sources = [
+    "msi.cpp",
+  ]
+}
diff --git a/zircon/kernel/dev/interrupt/arm_gic/common/BUILD.gn b/zircon/kernel/dev/interrupt/arm_gic/common/BUILD.gn
new file mode 100644
index 0000000..a32199e8
--- /dev/null
+++ b/zircon/kernel/dev/interrupt/arm_gic/common/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("common") {
+  kernel = true
+  sources = [
+    "arm_gic_hw_interface.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+  ]
+}
diff --git a/zircon/kernel/dev/interrupt/arm_gic/v2/BUILD.gn b/zircon/kernel/dev/interrupt/arm_gic/v2/BUILD.gn
new file mode 100644
index 0000000..7e28dd1
--- /dev/null
+++ b/zircon/kernel/dev/interrupt/arm_gic/v2/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 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.
+
+library("v2") {
+  kernel = true
+  sources = [
+    "arm_gicv2.cpp",
+    "arm_gicv2m.cpp",
+    "arm_gicv2m_msi.cpp",
+    "arm_gicv2m_pcie.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/interrupt/arm_gic/common",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/interrupt",
+    "$zx/kernel/lib/pow2_range_allocator",
+  ]
+}
diff --git a/zircon/kernel/dev/interrupt/arm_gic/v3/BUILD.gn b/zircon/kernel/dev/interrupt/arm_gic/v3/BUILD.gn
new file mode 100644
index 0000000..cee8eaa
--- /dev/null
+++ b/zircon/kernel/dev/interrupt/arm_gic/v3/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2019 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.
+
+library("v3") {
+  kernel = true
+  sources = [
+    "arm_gicv3.cpp",
+    "arm_gicv3_pcie.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/interrupt/arm_gic/common",
+    "$zx/kernel/dev/interrupt/arm_gic/v2:headers",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/interrupt",
+  ]
+}
diff --git a/zircon/kernel/dev/iommu/dummy/BUILD.gn b/zircon/kernel/dev/iommu/dummy/BUILD.gn
new file mode 100644
index 0000000..0c4d8ea
--- /dev/null
+++ b/zircon/kernel/dev/iommu/dummy/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("dummy") {
+  kernel = true
+  sources = [
+    "dummy_iommu.cpp",
+  ]
+}
diff --git a/zircon/kernel/dev/iommu/intel/BUILD.gn b/zircon/kernel/dev/iommu/intel/BUILD.gn
new file mode 100644
index 0000000..32a0ccb
--- /dev/null
+++ b/zircon/kernel/dev/iommu/intel/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2019 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.
+
+library("intel") {
+  kernel = true
+  sources = [
+    "context_table_state.cpp",
+    "device_context.cpp",
+    "domain_allocator.cpp",
+    "intel_iommu.cpp",
+    "iommu_impl.cpp",
+    "iommu_page.cpp",
+    "second_level_pt.cpp",
+  ]
+  deps = [
+    "$zx/kernel/arch/x86/page_tables",
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/user_copy",
+    "$zx/kernel/vm:headers",
+    "$zx/system/ulib/bitmap",
+    "$zx/system/ulib/hwreg",
+    "$zx/system/ulib/region-alloc",
+    "$zx/system/ulib/zxcpp",
+  ]
+  public_deps = [
+    # dev/iommu/intel.h has #include <fbl/ref_ptr.h>.
+    "$zx/kernel/lib/fbl:headers",
+  ]
+}
diff --git a/zircon/kernel/dev/pcie/BUILD.gn b/zircon/kernel/dev/pcie/BUILD.gn
new file mode 100644
index 0000000..299c9ab
--- /dev/null
+++ b/zircon/kernel/dev/pcie/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright 2019 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.
+
+library("pcie") {
+  kernel = true
+  sources = [
+    "address_provider/designware.cpp",
+    "address_provider/ecam_region.cpp",
+    "address_provider/mmio.cpp",
+    "address_provider/pio.cpp",
+    "debug.cpp",
+    "pci_config.cpp",
+    "pcie_bridge.cpp",
+    "pcie_bus_driver.cpp",
+    "pcie_caps.cpp",
+    "pcie_device.cpp",
+    "pcie_irqs.cpp",
+    "pcie_quirks.cpp",
+    "pcie_root.cpp",
+    "pcie_upstream_node.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/pci",
+    "$zx/kernel/vm:headers",
+    "$zx/system/ulib/region-alloc",
+    "$zx/system/ulib/zxcpp",
+  ]
+  public_deps = [
+    # <dev/pcie_platform.h> has #include <dev/interrupt.h>.
+    "$zx/kernel/dev/interrupt:headers",
+
+    # <dev/pcie_bus_driver.h> has #include <region-alloc/region-alloc.h>.
+    "$zx/system/ulib/region-alloc:headers",
+  ]
+
+  # TODO(mcgrathr): Say why this is needed.
+  cflags_cc = [ "-Wno-invalid-offsetof" ]
+}
diff --git a/zircon/kernel/dev/pdev/BUILD.gn b/zircon/kernel/dev/pdev/BUILD.gn
new file mode 100644
index 0000000..23c8cca
--- /dev/null
+++ b/zircon/kernel/dev/pdev/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("pdev") {
+  kernel = true
+  sources = [
+    "pdev.cpp",
+  ]
+  public_deps = [
+    # <pdev/interrupt.h> has #include <dev/interrupt.h>.
+    "$zx/kernel/dev/interrupt",
+  ]
+}
diff --git a/zircon/kernel/dev/pdev/interrupt/BUILD.gn b/zircon/kernel/dev/pdev/interrupt/BUILD.gn
new file mode 100644
index 0000000..4e48ddd
--- /dev/null
+++ b/zircon/kernel/dev/pdev/interrupt/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+source_set("interrupt") {
+  sources = [
+    "interrupt.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+  ]
+}
diff --git a/zircon/kernel/dev/pdev/power/BUILD.gn b/zircon/kernel/dev/pdev/power/BUILD.gn
new file mode 100644
index 0000000..96fb848
--- /dev/null
+++ b/zircon/kernel/dev/pdev/power/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+source_set("power") {
+  sources = [
+    "power.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/psci",
+  ]
+}
diff --git a/zircon/kernel/dev/pdev/uart/BUILD.gn b/zircon/kernel/dev/pdev/uart/BUILD.gn
new file mode 100644
index 0000000..2977730
--- /dev/null
+++ b/zircon/kernel/dev/pdev/uart/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+source_set("uart") {
+  sources = [
+    "uart.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+  ]
+}
diff --git a/zircon/kernel/dev/power/hisi/BUILD.gn b/zircon/kernel/dev/power/hisi/BUILD.gn
new file mode 100644
index 0000000..ee15b4d
--- /dev/null
+++ b/zircon/kernel/dev/power/hisi/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+source_set("hisi") {
+  sources = [
+    "power.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/power",
+    "$zx/kernel/dev/psci",
+  ]
+}
diff --git a/zircon/kernel/dev/psci/BUILD.gn b/zircon/kernel/dev/psci/BUILD.gn
new file mode 100644
index 0000000..ef46d93
--- /dev/null
+++ b/zircon/kernel/dev/psci/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("psci") {
+  kernel = true
+  sources = [
+    "psci.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/lib/console",
+  ]
+}
diff --git a/zircon/kernel/dev/timer/arm_generic/BUILD.gn b/zircon/kernel/dev/timer/arm_generic/BUILD.gn
new file mode 100644
index 0000000..1b70d00
--- /dev/null
+++ b/zircon/kernel/dev/timer/arm_generic/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+library("arm_generic") {
+  kernel = true
+  sources = [
+    "arm_generic_timer.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/lib/fixed_point",
+  ]
+}
diff --git a/zircon/kernel/dev/uart/amlogic_s905/BUILD.gn b/zircon/kernel/dev/uart/amlogic_s905/BUILD.gn
new file mode 100644
index 0000000..b8078d5
--- /dev/null
+++ b/zircon/kernel/dev/uart/amlogic_s905/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+source_set("amlogic_s905") {
+  sources = [
+    "uart.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/uart",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/debuglog",
+  ]
+}
diff --git a/zircon/kernel/dev/uart/msm/BUILD.gn b/zircon/kernel/dev/uart/msm/BUILD.gn
new file mode 100644
index 0000000..7573114
--- /dev/null
+++ b/zircon/kernel/dev/uart/msm/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+source_set("msm") {
+  sources = [
+    "uart.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/uart",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/debuglog",
+  ]
+}
diff --git a/zircon/kernel/dev/uart/nxp-imx/BUILD.gn b/zircon/kernel/dev/uart/nxp-imx/BUILD.gn
new file mode 100644
index 0000000..295bb31
--- /dev/null
+++ b/zircon/kernel/dev/uart/nxp-imx/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+source_set("nxp-imx") {
+  sources = [
+    "uart.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/uart",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/debuglog",
+  ]
+}
diff --git a/zircon/kernel/dev/uart/pl011/BUILD.gn b/zircon/kernel/dev/uart/pl011/BUILD.gn
new file mode 100644
index 0000000..d500769
--- /dev/null
+++ b/zircon/kernel/dev/uart/pl011/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+source_set("pl011") {
+  sources = [
+    "uart.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/uart",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/debuglog",
+  ]
+}
diff --git a/zircon/kernel/dev/udisplay/BUILD.gn b/zircon/kernel/dev/udisplay/BUILD.gn
new file mode 100644
index 0000000..942709a
--- /dev/null
+++ b/zircon/kernel/dev/udisplay/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2019 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.
+
+library("udisplay") {
+  kernel = true
+  sources = [
+    "udisplay.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/crashlog",
+    "$zx/kernel/lib/debuglog",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/gfx",
+    "$zx/kernel/lib/gfxconsole",
+    "$zx/kernel/vm:headers",
+  ]
+}
diff --git a/zircon/kernel/kernel/BUILD.gn b/zircon/kernel/kernel/BUILD.gn
new file mode 100644
index 0000000..c4e699c
--- /dev/null
+++ b/zircon/kernel/kernel/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2019 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.
+
+source_set("kernel") {
+  sources = [
+    "brwlock.cpp",
+    "cmdline.cpp",
+    "deadline.cpp",
+    "debug.cpp",
+    "dpc.cpp",
+    "event.cpp",
+    "init.cpp",
+    "mp.cpp",
+    "mutex.cpp",
+    "percpu.cpp",
+    "sched.cpp",
+    "thread.cpp",
+    "timer.cpp",
+    "wait.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/counters",
+    "$zx/kernel/lib/debug",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/heap",
+    "$zx/kernel/lib/libc",
+    "$zx/kernel/lib/version",
+    "$zx/kernel/object",
+    "$zx/kernel/vm",
+    "$zx/system/ulib/explicit-memory",
+    "$zx/system/ulib/zircon-internal",
+  ]
+}
diff --git a/zircon/kernel/lib/acpi_tables/BUILD.gn b/zircon/kernel/lib/acpi_tables/BUILD.gn
new file mode 100644
index 0000000..e13fbbc
--- /dev/null
+++ b/zircon/kernel/lib/acpi_tables/BUILD.gn
@@ -0,0 +1,33 @@
+# Copyright 2019 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.
+
+library("acpi_tables") {
+  kernel = true
+  sources = [
+    "acpi_tables.cpp",
+  ]
+  public_deps = [
+    # <lib/acpi_tables.h> has #include <acpica/acpi.h>.
+    "$zx/third_party/lib/acpica:headers",
+
+    # <lib/acpi_tables.h> has #include <arch/x86/apic.h.
+    "$zx/kernel/arch/x86:headers",
+  ]
+
+  # TODO: testonly
+  deps = [
+    ":test",
+  ]
+}
+
+source_set("test") {
+  # TODO: testonly = true
+  sources = [
+    "acpi_tables_test.cpp",
+  ]
+  deps = [
+    ":acpi_tables.headers",
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/lib/cbuf/BUILD.gn b/zircon/kernel/lib/cbuf/BUILD.gn
new file mode 100644
index 0000000..6aeddf0
--- /dev/null
+++ b/zircon/kernel/lib/cbuf/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("cbuf") {
+  kernel = true
+  sources = [
+    "cbuf.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/code_patching/BUILD.gn b/zircon/kernel/lib/code_patching/BUILD.gn
new file mode 100644
index 0000000..c39d640
--- /dev/null
+++ b/zircon/kernel/lib/code_patching/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("code_patching") {
+  kernel = true
+  sources = [
+    "code_patching.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/console/BUILD.gn b/zircon/kernel/lib/console/BUILD.gn
new file mode 100644
index 0000000..5197fc7
--- /dev/null
+++ b/zircon/kernel/lib/console/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("console") {
+  kernel = true
+  sources = [
+    "console.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/counters/BUILD.gn b/zircon/kernel/lib/counters/BUILD.gn
new file mode 100644
index 0000000..273ed7f
--- /dev/null
+++ b/zircon/kernel/lib/counters/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("counters") {
+  kernel = true
+  sources = [
+    "counters.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/crashlog/BUILD.gn b/zircon/kernel/lib/crashlog/BUILD.gn
new file mode 100644
index 0000000..e6d4055
--- /dev/null
+++ b/zircon/kernel/lib/crashlog/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("crashlog") {
+  kernel = true
+  sources = [
+    "crashlog.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/version",
+  ]
+}
diff --git a/zircon/kernel/lib/crypto/BUILD.gn b/zircon/kernel/lib/crypto/BUILD.gn
new file mode 100644
index 0000000..17bbf3d
--- /dev/null
+++ b/zircon/kernel/lib/crypto/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2019 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.
+
+library("crypto") {
+  kernel = true
+  sources = [
+    "global_prng.cpp",
+    "global_prng_unittest.cpp",
+    "prng.cpp",
+    "prng_unittest.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/unittest",
+    "$zx/system/ulib/explicit-memory",
+    "$zx/third_party/ulib/cryptolib",
+    "$zx/third_party/ulib/uboringssl",
+    "entropy",
+  ]
+  public_deps = [
+    # lib/crypto/prng.h has #include <openssl/sha.h>.
+    "$zx/third_party/ulib/uboringssl:headers",
+
+    # <lib/crypto/entropy/jitterentropy_collector.h> has #include <lib/jitterentropy/jitterentropy.h>.
+    "$zx/third_party/lib/jitterentropy:headers",
+  ]
+}
diff --git a/zircon/kernel/lib/crypto/entropy/BUILD.gn b/zircon/kernel/lib/crypto/entropy/BUILD.gn
new file mode 100644
index 0000000..7bfa71c
--- /dev/null
+++ b/zircon/kernel/lib/crypto/entropy/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2019 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.
+
+source_set("entropy") {
+  sources = [
+    "collector.cpp",
+    "collector_unittest.cpp",
+    "hw_rng_collector.cpp",
+    "jitterentropy_collector.cpp",
+    "quality_test.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/hw_rng",
+    "$zx/kernel/lib/crypto:headers",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/unittest",
+    "$zx/third_party/lib/jitterentropy",
+  ]
+}
diff --git a/zircon/kernel/lib/debug/BUILD.gn b/zircon/kernel/lib/debug/BUILD.gn
new file mode 100644
index 0000000..ab41571
--- /dev/null
+++ b/zircon/kernel/lib/debug/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+source_set("debug") {
+  sources = [
+    "debug.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/hw_rng",
+  ]
+}
diff --git a/zircon/kernel/lib/debugcommands/BUILD.gn b/zircon/kernel/lib/debugcommands/BUILD.gn
new file mode 100644
index 0000000..39d14ec
--- /dev/null
+++ b/zircon/kernel/lib/debugcommands/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+source_set("debugcommands") {
+  sources = [
+    "debugcommands.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/debug",
+  ]
+}
diff --git a/zircon/kernel/lib/debuglog/BUILD.gn b/zircon/kernel/lib/debuglog/BUILD.gn
new file mode 100644
index 0000000..fcfebad
--- /dev/null
+++ b/zircon/kernel/lib/debuglog/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+library("debuglog") {
+  kernel = true
+  sources = [
+    "debuglog.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/udisplay:headers",
+    "$zx/kernel/lib/crashlog",
+    "$zx/kernel/lib/version",
+  ]
+}
diff --git a/zircon/kernel/lib/fbl/BUILD.gn b/zircon/kernel/lib/fbl/BUILD.gn
new file mode 100644
index 0000000..2f155a2
--- /dev/null
+++ b/zircon/kernel/lib/fbl/BUILD.gn
@@ -0,0 +1,35 @@
+# Copyright 2019 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.
+
+library("fbl") {
+  kernel = true
+  sources = [
+    "arena.cpp",
+  ]
+  deps = [
+    ":tests",
+    "$zx/kernel/vm:headers",
+  ]
+  public_deps = [
+    "$zx/system/ulib/fbl",
+
+    # <fbl/arena.h> has #include <zxcpp/new.h>.
+    "$zx/system/ulib/zxcpp",
+  ]
+}
+
+source_set("tests") {
+  #TODO: testonly = true
+  visibility = [ ":*" ]
+  sources = [
+    "arena_tests.cpp",
+    "inline_array_tests.cpp",
+    "name_tests.cpp",
+  ]
+
+  deps = [
+    ":headers",
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/lib/fixed_point/BUILD.gn b/zircon/kernel/lib/fixed_point/BUILD.gn
new file mode 100644
index 0000000..eacd7aa
--- /dev/null
+++ b/zircon/kernel/lib/fixed_point/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("fixed_point") {
+  kernel = true
+  sources = [
+    "fixed_point.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/gfx/BUILD.gn b/zircon/kernel/lib/gfx/BUILD.gn
new file mode 100644
index 0000000..7a169e0
--- /dev/null
+++ b/zircon/kernel/lib/gfx/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("gfx") {
+  kernel = true
+  sources = [
+    "gfx.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+  ]
+}
diff --git a/zircon/kernel/lib/gfxconsole/BUILD.gn b/zircon/kernel/lib/gfxconsole/BUILD.gn
new file mode 100644
index 0000000..ac23b1c
--- /dev/null
+++ b/zircon/kernel/lib/gfxconsole/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2019 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.
+
+library("gfxconsole") {
+  kernel = true
+  sources = [
+    "gfxconsole.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/gfx",
+  ]
+  public_deps = [
+    # <lib/gfxconsole.h> has #include <lib/gfx.h>.
+    "$zx/kernel/lib/gfx",
+  ]
+}
diff --git a/zircon/kernel/lib/header_tests/BUILD.gn b/zircon/kernel/lib/header_tests/BUILD.gn
new file mode 100644
index 0000000..73dfc7c
--- /dev/null
+++ b/zircon/kernel/lib/header_tests/BUILD.gn
@@ -0,0 +1,12 @@
+# Copyright 2019 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.
+
+source_set("header_tests") {
+  sources = [
+    "pow2_tests.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/lib/heap/BUILD.gn b/zircon/kernel/lib/heap/BUILD.gn
new file mode 100644
index 0000000..5698fb6
--- /dev/null
+++ b/zircon/kernel/lib/heap/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("heap") {
+  kernel = true
+  sources = [
+    "heap_wrapper.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "cmpctmalloc",
+  ]
+}
diff --git a/zircon/kernel/lib/heap/cmpctmalloc/BUILD.gn b/zircon/kernel/lib/heap/cmpctmalloc/BUILD.gn
new file mode 100644
index 0000000..36885ff
--- /dev/null
+++ b/zircon/kernel/lib/heap/cmpctmalloc/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("cmpctmalloc") {
+  kernel = true
+  sources = [
+    "cmpctmalloc.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/counters",
+  ]
+}
diff --git a/zircon/kernel/lib/hypervisor/BUILD.gn b/zircon/kernel/lib/hypervisor/BUILD.gn
new file mode 100644
index 0000000..e322a2a
--- /dev/null
+++ b/zircon/kernel/lib/hypervisor/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2019 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.
+
+library("hypervisor") {
+  kernel = true
+  sources = [
+    "cpu.cpp",
+    "guest_physical_address_space.cpp",
+    "hypervisor_unittest.cpp",
+    "ktrace.cpp",
+    "trap_map.cpp",
+  ]
+  deps = [
+    "$zx/kernel/arch/$zircon_cpu/hypervisor",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/unittest",
+    "$zx/system/ulib/bitmap",
+  ]
+  public_deps = [
+    # <hypervisor/trap_map.h> has #include <object/port_dispatcher.h>.
+    "$zx/kernel/object:headers",
+
+    # <hypervisor/id_allocator.h> has #include <bitmap/raw-bitmap.h>.
+    "$zx/system/ulib/bitmap:headers",
+
+    # <hypervisor/guest_physical_address_space.h> has #include <vm/vm_aspace.h>.
+    "$zx/kernel/vm:headers",
+  ]
+}
diff --git a/zircon/kernel/lib/io/BUILD.gn b/zircon/kernel/lib/io/BUILD.gn
new file mode 100644
index 0000000..0f076eb
--- /dev/null
+++ b/zircon/kernel/lib/io/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2019 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.
+
+library("io") {
+  kernel = true
+  sources = [
+    "console.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/debuglog",
+  ]
+}
diff --git a/zircon/kernel/lib/ktrace/BUILD.gn b/zircon/kernel/lib/ktrace/BUILD.gn
new file mode 100644
index 0000000..7ca40431
--- /dev/null
+++ b/zircon/kernel/lib/ktrace/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright 2019 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("$zx/kernel/syscalls/abigen.gni")
+
+source_set("ktrace") {
+  sources = [
+    "ktrace.cpp",
+  ]
+  include_dirs = [ target_gen_dir ]
+  deps = [
+    ":ktrace-info",
+    "$zx/kernel/lib/hypervisor",
+    "$zx/system/ulib/zircon-internal",
+  ]
+}
+
+abigen("ktrace-info") {
+  visibility = [ ":*" ]
+  gen = [
+    {
+      args = [ "-trace" ]
+      outputs = [
+        "$target_gen_dir/zircon/syscall-ktrace-info.inc",
+      ]
+    },
+  ]
+}
diff --git a/zircon/kernel/lib/libc/BUILD.gn b/zircon/kernel/lib/libc/BUILD.gn
new file mode 100644
index 0000000..8be10b9
--- /dev/null
+++ b/zircon/kernel/lib/libc/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright 2019 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.
+
+source_set("libc") {
+  sources = [
+    "atexit.c",
+    "atoi.c",
+    "bsearch.c",
+    "cxa_atexit.cpp",
+    "eabi.c",
+    "errno.c",
+    "printf.c",
+    "qsort.c",
+    "rand.c",
+    "stdio.c",
+    "strtol.c",
+    "strtoll.c",
+  ]
+  deps = [
+    ":ctype",
+    "$zx/kernel/lib/heap",
+    "$zx/kernel/lib/io",
+    "string",
+  ]
+}
+
+source_set("ctype") {
+  sources = [
+    "ctype.c",
+  ]
+}
diff --git a/zircon/kernel/lib/libc/string/BUILD.gn b/zircon/kernel/lib/libc/string/BUILD.gn
new file mode 100644
index 0000000..9798cbb
--- /dev/null
+++ b/zircon/kernel/lib/libc/string/BUILD.gn
@@ -0,0 +1,34 @@
+# Copyright 2019 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.
+
+source_set("string") {
+  sources = [
+    "memchr.c",
+    "memcmp.c",
+    "memmove.c",
+    "strcat.c",
+    "strchr.c",
+    "strcmp.c",
+    "strcoll.c",
+    "strcpy.c",
+    "strlcat.c",
+    "strlcpy.c",
+    "strlen.c",
+    "strncat.c",
+    "strncmp.c",
+    "strncpy.c",
+    "strnicmp.c",
+    "strnlen.c",
+    "strpbrk.c",
+    "strrchr.c",
+    "strspn.c",
+    "strstr.c",
+    "strtok.c",
+    "strxfrm.c",
+  ]
+  deps = [
+    "$zx/kernel/lib/libc:ctype",
+    "arch/$zircon_cpu",
+  ]
+}
diff --git a/zircon/kernel/lib/libc/string/arch/arm64/BUILD.gn b/zircon/kernel/lib/libc/string/arch/arm64/BUILD.gn
new file mode 100644
index 0000000..b7d303f
--- /dev/null
+++ b/zircon/kernel/lib/libc/string/arch/arm64/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+source_set("arm64") {
+  sources = [
+    "$zx/third_party/lib/cortex-strings/src/aarch64/memcpy.S",
+    "$zx/third_party/lib/cortex-strings/no-neon/src/aarch64/memset.S",
+  ]
+}
diff --git a/zircon/kernel/lib/libc/string/arch/x86/BUILD.gn b/zircon/kernel/lib/libc/string/arch/x86/BUILD.gn
new file mode 100644
index 0000000..e4d04ef
--- /dev/null
+++ b/zircon/kernel/lib/libc/string/arch/x86/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2019 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.
+
+source_set("x86") {
+  sources = [
+    "memcpy.S",
+    "memset.S",
+    "selector.cpp",
+  ]
+  deps = [
+    ":tests",
+    "$zx/kernel/lib/code_patching",
+  ]
+}
+
+source_set("tests") {
+  # TODO(mcgrathr): Make this optional somehow and enable testonly taint.
+  # testonly = true
+  sources = [
+    "tests.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/lib/lockdep/BUILD.gn b/zircon/kernel/lib/lockdep/BUILD.gn
new file mode 100644
index 0000000..eeecfaa
--- /dev/null
+++ b/zircon/kernel/lib/lockdep/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2019 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.
+
+source_set("lockdep") {
+  sources = [
+    "lock_dep.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/version",
+  ]
+  public_deps = [
+    # The kernel lockdep library is just a slight augmentation of the
+    # userland lockdep library, which supplies all the API headers.  So
+    # kernel/lib/lockdep is used as if it were a library() itself and acts
+    # as the kernel's drop-in replacement for system/ulib/lockdep.
+    "$zx/system/ulib/lockdep",
+  ]
+}
diff --git a/zircon/kernel/lib/memory_limit/BUILD.gn b/zircon/kernel/lib/memory_limit/BUILD.gn
new file mode 100644
index 0000000..13b40b8
--- /dev/null
+++ b/zircon/kernel/lib/memory_limit/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("memory_limit") {
+  kernel = true
+  sources = [
+    "memory_limit.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/fbl",
+    "$zx/system/ulib/pretty",
+  ]
+}
diff --git a/zircon/kernel/lib/mtrace/BUILD.gn b/zircon/kernel/lib/mtrace/BUILD.gn
new file mode 100644
index 0000000..8f41e61
--- /dev/null
+++ b/zircon/kernel/lib/mtrace/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+source_set("mtrace") {
+  sources = [
+    "mtrace-ipt.cpp",
+    "mtrace-pmu.cpp",
+    "mtrace.cpp",
+  ]
+  deps = [
+    "$zx/kernel/object",
+  ]
+}
diff --git a/zircon/kernel/lib/oom/BUILD.gn b/zircon/kernel/lib/oom/BUILD.gn
new file mode 100644
index 0000000..b5ae3c7f
--- /dev/null
+++ b/zircon/kernel/lib/oom/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("oom") {
+  kernel = true
+  sources = [
+    "oom.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/system/ulib/pretty",
+  ]
+}
diff --git a/zircon/kernel/lib/pci/BUILD.gn b/zircon/kernel/lib/pci/BUILD.gn
new file mode 100644
index 0000000..0cbe127
--- /dev/null
+++ b/zircon/kernel/lib/pci/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("pci") {
+  kernel = true
+  sources = [
+    "pio.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/pow2_range_allocator/BUILD.gn b/zircon/kernel/lib/pow2_range_allocator/BUILD.gn
new file mode 100644
index 0000000..47e7435
--- /dev/null
+++ b/zircon/kernel/lib/pow2_range_allocator/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("pow2_range_allocator") {
+  kernel = true
+  sources = [
+    "pow2_range_allocator.cpp",
+  ]
+}
diff --git a/zircon/kernel/lib/topology/BUILD.gn b/zircon/kernel/lib/topology/BUILD.gn
new file mode 100644
index 0000000..fbbd945
--- /dev/null
+++ b/zircon/kernel/lib/topology/BUILD.gn
@@ -0,0 +1,26 @@
+# Copyright 2019 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.
+
+library("topology") {
+  host = true
+  kernel = true
+  sources = [
+    "system-topology.cpp",
+  ]
+  deps = [
+    ":test",
+    "$zx/system/ulib/fbl",
+  ]
+}
+
+source_set("test") {
+  # TODO: testonly = true
+  sources = [
+    "system-topology_test.cpp",
+  ]
+  include_dirs = [ "include" ]
+  deps = [
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/lib/unittest/BUILD.gn b/zircon/kernel/lib/unittest/BUILD.gn
new file mode 100644
index 0000000..c9d01e0
--- /dev/null
+++ b/zircon/kernel/lib/unittest/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2019 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.
+
+library("unittest") {
+  kernel = true
+  sources = [
+    "unittest.cpp",
+    "user_memory.cpp",
+  ]
+  public_deps = [
+    # <lib/unittest/user_memory.h> has #include <lib/crypto/prng.h>.
+    "$zx/kernel/vm:headers",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+  ]
+}
diff --git a/zircon/kernel/lib/user_copy/BUILD.gn b/zircon/kernel/lib/user_copy/BUILD.gn
new file mode 100644
index 0000000..44b8b7f
--- /dev/null
+++ b/zircon/kernel/lib/user_copy/BUILD.gn
@@ -0,0 +1,8 @@
+# Copyright 2019 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.
+
+library("user_copy") {
+  kernel = true
+  sources = []
+}
diff --git a/zircon/kernel/lib/userboot/BUILD.gn b/zircon/kernel/lib/userboot/BUILD.gn
new file mode 100644
index 0000000..9ff531f
--- /dev/null
+++ b/zircon/kernel/lib/userboot/BUILD.gn
@@ -0,0 +1,56 @@
+# Copyright 2019 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("$zx/kernel/lib/vdso/rodso.gni")
+
+source_set("userboot") {
+  sources = [
+    "userboot.cpp",
+  ]
+  include_dirs = [ target_gen_dir ]
+  deps = [
+    ":gen-userboot-code-header",
+    ":image",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/counters",
+    "$zx/kernel/lib/vdso",
+    "$zx/kernel/vm",
+  ]
+}
+
+# The userboot-code.h generated header file tells the userboot.cpp code
+# where the segment boundaries and entry points are.
+rodso_code_header("gen-userboot-code-header") {
+  visibility = [ ":*" ]
+  name = "USERBOOT"
+  outputs = [
+    "$target_gen_dir/userboot-code.h",
+  ]
+  deps = [
+    # TODO(mcgrathr): mv //system/core/userboot ./user
+    "$zx/system/core/userboot",
+  ]
+}
+
+# The generated header is also needed to tell .incbin how much of the
+# image file to embed (see $zx/kernel/lib/vdso/include/lib/rodso-asm.h).
+source_set("image") {
+  visibility = [ ":*" ]
+  sources = [
+    "userboot-image.S",
+  ]
+  include_dirs = [ target_gen_dir ]
+  deps = [
+    ":gen-userboot-code-header",
+    "$zx/kernel/lib/vdso",
+  ]
+
+  # userboot-image.S includes the userboot contents and so must be
+  # reassembled when that changes.  We can't express that in $inputs
+  # here because we don't know the exact name of the file since that
+  # depends on the toolchain selected.  Fortunately, we already depend
+  # on the generated userboot-code.h header, which is always
+  # regenerated whenever the userboot binary itself changes.  So this
+  # indirect dependency is sufficient.
+}
diff --git a/zircon/kernel/lib/vdso/BUILD.gn b/zircon/kernel/lib/vdso/BUILD.gn
index c96e6db..91a7614 100644
--- a/zircon/kernel/lib/vdso/BUILD.gn
+++ b/zircon/kernel/lib/vdso/BUILD.gn
@@ -2,8 +2,115 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# TODO: So far this is just here to get <lib/vdso-constants.h> visible to
-# $zx/system/ulib/zircon code.
+import("$zx/kernel/syscalls/abigen.gni")
+import("$zx/public/gn/toolchain/environment_redirect.gni")
+import("rodso.gni")
+
 library("vdso") {
-  sources = []
+  kernel = true
+  sources = [
+    "vdso-image.S",
+    "vdso.cpp",
+  ]
+
+  # vdso-image.S includes the vDSO (aka libzircon.so) contents and so must
+  # be reassembled when that changes.  But listing $zx/system/ulib/zircon
+  # in deps here will make GN try to link libzircon.so into the kernel.
+  # Fortunately, vdso-image.S also includes the "vdso-code.h" header file
+  # and normal depfile magic will discover that.  This header file is
+  # generated (below) from libzircon.so itself, so it will always be
+  # touched when libzircon.so has been touched and thus ensure vdso-image.S
+  # is reassembled with the new vDSO contents.
+  if (is_kernel) {
+    include_dirs = [ target_gen_dir ]
+    deps = [
+      ":gen-categories",
+      ":gen-vdso-code-header",
+      ":rodso",
+      "$zx/kernel/lib/version:config-buildid-header",
+      "$zx/kernel/syscalls",
+      "$zx/kernel/vm:headers",
+      "$zx/system/ulib/fbl",
+    ]
+    public_configs = [ ":vdso-valid-sysret" ]
+    public_deps = [
+      # Dependents can use the generated header via $public_configs
+      # (above), and so need to depend on the generation action.
+      ":gen-vdso-valid-sysret",
+
+      # <lib/rodso.h> has #include <object/handle.h>.
+      "$zx/kernel/object",
+    ]
+  }
+}
+
+source_set("rodso") {
+  sources = [
+    "rodso.cpp",
+  ]
+  deps = [
+    ":headers",
+    "$zx/kernel/vm:headers",
+  ]
+}
+
+config("vdso-valid-sysret") {
+  visibility = [ ":*" ]
+  include_dirs = [ target_gen_dir ]
+}
+
+action("gen-vdso-valid-sysret") {
+  visibility = [ ":*" ]
+
+  # TODO(mcgrathr): Move the script to this dir.
+  script = "$zx/scripts/gen-vdso-valid-sysret.sh"
+  sources = [
+    "$target_gen_dir/vdso-code.h",
+  ]
+  outputs = [
+    "$target_gen_dir/vdso-valid-sysret.h",
+  ]
+  args = rebase_path(sources + outputs)
+  deps = [
+    ":gen-vdso-code-header",
+  ]
+}
+
+# Redirect to the userland vDSO shared library target.
+environment_redirect("userland") {
+  environment_label = "$zx/public/gn/toolchain:user"
+  deps = [
+    "$zx/system/ulib/zircon",
+  ]
+}
+
+group("vdso-code-header") {
+  deps = [
+    ":gen-vdso-code-header",
+  ]
+}
+
+# This generated header file tells the vdso.cpp code
+# where the segment boundaries and entry points are.
+rodso_code_header("gen-vdso-code-header") {
+  visibility = [ ":*" ]
+  name = "VDSO"
+  outputs = [
+    "$target_gen_dir/vdso-code.h",
+  ]
+  deps = [
+    ":userland",
+  ]
+}
+
+abigen("gen-categories") {
+  visibility = [ ":*" ]
+  gen = [
+    {
+      args = [ "-category" ]
+      outputs = [
+        "$target_gen_dir/zircon/syscall-category.inc",
+      ]
+    },
+  ]
 }
diff --git a/zircon/kernel/lib/vdso/rodso.gni b/zircon/kernel/lib/vdso/rodso.gni
new file mode 100644
index 0000000..d661984
--- /dev/null
+++ b/zircon/kernel/lib/vdso/rodso.gni
@@ -0,0 +1,73 @@
+# Copyright 2019 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("$zx/public/gn/toolchain/c_utils.gni")
+
+# Generate a header file with address constants from an RODSO layout object.
+#
+# The userboot loadable_module() and the vdso (libzircon) shared_library()
+# both use the special RODSO layout (by default in lld or via rodso.ld in
+# gold).  The kernel needs to use address constants extracted from these
+# ELF files' headers and symbols.
+#
+# Parameters
+#
+#   outputs
+#     Required: See action().
+#
+#   deps
+#     Required; Should reach the loadable_module() or library() target
+#     and no other linking targets; see link_output_rspfile().
+#     Type: list(label)
+#
+template("rodso_code_header") {
+  main_target_name = target_name
+  rspfile_target_name = "_rodso_code_header.rsp.$main_target_name"
+  rspfile = "$target_gen_dir/$target_name.rsp"
+
+  link_output_rspfile(rspfile_target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "deps",
+                             "testonly",
+                           ])
+    outputs = [
+      rspfile,
+    ]
+    visibility = [ ":$main_target_name" ]
+  }
+
+  toolchain_utils_action(main_target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "testonly",
+                             "visibility",
+                           ])
+
+    deps = [
+      ":$rspfile_target_name",
+    ]
+    outputs = invoker.outputs
+    assert(outputs == [ outputs[0] ],
+           "rodso_code_header() outputs must have exactly one element")
+    depfile = "${outputs[0]}.d"
+
+    # TODO(mcgrathr): Move the script to this dir.
+    script = "$zx/scripts/gen-rodso-code.sh"
+    utils = [
+      "nm",
+      "readelf",
+    ]
+    sources = [
+      rspfile,
+    ]
+    args = [
+      "--depfile",
+      rebase_path(depfile, root_build_dir),
+      rebase_path(outputs[0], root_build_dir),
+      invoker.name,
+      "@" + rebase_path(rspfile, root_build_dir),
+    ]
+  }
+}
diff --git a/zircon/kernel/lib/version/BUILD.gn b/zircon/kernel/lib/version/BUILD.gn
new file mode 100644
index 0000000..1501f54
--- /dev/null
+++ b/zircon/kernel/lib/version/BUILD.gn
@@ -0,0 +1,69 @@
+# Copyright 2019 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.
+
+declare_args() {
+  # Version string embedded in the kernel for `zx_system_get_version`.
+  # If set to the default "", a string is generated based on the
+  # Zircon git revision of the checkout.
+  kernel_version_string = ""
+}
+
+# The version string depends solely on the source and doesn't vary across
+# machines or toolchains, so generate it only once.
+if (current_toolchain == default_toolchain) {
+  action("gen-config-buildid-header") {
+    visibility = [ ":*" ]
+    outputs = [
+      "$target_gen_dir/config-buildid.h",
+    ]
+    if (kernel_version_string != "") {
+      script = "/usr/bin/touch"
+    } else {
+      sources = [
+        "$zx/../.git/HEAD",
+        "$zx/../.git/index",
+      ]
+      script = "buildid.sh"
+    }
+    args = rebase_path(outputs, root_build_dir)
+  }
+} else {
+  library("version") {
+    kernel = true
+    sources = [
+      "version.cpp",
+    ]
+    defines = [
+      # TODO(ZX-3413): These should all go away; the values are useless.
+      "ARCH=\"$zircon_cpu\"",
+      "PROJECT=\"$current_cpu\"",
+      "PLATFORM=\"XXX\"",
+      "TARGET=\"XXX\"",
+    ]
+    deps = [
+      ":config-buildid-header",
+      "$zx/kernel/lib/console",
+    ]
+  }
+
+  gen_label = ":gen-config-buildid-header($default_toolchain)"
+
+  group("config-buildid-header") {
+    public_configs = [ ":config-buildid-header.config" ]
+    if (kernel_version_string == "") {
+      deps = [
+        gen_label,
+      ]
+    }
+  }
+
+  config("config-buildid-header.config") {
+    visibility = [ ":config-buildid-header" ]
+    if (kernel_version_string != "") {
+      defines = [ "BUILDID='\"$kernel_version_string\"'" ]
+    } else {
+      include_dirs = [ get_label_info(gen_label, "target_gen_dir") ]
+    }
+  }
+}
diff --git a/zircon/kernel/lib/version/buildid.sh b/zircon/kernel/lib/version/buildid.sh
index be143e0..4b384bc 100755
--- a/zircon/kernel/lib/version/buildid.sh
+++ b/zircon/kernel/lib/version/buildid.sh
@@ -18,12 +18,18 @@
 fi
 
 if [ $# -eq 1 ]; then
-  cat > "$1" <<END
+  cat > "$1.new" <<END
 #ifndef __BUILDID_H
 #define __BUILDID_H
-#define ${GIT_REV}
+#define BUILDID "${GIT_REV}"
 #endif
 END
+  # Update the existing file only if it's changed.
+  if [ -r "$1" ] && cmp -s "$1.new" "$1"; then
+    rm -f "$1.new"
+  else
+    mv -f "$1.new" "$1"
+  fi
 else
     echo "${GIT_REV}"
 fi
diff --git a/zircon/kernel/lib/watchdog/BUILD.gn b/zircon/kernel/lib/watchdog/BUILD.gn
new file mode 100644
index 0000000..bb43bd0
--- /dev/null
+++ b/zircon/kernel/lib/watchdog/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+library("watchdog") {
+  kernel = true
+  sources = [
+    "watchdog.c",
+  ]
+}
diff --git a/zircon/kernel/object/BUILD.gn b/zircon/kernel/object/BUILD.gn
new file mode 100644
index 0000000..3714b4d
--- /dev/null
+++ b/zircon/kernel/object/BUILD.gn
@@ -0,0 +1,99 @@
+# Copyright 2019 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.
+
+library("object") {
+  kernel = true
+  sources = [
+    "buffer_chain.cpp",
+    "bus_transaction_initiator_dispatcher.cpp",
+    "channel_dispatcher.cpp",
+    "diagnostics.cpp",
+    "dispatcher.cpp",
+    "event_dispatcher.cpp",
+    "event_pair_dispatcher.cpp",
+    "exception.cpp",
+    "excp_port.cpp",
+    "fifo_dispatcher.cpp",
+    "futex_context.cpp",
+    "futex_node.cpp",
+    "glue.cpp",
+    "guest_dispatcher.cpp",
+    "handle.cpp",
+    "interrupt_dispatcher.cpp",
+    "interrupt_event_dispatcher.cpp",
+    "iommu_dispatcher.cpp",
+    "job_dispatcher.cpp",
+    "job_policy.cpp",
+    "log_dispatcher.cpp",
+    "mbuf.cpp",
+    "message_packet.cpp",
+    "pager_dispatcher.cpp",
+    "pci_device_dispatcher.cpp",
+    "pci_interrupt_dispatcher.cpp",
+    "pinned_memory_token_dispatcher.cpp",
+    "port_dispatcher.cpp",
+    "process_dispatcher.cpp",
+    "profile_dispatcher.cpp",
+    "resource.cpp",
+    "resource_dispatcher.cpp",
+    "semaphore.cpp",
+    "socket_dispatcher.cpp",
+    "suspend_token_dispatcher.cpp",
+    "thread_dispatcher.cpp",
+    "timer_dispatcher.cpp",
+    "vcpu_dispatcher.cpp",
+    "virtual_interrupt_dispatcher.cpp",
+    "vm_address_region_dispatcher.cpp",
+    "vm_object_dispatcher.cpp",
+    "wait_state_observer.cpp",
+  ]
+  deps = [
+    ":tests",
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/iommu/dummy",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/counters",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/hypervisor",
+    "$zx/kernel/lib/oom",
+    "$zx/system/ulib/pretty",
+    "$zx/system/ulib/region-alloc",
+  ]
+  if (current_cpu == "x64") {
+    deps += [ "$zx/kernel/dev/iommu/intel" ]
+  }
+  public_deps = [
+    # <object/pci_device_dispatcher.h> has #include <dev/pci_common.h>
+    "$zx/kernel/dev/pcie:headers",
+
+    # <object/log_dispatcher.h> has #include <lib/debuglog.h>.
+    "$zx/kernel/lib/debuglog:headers",
+
+    # <object/resource_dispatcher.h> has #include <region-alloc/region-alloc.h>.
+    "$zx/system/ulib/region-alloc:headers",
+
+    # <object/vcpu_dispatcher.h> has #include <hypervisor/interrupt_tracker.h>.
+    #"$zx/kernel/lib/hypervisor:headers",
+
+    # <object/process_dispatcher.h> has #include <vm/vm_aspace.h>.
+    "$zx/kernel/vm:headers",
+  ]
+}
+
+source_set("tests") {
+  # TODO: testonly = true
+  sources = [
+    "buffer_chain_tests.cpp",
+    "job_policy_tests.cpp",
+    "mbuf_tests.cpp",
+    "message_packet_tests.cpp",
+    "state_tracker_tests.cpp",
+  ]
+  deps = [
+    ":headers",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/kernel/params.gni b/zircon/kernel/params.gni
index 4f48694c..93f6893 100644
--- a/zircon/kernel/params.gni
+++ b/zircon/kernel/params.gni
@@ -3,6 +3,48 @@
 # found in the LICENSE file.
 
 declare_args() {
+  # Maximum number of CPUs the kernel will run on (others will be ignored).
+  smp_max_cpus = 16
+
+  if (current_cpu == "arm64") {
+    # Maximum number of CPU clusters the kernel will support.
+    # The kernel will panic at boot on hardware with more clusters.
+    smp_max_clusters = 2
+  }
+
+  # Virtual address where the kernel is mapped statically.  This is the
+  # base of addresses that appear in the kernel symbol table.  At runtime
+  # KASLR relocation processing adjusts addresses in memory from this base
+  # to the actual runtime virtual address.
+  if (current_cpu == "arm64") {
+    kernel_base = "0xffffffff00000000"
+  } else if (current_cpu == "x64") {
+    kernel_base = "0xffffffff80100000"  # Has KERNEL_LOAD_OFFSET baked into it.
+  }
+
+  # Virtual address where the kernel address space begins.
+  # Below this is the user address space.
+  if (current_cpu == "arm64") {
+    kernel_aspace_base = "0xffff000000000000"
+  } else if (current_cpu == "x64") {
+    kernel_aspace_base = "0xffffff8000000000UL"  # -512GB
+  }
+
+  # Enable kernel lock dependency tracking.
+  enable_lock_dep = false
+
   # Enable userspace PCI and disable kernel PCI.
   enable_user_pci = false
+
+  # Extra macro definitions for kernel code, e.g. "DISABLE_KASLR",
+  # "ENABLE_KERNEL_LL_DEBUG".
+  kernel_extra_defines = []
+}
+
+declare_args() {
+  # Enable kernel lock dependency tracking tests.  By default this is
+  # enabled when tracking is enabled, but can also be eanbled independently
+  # to assess whether the tests build and *fail correctly* when lockdep is
+  # disabled.
+  enable_lock_dep_tests = enable_lock_dep
 }
diff --git a/zircon/kernel/platform/BUILD.gn b/zircon/kernel/platform/BUILD.gn
new file mode 100644
index 0000000..73acf75
--- /dev/null
+++ b/zircon/kernel/platform/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2019 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.
+
+source_set("platform") {
+  sources = [
+    "debug.cpp",
+    "init.cpp",
+    "power.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/system/ulib/zxcpp",
+  ]
+}
diff --git a/zircon/kernel/platform/generic-arm/BUILD.gn b/zircon/kernel/platform/generic-arm/BUILD.gn
new file mode 100644
index 0000000..d45cbf7
--- /dev/null
+++ b/zircon/kernel/platform/generic-arm/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2019 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("$zx/kernel/params.gni")
+
+source_set("generic-arm") {
+  sources = [
+    "platform.cpp",
+  ]
+  defines = [ "SMP_CPU_MAX_CLUSTERS=$smp_max_clusters" ]
+  deps = [
+    "$zx/kernel/dev/hdcp/amlogic_s912",
+    "$zx/kernel/dev/hw_rng",
+    "$zx/kernel/dev/interrupt/arm_gic/common",
+    "$zx/kernel/dev/interrupt/arm_gic/v2",
+    "$zx/kernel/dev/interrupt/arm_gic/v3",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/dev/pdev",
+    "$zx/kernel/dev/pdev/power",
+    "$zx/kernel/dev/power/hisi",
+    "$zx/kernel/dev/psci",
+    "$zx/kernel/dev/timer/arm_generic",
+    "$zx/kernel/dev/uart/amlogic_s905",
+    "$zx/kernel/dev/uart/msm",
+    "$zx/kernel/dev/uart/nxp-imx",
+    "$zx/kernel/dev/uart/pl011",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/lockdep",
+    "$zx/kernel/lib/memory_limit",
+    "$zx/kernel/lib/topology",
+    "$zx/kernel/object",
+    "$zx/kernel/vm",
+    "$zx/system/ulib/libzbi",
+  ]
+}
diff --git a/zircon/kernel/platform/pc/BUILD.gn b/zircon/kernel/platform/pc/BUILD.gn
new file mode 100644
index 0000000..582dcb1
--- /dev/null
+++ b/zircon/kernel/platform/pc/BUILD.gn
@@ -0,0 +1,44 @@
+# Copyright 2019 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.
+
+library("pc") {
+  kernel = true
+  sources = [
+    "console.cpp",
+    "debug.cpp",
+    "hpet.cpp",
+    "interrupts.cpp",
+    "keyboard.cpp",
+    "memory.cpp",
+    "pcie_quirks.cpp",
+    "pic.cpp",
+    "platform.cpp",
+    "platform_pcie.cpp",
+    "power.cpp",
+    "smbios.cpp",
+    "timer.cpp",
+  ]
+  deps = [
+    "$zx/kernel/dev/interrupt",
+    "$zx/kernel/dev/pcie",
+    "$zx/kernel/lib/acpi_tables",
+    "$zx/kernel/lib/cbuf",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/fixed_point",
+    "$zx/kernel/lib/gfxconsole",
+    "$zx/kernel/lib/lockdep",
+    "$zx/kernel/lib/memory_limit",
+    "$zx/kernel/lib/pow2_range_allocator",
+    "$zx/kernel/lib/version",
+    "$zx/system/ulib/libzbi",
+    "$zx/system/ulib/smbios",
+    "$zx/third_party/lib/acpica",
+    "$zx/third_party/ulib/cksum",
+  ]
+  public_deps = [
+    # <platform/pc/acpi.h> has #include <acpica/acpi.h>.
+    "$zx/third_party/lib/acpica:headers",
+  ]
+}
diff --git a/zircon/kernel/syscalls/BUILD.gn b/zircon/kernel/syscalls/BUILD.gn
index d5a3ded..85b088b60 100644
--- a/zircon/kernel/syscalls/BUILD.gn
+++ b/zircon/kernel/syscalls/BUILD.gn
@@ -4,10 +4,74 @@
 
 import("abigen.gni")
 
+source_set("syscalls") {
+  sources = [
+    "channel.cpp",
+    "ddk.cpp",
+    "ddk_${zircon_cpu}.cpp",
+    "ddk_pci.cpp",
+    "debug.cpp",
+    "exceptions.cpp",
+    "fifo.cpp",
+    "futex.cpp",
+    "handle_ops.cpp",
+    "hypervisor.cpp",
+    "object.cpp",
+    "object_wait.cpp",
+    "pager.cpp",
+    "port.cpp",
+    "profile.cpp",
+    "resource.cpp",
+    "socket.cpp",
+    "system.cpp",
+    "system_${zircon_cpu}.cpp",
+    "task.cpp",
+    "test.cpp",
+    "timer.cpp",
+    "vmar.cpp",
+    "vmo.cpp",
+    "zircon.cpp",
+  ]
+  deps = [
+    ":dispatch",
+    ":syscall-abi",
+    "$zx/kernel/dev/udisplay",
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/counters",
+    "$zx/kernel/lib/crypto",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/gfxconsole",
+    "$zx/kernel/lib/ktrace",
+    "$zx/kernel/lib/mtrace",
+    "$zx/kernel/lib/pci",
+    "$zx/kernel/lib/user_copy",
+    "$zx/kernel/object",
+    "$zx/system/ulib/explicit-memory",
+    "$zx/system/ulib/libzbi",
+    "$zx/system/ulib/region-alloc",
+  ]
+  if (current_cpu == "x64") {
+    deps += [ "$zx/kernel/platform/pc" ]
+  }
+}
+
+# Only this file depends on vdso-valid-sysret.h.
+source_set("dispatch") {
+  sources = [
+    "syscalls.cpp",
+  ]
+  deps = [
+    ":syscall-abi",
+    "$zx/kernel/lib/vdso:headers",
+  ]
+}
+
 group("syscall-abi") {
   visibility = [
     ":*",
+    "$zx/kernel/arch/$zircon_cpu:*",
     "$zx/system/ulib/zircon:*",
+    "$zx/system/utest/core/bad-syscall:*",
   ]
 
   public_configs = [ ":syscall-abi.config" ]
diff --git a/zircon/kernel/target/BUILD.gn b/zircon/kernel/target/BUILD.gn
new file mode 100644
index 0000000..2e99c6f
--- /dev/null
+++ b/zircon/kernel/target/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2019 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.
+
+source_set("target") {
+  sources = [
+    "init.cpp",
+  ]
+}
diff --git a/zircon/kernel/target/arm64/boot-shim/rules.mk b/zircon/kernel/target/arm64/boot-shim/rules.mk
index e7c41bfe..c87675e 100644
--- a/zircon/kernel/target/arm64/boot-shim/rules.mk
+++ b/zircon/kernel/target/arm64/boot-shim/rules.mk
@@ -74,8 +74,8 @@
 # The shim code should be purely position-independent code.
 $(BOOT_SHIM_ELF).pure-stamp: $(BOOT_SHIM_ELF) scripts/gen-kaslr-fixups.sh
 	$(call BUILDECHO,checking $<)
-	$(NOECHO)scripts/gen-kaslr-fixups.sh --pure \
-					     $< '$(READELF)' '$(OBJDUMP)' $@
+	$(NOECHO)scripts/gen-kaslr-fixups.sh '$(READELF)' '$(OBJDUMP)' \
+					     --pure $< $@
 
 $(BOOT_SHIM_BIN): $(BOOT_SHIM_ELF) $(BOOT_SHIM_ELF).pure-stamp
 	$(call BUILDECHO,generating $@)
diff --git a/zircon/kernel/target/pc/BUILD.gn b/zircon/kernel/target/pc/BUILD.gn
new file mode 100644
index 0000000..fd5335b
--- /dev/null
+++ b/zircon/kernel/target/pc/BUILD.gn
@@ -0,0 +1,10 @@
+# Copyright 2019 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.
+
+group("pc") {
+  deps = [
+    "$zx/kernel/dev/intel_rng",
+    "$zx/kernel/platform/pc",
+  ]
+}
diff --git a/zircon/kernel/tests/BUILD.gn b/zircon/kernel/tests/BUILD.gn
new file mode 100644
index 0000000..9cd737f
--- /dev/null
+++ b/zircon/kernel/tests/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2019 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.
+
+source_set("tests") {
+  # TODO: testonly = true
+  cflags = [ "-fno-builtin" ]
+  sources = [
+    "alloc_checker_tests.cpp",
+    "benchmarks.cpp",
+    "brwlock_tests.cpp",
+    "cache_tests.cpp",
+    "clock_tests.cpp",
+    "fibo.cpp",
+    "lock_dep_tests.cpp",
+    "mem_tests.cpp",
+    "mp_hotplug_tests.cpp",
+    "preempt_disable_tests.cpp",
+    "printf_tests.cpp",
+    "resource_tests.cpp",
+    "sleep_tests.cpp",
+    "string_tests.cpp",
+    "sync_ipi_tests.cpp",
+    "tests.cpp",
+    "thread_tests.cpp",
+    "timer_tests.cpp",
+    "uart_tests.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/crypto",
+    "$zx/kernel/lib/debuglog",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/header_tests",
+    "$zx/kernel/lib/unittest",
+    "$zx/kernel/object",
+  ]
+}
diff --git a/zircon/kernel/top/BUILD.gn b/zircon/kernel/top/BUILD.gn
new file mode 100644
index 0000000..276fbb3
--- /dev/null
+++ b/zircon/kernel/top/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2019 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.
+
+source_set("top") {
+  sources = [
+    "init.cpp",
+    "main.cpp",
+  ]
+  deps = [
+    "$zx/kernel/arch/$zircon_cpu",
+    "$zx/kernel/kernel",
+    "$zx/kernel/lib/debuglog",
+    "$zx/kernel/lib/userboot",
+    "$zx/kernel/lib/version",
+    "$zx/kernel/platform",
+    "$zx/kernel/target",
+  ]
+}
diff --git a/zircon/kernel/vm/BUILD.gn b/zircon/kernel/vm/BUILD.gn
new file mode 100644
index 0000000..d2ed1b4
--- /dev/null
+++ b/zircon/kernel/vm/BUILD.gn
@@ -0,0 +1,55 @@
+# Copyright 2019 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.
+
+library("vm") {
+  kernel = true
+  sources = [
+    "bootalloc.cpp",
+    "bootreserve.cpp",
+    "kstack.cpp",
+    "page.cpp",
+    "page_source.cpp",
+    "pinned_vm_object.cpp",
+    "pmm.cpp",
+    "pmm_arena.cpp",
+    "pmm_node.cpp",
+    "vm.cpp",
+    "vm_address_region.cpp",
+    "vm_address_region_or_mapping.cpp",
+    "vm_aspace.cpp",
+    "vm_mapping.cpp",
+    "vm_object.cpp",
+    "vm_object_paged.cpp",
+    "vm_object_physical.cpp",
+    "vm_page_list.cpp",
+    "vmm.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/console",
+    "$zx/kernel/lib/fbl",
+    "$zx/kernel/lib/user_copy",
+    "$zx/kernel/lib/vdso",
+    "$zx/system/ulib/pretty",
+    "$zx/third_party/ulib/cryptolib",
+  ]
+  public_deps = [
+    # <vm/vm_object.h> has #include <fbl/name.h>.
+    "$zx/kernel/lib/fbl:headers",
+
+    # <vm/vm_object.h> has #include <lib/user_copy/user_ptr.h>.
+    "$zx/kernel/lib/user_copy",
+
+    # <vm/vm_aspace.h> has #include <lib/crypto/prng.h>
+    "$zx/kernel/lib/crypto:headers",
+  ]
+}
+
+source_set("tests") {
+  sources = [
+    "vm_unittest.cpp",
+  ]
+  deps = [
+    "$zx/kernel/lib/unittest",
+  ]
+}
diff --git a/zircon/make/build.mk b/zircon/make/build.mk
index ff77a1e..9db480e 100644
--- a/zircon/make/build.mk
+++ b/zircon/make/build.mk
@@ -41,7 +41,7 @@
 KERNEL_FIXUPS := $(BUILDDIR)/kernel-fixups.inc
 $(KERNEL_FIXUPS): scripts/gen-kaslr-fixups.sh $(KERNEL_ELF)
 	$(call BUILDECHO,extracting relocations into $@)
-	$(NOECHO)$(SHELLEXEC) $^ '$(READELF)' '$(OBJDUMP)' $@
+	$(NOECHO)$(SHELLEXEC) $< '$(READELF)' '$(OBJDUMP)' $(KERNEL_ELF) $@
 GENERATED += $(KERNEL_FIXUPS)
 
 # Canned sequence to convert an ELF file to a raw binary.
@@ -57,13 +57,12 @@
 KERNEL_IMAGE_ASM := kernel/arch/$(ARCH)/image.S
 KERNEL_IMAGE_OBJ := $(BUILDDIR)/kernel.image.o
 ALLOBJS += $(KERNEL_IMAGE_OBJ)
-KERNEL_DEFINES += \
-    BOOT_HEADER_SIZE=$(BOOT_HEADER_SIZE) \
-    KERNEL_IMAGE='"$(KERNEL_RAW)"' \
+KERNEL_DEFINES += BOOT_HEADER_SIZE=$(BOOT_HEADER_SIZE)
 
 # Assemble the kernel image along with boot headers and relocation fixup code.
 # TODO(mcgrathr): Reuse compile.mk $(MODULE_ASMOBJS) commands here somehow.
-$(KERNEL_IMAGE_OBJ): $(KERNEL_IMAGE_ASM) $(KERNEL_FIXUPS) $(KERNEL_RAW)
+$(KERNEL_IMAGE_OBJ): $(KERNEL_IMAGE_ASM) $(KERNEL_FIXUPS) $(KERNEL_RAW) \
+		     $(BUILDDIR)/kernel_image.h
 	@$(MKDIR)
 	$(call BUILDECHO, assembling $<)
 	$(NOECHO)$(CC) $(GLOBAL_OPTFLAGS)  \
@@ -72,6 +71,11 @@
 	    $(KERNEL_INCLUDES) $(GLOBAL_INCLUDES) -I$(BUILDDIR) \
 	    -c $< -MD -MP -MT $@ -MF $(@:.o=.d) -o $@
 
+$(BUILDDIR)/kernel_image.h:
+	@$(MKDIR)
+	$(call BUILDECHO, generating $<)
+	$(NOECHO)echo '#define KERNEL_IMAGE "$(KERNEL_RAW)"' > $@
+
 # Now link the final load image, using --just-symbols to let image.S refer
 # to symbols defined in the kernel proper.
 $(KERNEL_IMAGE): $(KERNEL_IMAGE_OBJ) $(KERNEL_ELF) $(DEFSYM_SCRIPT) \
diff --git a/zircon/public/gn/BUILDCONFIG.gn b/zircon/public/gn/BUILDCONFIG.gn
index 373f721..06b440b 100644
--- a/zircon/public/gn/BUILDCONFIG.gn
+++ b/zircon/public/gn/BUILDCONFIG.gn
@@ -347,7 +347,18 @@
   not_needed([ "static_library" ])
 
   targets = false
-  if (is_host) {
+  if (is_kernel) {
+    if (kernel) {
+      targets = true
+      source_set(_library_name) {
+        forward_variables_from(invoker, "*", _library_params)
+        if (!defined(public_deps)) {
+          public_deps = []
+        }
+        public_deps += [ ":${_library_name}.headers" ]
+      }
+    }
+  } else if (is_host) {
     if (host) {
       targets = true
       target(static_library, _library_name) {
@@ -546,6 +557,11 @@
         ":${_library_name}.headers",
       ]
     }
+
+    # This is really only used in the $zx/kernel:kernel environment().
+    config("headers.config") {
+      include_dirs = [ "include" ]
+    }
     if (!is_kernel && !is_host) {
       if (static) {
         group("static") {
@@ -594,6 +610,14 @@
 #         Optional: The target type to match in $variants selectors.
 #         Type: string
 #         Default: $type
+#       label
+#         Optional: The target label to match in $variants selectors.
+#         Type: label_no_toolchain
+#         Default: ":$target_name"
+#       output_name
+#         Optional: The $output_name to match in $variants selectors.
+#         Type: string
+#         Default: $output_name (which defaults to $target_name)
 #       shlib
 #         Optional: Target always builds in shlib toolchain (loadable_module).
 #         Type: bool
@@ -616,6 +640,9 @@
     if (!defined(match)) {
       match = type
     }
+    if (!defined(label)) {
+      label = ":$target_name"
+    }
   }
 
   main_target_name = target_name
@@ -627,6 +654,10 @@
     output_name = target_name
   }
 
+  if (!defined(target.output_name)) {
+    target.output_name = output_name
+  }
+
   if (toolchain.variant_selectors == []) {
     # This toolchain does not participate in variant selection.
     # Each target is just what it seems.
@@ -665,7 +696,7 @@
         }
       }
       if (selector.dir != []) {
-        dir = get_label_info(":$target_name", "dir")
+        dir = get_label_info(target.label, "dir")
         if (selector.dir + [ dir ] - [ dir ] == selector.dir) {
           selector_matches = false
         }
@@ -679,13 +710,13 @@
         }
       }
       if (selector.label != []) {
-        label = get_label_info(":$target_name", "label_no_toolchain")
+        label = get_label_info(target.label, "label_no_toolchain")
         if (selector.label + [ label ] - [ label ] == selector.label) {
           selector_matches = false
         }
       }
       if (selector.name != []) {
-        name = get_name_info(":$target_name", "name_no_toolchain")
+        name = get_label_info(target.label, "name")
         if (selector.name + [ name ] - [ name ] == selector.name) {
           selector_matches = false
         }
@@ -696,8 +727,8 @@
         }
       }
       if (selector.output_name != []) {
-        if (selector.output_name + [ output_name ] - [ output_name ] ==
-            selector.output_name) {
+        if (selector.output_name + [ target.output_name ] -
+            [ target.output_name ] == selector.output_name) {
           selector_matches = false
         }
       }
@@ -925,6 +956,10 @@
                                  "visibility",
                                ])
         output_name = output_name
+
+        # This might actually be ignored if target.type is "action".
+        not_needed([ "output_name" ])
+
         forward_variables_from(invoker, [ "testonly" ])
         if (defined(invoker.visibility)) {
           # Make sure we're visible to the redirector groups.
diff --git a/zircon/public/gn/config/BUILD.gn b/zircon/public/gn/config/BUILD.gn
index d4c2e3d..9889643 100644
--- a/zircon/public/gn/config/BUILD.gn
+++ b/zircon/public/gn/config/BUILD.gn
@@ -248,6 +248,9 @@
 config("assert_level") {
   assert(assert_level >= 0)
   defines = [ "ZX_DEBUGLEVEL=$assert_level" ]
+  if (is_kernel) {
+    defines += [ "LK_DEBUGLEVEL=$assert_level" ]
+  }
   if (assert_level == 0) {
     defines += [ "NDEBUG" ]
   }
diff --git a/zircon/public/gn/toolchain/c_utils.gni b/zircon/public/gn/toolchain/c_utils.gni
index 1a73ff5..c4df581 100644
--- a/zircon/public/gn/toolchain/c_utils.gni
+++ b/zircon/public/gn/toolchain/c_utils.gni
@@ -15,20 +15,66 @@
 #     Optional:  Same as for action().  The script receives an implicit
 #     argument for each element in $utils giving the command to run.
 #     If omitted, then $utils must have only one element and that command
-#     itself will be run with $args just as given.
-#     Type: file
+#     itself will be run with $args just as given.  This can be true instead
+#     of a string for automatic response file handling; see notes below.
+#     Type: file or true (see below)
 #
 #   args
 #     Required: Same as for action().  If there is a $script,
 #     the implicit $utils arguments precede $args.
 #     Type: list(string)
 #
-#   deps, inputs, outputs, sources, testonly, visibility
+#   depfile, deps, inputs, outputs, sources, testonly, visibility
 #      See action().
 #
+#   variant_target
+#     Optional: If present, this target will participate in $variants
+#     selection.  This scope is passed through to _variant_target() as
+#     $target to control how the selector matching is done.  The main
+#     effect of this variant selection is on where the $utils will be
+#     found (e.g. clang with LLVM utilities vs gcc with GNU binutils).
+#     It also affects the toolchain context in which this target is
+#     evaluated, but usually the inputs/deps will themselves be targets
+#     like executable() that will do their own variant dispatch.
+#     Type: scope, see _variant_target() for details.
+#
+# Notes on response files
+#
+# When using "@rspfile" command-line syntax, its crucial that any input
+# files fed to $utils are recorded as dependencies.  GN won't be aware of
+# this file dependency because it only knows about the response *file*, not
+# the response file's *contents*.  This target will depend on the target
+# that generates the response file (e.g. a link_output_rspfile() target)
+# and that gives this target a transitive order-only dependency to ensure
+# the input exists.  To make Ninja aware of the dependency to ensure that
+# incremental rebuilds re-run this action when needed, use $depfile.
+#
+# When running $utils directly, set $script to true (and do not set
+# $depfile) to use a standard script that handles dependencies for the
+# simple "@RSPFILE" cases.  In this mode, each $args string that looks like
+# "@RSPFILE" will cause implicit dependencies (after the fact, via depfile)
+# on each file listed in "RSPFILE" (one file per line with no quoting).
+# Most toolchain utilities have built-in "@RSPFILE" support, but the script
+# also does remedial "@RSPFILE" expansion for utilities known to lack it.
+#
 template("toolchain_utils_action") {
   assert(defined(invoker.utils),
          "toolchain_utils_action(\"$target_name\") requires `utils`")
+
+  if (defined(invoker.variant_target)) {
+    target_type = "_variant_target"
+    extra_params = {
+      target = {
+        forward_variables_from(invoker.variant_target, "*", [ "type" ])
+        type = "action"
+      }
+    }
+  } else {
+    target_type = "action"
+    extra_params = {
+    }
+  }
+
   forward_variables_from(invoker, [ "script" ])
 
   utils_inputs = []
@@ -64,12 +110,14 @@
     }
   }
 
-  action(target_name) {
+  target(target_type, target_name) {
+    forward_variables_from(extra_params, "*")
     forward_variables_from(invoker,
                            "*",
                            [
                              "args",
                              "script",
+                             "target",
                              "utils",
                            ])
     if (!defined(inputs)) {
@@ -77,7 +125,20 @@
     }
     inputs += utils_inputs
     if (defined(script)) {
-      args = utils_paths + invoker.args
+      if (script == true) {
+        assert(!defined(depfile),
+               "script=true is incompatible with setting depfile")
+        script = "$zx/public/gn/toolchain/toolchain_utils_action.sh"
+        depfile = "$target_out_dir/_host_tool_action.$target_name.d"
+        args = [
+          rebase_path(outputs[0], root_build_dir),
+          rebase_path(depfile, root_build_dir),
+        ]
+      } else {
+        script = script
+        args = []
+      }
+      args += utils_paths + invoker.args
     } else {
       script = rebase_path(utils_paths[0], "", root_build_dir)
       assert(
@@ -119,3 +180,96 @@
     output_conversion = "list lines"
   }
 }
+
+# Define an action to convert an ELF file to a raw binary image file.
+#
+# Parameters
+#
+#   deps
+#     Required: Dependencies leading to a linking target (e.g. executable).
+#     The ${metadata.link_output} key is used to find the input ELF file.
+#     Type: list(label)
+#
+#   output_name
+#     Optional: Basename of the output file.
+#     Type: string
+#     Default: $target_name
+#
+#   output_dir
+#     Optional: Directory for the output file.
+#     Type: dir
+#     Default: $target_out_dir
+#
+#   output_extension
+#     Optional: Extension added to $output_name (after a `.` if nonempty).
+#     Type: string
+#     Default: "bin"
+#
+#   variant_target
+#     See toolchain_utils_action().
+#
+template("image_binary") {
+  image_target = target_name
+  rspfile_target = "_image_binary.rsp.$target_name"
+  rspfile = "$target_gen_dir/$target_name.image.rsp"
+
+  link_output_rspfile(rspfile_target) {
+    forward_variables_from(invoker,
+                           [
+                             "deps",
+                             "testonly",
+                           ])
+    visibility = [
+      ":$image_target",
+      ":$image_target._build",
+    ]
+    outputs = [
+      rspfile,
+    ]
+  }
+
+  toolchain_utils_action(image_target) {
+    deps = [
+      ":$rspfile_target",
+    ]
+    forward_variables_from(invoker,
+                           [
+                             "metadata",
+                             "output_dir",
+                             "output_extension",
+                             "output_name",
+                             "testonly",
+                             "variant_target",
+                             "visibility",
+                           ])
+    if (!defined(output_dir)) {
+      output_dir = target_out_dir
+    }
+    if (!defined(output_extension)) {
+      output_extension = "bin"
+    }
+    if (!defined(output_name)) {
+      output_name = target_name
+    }
+
+    output_file = "$output_dir/$output_name"
+    if (output_extension != "") {
+      output_file += ".$output_extension"
+    }
+
+    utils = [ "objcopy" ]
+    script = true
+    sources = [
+      rspfile,
+    ]
+    outputs = [
+      output_file,
+    ]
+    args = [
+      "-O",
+      "binary",
+      "@" + rebase_path(rspfile, root_build_dir),
+      rebase_path(output_file, root_build_dir),
+    ]
+  }
+}
diff --git a/zircon/public/gn/toolchain/toolchain_utils_action.sh b/zircon/public/gn/toolchain/toolchain_utils_action.sh
new file mode 100755
index 0000000..07a9a55
--- /dev/null
+++ b/zircon/public/gn/toolchain/toolchain_utils_action.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+
+# This script is used by c_utils.gni, which see.
+#
+# Usage: toolchain_utils_action.sh OUTPUT DEPFILE PROGRAM ARG...
+#
+# This runs PROGRAM ARG... with some special handling.
+# It always writes DEPFILE with OUTPUT as its target.
+#
+# For each ARG that is "@RSPFILE", RSPFILE should contain nothing
+# but file names, one per line.  Each such file will be added as
+# an input in the depfile.
+#
+# Most toolchain utilities handle "@RSPFILE" syntax themselves, so we let them
+# do so after scanning RSPFILE to collect dependencies.  However, for certain
+# named tools known to be lacking the support, this script will splice the
+# file contents into the argument list directly.
+
+set -e
+
+OUTPUT="$1"
+DEPFILE="$2"
+PROGRAM="$3"
+shift 3
+
+trap 'rm -f "$OUTPUT" "$DEPFILE"' ERR HUP INT TERM
+
+if [ "${PROGRAM##*/}" = llvm-objcopy ]; then
+  expand_rspfile=true
+else
+  expand_rspfile=false
+fi
+
+INPUTS=()
+ARGS=()
+
+read_rspfile() {
+  local file
+  while read file; do
+    INPUTS+=("$file")
+    if $expand_rspfile; then
+      ARGS+=("$file")
+    fi
+  done
+}
+
+for arg; do
+  if [[ "$arg" == @* ]]; then
+    rspfile="${arg#@}"
+    INPUTS+=("$rspfile")
+    read_rspfile < "$rspfile"
+    if $expand_rspfile; then
+      # Don't add $arg since its contents were already added.
+      continue
+    fi
+  fi
+  ARGS+=("$arg")
+done
+
+echo "$OUTPUT: ${FILES[*]}" > "$DEPFILE"
+
+exec "$PROGRAM" "${ARGS[@]}"
diff --git a/zircon/scripts/gen-kaslr-fixups.sh b/zircon/scripts/gen-kaslr-fixups.sh
index 9493b97..89636d8 100755
--- a/zircon/scripts/gen-kaslr-fixups.sh
+++ b/zircon/scripts/gen-kaslr-fixups.sh
@@ -25,25 +25,33 @@
 # each run of adjustments, and then #include's the output of this script.
 
 usage() {
-  echo >&2 "Usage: $0 [--pure] KERNEL READELF OBJDUMP OUTFILE"
+  echo >&2 "Usage: $0 READELF OBJDUMP [--pure] KERNEL OUTFILE [DEPFILE]"
   exit 2
 }
 
+if [ $# -lt 2 ]; then
+  usage
+fi
+
+READELF="$1"
+shift
+OBJDUMP="$1"
+shift
+
 PURE=0
-if [ $# -eq 5 -a "$1" = --pure ]; then
+if [ $# -gt 1 -a "$1" = --pure ]; then
   PURE=1
   shift
 fi
 
-if [ $# -ne 4 ]; then
+if [ $# -ne 2 -a $# -ne 3 ]; then
   usage
 fi
 
 AWK=awk
 KERNEL="$1"
-READELF="$2"
-OBJDUMP="$3"
-OUTFILE="$4"
+OUTFILE="$2"
+DEPFILE="$3"
 
 grok_fixups() {
   "$AWK" -v kernel="$KERNEL" -v objdump="$OBJDUMP" -v pure=$PURE '
@@ -87,6 +95,7 @@
     next
 }
 NF == 0 || $1 == "Offset" { next }
+!secname { exit(1); }
 # Ignore standard non-allocated sections.
 secname ~ /^\.debug/ || secname == ".comment" { next }
 # .text.boot contains code that runs before fixups.
@@ -201,6 +210,14 @@
   set -o pipefail
 fi
 
-trap 'rm -f "$OUTFILE"' ERR
+trap 'rm -f "$OUTFILE" ${DEPFILE:+"$DEPFILE"}' ERR INT HUP TERM
+
+if [[ "$KERNEL" == @* ]]; then
+  KERNEL="$(< "${KERNEL#@}")"
+fi
 
 LC_ALL=C "$READELF" -W -r "$KERNEL" | grok_fixups > "$OUTFILE"
+
+if [ -n "$DEPFILE" ]; then
+  echo "$OUTFILE: $KERNEL" > "$DEPFILE"
+fi
diff --git a/zircon/scripts/gen-rodso-code.sh b/zircon/scripts/gen-rodso-code.sh
index e53e057..94736d5 100755
--- a/zircon/scripts/gen-rodso-code.sh
+++ b/zircon/scripts/gen-rodso-code.sh
@@ -17,7 +17,7 @@
 # of entries in the table.
 
 usage() {
-  echo >&2 "Usage: $0 NM READELF OUTFILE {NAME DSO}..."
+  echo >&2 "Usage: $0 NM READELF [--depfile DEPFILE] OUTFILE {NAME DSO}..."
   exit 2
 }
 
@@ -29,6 +29,14 @@
 shift
 READELF="$1"
 shift
+
+DEPFILE=
+if [ $# -gt 2 -a "$1" = "--depfile" ]; then
+  DEPFILE="$2"
+  shift 2
+fi
+USED_FILES=()
+
 OUTFILE="$1"
 shift
 
@@ -135,15 +143,33 @@
   }; then : ; fi
 }
 
+trap 'rm -f "$OUTFILE" ${DEPFILE:+"$DEPFILE"}' ERR HUP INT TERM
+
 while [ $# -gt 0 ]; do
   if [ $# -lt 2 ]; then
     usage
   fi
-  echo "#define ${1}_FILENAME \"${2}\"" > $OUTFILE
-  find_segments "$1" "$2"
-  find_code_symbols "$1" "$2"
-  if [ $have_dynsym = yes ]; then
-    find_dynsym_slots "$1" "$2"
-  fi
+  name="$1"
+  dso="$2"
   shift 2
+
+  # This argument might be a response file.
+  if [[ "$dso" == @* ]]; then
+    rspfile="${dso#@}"
+    dso="$(< "$rspfile")"
+    USED_FILES+=("$rspfile" "$dso")
+  else
+    USED_FILES+=("$dso")
+  fi
+
+  echo "#define ${name}_FILENAME \"${dso}\"" > $OUTFILE
+  find_segments "$name" "$dso"
+  find_code_symbols "$name" "$dso"
+  if [ $have_dynsym = yes ]; then
+    find_dynsym_slots "$name" "$dso"
+  fi
 done
+
+if [ -n "$DEPFILE" ]; then
+  echo "$OUTFILE: ${USED_FILES[*]}" > "$DEPFILE"
+fi
diff --git a/zircon/scripts/gen-vdso-valid-sysret.sh b/zircon/scripts/gen-vdso-valid-sysret.sh
index db56bd7..5ff73e8c 100755
--- a/zircon/scripts/gen-vdso-valid-sysret.sh
+++ b/zircon/scripts/gen-vdso-valid-sysret.sh
@@ -63,6 +63,17 @@
 }
 
 set -e
+
+case $# in
+1)
+  exec < "$1"
+  ;;
+2)
+  trap "rm -f '$2'" ERR HUP INT TERM
+  exec < "$1" > "$2"
+  ;;
+esac
+
 header
 scan < "$1"
 footer
diff --git a/zircon/system/ulib/fbl/BUILD.gn b/zircon/system/ulib/fbl/BUILD.gn
index dd5c6d6..cde0ae5 100644
--- a/zircon/system/ulib/fbl/BUILD.gn
+++ b/zircon/system/ulib/fbl/BUILD.gn
@@ -63,6 +63,6 @@
 
   if (toolchain.environment == "kernel") {
     # Avoid circularity.
-    configs -= [ "$zx/kernel/vm:headers" ]
+    configs -= [ "$zx/kernel/vm:headers.config" ]
   }
 }
diff --git a/zircon/system/ulib/lockdep/BUILD.gn b/zircon/system/ulib/lockdep/BUILD.gn
new file mode 100644
index 0000000..ab84cde
--- /dev/null
+++ b/zircon/system/ulib/lockdep/BUILD.gn
@@ -0,0 +1,36 @@
+# Copyright 2019 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.
+
+library("lockdep") {
+  sdk = "source"
+  sdk_headers = [
+    "lockdep/common.h",
+    "lockdep/global_reference.h",
+    "lockdep/guard.h",
+    "lockdep/guard_multiple.h",
+    "lockdep/lock_class.h",
+    "lockdep/lock_class_state.h",
+    "lockdep/lock_dependency_set.h",
+    "lockdep/lock_policy.h",
+    "lockdep/lock_traits.h",
+    "lockdep/lockdep.h",
+    "lockdep/runtime_api.h",
+    "lockdep/thread_lock_state.h",
+  ]
+  kernel = true
+  static = true
+  sources = [
+    "lock_dep.cpp",
+  ]
+  public_deps = [
+    "$zx/system/ulib/fbl:headers",
+  ]
+  if (!is_kernel) {
+    configs += [ "$zx/public/gn/config:visibility_hidden" ]
+    deps = [
+      "$zx/system/ulib/fbl",
+      "$zx/system/ulib/zx",
+    ]
+  }
+}
diff --git a/zircon/system/ulib/pretty/BUILD.gn b/zircon/system/ulib/pretty/BUILD.gn
index eb50352..0acc364 100644
--- a/zircon/system/ulib/pretty/BUILD.gn
+++ b/zircon/system/ulib/pretty/BUILD.gn
@@ -12,9 +12,11 @@
   host = true
   static = true
   sources = [
-    "hexdump.c",
     "sizes.c",
   ]
+  if (!is_kernel) {
+    sources += [ "hexdump.c" ]
+  }
   if (!is_kernel && is_fuchsia) {
     deps = [
       "$zx/system/ulib/fdio",
diff --git a/zircon/system/ulib/smbios/BUILD.gn b/zircon/system/ulib/smbios/BUILD.gn
new file mode 100644
index 0000000..f5378d9
--- /dev/null
+++ b/zircon/system/ulib/smbios/BUILD.gn
@@ -0,0 +1,14 @@
+# Copyright 2019 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.
+
+library("smbios") {
+  kernel = true
+  static = true
+  sources = [
+    "smbios.cpp",
+  ]
+  deps = [
+    "$zx/system/ulib/fbl",
+  ]
+}
diff --git a/zircon/third_party/lib/jitterentropy/BUILD.gn b/zircon/third_party/lib/jitterentropy/BUILD.gn
new file mode 100644
index 0000000..e91f121
--- /dev/null
+++ b/zircon/third_party/lib/jitterentropy/BUILD.gn
@@ -0,0 +1,31 @@
+# Copyright 2019 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.
+
+library("jitterentropy") {
+  kernel = true
+  sources = [
+    "jitterentropy-base.c",
+  ]
+  include_dirs = [ "arch/$zircon_cpu" ]
+
+  # According to its documentation, jitterentropy must be compiled at
+  # optimization level -O0.
+  #
+  # TODO(SEC-14): Test the code generated at various optimization
+  # levels. If there is a significant difference in entropy quality,
+  # replace the relevant C code by assembly code to protect against future
+  # compiler changes.
+  configs -= [ "$zx/public/gn/config:opt_level" ]
+  configs += [ ":config" ]
+}
+
+config("config") {
+  visibility = [ ":*" ]
+  cflags = [
+    "-O0",
+
+    # The original Makefile also specifies -fwrapv.
+    "-fwrapv",
+  ]
+}
diff --git a/zircon/third_party/ulib/uboringssl/BUILD.gn b/zircon/third_party/ulib/uboringssl/BUILD.gn
index 7d9131d..853b4a0 100644
--- a/zircon/third_party/ulib/uboringssl/BUILD.gn
+++ b/zircon/third_party/ulib/uboringssl/BUILD.gn
@@ -15,7 +15,7 @@
     sources += [ "crypto/chacha/chacha.c" ]
 
     # Avoid circularity.
-    configs -= [ "$zx/kernel/vm:headers" ]
+    configs -= [ "$zx/kernel/vm:headers.config" ]
 
     defines = [
       # The assembly code uses vector registers, which is not allowed in