日期:2014-05-16 浏览次数:20819 次
drivers/usb/core/usb.c
subsys_init(usb_init);我们 看到一个subsys_initcall,它也是一个宏,我们可以把它理解为module_init,只不过这部分代码比较核心,开发者们把它看做一个子系统,而不仅仅是一个模块。usbcore这个模块它代表的不是某一个设备,而是所有usb设备赖以生存的模块,Linux中,像这样一个类别的设备驱动被鬼节为一个子系统。比如PCI子系统、SCSI子系统,基本上,drivers/目录西面的每一个目录就算为一个子系统,因为他们代表了一类设备。
subsys_initcall(usb_init)的意思就是告诉我们usb_init是usb子系统真正的初始化函数,而usb_exit()将是整个usb子系统的结束时的清理函数。
我们需要从usb_init函数开始分析:
static int __init usb_init(void)
__init标记:它对于内核来说就是一种暗示,表明这个函数仅仅在初始化期间使用,在模块被装载之后,它占用的资源就会释放掉,用作别用。__init的定义在include/linux/init.h中
#define __init
__section(.init.text) __cold notrace
__attribute__、__section__等等都是GNUC的扩展,GNUC作为能够编译内核的唯一编译器。通常编译器将函数放在.text段,变量放在.data或.bss段,使用section属性,可以让编译器将函数或变量放在指定的段中。__init的定义便表示将它修饰的代码放在.init.text段中。连接器可以把相同段的代码或数据安排在一起,比如__init修饰的所有代码都被放在.init.text段中,初始化结束后就可以释放这部分内存。
设备模型:
总线、设备、驱动:(bus、device、driver)定义在include/linux/device.h
struct bus_type {
const char *name;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
struct dev_pm_ops *pm;
struct bus_type_private *p;
};
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
struct attribute_group **groups;
struct dev_pm_ops *pm;
struct driver_private *p;
};
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device */
struct device_type *type;
struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
*/
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power;
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
struct device_dma_parameters *dma_parms;
struct list_head dma_pools; /* dma pools (if dma'ble) */