Commit e9ba0414 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by Tom Rini

kbuild: Simplify generating vmlinux

Generating vmlinux in top-level Makefile were getting a bit messy after kallsyms
support were added. Also the full link of all the .o files were duplicaed a number of times.
This patch does the following:
- Introduce built-in.o which is a prelink of most .o files
- Make the build process a bit more verbose telling when linking .tmpvmlinux*
- Use less magic when determing when to generate a new version
- Allow architectures to override the defineition of cmd_vmlinux__
- Add more comments to the MAkefile and clean up soem other comments
- Display more commends during V=1 builds

The resulting kernel boots and rn here.
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent ef41e994
...@@ -545,57 +545,83 @@ libs-y := $(libs-y1) $(libs-y2) ...@@ -545,57 +545,83 @@ libs-y := $(libs-y1) $(libs-y2)
# Build vmlinux # Build vmlinux
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# vmlinux is build from the objects seleted by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
# ^
# |
# +-< $(vmlinux-init)
# | +--< init/version.o + more
# |
# +-< built-in.o
# | +--< $(vmlinux-main)
# | +--< driver/built-in.o mm/built-in.o + more
# |
# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
#
# vmlinux version cannot be updated during normal descending-into-subdirs
# phase since we do not yet know if we need to update vmlinux.
# Therefore this step is delayed until just before final link of vmlinux -
# except in kallsyms case where it is done just before adding the
# symbols to the kernel.
#
# System.map is generated to document addresses of all kernel symbols
# This is a bit tricky: If we need to relink vmlinux, we want vmlinux-init := $(head-y) $(init-y)
# the version number incremented, which means recompile init/version.o vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
# and relink init/init.o. However, we cannot do this during the vmlinux-all := $(vmlinux-init) built-in.o
# normal descending-into-subdirs phase, since at that time vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
# we cannot yet know if we will need to relink vmlinux.
# So we descend into init/ inside the rule for vmlinux again.
vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)
# Rule to link vmlinux - also used during CONFIG_KALLSYMS
# May be overridden by arch/$(ARCH)/Makefile
quiet_cmd_vmlinux__ = LD $@ quiet_cmd_vmlinux__ = LD $@
define cmd_vmlinux__ cmd_vmlinux__ = $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(head-y) $(init-y) \ -T $(filter-out FORCE, $^) -o $@
--start-group \
$(core-y) \
$(libs-y) \
$(drivers-y) \
$(net-y) \
--end-group \
$(filter .tmp_kallsyms%,$^) \
-o $@
endef
# set -e makes the rule exit immediately on error
define rule_vmlinux__ # Generate new vmlinux version
+set -e; \ quiet_cmd_vmlinux_version = GEN .version
$(if $(filter .tmp_kallsyms%,$^),, \ cmd_vmlinux_version = set -e; \
echo ' GEN .version'; \
. $(srctree)/scripts/mkversion > .tmp_version; \ . $(srctree)/scripts/mkversion > .tmp_version; \
mv -f .tmp_version .version; \ mv -f .tmp_version .version; \
$(MAKE) $(build)=init; \ $(MAKE) $(build)=init
) \
$(if $($(quiet)cmd_vmlinux__), \
echo ' $($(quiet)cmd_vmlinux__)' &&) \
$(cmd_vmlinux__); \
echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef
# Generate System.map
quiet_cmd_sysmap = SYSMAP quiet_cmd_sysmap = SYSMAP
cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds # Link of vmlinux
# If CONFIG_KALLSYMS is set .version is already updated
# Generate System.map and verify that the content is consistent
define rule_vmlinux__
$(if $(CONFIG_KALLSYMS),,$(call cmd,vmlinux_version))
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
$(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) System.map' &&) \
$(cmd_sysmap) $@ System.map; \
if [ $$? -ne 0 ]; then \
rm -f $@; \
/bin/false; \
fi;
$(verify_kallsyms)
endef
# Generate section listing all symbols and add it into vmlinux ifdef CONFIG_KALLSYMS
# Generate section listing all symbols and add it into vmlinux $(kallsyms.o)
# It's a three stage process: # It's a three stage process:
# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is # o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
# empty # empty
# Running kallsyms on that gives us .tmp_kallsyms1.o with # Running kallsyms on that gives us .tmp_kallsyms1.o with
# the right size # the right size - vmlinux version updated during this step
# o .tmp_vmlinux2 now has a __kallsyms section of the right size, # o .tmp_vmlinux2 now has a __kallsyms section of the right size,
# but due to the added section, some addresses have shifted # but due to the added section, some addresses have shifted.
# From here, we generate a correct .tmp_kallsyms2.o # From here, we generate a correct .tmp_kallsyms2.o
# o The correct .tmp_kallsyms2.o is linked into the final vmlinux. # o The correct .tmp_kallsyms2.o is linked into the final vmlinux.
# o Verify that the System.map from vmlinux matches the map from # o Verify that the System.map from vmlinux matches the map from
...@@ -605,8 +631,6 @@ LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds ...@@ -605,8 +631,6 @@ LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds
# temporary bypass to allow the kernel to be built while the # temporary bypass to allow the kernel to be built while the
# maintainers work out what went wrong with kallsyms. # maintainers work out what went wrong with kallsyms.
ifdef CONFIG_KALLSYMS
ifdef CONFIG_KALLSYMS_EXTRA_PASS ifdef CONFIG_KALLSYMS_EXTRA_PASS
last_kallsyms := 3 last_kallsyms := 3
else else
...@@ -615,16 +639,28 @@ endif ...@@ -615,16 +639,28 @@ endif
kallsyms.o := .tmp_kallsyms$(last_kallsyms).o kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
define rule_verify_kallsyms define verify_kallsyms
$(Q)$(if $($(quiet)cmd_sysmap), \ $(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \ echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
$(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
$(Q)cmp -s System.map .tmp_System.map || \ $(Q)cmp -s System.map .tmp_System.map || \
(echo Inconsistent kallsyms data, try setting CONFIG_KALLSYMS_EXTRA_PASS ; rm .tmp_kallsyms* ; false) (echo Inconsistent kallsyms data; \
echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
rm .tmp_kallsyms* ; /bin/false )
endef
# Update vmlinux version before link
cmd_ksym_ld = $(cmd_vmlinux__)
define rule_ksym_ld
$(call cmd,vmlinux_version)
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef endef
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@ quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
$(call if_changed_dep,as_o_S) $(call if_changed_dep,as_o_S)
...@@ -632,43 +668,39 @@ cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--al ...@@ -632,43 +668,39 @@ cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--al
.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS) .tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
$(call cmd,kallsyms) $(call cmd,kallsyms)
.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/kernel/vmlinux.lds FORCE # .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
$(call if_changed_rule,vmlinux__) .tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
$(call if_changed_rule,ksym_ld)
.tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/kernel/vmlinux.lds FORCE .tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
$(call if_changed_rule,vmlinux__) $(call if_changed,vmlinux__)
.tmp_vmlinux3: $(vmlinux-objs) .tmp_kallsyms2.o arch/$(ARCH)/kernel/vmlinux.lds FORCE .tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
$(call if_changed_rule,vmlinux__) $(call if_changed,vmlinux__)
# Needs to visit scripts/ before $(KALLSYMS) can be used. # Needs to visit scripts/ before $(KALLSYMS) can be used.
$(KALLSYMS): scripts ; $(KALLSYMS): scripts ;
endif endif # ifdef CONFIG_KALLSYMS
# Finally the vmlinux rule # vmlinux image - including updated kernel symbols
# This rule is also used to generate System.map vmlinux: $(vmlinux-lds) $(vmlinux-init) built-in.o $(kallsyms.o) FORCE
# and to verify that the content of kallsyms are consistent $(call if_changed_rule,vmlinux__)
define rule_vmlinux # Link $(vmlinux-main) to speed up rest of build phase. No need to
$(rule_vmlinux__); # relink this part too many times.
$(Q)$(if $($(quiet)cmd_sysmap), \ # Use start/end-group to make sure to resolve all possible symbols
echo ' $($(quiet)cmd_sysmap) System.map' &&) \ quiet_rule_vmlinux_partial = LD $@
$(cmd_sysmap) $@ System.map; \ cmd_vmlinux_partial = $(LD) $(LDFLAGS) $(LDFLAGS_$(*F)) -r \
if [ $$? -ne 0 ]; then \ --start-group $(filter-out FORCE, $^) \
rm -f $@; \ --end-group -o $@
/bin/false; \
fi;
$(rule_verify_kallsyms)
endef
vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/kernel/vmlinux.lds FORCE built-in.o: $(vmlinux-main) FORCE
$(call if_changed_rule,vmlinux) $(call if_changed,vmlinux_partial)
# The actual objects are generated when descending, # The actual objects are generated when descending,
# make sure no implicit rule kicks in # make sure no implicit rule kicks in
$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
$(sort $(vmlinux-objs)) arch/$(ARCH)/kernel/vmlinux.lds: $(vmlinux-dirs) ;
# Handle descending into subdirectories listed in $(vmlinux-dirs) # Handle descending into subdirectories listed in $(vmlinux-dirs)
# Preset locale variables to speed up the build process. Limit locale # Preset locale variables to speed up the build process. Limit locale
...@@ -1188,13 +1220,22 @@ ifneq ($(cmd_files),) ...@@ -1188,13 +1220,22 @@ ifneq ($(cmd_files),)
include $(cmd_files) include $(cmd_files)
endif endif
# Execute command and generate cmd file
if_changed = $(if $(strip $? \
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(cmd_$(1)); \
echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
# execute the command and also postprocess generated .d dependencies # execute the command and also postprocess generated .d dependencies
# file # file
if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
$(filter-out $(cmd_$(1)),$(cmd_$@))\ $(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\ $(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \ $(Q)set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \ $(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(cmd_$(1)); \ $(cmd_$(1)); \
scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \ scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
...@@ -1208,7 +1249,7 @@ if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\ ...@@ -1208,7 +1249,7 @@ if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
if_changed_rule = $(if $(strip $? \ if_changed_rule = $(if $(strip $? \
$(filter-out $(cmd_$(1)),$(cmd_$(@F)))\ $(filter-out $(cmd_$(1)),$(cmd_$(@F)))\
$(filter-out $(cmd_$(@F)),$(cmd_$(1)))),\ $(filter-out $(cmd_$(@F)),$(cmd_$(1)))),\
@$(rule_$(1))) $(Q)$(rule_$(1)))
# If quiet is set, only print short version of command # If quiet is set, only print short version of command
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment