本文来源于源linux 3.14.3版本号/lib/kobject.c文件

/**

 * kobject_create_and_add - 动态地创建kobject结构和寄存器sysfs

 *

 * @name: kobject的名称

 * @parent: kobject的parent kobject of this kobject, 假设有的话

 *

 * 该方法动态创建一个kobject结构并注冊到sysfs。当你完毕该结构

 * 之后. 调用kobject_put()。这样该结构在不再使用时将会动态的释放。

*

 * 假设该kobject无法被创建。将会返回NULL。

*/

struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)

{

        struct kobject *kobj;

        int retval;



        kobj = kobject_create();

        if (!kobj)

                return NULL;



        retval = kobject_add(kobj, parent, "%s", name);

        if (retval) {

                printk(KERN_WARNING "%s: kobject_add error: %d\n",  __func__, retval);

                kobject_put(kobj);

                kobj = NULL;

        }

        return kobj;

}

/**

 * kobject_create - 动态创建一个kobject结构

 *

 * 动态创建一个kobject结构。并将其设置为一个带默认释放方法的

 * 动态的kobject。

*

 * 假设无法创建kobject。将会返回NULL。

从这里返回的kobject 结构释放

 * 必须调用kobject_put() 方法而不是kfree(),由于kobject_init()已经被调用

 * 过了。

 */

struct kobject *kobject_create(void)

{

        struct kobject *kobj;



        kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);

        if (!kobj)

                return NULL;



        kobject_init(kobj, &dynamic_kobj_ktype);

        return kobj;

}

/**

 * kobject_init - 初始化一个kobject结构

 * @kobj: 指向要初始化的kobject的指针

 * @ktype: 指向该kobject 的ktype的指针

 *

 * 该方法会正确的初始化一个kobject来保证它能够被传递给kobject_add()

 * 调用.

 *

 * 该功能被调用后,kobject必须通过调用kobject_put()来清理,而不是直接

 * 调用kfree。来保证全部的内存都能够被正确的清理。

*/

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

{

        char *err_str;



        if (!kobj) {

                err_str = "invalid kobject pointer!";

                goto error;

        }

        if (!ktype) {

                err_str = "must have a ktype to be initialized properly!\n";

                goto error;

        }

        if (kobj->state_initialized) {

                /* do not error out as sometimes we can recover */

                printk(KERN_ERR "kobject (%p): tried to init an initialized object, something is seriously wrong.\n", kobj);

                dump_stack();

}



        kobject_init_internal(kobj);

        kobj->ktype = ktype;

        return;



error:

        printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str);

        dump_stack();

}

static void kobject_init_internal(struct kobject *kobj)

{

        if (!kobj)

                return;

        kref_init(&kobj->kref);

        INIT_LIST_HEAD(&kobj->entry);

        kobj->state_in_sysfs = 0;

        kobj->state_add_uevent_sent = 0;

        kobj->state_remove_uevent_sent = 0;

        kobj->state_initialized = 1;

}

/**

 * kobject_add - kobject加入主方法

 * @kobj: 要加入的kobject

 * @parent: 指向父kobject的指针

 * @fmt: kobject带的名称格式

 *

 * 本方法中会设置kobject名称并加入到kobject阶层。

*

 * 假设设置了@parent, 那么@kobj的parent将会被设置为它.

 * 假设 @parent为空, 那么该@kobj的 parent会被设置为与该kobject

 * 相关联的.  假设没有kset分配给这个kobject。那么该kobject会放在

 * sysfs的根文件夹。

 *

 * 假设该方法返回错误。必须调用 kobject_put()来正确的清理该object

 * 相关联的内存。

 * 在不论什么情况下都不要直接通过调用to kfree()来直接释放传递给该方法

 * 的kobject,那样会导致内存泄露。

 *

 * 注意。该调用不会创建"add" uevent, 调用方须要为该object设置好全部

 * 必要的sysfs文件,然后再调用带UEVENT_ADD 參数的kobject_uevent() 

 * 来保证用户控件能够正确的收到该kobject创建的通知。

 */

int kobject_add(struct kobject *kobj, struct kobject *parent,

const char *fmt, ...)

{

        va_list args;

        int retval;



        if (!kobj)

                return -EINVAL;



        if (!kobj->state_initialized) {

                printk(KERN_ERR "kobject '%s' (%p): tried to add an "

                      "uninitialized object, something is seriously wrong.\n",

                kobject_name(kobj), kobj);

                dump_stack();

                return -EINVAL;

        }

        va_start(args, fmt);

        retval =
kobject_add_varg(kobj, parent, fmt, args);

        va_end(args);



        return retval;

}

static int kobject_add_varg(struct kobject *kobj, struct kobject *parent,

   const char *fmt, va_list vargs)

{

        int retval;



        retval = kobject_set_name_vargs(kobj, fmt, vargs);

        if (retval) {

                printk(KERN_ERR "kobject: can not set name properly!\n");

                return retval;

}

        kobj->parent = parent;

        return kobject_add_internal(kobj);

}

/**

 * kobject_set_name_vargs - 设置一个kobject的名称

 * @kobj: 要设置名称的kobject

 * @fmt: 用来构建名称的字符串格式

 * @vargs: 构建字符串的參数

 */

int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,

 va_list vargs)

{

        const char *old_name = kobj->name;

        char *s;



        if (kobj->name && !fmt)

                return 0;



        kobj->name =
kvasprintf(GFP_KERNEL, fmt, vargs);

        if (!kobj->name) {

                kobj->name = old_name;

                return -ENOMEM;

        }





        /* ewww... some of these buggers have '/' in the name ... */

        while ((s = strchr(kobj->name, '/')))

                s[0] = '!';



        kfree(old_name);

        return 0;

}

kobject_add_internal在源代码前面已被粘贴在,有没有再继续贴

kobject_create_and_add的更多相关文章

  1. Linux设备管理(五)_写自己的sysfs接口

    我们在Linux设备管理(一)_kobject, kset,ktype分析一文中介绍了kobject的相关知识,在Linux设备管理(二)_从cdev_add说起和Linux设备管理(三)_总线设备的 ...

  2. Linux驱动学习 —— 在/sys下面创建目录示例

    有时我们需要在/sys下面创建一些目录, 下面给出了一个示例. 在加载驱动模块后, 在/sys下面会创建一个名为sysfs_demo的目录,并在其中在创建几个文件和目录. [root@tiny4412 ...

  3. Linux Device Driver && Device File

    catalog . 设备驱动程序简介 . I/O体系结构 . 访问设备 . 与文件系统关联 . 字符设备操作 . 块设备操作 . 资源分配 . 总线系统 1. 设备驱动程序简介 设备驱动程序是内核的关 ...

  4. linux 驱动入门4

    不吃苦中苦,难为人上人.努力,给老婆孩子提供个良好的生活居住环境.http://www.cnblogs.com/nan-jing/articles/5806399.html上文提到了如何创建proc节 ...

  5. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块

    本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...

  6. 20135220谈愈敏Linux Book_17

    第17章 设备与模块 关于设备驱动和设备管理的四种内核成分: 设备类型:在所有 Unix 系统中为了统一普通设备的操作所采用的分类. 模块: Linux 内核中用于按需加载和卸载目标码的机制. 内核对 ...

  7. linux设备模型_转

    建议原博文查看,效果更佳. 转自:http://www.cnblogs.com/wwang/category/269350.html Linux设备模型 (1) 随着计算机的周边外设越来越丰富,设备管 ...

  8. sysfs接口函数的建立_DEVICE_ATTR(转)

    sysfs接口函数到建立_DEVICE_ATTR 最近在弄Sensor驱动,看过一个某厂家的成品驱动,里面实现的全都是sysfs接口,hal层利用sysfs生成的接口,对Sensor进行操作. 说道s ...

  9. linux内核调试指南

    linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...

随机推荐

  1. 使用BackgroundWorker组件进行异步操作编程

    本文介绍了BackgroundWorker组件的功能及在基于事件的异步操作编程中的应用,并对组件的实现原理进行简述.在应用程序中,可能会遇到一些执行耗时的功能操作,比如数据下载.复杂计算及数据库事务等 ...

  2. JDBC batch批量Statement executeBatch 详细解释

    JDBC提供了数据库batch处理的能力,在数据大批量操作(新增.删除等)的情况下能够大幅度提升系统的性能.我曾经接触的一个项目,在没有採用batch处理时,删除5万条数据大概要半个小时左右,后来对系 ...

  3. jQuery照片伸缩效应,这不是一个简单的图像缩放,它不影响其它元素的布局

    之前在网上看到这样的效果,但我没有收藏夹网址,后来被我不知道如何来实现这种效果. 如今,互联网已收集有关专门.真是功夫不负有心人,被我发现. 我也努力过自己尝试着写: 但仅仅是单纯的图片放大.并且还影 ...

  4. Linux(Centos)中tcpdump参数用法详解(转)

    在linux下进行编程开发的人尤其是网络编程的人会经常需要分析数据包,那么一定会用到tcpdump,下面就是关于tcpdump的使用方法说明(1). tcpdump的选项 -a       将网络地址 ...

  5. cookie在vs又一次run的时候丢失

    今天写个关于http cookie的demo,发现仅仅要vs又一次执行后cookie的值就会丢失,代码例如以下 protected void Page_Load(object sender, Even ...

  6. isset,empty,is_null小知识

    <?php /** 在这项研究开始时,有那么多的人不能很好的运用isset,empty,is_null正确null,false等待值回报值做出正确的推理,在这里,我自己总结通过学习小知识,随后的 ...

  7. 文件搜索神器everything 你不知道的技巧总结

    everything这个软件用了很久,总结了一些大家可能没注意到的技巧,分享给大家 1.指定文件目录搜索示例: TDDOWNLOAD\ abc        在所有TDDOWNLOAD文件夹下搜索包含 ...

  8. Visual Studio 使用及调试必知必会

    原文:Visual Studio 使用及调试必知必会   一:C# CODING 技巧 1:TODO 然后 CTRL + W + T,打开任务列表,选中 Comments,就会显示所有待做的任务 2: ...

  9. 黑马程序猿——java基金会--jdk、变量

    学习内容: 1.Java发展历史 2.jdk和jre的差别,功能. 3.jdk和jre的下载和安装 4.配置环境.path和classpath 5.helloworld程序 6.进制之间的转换 7.凝 ...

  10. C# 字段、属性、成员变量

    引言: C#与java,C++中的这些基本概念略有不同. 由于easy混淆,所以这里总结下差别. 希望能对刚開始学习的人有帮助! 一.定义与作用 1.字段(field):是C#类级别定义的,和方法同一 ...