linux/scripts/Makefile.vmlinux
Masahiro Yamada 654102df2a kbuild: add generic support for built-in boot DTBs
Some architectures embed boot DTBs in vmlinux. A potential issue for
these architectures is a race condition during parallel builds because
Kbuild descends into arch/*/boot/dts/ twice.

One build thread is initiated by the 'dtbs' target, which is a
prerequisite of the 'all' target in the top-level Makefile:

  ifdef CONFIG_OF_EARLY_FLATTREE
  all: dtbs
  endif

For architectures that support the built-in boot dtb, arch/*/boot/dts/
is visited also during the ordinary directory traversal in order to
build obj-y objects that wrap DTBs.

Since these build threads are unaware of each other, they can run
simultaneously during parallel builds.

This commit introduces a generic build rule to scripts/Makefile.vmlinux
to support embedded boot DTBs in a race-free way. Architectures that
want to use this rule need to select CONFIG_GENERIC_BUILTIN_DTB.

After the migration, Makefiles under arch/*/boot/dts/ will be visited
only once to build only *.dtb files.

This change also aims to unify the CONFIG options used for built-in DTBs
support. Currently, different architectures use different CONFIG options
for the same purposes.

With this commit, the CONFIG options will be unified as follows:

 - CONFIG_GENERIC_BUILTIN_DTB

   This enables the generic rule for built-in boot DTBs. This will be
   renamed to CONFIG_BUILTIN_DTB after all architectures migrate to the
   generic rule.

 - CONFIG_BUILTIN_DTB_NAME

   This specifies the path to the embedded DTB.
   (relative to arch/*/boot/dts/)

 - CONFIG_BUILTIN_DTB_ALL

   If this is enabled, all DTB files compiled under arch/*/boot/dts/ are
   embedded into vmlinux. Only used by MIPS.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
2024-11-04 17:53:09 +09:00

114 lines
3.2 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0-only
PHONY := __default
__default: vmlinux
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include
# for c_flags
include $(srctree)/scripts/Makefile.lib
targets :=
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
%.o: %.c FORCE
$(call if_changed_dep,cc_o_c)
quiet_cmd_as_o_S = AS $@
cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
%.o: %.S FORCE
$(call if_changed_dep,as_o_S)
# Built-in dtb
# ---------------------------------------------------------------------------
quiet_cmd_wrap_dtbs = WRAP $@
cmd_wrap_dtbs = { \
echo '\#include <asm-generic/vmlinux.lds.h>'; \
echo '.section .dtb.init.rodata,"a"'; \
while read dtb; do \
symbase=__dtb_$$(basename -s .dtb "$${dtb}" | tr - _); \
echo '.balign STRUCT_ALIGNMENT'; \
echo ".global $${symbase}_begin"; \
echo "$${symbase}_begin:"; \
echo '.incbin "'$$dtb'" '; \
echo ".global $${symbase}_end"; \
echo "$${symbase}_end:"; \
done < $<; \
} > $@
.builtin-dtbs.S: .builtin-dtbs-list FORCE
$(call if_changed,wrap_dtbs)
quiet_cmd_gen_dtbs_list = GEN $@
cmd_gen_dtbs_list = \
$(if $(CONFIG_BUILTIN_DTB_NAME), echo "arch/$(SRCARCH)/boot/dts/$(CONFIG_BUILTIN_DTB_NAME).dtb",:) > $@
.builtin-dtbs-list: arch/$(SRCARCH)/boot/dts/dtbs-list FORCE
$(call if_changed,$(if $(CONFIG_BUILTIN_DTB_ALL),copy,gen_dtbs_list))
targets += .builtin-dtbs-list
ifdef CONFIG_GENERIC_BUILTIN_DTB
targets += .builtin-dtbs.S .builtin-dtbs.o
vmlinux: .builtin-dtbs.o
endif
# vmlinux
# ---------------------------------------------------------------------------
ifdef CONFIG_MODULES
targets += .vmlinux.export.o
vmlinux: .vmlinux.export.o
endif
ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
# Final link of vmlinux with optional arch pass after final link
cmd_link_vmlinux = \
$< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
targets += vmlinux
vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
+$(call if_changed_dep,link_vmlinux)
# module.builtin.ranges
# ---------------------------------------------------------------------------
ifdef CONFIG_BUILTIN_MODULE_RANGES
__default: modules.builtin.ranges
quiet_cmd_modules_builtin_ranges = GEN $@
cmd_modules_builtin_ranges = gawk -f $(real-prereqs) > $@
targets += modules.builtin.ranges
modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
modules.builtin vmlinux.map vmlinux.o.map FORCE
$(call if_changed,modules_builtin_ranges)
vmlinux.map: vmlinux
@:
endif
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
PHONY += FORCE
FORCE:
# Read all saved command lines and dependencies for the $(targets) we
# may be building above, using $(if_changed{,_dep}). As an
# optimization, we don't need to read them if the target does not
# exist, we will rebuild anyway in that case.
existing-targets := $(wildcard $(sort $(targets)))
-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd)
.PHONY: $(PHONY)