2000-10-27 19:58:50

by Dunlap, Randy

[permalink] [raw]
Subject: RE: test[9-10] USB depmod unresolved symbols

Hunt, Claude, Jean-Luc:

I'm hoping that this will help explain some of
the confusion that you have been or are seeing,
although it doesn't explain it fully for me,
but maybe it does for someone else (like Keith
Owens ?).

I was able to reproduce the problem that Hunt
described below. 'depmod -ae' gave me similar
output (but lots more of them since I compiled
everything possible as a USB module -- except
for the USB core [USB Support option]).

I'm currently using 2.4.0-test10-pre6.
My normal (?) kernel has NO USB built into it.
That is, I normally build USB all as modules.
Call this no-USB kernel 't10pre6'.

But for this test, I built usbcore into the kernel.
Call this usbcore-kernel 't10pre6-kuc'.

Now if I am running 't10pre6' (no USB in kernel)
and I do 'depmod -ae', I get lots of these
"Unresolved symbol" messages from depmod.
However, if I boot 't10pre6-kuc' (USBcore in kernel)
and i do 'depmod -ae', it works fine, no errors.

Is this like what you are seeing?
Are you seeing depmod errors before loading
the kernel that includes the USB core?

And finally (for anyone), is this the normal,
expected usage & behavior of depmod?

Thanks,
~Randy


> From: Hunt Kent [mailto:[email protected]]
>
> Okay, updates:
>
> Compiled modutils 2.3.19 and the problem persists.
> Arch is i386, AMD K-6.
>
> Result for modprobe -ae (test10-pre5):
>
> depmod: *** Unresolved symbols in
> /lib/modules/2.4.0-test10-pre5/kernel/drivers/usb/dc2xx.o
> depmod: usb_bulk_msg
> depmod: usb_deregister
> depmod: usb_free_dev
> depmod: usb_inc_dev_use
> depmod: usb_register
> depmod: *** Unresolved symbols in
> /lib/modules/2.4.0-test10-pre5/kernel/drivers/usb/ov511.o
> depmod: usb_deregister
> depmod: usb_free_urb
> depmod: usb_alloc_urb
> depmod: usb_register
> depmod: usb_submit_urb
> depmod: usb_driver_release_interface
> depmod: usb_control_msg
> depmod: usb_set_interface
> depmod: usb_unlink_urb
> depmod: *** Unresolved symbols in
> /lib/modules/2.4.0-test10-pre5/kernel/drivers/usb/printer.o
> depmod: usb_deregister
> depmod: usb_register
> depmod: usb_submit_urb
> depmod: usb_set_interface
> depmod: usb_unlink_urb
> depmod: *** Unresolved symbols in
> /lib/modules/2.4.0-test10-pre5/kernel/drivers/usb/scanner.o
> depmod: usb_bulk_msg
> depmod: usb_deregister
> depmod: usb_register
> depmod: usb_submit_urb
> depmod: usb_driver_release_interface
> depmod: usb_unlink_urb
>
> Let me know if you need more info.


2000-10-28 01:30:02

by Keith Owens

[permalink] [raw]
Subject: Re: test[9-10] USB depmod unresolved symbols

On Fri, 27 Oct 2000 12:55:57 -0700,
"Dunlap, Randy" <[email protected]> wrote:
>I'm currently using 2.4.0-test10-pre6.
>Now if I am running 't10pre6' (no USB in kernel)
>and I do 'depmod -ae', I get lots of these
>"Unresolved symbol" messages from depmod.
>However, if I boot 't10pre6-kuc' (USBcore in kernel)
>and i do 'depmod -ae', it works fine, no errors.

The problem is actually caused by the drivers/usb/Makefile. Right at
the start we have

# Objects that export symbols.
export-objs := usb.o

Tells the kernel build that usb.o needs compile flag -DEXPORT_SYMTAB.

# Multipart objects.
list-multi := usbcore.o
usbcore-objs := usb.o usb-debug.o hub.o

Tells kbuild that usb.o is not a free standing module, instead usb.o,
usb-debug.o and hub.o are linked into module usbcore.o. There is no
reference to usb.o in the rest of the Makefile, instead you have

obj-$(CONFIG_USB) += usbcore.o

All of this is quite normal, kbuild massages the object lists according
to whether they are being built as an object or as a module, part of
that massaging is to handle multiple objects linked into a single
object. After all the config dependencies have been created, there is
bolierplate code to handle overlapping entries in the various variable
lists, starting with

# Extract lists of the multi-part drivers.

However there are two lines missing from the end of this boilerplate
code.

# Take multi-part drivers out of obj-y and put components in.
obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)

Because those lines are missing, when USB is built into the kernel,
obj-y contains usbcore.o instead of its expansion (usb.o usb-debug.o
hub.o). When kdbuild compiles the USB objects for the kernel, it does
not know about the special compile flags for usb.o. usb.o is built as
a normal object (no -DEXPORT_SYMTAB) and linked into usbcore.o which in
turn is linked into usbdrv.o. What should happen is that usb.o is
compiled with -DEXPORT_SYMTAB, usb-debug.o and hub.o are compiled
without -DEXPORT_SYMTAB, all three are linked directly into usbdrv.o,
The object usbcore.o should not be built when USB is in the kernel, it
is a module only object.

The incorrect compile flags on usb.o mean that instead of exporting
usb_deregister in /proc/ksyms, it exports __VERSIONED_SYMBOL(usb_deregister),
the macro does not get expanded. This causes all the unresolved
symbols. At first glance the fix is easy, just put the missing lines
back into Makefile, that definitely fixes the export symbol problem.

# Take multi-part drivers out of obj-y and put components in.
obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)

However USB has another problem, which is probably why those lines were
removed in the first place. Adding $int-y to the end of the obj-y list
means that usb.o, usb-debug.o and hub.o are linked into usbdrv.o as the
last objects. This disturbs the order of the __init routines, usb_init
in usb.o is executed last when the above lines are in Makefile.

This is a generic kbuild problem, other directories have similar link
order problems, they get around it by explicitly ordering entries in
Makefile. This kludge will not work for USB because you have a special
case, nobody else has this order problem with a multi part object. If
usbcore was a single source instead of being built from three sources
then the explicit order kludge would work.

The kbuild group has been discussing adding a couple of extra variables
to kbuild to solve this link order problem, LINK_FIRST and LINK_LAST.
We were going to leave it until kernel 2.5 but it looks like we need
this functionality now. LINK_FIRST says "iff these objects are part of
O_TARGET then link them into O_TARGET before all other objects".
LINK_LAST says "iff these objects are part of O_TARGET then link them
into O_TARGET after all other objects". The rest of the objects will
then be linked into O_TARGET in an *arbitrary* order (probably sorted
alphabetically) after LINK_FIRST and before LINK_LAST.

The only justification for LINK_FIRST is to ensure that initialisation
routines run in the correct order. The only justification for
LINK_LAST is to put older device drivers after newer ones when the
hardware is such that both drivers would recognise it but you want the
newer driver to probe first. The kbuild group requires that all use of
LINK_FIRST and LINK_LAST be justified and documented, to avoid
undocumented gotchas coming back to bite us.

I will add LINK_FIRST and LINK_LAST to kbuild this weekend and
reinstate the missing lines in drivers/usb/Makefile. What I need from
the USB group is a documented (i.e. *why* is this order required)
definition of what needs to be linked first into usbdrv.o, and somebody
we can query if there are problems in the future. It will probably be
as simple as

# usb.o contains __init usb_init which must be executed before all
# other usb __init routines, the remaining usb __init routines can be
# executed in any order. Execution order of __init routines depends on
# link order so usb.o must be linked first. Joe Bloggs 28 Oct 2000.
LINK_FIRST := usb.o

but you know better than I what the required order will be and why.
Are there any other link order problems in USB? Replace Joe Bloggs
with somebody in the USB group who defined the list.

2000-10-28 03:51:41

by Greg KH

[permalink] [raw]
Subject: Re: test[9-10] USB depmod unresolved symbols

Thanks Keith for that detailed description of what is going wrong, I
would have never figured that out.

On Sat, Oct 28, 2000 at 12:29:39PM +1100, Keith Owens wrote:
>
> I will add LINK_FIRST and LINK_LAST to kbuild this weekend and
> reinstate the missing lines in drivers/usb/Makefile. What I need from
> the USB group is a documented (i.e. *why* is this order required)
> definition of what needs to be linked first into usbdrv.o, and somebody
> we can query if there are problems in the future. It will probably be
> as simple as

Yeah, a valid reason for LINK_FIRST and LINK_LAST!

I'll try my hand at the wording. Randy, does this look acceptable:

# usb.o contains __init usb_init which must be executed before all
# other usb __init routines, the remaining usb __init routines can be
# executed in any order. Execution order of __init routines depends
# on link order so usb.o must be linked first. 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

> but you know better than I what the required order will be and why.
> Are there any other link order problems in USB?

That's the only known link problem for the USB drivers.

Thanks,

greg k-h

--
[email protected](kroah|wirex).com
http://immunix.org/~greg


Attachments:
(No filename) (1.58 kB)
(No filename) (232.00 B)
Download all attachments