Chinese translated version of Documentation/CodingStyle
If you have any comment or update to the content, please post to LKML directly.
However, if you have problem communicating in English you can also ask the
Chinese maintainer for help. Contact the Chinese maintainer, if this
translation is outdated or there is problem with translation.
Chinese maintainer: ytian
---------------------------------------------------------------------
Documentation/CodingStyle的中文翻译
如果想评论或更新本文的内容,请直接发信到LKML。如果你使用英文交流有困难的话,也可
以向中文版维护者求助。如果本翻译更新不及时或者翻译存在问题,请联系中文版维护者。
中文版维护者:田雨
中文版翻译者:田雨
中文版校译者:田雨
以下为正文
sysfs - _The_ filesystem for exporting kernel objects.
文件系统内核对象的出口。
Patrick Mochel <mochel@osdl.org>
Mike Murphy <mamurph@cs.clemson.edu>
Revised: 16 August 2011修订:2011年8月16日
Original: 10 January 2003初版:2003年1月10日
What it is:它是什么
~~~~~~~~~~~
sysfs is a ram-based filesystem initially based on ramfs. It provides
a means to export kernel data structures, their attributes, and the
linkages between them to userspace.
sysfs是一个基于ram的文件系统最初基于ramfs。它提供了
一个意味着出口内核数据结构,它们的属性,和
它们之间联系到用户空间。
sysfs is tied inherently to the kobject infrastructure. Please read
Documentation/kobject.txt for more information concerning the kobject
interface.
sysfs是天生的kobject挂钩基础设施。请阅读
文档/ kobject。为更多的信息关于三kobject
接口。
Using sysfs
~~使用sysfs~~~~~~~~~
sysfs is always compiled in if CONFIG_SYSFS is defined. You can access
it by doing:
sysfsis总是在编译如果CONFIG_SYSFS被定义。你可以访问
它,通过做:
mount -t sysfs sysfs /sys
Directory Creation创建目录
~~~~~~~~~~~~~~~~~~
For every kobject that is registered with the system, a directory is
created for it in sysfs. That directory is created as a subdirectory
of the kobject's parent, expressing internal object hierarchies to
userspace. Top-level directories in sysfs represent the common
ancestors of object hierarchies; i.e. the subsystems the objects
belong to.
对于每个kobject来说,是在系统中注册,一个目录
为它在系统文件中被创建。该目录是创建一个子目录
的kobject母公司内部对象层次来表达
用户空间。顶级目录sysfs代表共同
祖先的对象层次结构,即属于的子系统对象。
。
Sysfs internally stores a pointer to the kobject that implements a
directory in the sysfs_dirent object associated with the directory. In
the past this kobject pointer has been used by sysfs to do reference
counting directly on the kobject whenever the file is opened or closed.
With the current sysfs implementation the kobject reference count is
only modified directly by the function sysfs_schedule_callback().
Sysfs内部存储的指针,它实现了一个kobject
目录在sysfs_dirent与对象关联的目录。在
过去这个kobject的指针只要文件被打开或关闭已被用于sysfs中做参考
直接计数的kobject。
随着当前的sysfs实现kobject的引用计数
只有直接由的功能sysfs_schedule_callback()修改
. .
Attributes
~~属性~~~~~~~~
Attributes can be exported for kobjects in the form of regular files in
the filesystem. Sysfs forwards file I/O operations to methods defined
for the attributes, providing a means to read and write kernel
attributes.
在
文件系统中属性可以被导出为kobjects常规文件的形式。Sysfs转发文件I / O操作的方法定义
的属性,提供一个意味着读和写内核
属性。
Attributes should be ASCII text files, preferably with only one value
per file. It is noted that it may not be efficient to contain only one
value per file, so it is socially acceptable to express an array of
values of the same type.
ttributes应该ASCII文本文件,最好是只有一个值
每个文件。t是指出,它可能不是有效的,只包含一个
值在每个文件,所以它是社会可接受的表达一组
相同类型的值。
Mixing types, expressing multiple lines of data, and doing fancy
formatting of data is heavily frowned upon. Doing these things may get
you publicly humiliated and your code rewritten without notice.
混合类型,表达多行数据,和做花式
格式化的数据严重不满。做这些事情可以得到
你公开羞辱和代码重写,恕不另行通知。
An attribute definition is simply:
struct attribute {
char * name;
struct module *owner;
umode_t mode;
};
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr);
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr);
A bare attribute contains no means to read or write the value of the
attribute. Subsystems are encouraged to define their own attribute
structure and wrapper functions for adding and removing attributes for
a specific object type.
一个裸属性包含不读或写的价值
属性.子系统是鼓励去定义自己的属性
结构和包装器函数来添加和删除属性
一个特定的对象类型。
.
For example, the driver model defines struct device_attribute like:
例如,驾驶员模型定义结构体设备属性像
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
int device_create_file(struct device *, const struct device_attribute *);
void device_remove_file(struct device *, const struct device_attribute *);
It also defines this helper for defining device attributes:
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
For example, declaring
static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);
is equivalent to doing:
static struct device_attribute dev_attr_foo = {
.attr = {
.name = "foo",
.mode = S_IWUSR | S_IRUGO,
.show = show_foo,
.store = store_foo,
},
};
子系统具体的回调
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a subsystem defines a new attribute type, it must implement a
set of sysfs operations for forwarding read and write calls to the
show and store methods of the attribute owners.
当一个子系统定义了一个新的属性类型,必须执行
组sysfs操作转发读和写调用
显示和存储方法的属性所有者。
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
};
[ Subsystems should have already defined a struct kobj_type as a
descriptor for this type, which is where the sysfs_ops pointer is
stored. See the kobject documentation for more information. ]
子系统应该已经定义了一个struct kobj_type作为
对于这种类型的描述符,这是sysfs行动指针
存储。看到kobject文档了解更多信息。
When a file is read or written, sysfs calls the appropriate method
for the type. The method then translates the generic struct kobject
and struct attribute pointers to the appropriate pointer types, and
calls the associated methods.
当一个文件被读取或写入,sysfs调用适当的方法
的类型。该方法然后翻译kobject通用结构
和结构属性指向相应的指针类型,和
调用相关方法。
To illustrate:说明:
#define to_dev(obj) container_of(obj, struct device, kobj)
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct device_attribute *dev_attr = to_dev_attr(attr);
struct device *dev = to_dev(kobj);
ssize_t ret = -EIO;
if (dev_attr->show)
ret = dev_attr->show(dev, dev_attr, buf);
if (ret >= (ssize_t)PAGE_SIZE) {
print_symbol("dev_attr_show: %s returned bad count\n",
(unsigned long)dev_attr->show);
}
return ret;
}
读/写属性数据
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To read or write attributes, show() or store() methods must be
specified when declaring the attribute. The method types should be as
simple as those defined for device attributes:
o读写属性,显示()或存储()方法必须
当声明指定的属性。该方法类型应该是
这些定义的简单设备属性:
ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
IOW, they should take only an object, an attribute, and a buffer as parameters.
也就是说,他们应该只以一个对象,一个属性和一个缓冲作为参数。
sysfs allocates a buffer of size (PAGE_SIZE) and passes it to the
method. Sysfs will call the method exactly once for each read or
write. This forces the following behavior on the method
implementations:
分配一个缓冲区大小的sysfs(页大小),并将其传递给
法。Sysfs将调用该方法为每个读或执行一次
写。这迫使以下行为的方法
实现:
- On read(2), the show() method should fill the entire buffer.
Recall that an attribute should only be exporting one value, or an
array of similar values, so this shouldn't be that expensive.
在阅读(2),显示()方法应该填满整个缓冲区。
回想一下,一个属性只能出口一个值或一个
一系列类似的值,所以这并不贵。
This allows userspace to do partial reads and forward seeks
arbitrarily over the entire file at will. If userspace seeks back to
zero or does a pread(2) with an offset of '0' the show() method will
be called again, rearmed, to fill the buffer.
他允许用户空间做部分读取和转发寻求
任意在整个文件将。如果用户空间寻求回
零还是一个帖子(2)使用一个偏移的' 0 '这个节目()方法将
又被称为,rearmed,填满缓冲区. .
- On write(2), sysfs expects the entire buffer to be passed during the
first write. Sysfs then passes the entire buffer to the store()
method.
在写(2),sysfs预计整个缓冲区中通过
第一次写。然后通过Sysfs整个缓冲区到商店()
法。
When writing sysfs files, userspace processes should first read the
entire file, modify the values it wishes to change, then write the
entire buffer back.
当编写sysfs文件,用户空间进程应该首先阅读
整个文件,修改值它希望改变,然后编写
整个缓冲区回来。
Attribute method implementations should operate on an identical
buffer when reading and writing values.
属性方法实现应该操作相同
缓冲当阅读和写作值。
Other notes:其他的注释:
- Writing causes the show() method to be rearmed regardless of current
file position.
写作使show()方法rearmed不管电流
文件位置。
- show() methods should return the number of bytes printed into the
buffer. This is the return value of scnprintf().
show()方法应该返回的字节数的印刷
缓冲。这是scnprintf()的返回值。
- show() should always use scnprintf().
show()应该总是使用scnprintf()
- store() should return the number of bytes used from the buffer. If the
entire buffer has been used, just return the count argument.
商店()应该返回的字节数从缓冲区使用。如果
整个缓冲区已经被使用,仅返回计数参数。
- show() or store() can always return errors. If a bad value comes
through, be sure to return an error.
show()或()可以存储总是返回错误。如果一个坏值来
通过,一定要返回一个错误. .
- The object passed to the methods will be pinned in memory via sysfs
referencing counting its embedded object. However, the physical
entity (e.g. device) the object represents may not be present. Be
sure to have a way to check this, if necessary.
对象传递给这个方法将通过sysfs内存中驻留
引用计数其嵌入的对象。然而,物理
实体(如设备)对象表示可能不存在。是
肯定有一种方式来检查这个,如果必要的
A very simple (and naive) implementation of a device attribute is:
一个非常简单的(和天真)实现设备的属性是:
static ssize_t show_name(struct device *dev, struct device_attribute *attr,
char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%s\n", dev->name);
}
static ssize_t store_name(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
snprintf(dev->name, sizeof(dev->name), "%.*s",
(int)min(count, sizeof(dev->name) - 1), buf);
return count;
}
static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);
(Note that the real implementation doesn't allow userspace to set the
name for a device.)
Top Level Directory Layout顶级目录布局
~~~~~~~~~~~~~~~~~~~~~~~~~~
系统文件目录安排公开关系的内核
数据结构。
The top level sysfs directory looks like:
block/
bus/
class/
dev/
devices/
firmware/
net/
fs/
devices/ contains a filesystem representation of the device tree. It maps
directly to the internal kernel device tree, which is a hierarchy of
struct device.
设备/包含一个文件系统表示的设备树。这地图
直接向内部内核设备树,这是一个层次的
结构体装置。
bus/ contains flat directory layout of the various bus types in the
kernel. Each bus's directory contains two subdirectories:
公共汽车/包含平面目录布局的各种总线类型
内核。每个总线的目录包含两个子目录:
devices/
drivers/
devices/ contains symlinks for each device discovered in the system
that point to the device's directory under root/.
设备/包含符号链接为每个设备系统中发现的
指向设备的目录在根/。
drivers/ contains a directory for each device driver that is loaded
for devices on that particular bus (this assumes that drivers do not
span multiple bus types).
司机/包含一个目录中为每一个设备驱动程序被加载
设备在特定总线(这个假设司机不
跨越多个总线类型)。
fs/ contains a directory for some filesystems. Currently each
filesystem wanting to export attributes must create its own hierarchy
below fs/ (see ./fuse.txt for an example).
fs /包含一些文件系统目录。目前每个
文件系统要导出属性必须创建自己的层次结构
低于fs /(见。/保险丝。三为例)。
dev/ contains two directories char/ and block/. Inside these two
directories there are symlinks named <major>:<minor>. These symlinks
point to the sysfs directory for the given device. /sys/dev provides a
quick way to lookup the sysfs interface for a device from the result of
a stat(2) operation.
dev /包含两个目录char /和块/。里面这两个
有符号链接的目录命名为<主要>:<小>。这些符号链接
点到sysfs目录给定装置。/ sys / dev提供
快速查找接口设备的sysfs的结果
一个stat(2)操作。
More information can driver-model specific features can be found in
Documentation/driver-model/.
更多的信息可以驱动模型中可以找到特定的特性
文档/驱动程序模型/。
TODO: Finish this section.
待办事项:完成本节。
Current Interfaces
~当前接口
~~~~~~~~~~~~~~~~~
The following interface layers currently exist in sysfs:
下面的界面层目前存在于sysfs:
- devices (include/linux/device.h)
----------------------------------
Structure:
struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf);
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
};
Declaring:
DEVICE_ATTR(_name, _mode, _show, _store);
Creation/Removal:
int device_create_file(struct device *dev, const struct device_attribute * attr);
void device_remove_file(struct device *dev, const struct device_attribute * attr);
- bus drivers (include/linux/device.h)
--------------------------------------
Structure:
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf);
ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
};
Declaring:
BUS_ATTR(_name, _mode, _show, _store)
Creation/Removal:
int bus_create_file(struct bus_type *, struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);
- device drivers (include/linux/device.h)
-----------------------------------------
Structure:
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *, char * buf);
ssize_t (*store)(struct device_driver *, const char * buf,
size_t count);
};
Declaring:
DRIVER_ATTR(_name, _mode, _show, _store)
Creation/Removal:
int driver_create_file(struct device_driver *, const struct driver_attribute *);
void driver_remove_file(struct device_driver *, const struct driver_attribute *);
Documentation
~文档
~~~~~~~~~~~~
The sysfs directory structure and the attributes in each directory define an
ABI between the kernel and user space. As for any ABI, it is important that
this ABI is stable and properly documented. All new sysfs attributes must be
documented in Documentation/ABI. See also Documentation/ABI/README for more
information.
系统文件目录结构和属性在每个目录定义一个
ABI在内核和用户空间之间。至于任何ABI,这是非常重要的
这是稳定的和正确记录ABI。所有新sysfs属性必须
记录在文档/ ABI。参见文档/ ABI / README更多
信息。