1343171Sdim# Copyright 2016 The Fuchsia Authors
2343171Sdim# Copyright (c) 2008-2015 Travis Geiselbrecht
3353358Sdim#
4353358Sdim# Use of this source code is governed by a MIT-style
5353358Sdim# license that can be found in the LICENSE file or at
6343171Sdim# https://opensource.org/licenses/MIT
7343171Sdim
8343171Sdimifneq (,$(EXTRA_BUILDRULES))
9343171Sdim-include $(EXTRA_BUILDRULES)
10343171Sdimendif
11343171Sdim
12343171Sdim# Generate an input linker script to define as symbols all the
13343171Sdim# variables set in makefiles that the linker script needs to use.
14343171SdimLINKER_SCRIPT_VARS := KERNEL_BASE SMP_MAX_CPUS BOOT_HEADER_SIZE
15343171SdimDEFSYM_SCRIPT := $(BUILDDIR)/kernel-vars.ld
16343171Sdim$(DEFSYM_SCRIPT): FORCE
17343171Sdim	$(call BUILDECHO,generating $@)
18343171Sdim	@$(MKDIR)
19343171Sdim	$(NOECHO)($(foreach var,$(LINKER_SCRIPT_VARS),\
20343171Sdim			    echo 'PROVIDE_HIDDEN($(var) = $($(var)));';)\
21343171Sdim		 ) > $@.tmp
22343171Sdim	@$(call TESTANDREPLACEFILE,$@.tmp,$@)
23343171SdimGENERATED += $(DEFSYM_SCRIPT)
24343171Sdim
25343171Sdim$(KERNEL_ELF): kernel/kernel.ld $(DEFSYM_SCRIPT) $(ALLMODULE_OBJS)
26343171Sdim	$(call BUILDECHO,linking $@)
27343171Sdim	$(NOECHO)$(LD) $(GLOBAL_LDFLAGS) $(KERNEL_LDFLAGS) -T $^ -o $@
28343171Sdim# enable/disable the size output based on a combination of ENABLE_BUILD_LISTFILES
29343171Sdim# and QUIET
30343171Sdimifeq ($(call TOBOOL,$(ENABLE_BUILD_LISTFILES)),true)
31343171Sdimifeq ($(call TOBOOL,$(QUIET)),false)
32343171Sdim	$(NOECHO)$(SIZE) $@
33343171Sdimendif
34360784Sdimendif
35343171Sdim
36343171Sdim# Tell the linker to record all the relocations it applied.
37343171SdimKERNEL_LDFLAGS += --emit-relocs
38343171Sdim
39343171Sdim# Use the --emit-relocs records to extract the fixups needed to relocate
40343171Sdim# the kernel at boot.
41343171SdimKERNEL_FIXUPS := $(BUILDDIR)/kernel-fixups.inc
42343171Sdim$(KERNEL_FIXUPS): scripts/gen-kaslr-fixups.sh $(KERNEL_ELF)
43343171Sdim	$(call BUILDECHO,extracting relocations into $@)
44343171Sdim	$(NOECHO)$(SHELLEXEC) $^ '$(READELF)' '$(OBJDUMP)' $@
45343171SdimGENERATED += $(KERNEL_FIXUPS)
46343171Sdim
47343171Sdim# Canned sequence to convert an ELF file to a raw binary.
48343171Sdimdefine elf2bin-commands
49343171Sdim	$(call BUILDECHO,generating image $@)
50343171Sdim	$(NOECHO)$(OBJCOPY) -O binary $< $@
51343171Sdimendef
52343171Sdim
53343171Sdim# Extract the raw binary image of the kernel proper.
54343171SdimKERNEL_RAW := $(KERNEL_ELF).bin
55343171Sdim$(KERNEL_RAW): $(KERNEL_ELF); $(elf2bin-commands)
56343171Sdim
57360784SdimKERNEL_IMAGE_ASM := kernel/arch/$(ARCH)/image.S
58343171SdimKERNEL_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	    $(GLOBAL_INCLUDES) $(KERNEL_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
126$(BUILDDIR)/%.strip: $(BUILDDIR)/%
127	$(call BUILDECHO,generating $@)
128	$(NOECHO)$(STRIP) $< $@
129
130$(BUILDDIR)/%.sym: $(BUILDDIR)/%
131	$(call BUILDECHO,generating symbols $@)
132	$(NOECHO)$(OBJDUMP) -t $< | $(CPPFILT) > $@
133
134$(BUILDDIR)/%.sym.sorted: $(BUILDDIR)/%
135	$(call BUILDECHO,generating sorted symbols $@)
136	$(NOECHO)$(OBJDUMP) -t $< | $(CPPFILT) | sort > $@
137
138$(BUILDDIR)/%.size: $(BUILDDIR)/%
139	$(call BUILDECHO,generating size map $@)
140	$(NOECHO)$(NM) -S --size-sort $< > $@
141
142$(BUILDDIR)/%.id: $(BUILDDIR)/%
143	$(call BUILDECHO,generating id file $@)
144	$(NOECHO)env READELF="$(READELF)" scripts/get-build-id $< > $@
145
146# EXTRA_USER_MANIFEST_LINES is a space-separated list of
147# </boot-relative-path>=<local-host-path> entries to add to USER_MANIFEST.
148# This lets users add files to the bootfs via make without needing to edit the
149# manifest or call zbi directly.
150ifneq ($(EXTRA_USER_MANIFEST_LINES),)
151USER_MANIFEST_LINES += $(EXTRA_USER_MANIFEST_LINES)
152$(info EXTRA_USER_MANIFEST_LINES = $(EXTRA_USER_MANIFEST_LINES))
153endif
154
155# generate a new manifest and compare to see if it differs from the previous one
156# USER_MANIFEST_DEBUG_INPUTS is a dependency here as the file name to put in
157# the manifest must be computed *after* the input file is produced (to get the
158# build id).
159.PHONY: usermanifestfile
160$(USER_MANIFEST): usermanifestfile $(USER_MANIFEST_DEBUG_INPUTS)
161	$(call BUILDECHO,generating $@)
162	@$(MKDIR)
163	$(NOECHO)echo $(USER_MANIFEST_LINES) | tr ' ' '\n' | sort > $@.tmp
164	$(NOECHO)for f in $(USER_MANIFEST_DEBUG_INPUTS) ; do \
165	  echo debug/$$(env READELF=$(READELF) $(SHELLEXEC) scripts/get-build-id $$f).debug=$$f >> $@.tmp ; \
166	done
167	$(NOECHO)$(call TESTANDREPLACEFILE,$@.tmp,$@)
168
169GENERATED += $(USER_MANIFEST)
170
171# Manifest Lines are bootfspath=buildpath
172# Extract the part after the = for each line
173# to generate dependencies
174USER_MANIFEST_DEPS := $(foreach x,$(USER_MANIFEST_LINES),$(lastword $(subst =,$(SPACE),$(strip $(x)))))
175
176.PHONY: user-manifest additional-bootdata
177user-manifest: $(USER_MANIFEST) $(USER_MANIFEST_DEPS)
178additional-bootdata: $(ADDITIONAL_BOOTDATA_ITEMS)
179
180$(ZIRCON_BOOTIMAGE): \
181    $(ZBI) $(KERNEL_ZBI) \
182    $(USER_MANIFEST) $(USER_MANIFEST_DEPS) \
183    $(ADDITIONAL_BOOTDATA_ITEMS)
184	$(call BUILDECHO,generating $@)
185	@$(MKDIR)
186	$(NOECHO)$< -o $@ --complete=$(PROJECT) $(KERNEL_ZBI) \
187		    $(USER_MANIFEST_GROUPS) $(USER_MANIFEST) \
188		    $(ADDITIONAL_BOOTDATA_ITEMS)
189GENERATED += $(ZIRCON_BOOTIMAGE)
190
191.PHONY: image
192image: $(ZIRCON_BOOTIMAGE)
193kernel: image
194
195# TODO(mcgrathr): Remove these when all consumers of the build
196# only expect the new kernel.zbi and/or zircon.zbi names.
197.PHONY: legacy
198kernel: legacy
199legacy: $(BUILDDIR)/zircon.bin $(BUILDDIR)/bootdata.bin
200$(BUILDDIR)/zircon.bin: $(KERNEL_ZBI)
201	$(call BUILDECHO,compat kernel name $@)
202	$(NOECHO)ln -f $< $@
203# This has an extra copy of the kernel that won't be used at runtime.
204$(BUILDDIR)/bootdata.bin: $(ZIRCON_BOOTIMAGE)
205	$(call BUILDECHO,compat initrd name $@)
206	$(NOECHO)ln -f $< $@
207