Documentation/translations/zh_CN/core-api/kobject.rst

Source file repositories/reference/linux-study-clean/Documentation/translations/zh_CN/core-api/kobject.rst

File Facts

System
Linux kernel
Corpus path
Documentation/translations/zh_CN/core-api/kobject.rst
Extension
.rst
Size
17793 bytes
Lines
380
Domain
Support Tooling And Documentation
Bucket
Documentation
Inferred role
Support Tooling And Documentation: documentation
Status
atlas-only

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct uio_map {
            struct kobject kobj;
            struct uio_mem *mem;
    };

如果你有一个uio_map结构体,找到其嵌入的kobject只是一个使用kobj成员的问题。
然而,与kobjects一起工作的代码往往会遇到相反的问题:给定一个结构体kobject
的指针,指向包含结构体的指针是什么?你必须避免使用一些技巧(比如假设
kobject在结构的开头),相反,你得使用container_of()宏,其可以在 ``<linux/kernel.h>``
中找到::

    container_of(ptr, type, member)

其中:

  * ``ptr`` 是一个指向嵌入kobject的指针,
  * ``type`` 是包含结构体的类型,
  * ``member`` 是 ``指针`` 所指向的结构体域的名称。

container_of()的返回值是一个指向相应容器类型的指针。因此,例如,一个嵌入到
uio_map结构 **中** 的kobject结构体的指针kp可以被转换为一个指向 **包含** uio_map
结构体的指针,方法是::

    struct uio_map *u_map = container_of(kp, struct uio_map, kobj);

为了方便起见,程序员经常定义一个简单的宏,用于将kobject指针 **反推** 到包含
类型。在早期的 ``drivers/uio/uio.c`` 中正是如此,你可以在这里看到::

    struct uio_map {
            struct kobject kobj;
            struct uio_mem *mem;
    };

    #define to_map(map) container_of(map, struct uio_map, kobj)

其中宏的参数“map”是一个指向有关的kobject结构体的指针。该宏随后被调用::

    struct uio_map *map = to_map(kobj);


kobjects的初始化
================

当然,创建kobject的代码必须初始化该对象。一些内部字段是通过(强制)调用kobject_init()
来设置的::

    void kobject_init(struct kobject *kobj, struct kobj_type *ktype);

ktype是正确创建kobject的必要条件,因为每个kobject都必须有一个相关的kobj_type。
在调用kobject_init()后,为了向sysfs注册kobject,必须调用函数kobject_add()::

    int kobject_add(struct kobject *kobj, struct kobject *parent,
                    const char *fmt, ...);

这将正确设置kobject的父级和kobject的名称。如果该kobject要与一个特定的kset相关
联,在调用kobject_add()之前必须分配kobj->kset。如果kset与kobject相关联,则
kobject的父级可以在调用kobject_add()时被设置为NULL,则kobject的父级将是kset
本身。

由于kobject的名字是在它被添加到内核时设置的,所以kobject的名字不应该被直接操作。
如果你必须改变kobject的名字,请调用kobject_rename()::

    int kobject_rename(struct kobject *kobj, const char *new_name);

kobject_rename()函数不会执行任何锁定操作,也不会对name进行可靠性检查,所以调用
者自己检查和串行化操作是明智的选择

有一个叫kobject_set_name()的函数,但那是历史遗产,正在被删除。如果你的代码需
要调用这个函数,那么它是不正确的,需要被修复。

Annotation

Implementation Notes