??????
?????
struct device {struct device*parent;/*????????*//*???????device???device?????device??????????*/struct device_private*p;struct kobject kobj;/*???kobject??*/const char*init_name; /* initial name of the device */struct device_type*type;struct semaphoresem;/* 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*platform_data;/*??????????????????*//* Platform specific data, device core doesn't touch it */struct dev_pm_infopower;#ifdef CONFIG_NUMAintnuma_node;/* NUMA node this device is close to */#endifu64*dma_mask;/* dma mask (if dma'able device) */u64coherent_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_headdma_pools;/*???DMA????????*//* dma pools (if dma'ble) */struct dma_coherent_mem*dma_mem;/*???????????DMA?????????*//* internal for coherent mem override *//* arch specific additions */struct dev_archdataarchdata;dev_tdevt;/* dev_t, creates the sysfs "dev" */spinlock_tdevres_lock;struct list_headdevres_head;struct klist_nodeknode_class;struct class*class;const struct attribute_group **groups;/* optional groups */void(*release)(struct device *dev);/*????????????*/};
Bus???
struct bus_type {const char*name;/*??????*//*??????????????????????????sysfs???????*/struct bus_attribute*bus_attrs;/*?????????????????????????sysfs???????*/struct device_attribute*dev_attrs;/*??????????????????????????????sysfs?????*/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);const 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 */bool suppress_bind_attrs;/* disables bind/unbind via sysfs */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);/*???????????????*/const struct attribute_group **groups;const struct dev_pm_ops *pm;struct driver_private *p;};
????
/* * device classes */struct class {const char*name;struct module*owner;struct class_attribute*class_attrs;struct device_attribute*dev_attrs;struct kobject*dev_kobj;int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);char *(*devnode)(struct device *dev, mode_t *mode);void (*class_release)(struct class *class);void (*dev_release)(struct device *dev);int (*suspend)(struct device *dev, pm_message_t state);int (*resume)(struct device *dev);const struct dev_pm_ops *pm;struct class_private *p;};
????????????????
/** * struct device_private - structure to hold the private to the driver core portions of the device structure. * * @klist_children - klist containing all children of this device * @knode_parent - node in sibling list * @knode_driver - node in driver list * @knode_bus - node in bus list * @driver_data - private pointer for driver specific info. Will turn into a * list soon. * @device - pointer back to the struct class that this structure is * associated with. * * Nothing outside of the driver core should ever touch these fields. */struct device_private {struct klist klist_children;struct klist_node knode_parent;struct klist_node knode_driver;struct klist_node knode_bus;void *driver_data;struct device *device;};struct class_private {struct kset class_subsys;struct klist class_devices;struct list_head class_interfaces;struct kset class_dirs;struct mutex class_mutex;struct class *class;};/** * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. * * @subsys - the struct kset that defines this bus. This is the main kobject * @drivers_kset - the list of drivers associated with this bus * @devices_kset - the list of devices associated with this bus * @klist_devices - the klist to iterate over the @devices_kset * @klist_drivers - the klist to iterate over the @drivers_kset * @bus_notifier - the bus notifier list for anything that cares about things * on this bus. * @bus - pointer back to the struct bus_type that this structure is associated * with. * * This structure is the one that is the actual kobject allowing struct * bus_type to be statically allocated safely. Nothing outside of the driver * core should ever touch these fields. */struct bus_type_private {struct kset subsys;struct kset *drivers_kset;struct kset *devices_kset;struct klist klist_devices;struct klist klist_drivers;struct blocking_notifier_head bus_notifier;unsigned int drivers_autoprobe:1;struct bus_type *bus;};struct driver_private {struct kobject kobj;struct klist klist_devices;struct klist_node knode_bus;struct module_kobject *mkobj;struct device_driver *driver;};
?????????
/* FIXME * The *owner field is no longer used. * x86 tree has been cleaned up. The owner * attribute is still left for other arches. */struct attribute {const char*name;struct module*owner;mode_tmode;};
???????????????????????????
?????????
?????????????????????????????????????????sys/???????????start_kernel()->rest_init()->
static noinline void __init_refok rest_init(void)__releases(kernel_lock){……/*?????????kernel_init?????????????*/kernel_thread(kernel_init, NULL,Monster Online, CLONE_FS CLONE_SIGHAND);……}
????kernel_init()????????
kernel_init()->do_basic_setup()->driver_init()
/** * driver_init - initialize driver model. * * Call the driver model init functions to initialize their * subsystems. Called early from init/main.c. */ /*?????????????*/void __init driver_init(void){/* These are the core pieces */ /*devtmpfs ????? Linux ?? ??????????? /dev? ??????????? udev??? GNU/Linux ??????devtmpfs ? 2009 ??????????????? Linux 2.6.32 ????*/devtmpfs_init();/*???????*/devices_init();/*bus???*/buses_init();/*class???*/classes_init();/*firmware???*/firmware_init();/*?????hypervisor??????? ??????????????????????????????????????????????????????????????????????????????????? hypervisor ???????????? ? VMM??????????????VM?,Moncler Jacken?????? VM ?????????????????*/hypervisor_init();/* These are also core pieces, but must come after the * core core pieces. */platform_bus_init();/*???system_bus???sys/devices?????system??*/system_bus_init();/*cpu_dev???*/cpu_dev_init();/*?/sys/devices/system?????memory????????????????????????*/memory_dev_init();}/*?sys????????????*/int __init devices_init(void){/*???sys???devices???*/devices_kset = kset_create_and_add("devices",UGG Boots, &device_uevent_ops, NULL);if (!devices_kset)return -ENOMEM;/*??????dev???*/dev_kobj = kobject_create_and_add("dev", NULL);if (!dev_kobj)goto dev_kobj_err;/*?dev??????block???*/sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);if (!sysfs_dev_block_kobj)goto block_kobj_err;/*?dev??????char???*/sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);if (!sysfs_dev_char_kobj)goto char_kobj_err;return 0; char_kobj_err:kobject_put(sysfs_dev_block_kobj); block_kobj_err:kobject_put(dev_kobj); dev_kobj_err:kset_unregister(devices_kset);return -ENOMEM;}
???????????????
/sys/??dev/?devices/??

/sys/dev/??block/?char/??

?????
int __init buses_init(void){/*?sys?????bus???*/bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);if (!bus_kset)return -ENOMEM;return 0;}
???????/sys/?????/bus/??

Class???
int __init classes_init(void){/*?sys??????class???*/class_kset = kset_create_and_add("class", NULL, NULL);if (!class_kset)return -ENOMEM;return 0;}
??????/sys/?????/class/??

Firmware???
int __init firmware_init(void){/*?sys??????firmware???*/firmware_kobj = kobject_create_and_add("firmware", NULL);if (!firmware_kobj)return -ENOMEM;return 0;}
????,UGG UK??/sys/?????/firmware/??

Hypervisor?????????????????????????CONFIG_SYS_HYPERVISOR???????????????
int __init hypervisor_init(void){/*?sys??????hypervisor???*/hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);if (!hypervisor_kobj)return -ENOMEM;return 0;}
Platform_bus???????????
int __init platform_bus_init(void){int error;/*??early_platform_device_list??*/early_platform_cleanup();/*??platform_bus*/error = device_register(&platform_bus);if (error)return error;/*bus??*/error = bus_register(&platform_bus_type);if (error)device_unregister(&platform_bus);return error;}struct device platform_bus = {/*???????"/sys/devices/platform"*/.init_name= "platform",};
??platform_bus??
platform_bus_init()->device_register()
int device_register(struct device *dev){device_initialize(dev);return device_add(dev);}
?????
/** * device_initialize - init device structure. * @dev: device. * * This prepares the device for use by other layers by initializing * its fields. * It is the first half of device_register(), if called by * that function, though it can also be called separately, so one * may use @dev's fields. In particular, get_device()/put_device() * may be used for reference counting of @dev after calling this * function. * * NOTE: Use put_device() to give up your reference instead of freeing * @dev directly once you have called this function. */ /*???device??*/void device_initialize(struct device *dev){/*???devices_kset??????kobj?/sys/devices/*/dev->kobj.kset = devices_kset;kobject_init(&dev->kobj, &device_ktype);INIT_LIST_HEAD(&dev->dma_pools);init_MUTEX(&dev->sem);spin_lock_init(&dev->devres_lock);INIT_LIST_HEAD(&dev->devres_head);device_init_wakeup(dev, 0);/*??power???wake????????*/device_pm_init(dev);/*???dev?power??*/set_dev_node(dev, -1);/*CONFIG_NUMA???????*/}
???????????????????????
intdevice_add(structdevice*dev)
{
structdevice*parent=NULL;
structclass_interface*class_intf;/*class??*/
interror=-EINVAL;
dev=get_device(dev);/*??dev?kobject?????*/
if(!dev)
gotodone;
if(!dev->p){/*?????????????????????*/
error=device_private_init(dev);
if(error)
gotodone;
}
/*
*forstaticallyallocateddevices,whichshouldallbeconverted
*someday,weneedtoinitializethename.Wepreventreadingback
*thename,andforcetheuseofdev_name()
*/
if(dev->init_name){/*??????kobj?*/
dev_set_name(dev,"%s",dev->init_name);
dev->init_name=NULL;
}
if(!dev_name(dev))/*?kobj??????????*/
gotoname_error;
pr_debug("device:'%s':%s\n",dev_name(dev),__func__);
/*?????????????????*/
parent=get_device(dev->parent);
/*?????obj?????????*/
setup_parent(dev,parent);
/*useparentnuma_node*/
if(parent)
set_dev_node(dev,dev_to_node(parent));
/*first,registerwithgenericlayer.*/
/*werequirethenametobesetbefore,andpassNULL*/
/*?obj??????????????????platform???sys???*/
error=kobject_add(&dev->kobj,dev->kobj.parent,NULL);
?????????/sys/devices/?????platform????

if(error)
gotoError;
/*notifyplatformofdeviceentry*/
if(platform_notify)
platform_notify(dev);
/*?????dient??(??????)?????dient????*/
/*?????????uevent??*/
error=device_create_file(dev,&uevent_attr);
?????/sys/devices/platform???uevent??

if(error)
gotoattrError;
/*??????????????????????*/
if(MAJOR(dev->devt)){
/*??dient???????????????dev??*/
error=device_create_file(dev,&devt_attr);
??????????dev->kobj???dev??????/sys/devices/virtual/mem/random????????1??????8??/sys/devices/virtual/mem/random?????dev???

??dev?????????????major:minor?????1?8?

if(error)
gotoueventattrError;
/*??/dev????(???dient?????????)*/
/*????????sys/dev/char?block???????dev_obj?????????????????major:minor,?1?8???dev???*/
error=device_create_sys_dev_entry(dev);
?????????????/sys/dev/char/???1:8/??????/sys/devices/virtual/mem/random???

if(error)
gotodevtattrError;
devtmpfs_create_node(dev);
}
/*???????dev?class????????????*/
error=device_add_class_symlinks(dev);
if(error)
gotoSymlinkError;
/*????device?????????????????
??class??dev_attrs?device_type??groups???device?
??groups?*/
error=device_add_attrs(dev);
if(error)
gotoAttrsError;
/*adddevicetobus*/
/*??device?bus???bus?device???????????*/
error=bus_add_device(dev);
if(error)
gotoBusError;
/*?dev->kobj?????power?????????*/
error=dpm_sysfs_add(dev);
?dev->kobj??????power???????????????????platform?

if(error)
gotoDPMError;
/*?????PM??*/
device_pm_add(dev);
/*Notifyclientsofdeviceaddition.Thiscallmustcome
*afterdpm_sysf_add()andbeforekobject_uevent().
*/
if(dev->bus)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_ADD_DEVICE,dev);
kobject_uevent(&dev->kobj,KOBJ_ADD);
/*????????????????*/
bus_probe_device(dev);
/*???????????????*/
if(parent)
klist_add_tail(&dev->p->knode_parent,
&parent->p->klist_children);
if(dev->class){
mutex_lock(&dev->class->p->class_mutex);
/*tietheclasstothedevice*/
klist_add_tail(&dev->knode_class,
&dev->class->p->class_devices);
/*notifyanyinterfacesthatthedeviceishere*/
list_for_each_entry(class_intf,
&dev->class->p->class_interfaces,node)
if(class_intf->add_dev)
class_intf->add_dev(dev,class_intf);
mutex_unlock(&dev->class->p->class_mutex);
}
……
}
????????????
int device_private_init(struct device *dev){/*?cache???private???*/dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);if (!dev->p)return -ENOMEM;dev->p->device = dev;/*??dev private???device???*//*???klist_children?????????????get?put????????????????????*/klist_init(&dev->p->klist_children, klist_children_get, klist_children_put);return 0;}static struct kobject *get_device_parent(struct device *dev, struct device *parent){int retval;if (dev->class) {/*??device??class*/struct kobject *kobj = NULL;struct kobject *parent_kobj;struct kobject *k;/* * If we have no parent, we live in "virtual". * Class-devices with a non class-device as parent, live * in a "glue" directory to prevent namespace collisions. */if (parent == NULL)/*????????????'virtual'?kobj????????????????class?????'virtual'(??class??)?????kobj????class????*/parent_kobj = virtual_device_parent(dev);else if (parent->class)/*??????class?????????kobj*/return &parent->kobj;else/*??????????class??*/parent_kobj = &parent->kobj;/* find our class-directory at the parent and reference it */spin_lock(&dev->class->p->class_dirs.list_lock);list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)if (k->parent == parent_kobj) {/*??????kobj??????*/kobj = kobject_get(k);/*???????*/break;}spin_unlock(&dev->class->p->class_dirs.list_lock);if (kobj)return kobj;/* or create a new class-directory at the parent device *//*????????????dev->class???k->parent==parent_kobj?kobj,?????*/k = kobject_create();if (!k)return NULL;/*?????kobj?kset?dev?class->p->class_dirs*/k->kset = &dev->class->p->class_dirs;/*??kobj??parent?kobj???parent?????parent_kobj*/retval = kobject_add(k, parent_kobj, "%s", dev->class->name);if (retval < 0) {kobject_put(k);return NULL;}/* do not emit an uevent for this simple "glue" directory */return k;}if (parent)/*??parent?????????kobj*/return &parent->kobj;return NULL;}static struct kobject *virtual_device_parent(struct device *dev){static struct kobject *virtual_dir = NULL;if (!virtual_dir)/*????virtual?kobj??????????*/virtual_dir = kobject_create_and_add("virtual", &devices_kset->kobj);/*?????kobj*/return virtual_dir;}
???????Linux???????


???class??
staticintdevice_add_class_symlinks(structdevice*dev)
{
interror;
/*??class???????*/
if(!dev->class)
return0;
/*?dev->kobj?????????'subsystem'????????????class?sys???/sys/class/***???????????
*/
error=sysfs_create_link(&dev->kobj,
&dev->class->p->class_subsys.kobj,
"subsystem");
?????

……
}
device??bus
intbus_add_device(structdevice*dev)
{
structbus_type*bus=bus_get(dev->bus);
interror=0;
/*??bus??????????*/
if(bus){
pr_debug("bus:'%s':adddevice%s\n",bus->name,dev_name(dev));
/*??????,??????bus???*/
error=device_add_attrs(bus,dev);
if(error)
gotoout_put;
/*?bus?devices??????dev->kobj???,???dev->kobj???*/
error=sysfs_create_link(&bus->p->devices_kset->kobj,
&dev->kobj,dev_name(dev));
??????/sys/devices/platform/devices/??serial8250?????/sys/devices/platform/serial8250

if(error)
gotoout_id;
/*dev->kobj???subsystem?????bus???
?????*/
error=sysfs_create_link(&dev->kobj,
&dev->bus->p->subsys.kobj,"subsystem");
?????????serial8250??????subsystem?????/sys/bus/platform/

if(error)
gotoout_subsys;
/*dev->kobj????bus???bus???????
?????????????*/
error=make_deprecated_bus_links(dev);
if(error)
gotoout_deprecated;
/*??bus??????dev??bus???*/
klist_add_tail(&dev->p->knode_bus,&bus->p->klist_devices);
}
return0;
……
}
????????
/** * bus_probe_device - probe drivers for a new device * @dev: device to probe * * - Automatically probe for a driver if the bus allows it. *//*??????bus?????bus???????????????*/void bus_probe_device(struct device *dev){struct bus_type *bus = dev->bus;int ret;if (bus && bus->p->drivers_autoprobe) {ret = device_attach(dev);/*????*/WARN_ON(ret < 0);}}
Device_attach()??????driver_sysfs_add()????????
staticintdriver_sysfs_add(structdevice*dev)
{
intret;
/*?????dev->kobj?????dev->kobj*/
ret=sysfs_create_link(&dev->driver->p->kobj,&dev->kobj,
kobject_name(&dev->kobj));
?????serial8250????????????????

if(ret==0){
/*?dev->kobj????driver??????????*/
ret=sysfs_create_link(&dev->kobj,&dev->driver->p->kobj,
"driver");
????????????

if(ret)
sysfs_remove_link(&dev->driver->p->kobj,
kobject_name(&dev->kobj));
}
returnret;
}
??bus
struct bus_type platform_bus_type = {.name= "platform",/*????/sys/bus/platform???*/.dev_attrs= platform_dev_attrs,.match= platform_match,.uevent= platform_uevent,.pm= &platform_dev_pm_ops,};int bus_register(struct bus_type *bus){int retval;struct bus_type_private *priv;/*?priv??????*/priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);if (!priv)return -ENOMEM;/*???bus?????*/priv->bus = bus;bus->p = priv;BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);/*??priv?subsys????bus???*/retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);if (retval)goto out;/*??kset ?ktype????????parent?kset?kobj??*/priv->subsys.kobj.kset = bus_kset;priv->subsys.kobj.ktype = &bus_ktype;priv->drivers_autoprobe = 1;/*?????kset??????sd??*/retval = kset_register(&priv->subsys);if (retval)goto out;/*??????uevent*/retval = bus_create_file(bus, &bus_attr_uevent);if (retval)goto bus_uevent_fail;/*?priv->subsys.kobj?????devices??*/priv->devices_kset = kset_create_and_add("devices", NULL, &priv->subsys.kobj);if (!priv->devices_kset) {retval = -ENOMEM;goto bus_devices_fail;}/*?priv->subsys.kobj?????drivers????*/priv->drivers_kset = kset_create_and_add("drivers", NULL, &priv->subsys.kobj);if (!priv->drivers_kset) {retval = -ENOMEM;goto bus_drivers_fail;}?/*???priv?????*/klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);klist_init(&priv->klist_drivers, NULL, NULL);/*?bus????????????drivers_probe?drivers_autoprobe*/retval = add_probe_files(bus);if (retval)goto bus_probe_files_fail;/*???bus????????????????*/retval = bus_add_attrs(bus);if (retval)goto bus_attrs_fail;pr_debug("bus: '%s': registered\n", bus->name);return 0;bus_attrs_fail:remove_probe_files(bus);bus_probe_files_fail:kset_unregister(bus->p->drivers_kset);bus_drivers_fail:kset_unregister(bus->p->devices_kset);bus_devices_fail:bus_remove_file(bus, &bus_attr_uevent);bus_uevent_fail:kset_unregister(&bus->p->subsys);kfree(bus->p);out:bus->p = NULL;return retval;}
?????????/sys/bus/platform?????drivers?devices??????uevent?drivers_probe?drivers_autoprobe????

???system_bus???????/sys/devices/???system???
int __init system_bus_init(void){system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);if (!system_kset)return -ENOMEM;return 0;}

cpu_dev???
int __init cpu_dev_init(void){int err;/*??cpu,??/sys/devices/system?????cpu????*/err = sysdev_class_register(&cpu_sysdev_class);if (!err)err = cpu_states_init();#if defined(CONFIG_SCHED_MC) defined(CONFIG_SCHED_SMT)if (!err)err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class);#endifreturn err;}
?????????/sys/devices/system???cpu???

????????????????????????????????????????????????,UGG Boots????????????????????????
????????????
Related articles?
http://www.czs.gov.cn:8082/forumdisplay.php?fid=5