对于没有指定dev
-
>parent的dev都将被添加到
/sys
/devices
/
virtual
/tty
/ 目录下
如果指定了dev - >parent ,那么同时该dev - >class存在 ,同时parent - >class存在 ,
那么该dev - >name目录将被添加到parent - >class所在目录下 [luther .gliethttp ]
luther@gliethttp : ~ $ ll /sys / class /tty /console
lrwxrwxrwx 1 root root 0 2009 -06 -30 09 :40 /sys / class /tty /console - > . . / . . /devices / virtual /tty /console
luther@gliethttp : ~ $ ll /sys /devices / virtual /tty /console /
total 0
-rw -r - -r - - 1 root root 4 .0K 2009 -06 -30 10 :51 uevent
drwxr -xr -x 2 root root 0 2009 -06 -30 10 :51 power
lrwxrwxrwx 1 root root 0 2009 -06 -30 10 :57 subsystem - > . . / . . / . . / . . / class /tty
-r - -r - -r - - 1 root root 4 .0K 2009 -06 -30 10 :57 dev
来看看linux2 .6 .25内核源码 ,是怎么做得 .
device_create (tty_class , NULL , MKDEV (TTYAUX_MAJOR , 1 ) , "console" ) ;
= = >device_register
= = >device_add
= = >setup_parent
= = >get_device_parent
= = >dev - >kobj .parent = kobj ( "/sys/devices/virtual/tty" ) ; //所以所有的文件添加都将指向该目录[luther.gliethttp]
# ifdef CONFIG_SYSFS_DEPRECATED
static struct kobject *get_device_parent ( struct device *dev ,
struct device *parent )
{
/* class devices without a parent live in /sys/class/<classname>/ */
if (dev - > class & & ( !parent | | parent - > class ! = dev - > class ) )
return &dev - > class - >subsys .kobj ;
/* all other devices keep their parent */
else if (parent )
return &parent - >kobj ;
return NULL ;
}
# else
// 在我的ubnutu 8.10中使用的如下函数
static struct kobject *get_device_parent ( struct device *dev ,
struct device *parent )
{
int retval ;
if (dev - > 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 )
parent_kobj = virtual_device_parent (dev ) ; // 获取/sys/devices/virtual目录对应的kobj
else if (parent - > class )
return &parent - >kobj ;
else
parent_kobj = &parent - >kobj ;
/* find our class-directory at the parent and reference it */
spin_lock ( &dev - > class - >class_dirs .list_lock ) ;
// class->class_dirs本身就是一个kset
// 如果该kset的list链表上没有挂接到/sys/devices/virtual目录上的son,那么说明该class_dirs还没有在
// /sys/devices/virtual目录下创建,所以就需要创建该class名对应的目录[luther.gliethttp]
list_for_each_entry (k , &dev - > class - >class_dirs . list , entry )
if (k - >parent = = parent_kobj ) {
kobj = kobject_get (k ) ;
break ;
}
spin_unlock ( &dev - > class - >class_dirs .list_lock ) ;
if (kobj )
return kobj ;
// 创建/sys/devices/virtual/tty这个tty_class对应的目录
/* or create a new class-directory at the parent device */
k = kobject_create ( ) ;
if ( !k )
return NULL ;
k - >kset = &dev - > class - >class_dirs ; // 名在/sys/devices/virtual/目录下创建以tty_class的name为目录名的目录[luther.gliethttp]
retval = kobject_add (k , parent_kobj , "%s" , dev - > class - >name ) ; // 将kobj添加到parent_kobj对应目录下[luther.gliethttp]
if (retval < 0 ) {
kobject_put (k ) ;
return NULL ;
}
/* do not emit an uevent for this simple "glue" directory */
return k ;
}
if (parent )
return &parent - >kobj ;
return NULL ;
}
# endif
如果指定了dev - >parent ,那么同时该dev - >class存在 ,同时parent - >class存在 ,
那么该dev - >name目录将被添加到parent - >class所在目录下 [luther .gliethttp ]
luther@gliethttp : ~ $ ll /sys / class /tty /console
lrwxrwxrwx 1 root root 0 2009 -06 -30 09 :40 /sys / class /tty /console - > . . / . . /devices / virtual /tty /console
luther@gliethttp : ~ $ ll /sys /devices / virtual /tty /console /
total 0
-rw -r - -r - - 1 root root 4 .0K 2009 -06 -30 10 :51 uevent
drwxr -xr -x 2 root root 0 2009 -06 -30 10 :51 power
lrwxrwxrwx 1 root root 0 2009 -06 -30 10 :57 subsystem - > . . / . . / . . / . . / class /tty
-r - -r - -r - - 1 root root 4 .0K 2009 -06 -30 10 :57 dev
来看看linux2 .6 .25内核源码 ,是怎么做得 .
device_create (tty_class , NULL , MKDEV (TTYAUX_MAJOR , 1 ) , "console" ) ;
= = >device_register
= = >device_add
= = >setup_parent
= = >get_device_parent
= = >dev - >kobj .parent = kobj ( "/sys/devices/virtual/tty" ) ; //所以所有的文件添加都将指向该目录[luther.gliethttp]
# ifdef CONFIG_SYSFS_DEPRECATED
static struct kobject *get_device_parent ( struct device *dev ,
struct device *parent )
{
/* class devices without a parent live in /sys/class/<classname>/ */
if (dev - > class & & ( !parent | | parent - > class ! = dev - > class ) )
return &dev - > class - >subsys .kobj ;
/* all other devices keep their parent */
else if (parent )
return &parent - >kobj ;
return NULL ;
}
# else
// 在我的ubnutu 8.10中使用的如下函数
static struct kobject *get_device_parent ( struct device *dev ,
struct device *parent )
{
int retval ;
if (dev - > 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 )
parent_kobj = virtual_device_parent (dev ) ; // 获取/sys/devices/virtual目录对应的kobj
else if (parent - > class )
return &parent - >kobj ;
else
parent_kobj = &parent - >kobj ;
/* find our class-directory at the parent and reference it */
spin_lock ( &dev - > class - >class_dirs .list_lock ) ;
// class->class_dirs本身就是一个kset
// 如果该kset的list链表上没有挂接到/sys/devices/virtual目录上的son,那么说明该class_dirs还没有在
// /sys/devices/virtual目录下创建,所以就需要创建该class名对应的目录[luther.gliethttp]
list_for_each_entry (k , &dev - > class - >class_dirs . list , entry )
if (k - >parent = = parent_kobj ) {
kobj = kobject_get (k ) ;
break ;
}
spin_unlock ( &dev - > class - >class_dirs .list_lock ) ;
if (kobj )
return kobj ;
// 创建/sys/devices/virtual/tty这个tty_class对应的目录
/* or create a new class-directory at the parent device */
k = kobject_create ( ) ;
if ( !k )
return NULL ;
k - >kset = &dev - > class - >class_dirs ; // 名在/sys/devices/virtual/目录下创建以tty_class的name为目录名的目录[luther.gliethttp]
retval = kobject_add (k , parent_kobj , "%s" , dev - > class - >name ) ; // 将kobj添加到parent_kobj对应目录下[luther.gliethttp]
if (retval < 0 ) {
kobject_put (k ) ;
return NULL ;
}
/* do not emit an uevent for this simple "glue" directory */
return k ;
}
if (parent )
return &parent - >kobj ;
return NULL ;
}
# endif