为什么会有这个问题
因为这个问题在电话面试的时候被问的次数太多了,哈哈,目前,市面上也没有很好的教程去说明这个问题。
再次总结下自己的学习kernel艰苦的路程。我发现了,所谓的自己深入不进去,是自己读的太少或者认真思考的太少,包括这几次面试,都是问的一些基础知识,那为什么掌握不了呢?这需要自己好好反思了。到底哪里出了问题。
千方百计,毛主席说过的话,自己何尝努力了几分之几。对吧,这个样子,是自己不上心的后果之一。
简单记录
我知道的一个问题就是,自己看不懂的就不记了,其实你说这些都不能记住吗?东西也就是那么多,自己记住一点是一点。
就从网卡说起吧。 版本2.6.x
以这篇文章为例这篇文章不会设计具体的函数,大体记录下简要。
struct pci_device_id {
__u32 vendor, device;
...
}
大多数网卡就是一个PCI设备,然后是一个 **struct pci_device_id **的数组。
static struct pci_device_id e100_id_table[] = {
INTEL_8255X_ETHERNET_DEVICE(0x1029, 0),
INTEL_8255X_ETHERNET_DEVICE(0x1030, 0),
INTEL_8255X_ETHERNET_DEVICE(0x1031, 3),
……/*略过一大堆支持的设备*/}
同时,pci设备需要pci_driver:
struct pci_driver {
struct list_head node;
char *name;
struct module *owner;
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
int (*resume) (struct pci_dev *dev); /* Device woken up */
int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */
void (*shutdown) (struct pci_dev *dev);
struct device_driver driver;
struct pci_dynids dynids;
};
在系统引导的时候,PCI设备可以被发现,其实这个引导的过程应该很有趣,实在是应该探究一番去瞧一瞧。
当内核发现一个已经检测到的设备同驱动注册的id_table中的信息相匹配时, 它就会触发驱动的probe函数,以e100为例:
/*
* 定义一个名为e100_driver的PCI设备
* 1、设备的探测函数为e100_probe;
* 2、设备的id_table表为e100_id_table
*/
static struct pci_driver e100_driver = {
.name = DRV_NAME,
.id_table = e100_id_table,
.probe = e100_probe,
.remove = __devexit_p(e100_remove),
#ifdef CONFIG_PM
.suspend = e100_suspend,
.resume = e100_resume,
#endif
.driver = {
.shutdown = e100_shutdown,
}
};
这样,如果系统检测到与id_table 中对应的设备时, 就会调用驱动的probe函数。 驱动设备在init函数中,调用pci_module_init函数初始化PCI设备e100_driver:
tatic int __init e100_init_module(void)
{
if(((1 << debug) - 1) & NETIF_MSG_DRV) {
printk(KERN_INFO PFX "%s, %s/n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO PFX "%s/n", DRV_COPYRIGHT);
}
return pci_module_init(&e100_driver);
}
下面的问题就很重要了,需要记忆的东西比较多