1# Copyright 2016 The Fuchsia Authors 2# Copyright (c) 2008-2015 Travis Geiselbrecht 3# 4# Use of this source code is governed by a MIT-style 5# license that can be found in the LICENSE file or at 6# https://opensource.org/licenses/MIT 7 8ifneq (,$(EXTRA_BUILDRULES)) 9-include $(EXTRA_BUILDRULES) 10endif 11 12# Generate an input linker script to define as symbols all the 13# variables set in makefiles that the linker script needs to use. 14LINKER_SCRIPT_VARS := KERNEL_BASE SMP_MAX_CPUS BOOT_HEADER_SIZE 15DEFSYM_SCRIPT := $(BUILDDIR)/kernel-vars.ld 16$(DEFSYM_SCRIPT): FORCE 17 $(call BUILDECHO,generating $@) 18 @$(MKDIR) 19 $(NOECHO)($(foreach var,$(LINKER_SCRIPT_VARS),\ 20 echo 'PROVIDE_HIDDEN($(var) = $($(var)));';)\ 21 ) > $@.tmp 22 @$(call TESTANDREPLACEFILE,$@.tmp,$@) 23GENERATED += $(DEFSYM_SCRIPT) 24 25$(KERNEL_ELF): kernel/kernel.ld $(DEFSYM_SCRIPT) $(ALLMODULE_OBJS) 26 $(call BUILDECHO,linking $@) 27 $(NOECHO)$(LD) $(GLOBAL_LDFLAGS) $(KERNEL_LDFLAGS) -T $^ -o $@ 28# enable/disable the size output based on a combination of ENABLE_BUILD_LISTFILES 29# and QUIET 30ifeq ($(call TOBOOL,$(ENABLE_BUILD_LISTFILES)),true) 31ifeq ($(call TOBOOL,$(QUIET)),false) 32 $(NOECHO)$(SIZE) $@ 33endif 34endif 35 36# Tell the linker to record all the relocations it applied. 37KERNEL_LDFLAGS += --emit-relocs 38 39# Use the --emit-relocs records to extract the fixups needed to relocate 40# the kernel at boot. 41KERNEL_FIXUPS := $(BUILDDIR)/kernel-fixups.inc 42$(KERNEL_FIXUPS): scripts/gen-kaslr-fixups.sh $(KERNEL_ELF) 43 $(call BUILDECHO,extracting relocations into $@) 44 $(NOECHO)$(SHELLEXEC) $^ '$(READELF)' '$(OBJDUMP)' $@ 45GENERATED += $(KERNEL_FIXUPS) 46 47# Canned sequence to convert an ELF file to a raw binary. 48define elf2bin-commands 49 $(call BUILDECHO,generating image $@) 50 $(NOECHO)$(OBJCOPY) -O binary $< $@ 51endef 52 53# Extract the raw binary image of the kernel proper. 54KERNEL_RAW := $(KERNEL_ELF).bin 55$(KERNEL_RAW): $(KERNEL_ELF); $(elf2bin-commands) 56 57KERNEL_IMAGE_ASM := kernel/arch/$(ARCH)/image.S 58KERNEL_IMAGE_OBJ := $(BUILDDIR)/kernel.image.o 59ALLOBJS += $(KERNEL_IMAGE_OBJ) 60KERNEL_DEFINES += \ 61 BOOT_HEADER_SIZE=$(BOOT_HEADER_SIZE) \ 62 KERNEL_IMAGE='"$(KERNEL_RAW)"' \ 63 64# Assemble the kernel image along with boot headers and relocation fixup code. 65# TODO(mcgrathr): Reuse compile.mk $(MODULE_ASMOBJS) commands here somehow. 66$(KERNEL_IMAGE_OBJ): $(KERNEL_IMAGE_ASM) $(KERNEL_FIXUPS) $(KERNEL_RAW) 67 @$(MKDIR) 68 $(call BUILDECHO, assembling $<) 69 $(NOECHO)$(CC) $(GLOBAL_OPTFLAGS) \ 70 $(GLOBAL_COMPILEFLAGS) $(KERNEL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) \ 71 $(GLOBAL_ASMFLAGS) $(KERNEL_ASMFLAGS) $(ARCH_ASMFLAGS) \ 72 $(KERNEL_INCLUDES) $(GLOBAL_INCLUDES) -I$(BUILDDIR) \ 73 -c $< -MD -MP -MT $@ -MF $(@:.o=.d) -o $@ 74 75# Now link the final load image, using --just-symbols to let image.S refer 76# to symbols defined in the kernel proper. 77$(KERNEL_IMAGE): $(KERNEL_IMAGE_OBJ) $(KERNEL_ELF) $(DEFSYM_SCRIPT) \ 78 kernel/image.ld 79 $(call BUILDECHO,linking $@) 80 @$(MKDIR) 81 $(NOECHO)$(LD) $(GLOBAL_LDFLAGS) --build-id=none \ 82 -o $@ -T kernel/image.ld --just-symbols $(KERNEL_ELF) \ 83 $(DEFSYM_SCRIPT) $(KERNEL_IMAGE_OBJ) 84 85# Finally, extract the raw binary of the kernel load image. 86$(KERNEL_ZBI): $(KERNEL_IMAGE); $(elf2bin-commands) 87 88$(KERNEL_ELF)-gdb.py: scripts/zircon.elf-gdb.py 89 $(call BUILDECHO, generating $@) 90 @$(MKDIR) 91 $(NOECHO)cp -f $< $@ 92EXTRA_BUILDDEPS += $(KERNEL_ELF)-gdb.py 93 94# print some information about the build 95#$(BUILDDIR)/srcfiles.txt: 96# @echo generating $@ 97# $(NOECHO)echo $(sort $(ALLSRCS)) | tr ' ' '\n' > $@ 98# 99#.PHONY: $(BUILDDIR)/srcfiles.txt 100#GENERATED += $(BUILDDIR)/srcfiles.txt 101# 102#$(BUILDDIR)/include-paths.txt: 103# @echo generating $@ 104# $(NOECHO)echo $(subst -I,,$(sort $(KERNEL_INCLUDES))) | tr ' ' '\n' > $@ 105# 106#.PHONY: $(BUILDDIR)/include-paths.txt 107#GENERATED += $(BUILDDIR)/include-paths.txt 108# 109#.PHONY: $(BUILDDIR)/user-include-paths.txt 110#GENERATED += $(BUILDDIR)/user-include-paths.txt 111 112# debug info rules 113 114$(BUILDDIR)/%.dump: $(BUILDDIR)/% 115 $(call BUILDECHO,generating $@) 116 $(NOECHO)$(OBJDUMP) -x $< > $@ 117 118$(BUILDDIR)/%.lst: $(BUILDDIR)/% 119 $(call BUILDECHO,generating listing $@) 120 $(NOECHO)$(OBJDUMP) $(OBJDUMP_LIST_FLAGS) -d $< | $(CPPFILT) > $@ 121 122$(BUILDDIR)/%.debug.lst: $(BUILDDIR)/% 123 $(call BUILDECHO,generating debug listing $@) 124 $(NOECHO)$(OBJDUMP) $(OBJDUMP_LIST_FLAGS) -S $< | $(CPPFILT) > $@ 125 126BUILD_ID_DIR = $(BUILDDIR)/.build-id 127ifeq ($(call TOBOOL,$(USE_CLANG)),true) 128define strip-command 129$(STRIP) --build-id-link-dir=$(BUILD_ID_DIR) \ 130 --build-id-link-input=.debug --build-id-link-output= \ 131 $< $@ 132endef 133else 134define strip-command 135$(STRIP) $< $@ && \ 136eval $$("$(READELF)" -n $< | \ 137 sed -n 's/.*Build ID: \(..\)\(.*\)$$/id0=\1 id1=\2/p') && \ 138{ test -z "$$id0" || \ 139 { mkdir -p "$(BUILD_ID_DIR)/$$id0" && \ 140 ln -f $< "$(BUILD_ID_DIR)/$$id0/$$id1.debug" && \ 141 ln -f $@ "$(BUILD_ID_DIR)/$$id0/$$id1" ; } ; } 142endef 143endif 144 145$(BUILDDIR)/%.strip: $(BUILDDIR)/% 146 $(call BUILDECHO,generating $@) 147 $(NOECHO)$(strip-command) 148 149$(BUILDDIR)/%.sym: $(BUILDDIR)/% 150 $(call BUILDECHO,generating symbols $@) 151 $(NOECHO)$(OBJDUMP) -t $< | $(CPPFILT) > $@ 152 153$(BUILDDIR)/%.sym.sorted: $(BUILDDIR)/% 154 $(call BUILDECHO,generating sorted symbols $@) 155 $(NOECHO)$(OBJDUMP) -t $< | $(CPPFILT) | sort > $@ 156 157$(BUILDDIR)/%.size: $(BUILDDIR)/% 158 $(call BUILDECHO,generating size map $@) 159 $(NOECHO)$(NM) -S --size-sort $< > $@ 160 161$(BUILDDIR)/%.id: $(BUILDDIR)/% 162 $(call BUILDECHO,generating id file $@) 163 $(NOECHO)env READELF="$(READELF)" scripts/get-build-id $< > $@ 164 165# EXTRA_USER_MANIFEST_LINES is a space-separated list of 166# </boot-relative-path>=<local-host-path> entries to add to USER_MANIFEST. 167# This lets users add files to the bootfs via make without needing to edit the 168# manifest or call zbi directly. 169ifneq ($(EXTRA_USER_MANIFEST_LINES),) 170USER_MANIFEST_LINES += $(EXTRA_USER_MANIFEST_LINES) 171$(info EXTRA_USER_MANIFEST_LINES = $(EXTRA_USER_MANIFEST_LINES)) 172endif 173 174# generate a new manifest and compare to see if it differs from the previous one 175# USER_MANIFEST_DEBUG_INPUTS is a dependency here as the file name to put in 176# the manifest must be computed *after* the input file is produced (to get the 177# build id). 178.PHONY: usermanifestfile 179$(USER_MANIFEST): usermanifestfile $(USER_MANIFEST_DEBUG_INPUTS) 180 $(call BUILDECHO,generating $@) 181 @$(MKDIR) 182 $(NOECHO)echo $(USER_MANIFEST_LINES) | tr ' ' '\n' | sort > $@.tmp 183 $(NOECHO)for f in $(USER_MANIFEST_DEBUG_INPUTS) ; do \ 184 echo debug/$$(env READELF=$(READELF) $(SHELLEXEC) scripts/get-build-id $$f).debug=$$f >> $@.tmp ; \ 185 done 186 $(NOECHO)$(call TESTANDREPLACEFILE,$@.tmp,$@) 187 188GENERATED += $(USER_MANIFEST) 189 190# Manifest Lines are bootfspath=buildpath 191# Extract the part after the = for each line 192# to generate dependencies 193USER_MANIFEST_DEPS := $(foreach x,$(USER_MANIFEST_LINES),$(lastword $(subst =,$(SPACE),$(strip $(x))))) 194 195.PHONY: user-manifest additional-bootdata 196user-manifest: $(USER_MANIFEST) $(USER_MANIFEST_DEPS) 197additional-bootdata: $(ADDITIONAL_BOOTDATA_ITEMS) 198 199$(ZIRCON_BOOTIMAGE): \ 200 $(ZBI) $(KERNEL_ZBI) \ 201 $(USER_MANIFEST) $(USER_MANIFEST_DEPS) \ 202 $(ADDITIONAL_BOOTDATA_ITEMS) 203 $(call BUILDECHO,generating $@) 204 @$(MKDIR) 205 $(NOECHO)$< -o $@ --complete=$(PROJECT) $(KERNEL_ZBI) \ 206 $(USER_MANIFEST_GROUPS) $(USER_MANIFEST) \ 207 $(ADDITIONAL_BOOTDATA_ITEMS) 208GENERATED += $(ZIRCON_BOOTIMAGE) 209 210.PHONY: image 211image: $(ZIRCON_BOOTIMAGE) 212kernel: image 213