[lkml]   [2000]   [Mar]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectHow to register non-modular net drivers?
    [ kernel 2.3.48 ]

    How should a non-modularised network device driver register itself? If
    it's a module then its init_module() function can call register_netdev()
    but having done a pretty extensive walkthrough I can't see how a
    linked-in driver is supposed to do it. I've appended my analysis of
    the initialisation sequence here. I'd be interested if it has a hole.
    (Is the network layer _really_ initialised via the fs partition

    I wonder if there should be a walk down the net device list right at the
    end of net_dev_init().

    Also, is register_netdev() buggy? It calls rtnl_lock() but has two
    error return paths which fail to call rtnl_unlock().


    Bootup walkthrough from the netdevice POV follows. Might be useful for

    Before anything happens: static storage

    There is a global list of struct net_device's. The head is pointed to
    by the global variable drivers/net/Space.c:dev_base.

    dev_base is initialised at load time to point to the head of a linked
    list of struct net_devices which describe ethernet devices. These all
    have the name "eth%d". They are defined in Space.c:eth[0-7]_dev.
    Their init() methods are all initialised to point to

    There is a magic flag in net/core/dev.c:dev_boot_phase which is
    initialised to 1. Remember this intteger for later.

    When the kernel runs

    arch/i386/kernel/head.S calls start_kernel()

    init/main.c:start_kernel() initialises lots of low-level things then
    starts a kernel thread based on the function init/main.c:init().

    init/main.c:init() calls init/main.c:do_basic_setup().

    do_basic_setup initialises lots of stuff. Partway through it calls
    do_initcalls() which walks through all the kernel functions which are
    declared as being __initcall's. One of these is

    fs/partitions/check.c:partition_setup() is an __initcall function

    fs/partitions/check.c:partition_setup() calls device_init()

    drivers/block/genhd.c:device_init() calls net_dev_init()

    net/core/dev.c:net_dev_init() initialises a bunch of stuff then walks
    the net_device_list which is pointed to by dev_base (see previous

    For each device in the dev_base list net_dev_init() converts the
    device's name from "eth%d" to "eth0", etc. with
    dev.c:dev_alloc_name(). It also calls the device's init() method. At
    this time, each device's init() method points at Space.c:ethif_probe().

    Space.c:ethif_probe() walks all the compiled-in device drivers,
    calling their probe() routines. If the probe succeeds it returns
    zero and the device's init() method is considered to have succeeded..

    The device driver's probe() routine cannot successfully
    register itself via register_netdev() because the netdevice layer
    is not yet fully initialised and ready for it (dev_boot_phase ==
    1). If the driver attempts to register itself via
    drivers/net/net_init.c:register_netdev() (which calls
    net/core/dev.c:register_netdevice()), register_netdevice() will
    print "early initialization of device %s is deferred" and will
    queue the device on the dev_base queue if it's not already there.
    The initial eight devices _will_ already be there.

    Back to net_dev_init(): If the init() method succeeds, net_dev_init()
    marks the device as available. If it fails, it is marked as dead and
    unlinked from the dev_base list.

    At the end of processing, net_dev_init() sets dev_boot_phase to zero
    and calls drivers/net/setup.c:net_device_init() - very similar name!

    net_device_init() calls a bunch of probing routines, including
    pci_probe(), which does more device probing. It also causes
    registration of things like the dummy and loopback devices (via

    So when we hit the end of net/core/dev.c:net_dev_init() we still
    haven't successfully called register_netdevice() for this device. I
    tried outting this in right at the end of net_dev_init() but it blew up

    We can't call register_netdev() from within the device driver's init()
    method because register_netdev() calls the init() method!

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    Please read the FAQ at

     \ /
      Last update: 2005-03-22 13:56    [W:0.022 / U:14.192 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site