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