网络设备模块与驱动的初始化顺序控制

网络设备模块的初始化,使用subsys_initcall调用。subsys初始化例程的优先级为4,排在pure_initcall(优先级0)、core_initcall(1)、postcore_initcall(2)和arch_initcall(优先级3)之后。排在device_initcall(优先级6)之前。系统在启动过程中,函数do_initcalls按照优先级顺序依次调用注册的initcall函数。

subsys_initcall(net_dev_init);
#define subsys_initcall(fn)     __define_initcall(fn, 4)
#define device_initcall(fn)     __define_initcall(fn, 6)


网卡驱动程序初始化使用module_init函数,其定义为device_initcall,优先级为6,位于subsys_initcall之后。即必须在DEVICE模块初始化之后才能初始化网卡驱动程序。

#define module_init(x)  __initcall(x);
#define __initcall(fn) device_initcall(fn)

为保证net_dev_init函数率先执行,内核定义了全局变量dev_boot_phase,初始值为1,当net_dev_init初始化后将其设置为0。如果在dev_boot_phase为1时,初始化了网卡驱动,必然会调用到网络设备注册/注销函数。内核在这两个函数开头做了判断,如果dev_boot_phase为1,提示BUG发生。

int register_netdevice(struct net_device *dev)
{
    BUG_ON(dev_boot_phase);
}
static void rollback_registered_many(struct list_head *head)
{
    BUG_ON(dev_boot_phase);
}

内核版本

Linux-4.15

猜你喜欢

转载自blog.csdn.net/sinat_20184565/article/details/81507236