Linux网卡驱动分析之RTL8139(一)
时间:2010-06-01 来源:michael_dingtao
RTL8139too 芯片的主要结构
驱动模块的装载和卸载
当我们正确编译完我们的程序后,我们就需要把生成的目标文件加载到内核中去,我们
会先ifconfig eth0 down 和rmmod 8139too 来卸载正在使用的网卡驱动,然后insmod
8139too.o 把我们的驱动加载进去(其中8139too.o 是我们编译生成的目标文件)。
就像C 程序有主函数main()一样, 模块也有第一个执行 的函数, 即
module_init(rtl8139_init_module);在我们的程序中,rtl8139_init_module()在 insmod 之后首先执行,就像其它的驱动程序一样,驱动程序在使用 insmod 载入时,第一个初呼叫的函数是rtl8139_init_module,在使用 rmmod 移除时,rtl8139_cleanup_module 会被呼叫。
module_init(rtl8139_init_module); |
rtl8139_init_module
static struct pci_driver rtl8139_pci_driver = { |
pci_module_init()在驱动代码里没有定义,你一定想到了,它是Linux 内核提供给模块是
一个标准接口,那么这个接口都干了些什么,这个函数。
里面调用了pci_register_driver(),这个函数代码在Linux/drivers/pci/pci.c 中,
pci_register_driver 做了三件事情。
① 是把带过来的参数 rtl8139_pci_driver 在内核中进行了注册,内核中有一个PCI 设备的大
的链表,这里负责把这个PCI 驱动挂到里面去。
② ②是查看总线上所有 PCI 设备(网卡设备属于PCI 设备的一种)的配置空间如果发现标
识信息与rtl8139_pci_driver 中的id_table 相同即rtl8139_pci_tbl,
③是把这个rtl8139_pci_driver 结构挂在这个设备的数据结构(pci_dev)上,表示这个设备,从此就有了自己的驱 动了。而驱动也找到了它服务的对象了。
pci_register_driver(src/include/linux/pci.h)
static inline int __must_check pci_register_driver(struct pci_driver |
__pci_register_driver(src/drivers/pci/pcidriver.c)
/** |
driver_register(src/drivers/base/driver.c)
/** |
bus_add_driver(src/drivers/base/bus.c)
/** |
driver_attach(src/drivers/base/dd.c)
/** //这是个重要的函数,它会遍历设备链表,试图匹配这个总线上的设备 |
__driver_attach(src/drivers/base/dd.c)
static int __driver_attach(struct device * dev, void * data) |
bus_for_each_dev(src/drivers/base/bus.c)
/** |
driver_probe_device
/** |
rtl8139_cleanup_module
static void __exit rtl8139_cleanup_module (void) |