kobj顾名思意,即内核object,其层次表现上为一颗倒置的树,用来管理包括各种驱动模块,核心组件,运行时状态等。在文件系统中,通过sysfs接口绑定kobj节点,来实现对该节点的读写操作。sysfs接口有两种最基本的用途:1,组件的外部操作接口,比如应用可以通过此接口操作设备。2,调试驱动模块,或查看运行时状态。</span>

引言

实现kobj可以对任何形态的组件实现高度抽象,是各种组件的基石,系统中提供了一组API,以方便管理kobj。理解kobj,对后面理解xboot中的各种组件而言有相当大的帮助,建议细心阅读。

kobj节点类型

kobj有两种基本类型,一个是目录,其可以挂接子节点,另一个是文件,代表一颗树的末端,不可拥有子节点,但提供了读或者写该节点的操作,声明如下:

enum kobj_type_t {KOBJ_TYPE_DIR,KOBJ_TYPE_REG,
};

kobj结构体定义

kobj结构体拥有名字,节点类型,父节点指针,当前节点链表,子节点链表头,节点锁,读写接口函数及一个私有数据指针,详细定义如下:

struct kobj_t
{/* kobj name */char * name;/* kobj type DIR or REG */enum kobj_type_t type;/* kobj's parent */struct kobj_t * parent;/* kobj's entry */struct list_head entry;/* kobj's children */struct list_head children;/* kobj lock */spinlock_t lock;/* kobj read */ssize_t (*read)(struct kobj_t * kobj, void * buf, size_t size);/* kobj write */ssize_t (*write)(struct kobj_t * kobj, void * buf, size_t size);/* private data */void * priv;
};

分配kobj节点

其为一内部函数,主要是分配一段内存,然后利用传递的参数进行初始化,并返回分配的kobj节点。

static struct kobj_t * __kobj_alloc(const char * name, enum kobj_type_t type, kobj_read_t read, kobj_write_t write, void * priv)
{struct kobj_t * kobj;if(!name)return NULL;kobj = malloc(sizeof(struct kobj_t));if(!kobj)return NULL;kobj->name = strdup(name);kobj->type = type;kobj->parent = kobj;init_list_head(&kobj->entry);init_list_head(&kobj->children);spin_lock_init(&kobj->lock);kobj->read = read;kobj->write = write;kobj->priv = priv;return kobj;
}

分配目录或文件节点

其为函数为内部函数__kobj_alloc的二次封装,快速分配指定类型的节点。分配一个目录节点实现如下:

struct kobj_t * kobj_alloc_directory(const char * name)
{return __kobj_alloc(name, KOBJ_TYPE_DIR, NULL, NULL, NULL);
}

分配一个文件节点实现如下:

struct kobj_t * kobj_alloc_regular(const char * name, kobj_read_t read, kobj_write_t write, void * priv)
{return __kobj_alloc(name, KOBJ_TYPE_REG, read, write, priv);
}

释放kobj节点

将动态分配的内存进行回收,实现如下:

bool_t kobj_free(struct kobj_t * kobj)
{if(!kobj)return FALSE;free(kobj->name);free(kobj);return TRUE;
}

搜索kobj节点

从一个父节点中搜索一个名为name的子节点。

struct kobj_t * kobj_search(struct kobj_t * parent, const char * name)
{struct kobj_t * pos, * n;if(!parent)return NULL;if(parent->type != KOBJ_TYPE_DIR)return NULL;if(!name)return NULL;list_for_each_entry_safe(pos, n, &(parent->children), entry){if(strcmp(pos->name, name) == 0)return pos;}return NULL;
}

搜索kobj节点,如不存在该子节点则创建之。

与上一个函数类似,不同之处在于未搜索到名为name的子节点时,自动创建一个子节点,该节点为目录类型。

struct kobj_t * kobj_search_directory_with_create(struct kobj_t * parent, const char * name)
{struct kobj_t * kobj;if(!parent)return NULL;if(parent->type != KOBJ_TYPE_DIR)return NULL;if(!name)return NULL;kobj = kobj_search(parent, name);if(!kobj){kobj = kobj_alloc_directory(name);if(!kobj)return NULL;if(!kobj_add(parent, kobj)){kobj_free(kobj);return NULL;}}else if(kobj->type != KOBJ_TYPE_DIR){return NULL;}return kobj;
}

添加kobj节点

将一个节点,可以是目录节点或文件节点,添加至父目录节点,成功返回真,否则返回假。

bool_t kobj_add(struct kobj_t * parent, struct kobj_t * kobj)
{if(!parent)return FALSE;if(parent->type != KOBJ_TYPE_DIR)return FALSE;if(!kobj)return FALSE;if(kobj_search(parent, kobj->name))return FALSE;spin_lock_irq(&parent->lock);spin_lock_irq(&kobj->lock);kobj->parent = parent;list_add_tail(&kobj->entry, &parent->children);spin_unlock_irq(&kobj->lock);spin_unlock_irq(&parent->lock);return TRUE;
}

删除kobj节点

从一个父目录节点中删除一个子节点,为“添加kobj节点”的逆过程。同样,成功返回真,否则返回假。

bool_t kobj_remove(struct kobj_t * parent, struct kobj_t * kobj)
{struct kobj_t * pos, * n;if(!parent)return FALSE;if(parent->type != KOBJ_TYPE_DIR)return FALSE;if(!kobj)return FALSE;list_for_each_entry_safe(pos, n, &(parent->children), entry){if(pos == kobj){spin_lock_irq(&parent->lock);spin_lock_irq(&kobj->lock);pos->parent = pos;list_del(&(pos->entry));spin_unlock_irq(&kobj->lock);spin_unlock_irq(&parent->lock);return TRUE;}}return FALSE;
}

快捷函数之添加目录节点或文件节点

此接口实现的目的是为了快速添加子节点,其根据所传递的参数,自动创建节点并添加到父节点上,添加子目录节点:

bool_t kobj_add_directory(struct kobj_t * parent, const char * name)
{struct kobj_t * kobj;if(!parent)return FALSE;if(parent->type != KOBJ_TYPE_DIR)return FALSE;if(!name)return FALSE;if(kobj_search(parent, name))return FALSE;kobj = kobj_alloc_directory(name);if(!kobj)return FALSE;if(!kobj_add(parent, kobj))kobj_free(kobj);return TRUE;
}

添加子文件节点:

bool_t kobj_add_regular(struct kobj_t * parent, const char * name, kobj_read_t read, kobj_write_t write, void * priv)
{struct kobj_t * kobj;if(!parent)return FALSE;if(parent->type != KOBJ_TYPE_DIR)return FALSE;if(!name)return FALSE;if(kobj_search(parent, name))return FALSE;kobj = kobj_alloc_regular(name, read, write, priv);if(!kobj)return FALSE;if(!kobj_add(parent, kobj))kobj_free(kobj);return TRUE;
}

递归删除节点

此接口会将自身及其所以子节点以递归方式删除:

bool_t kobj_remove_self(struct kobj_t * kobj)
{struct kobj_t * parent;struct kobj_t * pos, * n;bool_t ret;if(!kobj)return FALSE;if(kobj->type == KOBJ_TYPE_DIR){list_for_each_entry_safe(pos, n, &(kobj->children), entry){kobj_remove_self(pos);}}parent = kobj->parent;if(parent && (parent != kobj)){ret = kobj_remove(parent, kobj);if(ret)kobj_free(kobj);return ret;}kobj_free(kobj);return TRUE;
}

根节点

系统启动时,会自动创建一个根节点,名为"kobj",该节点为一个全局静态变量,是顶层目录节点,在mount文件系统时会挂接到sysfs接口。

void do_init_kobj(void)
{__kobj_root = kobj_alloc_directory("kobj");
}

总结

对于如何使用kobj,请参见各种驱动模块的实现,每个驱动模块都含有一个kobj对象,在注册设备时,会依据设备的名称及类型自动创建一组kobj对象。如何通过文件系统访问kobj,则参见虚拟文件系统中的sysfs文件系统的实现。综上所述,kobj API归纳如下:

struct kobj_t * kobj_get_root(void);
struct kobj_t * kobj_search(struct kobj_t * parent, const char * name);
struct kobj_t * kobj_search_directory_with_create(struct kobj_t * parent, const char * name);
struct kobj_t * kobj_alloc_directory(const char * name);
struct kobj_t * kobj_alloc_regular(const char * name, kobj_read_t read, kobj_write_t write, void * priv);
bool_t kobj_free(struct kobj_t * kobj);
bool_t kobj_add(struct kobj_t * parent, struct kobj_t * kobj);
bool_t kobj_remove(struct kobj_t * parent, struct kobj_t * kobj);
bool_t kobj_add_directory(struct kobj_t * parent, const char * name);
bool_t kobj_add_regular(struct kobj_t * parent, const char * name, kobj_read_t read, kobj_write_t write, void * priv);
bool_t kobj_remove_self(struct kobj_t * kobj);

XBOOT核心组件之KOBJ技术详解相关推荐

  1. 【H.264/AVC视频编解码技术详解】十九:熵编码算法(5)——H.264的CABAC(上):语法元素的二值化方法...

    <H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行 ...

  2. Linux磁盘阵列技术详解(二)--raid 1创建

    我在Linux磁盘阵列技术详解(一)里已经详细介绍了几种RAID磁盘阵列方式,原理以及创建raid 0 的详细步骤.那么这篇文档就着重讲解如何创建raid 1的技术: 步骤如下: ① 分区 同样我们还 ...

  3. 《Hadoop技术详解》一导读

    前 言 Hadoop技术详解 本书采用的约定 本书采用以下排版约定. 斜体 用于表明新的术语.URL.电子邮件地址.文件名和文件扩展名. 等宽字体 用于程序清单,正文段落中有关的程序元素,如变量及函数 ...

  4. 科普:5G网络关键技术详解

    不久前,中国华为公司主推的Polar Code(极化码)方案,成为5G控制信道eMBB场景编码方案.消息一出,在网络上就炸开了锅,甚至有媒体用"华为碾压高通,拿下5G时代"来形容这 ...

  5. zookeeper 分布式过程协同技术详解.pdf_阿里大牛耗时18个月整理这份ZooKeeper分布式详解文档...

    前言 摩尔定律揭示了集成电路每18个月计算性能就会增加一倍.随着信息的飞速膨胀,很多应用都无法依赖单个服务器的性能升级来处理如此庞大的数据量,分布式系统和应用越来越受到人们的青睐.分布式系统和应用不仅 ...

  6. Qtum量子链研究院:Plasma技术详解(下篇)

    Plasma的设计模型有两个主要的分支:Plasma MVP(Minimal Viable Plasma,最小可行的Plasma)和Plasma Cash.Plasma MVP的目标是为最基本的可用的 ...

  7. Python数据科学-技术详解与商业实践视频教程

    Python数据科学-技术详解与商业实践(八大案例) 网盘地址:https://pan.baidu.com/s/13QrR_5Er6LgWCWzSb7qOrQ 提取码:s7vw 备用地址(腾讯微云): ...

  8. 视频直播技术详解(8)直播云 SDK 性能测试模型

    <视频直播技术详解>系列之八:直播云 SDK 性能测试模型 牛小七2016年10月12日发布在 视频直播技术详解 七牛云于 6 月底发布了一个针对视频直播的实时流网络 LiveNet 和完 ...

  9. 视频直播技术详解(7)现代播放器原理

    <视频直播技术详解>系列之七:现代播放器原理 牛小七2016年9月29日发布在 视频直播技术详解 from: http://blog.qiniu.com/archives/7040 七牛云 ...

最新文章

  1. 双网口相机平台搭建C++(大恒水星)
  2. python3 post 文件 消息
  3. python缩进的用途和使用方法_如何用Python减少循环层次和缩进的技巧
  4. MySQL主从同步(复制)
  5. 搭建Telnet服务器
  6. python网络编程-一些常用有用的函数
  7. linux安装源码mysql失败,linux停mysql源码安装
  8. pillow 图像 基本概念
  9. CentOS7没有ifconfig命令的解决方法
  10. java kotlin相互调用_Kotlin的互操作——Kotlin与Java互相调用
  11. 四行代码创建复杂(无限级)树
  12. ubuntu14.04安装V-REP和用户使用手册
  13. (8)Python_分割numpy数组
  14. Effective C++中文版
  15. 【MATLAB】三维绘图 三维数据插值
  16. 【DDNS更新】--公云的DDNS自动更新
  17. 2020python二级考试时间_2020年计算机二级考试时间及考试科目
  18. 中国工程院院士、中国人工智能学会理事长李德毅:人工智能研究新进展
  19. 鼠标的光标变成了下划线
  20. 阿里云esc服务器上装hadoop

热门文章

  1. go语言 python哪个好学_go语言和python哪个难
  2. 智障者失踪3年被发现在服刑 家属疑其系顶罪
  3. vue dplayer插件 播放m3u8(直播推流)
  4. android 本地视频分享到朋友圈,Android挂逼修炼之行---微信实现本地视频发布到朋友圈功能...
  5. 人人旗下风车网产品经理的创业失败教训总结【转载】
  6. (思维)1414 冰雕
  7. 修改echarts的x轴y轴的刻度和刻度线文本颜色和xy轴的轴线颜色和标题title的字体颜色
  8. 字节跳动面试官:请你实现一个大文件上传和断点续传
  9. 45岁~55岁的职业发展危机:生存危机
  10. Python编程基础之Python语言的输入输出