@@ -18,6 +18,18 @@ O_OBJS :=
export-objs := usb.o
+# usb.o contains usb_init which is marked as __initcall (actually
+# module_init). usb_init must be executed before all other usb __initcall
+# routines, otherwise the individual drivers will be initialized before the
+# hub driver is, causing the hub driver initialization sequence to
+# needlessly probe every USB driver with the root hub device. This causes
+# a lot of unnecessary system log messages, a lot of user confusion, and
+# has been known to cause a incorrectly programmed USB device driver to
+# grab the root hub device improperly.
+# Greg Kroah-Hartman, 27 Oct 2000
+
+LINK_FIRST := usb.o
+
# Multipart objects.
list-multi := usbcore.o
@@ -98,6 +110,10 @@ int-m := $(sort $(foreach m, $(multi-m)
obj-m := $(filter-out $(obj-y), $(obj-m))
int-m := $(filter-out $(int-y), $(int-m))
+
+# Take multi-part drivers out of obj-y and put components in.
+
+obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
# Translate to Rules.make lists.
@@ -31,6 +31,9 @@ unexport LX_OBJS
unexport MX_OBJS
unexport MIX_OBJS
unexport SYMTAB_OBJS
+# Control link order, added 29 Oct 200 Keith Owens <kaos@ocs.com.au>
+unexport LINK_FIRST
+unexport LINK_LAST
#
# Get things started.
@@ -84,8 +87,19 @@ all_targets: $(O_TARGET) $(L_TARGET)
#
# Rule to compile a set of .o files into one .o file
#
+# Note: if LINK_FIRST or LINK_LAST are specified, the rest of the
+# object files are sorted to remove duplicates. Thus, if you use
+# LINK_FIRST/LAST, make sure they specify all ordering requirements.
+#
ifdef O_TARGET
-ALL_O = $(OX_OBJS) $(O_OBJS)
+ ALL_O = $(OX_OBJS) $(O_OBJS)
+ ifneq ($(strip $(LINK_FIRST)$(LINK_LAST)),)
+ ALL_O := $(sort $(ALL_O))
+ ALL_O := \
+ $(filter $(ALL_O), $(LINK_FIRST)) \
+ $(filter-out $(LINK_FIRST) $(LINK_LAST), $(ALL_O)) \
+ $(filter $(ALL_O), $(LINK_LAST))
+ endif
$(O_TARGET): $(ALL_O)
rm -f $@
ifneq "$(strip $(ALL_O))" ""
@@ -1,6 +1,8 @@
Linux Kernel Makefiles
2000-September-14
Michael Elizabeth Chastain, <mec@shout.net>
+2000-October-29
+LINK_FIRST/LAST Keith Owens <kaos@ocs.com.au>
@@ -656,7 +658,12 @@ The public interface of Rules.make consi
with the name $(O_TARGET). This $(O_TARGET) name also appears
in the top Makefile.
- The order of files in $(O_OBJS) and $(OX_OBJS) is significant.
+ Even if a subdirectory Makefile has an $(O_TARGET), the .config
+ options still control whether or not its $(O_TARGET) goes into
+ vmlinux. See the $(M_OBJS) example below.
+
+ If neither of LINK_FIRST nor LINK_LAST are defined then the
+ order of files in $(O_OBJS) and $(OX_OBJS) is significant.
All $(OX_OBJS) files come first, in the order listed, followed by
all $(O_OBJS) files, in the order listed. Duplicates in the lists
are allowed: the first instance will be linked into $(O_TARGET)
@@ -680,9 +687,53 @@ The public interface of Rules.make consi
O_OBJS += pci.o pci_iommu.o
endif
- Even if a subdirectory Makefile has an $(O_TARGET), the .config
- options still control whether or not its $(O_TARGET) goes into
- vmlinux. See the $(M_OBJS) example below.
+ If either of LINK_FIRST or LINK_LAST are defined then the order of
+ files in $(O_OBJS) and $(OX_OBJS) is ignored. Instead the files
+ are linked in the order $(LINK_FIRST), the rest, $(LINK_LAST). The
+ order of entries in LINK_FIRST and LINK_LAST is preserved exactly
+ as specified. The order of the rest of the files is undefined,
+ currently it is alphabetical but you must not rely on any order for
+ the rest of the files. When either LINK_FIRST or LINK_LAST are
+ defined, they must define the complete link order for all files, do
+ not rely on manual ordering of the rest of the filenames in the
+ Makefile.
+
+ The only justification for LINK_FIRST and LINK_LAST is to control
+ the order of initialization routines. Routines which are defined
+ as __initcall or module_init and are linked into the kernel will be
+ executed during kernel startup in the order they were linked. So
+ moving objects to the start of their O_TARGET via LINK_FIRST
+ defines which initialization routines in O_TARGET are executed
+ first.
+
+ Use LINK_FIRST for routines which must be executed before all
+ others. For example, usb_init in usb_init must be executed before
+ all other usb initialization routines so drivers/usb/Makefile has
+ LINK_FIRST := usb.o.
+
+ Use LINK_LAST where you have multiple drivers that can recognise a
+ piece of hardware and you want the older drivers to be tried last.
+ For example, SCSI card foo can be controlled by drivers bar.o and
+ baz.o but you only want to try bar.o if all else fails.
+ LINK_LAST := bar.o
+ will ensure that the initialization routines in bar.o are tried
+ last.
+
+ LINK_FIRST and LINK_LAST must not contain any duplicate object
+ names. There is no need to make any entries in LINK_FIRST/LAST
+ conditional on CONFIG_xxx options, the ordering lists are only
+ effective if the specified objects are actually compiled. In other
+ words, when you use LINK_FIRST/LAST, specify all the objects in one
+ assignment, do not create LINK_FIRST/LAST from multiple
+ assignments.
+
+ All uses of LINK_FIRST and LINK_LAST must be justified and fully
+ documented in the Makefile. Historically entries in Makefile were
+ manually ordered with no documentation, now we do not know if an
+ order is coincidence or it is required and, if it is required, why
+ the order matters. This lack of critical information is
+ unacceptable. See drivers/usb/Makefile for an example of the level
+ of detail required.