日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux设备驱动模型之 kset原理与实例分析

發布時間:2025/3/21 linux 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux设备驱动模型之 kset原理与实例分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、 Kset

???????kset是具有相同類型的kobject的集合,在sysfs中體現成一個目錄,在內核中用kset數據結構表示,定義為:

struct kset {

struct list_head list; //連接該kset中所有kobject的鏈表頭

spinlock_t list_lock;

struct kobject kobj; //內嵌的kobject

struct kset_uevent_ops *uevent_ops; //處理熱插拔事件的操作集合

}


2、 Kset操作

?????? 1)int kset_register(struct kset *kset)

?????? 在內核中注冊一個kset

?????? 2)void kset_unregister(struct kset *kset)

?????? 從內核中注銷一個kset

3、 熱插拔事件

?????? 在Linux系統中,當系統配置發生變化時,如:添加kset到系統;移動kobject, 一個通知會從內核空間發送到用戶空間,這就是熱插拔事件。熱插拔事件會導致用戶空間中相應的處理程序(如udev,mdev)被調用, 這些處理程序會通過加載驅動程序, 創建設備節點等來響應熱插拔事件。

4、熱插拔事件操作集合

????? Struct kset_uevent_ops {

int (*filter)(struct kset *kset, struct kobject *kobj);

const char *(*name)(struct kset *kset, struct kobject *kobj);

int (*uevent)(struct kset *kset, struct kobject *kobj,

struct kobj_uevent_env *env);

}

kset_uevent_ops這三個函數什么時候調用?

當該kset所管理的kobject和kset狀態發生變化時(如被加入,移動),這三個函數將被調用。(例:kobject_uevent調用)

這三個函數的功能是什么?

?????? 1)filter:決定是否將事件傳遞到用戶空間。如果filter返回0,將不傳遞事件。(例: uevent_filter)

?????? 2)name:用于將字符串傳遞給用戶空間的熱插拔處理程序。

?????? 3)uevent:將用戶空間需要的參數添加到環境變量中。(例:dev_uevent)

5、 kset實例分析

????#include <linux/device.h>
??? #include <linux/module.h>
??? #include <linux/kernel.h>
??? #include <linux/init.h>
??? #include <linux/string.h>
??? #include <linux/sysfs.h>
??? #include <linux/stat.h>
??? #include <linux/kobject.h>

??? MODULE_AUTHOR("yinjiabin");
??? MODULE_LICENSE("GPL");

??? struct kset *kset_p;
??? struct kset kset_c;

??? /* 函數聲明 */
??? void obj_test_release(struct kobject *);
??? ssize_t kobj_test_show(struct kobject *,struct attribute *,char *);
??? ssize_t kobj_test_store(struct kobject *,struct attribute *,const char *,size_t);

??? static struct attribute test_attr =
??? {
??????????? .name = "kobj_config",
??????????? .mode = S_IRWXUGO,
??? };

??? static struct attribute *def_attrs[] =
??? {
??????????? &test_attr,
??????????? NULL,
??? };

??? static struct sysfs_ops obj_test_sysops =
??? {
??????????? .show = kobj_test_show,
??????????? .store = kobj_test_store,
??? };

??? static struct kobj_type ktype =
??? {
??????????? .release = obj_test_release,
??????????? .sysfs_ops = &obj_test_sysops,
??????????? .default_attrs = def_attrs,
};

??? void obj_test_release(struct kobject *kobject)
??? {
??????????? printk("[kobj_test: release!]\n");
??? }

??? ssize_t kobj_test_show(struct kobject *kobject,struct attribute *attr,char *buf)
??? {
??????????? printk("Have show -->\n");
??????????? printk("attrname: %s.\n",attr->name);
??????????? sprintf("buf,%s\n",attr->name);
??????????? return strlen(attr->name) + 2;
??? }

??? ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr, const char *buf,size_t size)
??? {
??????????? printk("Have store -->\n");
??????????? printk("write: %s.\n",buf);
??????????? return size;
??? }

??? static int kset_filter(struct kset *kset,struct kobject *kobj)
??? {
??????? printk("Filter: kobj %s.\n",kobj->name);
??????? return 1;
??? }

??? static const char *kset_name(struct kset *kset,struct kobject *kobj)
??? {
??????? static char buf[20];
??????? printk("Name kobj %s.\n",kobj->name);
??????? sprintf(buf,"%s","kset_name");
??????? return buf;
??? }

??? static int kset_uevent(struct kset *kset,struct kobject *kobj, struct kobj_uevent_env *env)

{
??????? int i = 0;
??????? printk("uevent: kobj %s.\n",kobj->name);

??????? while(i < env->envp_idx)
??????? {
??????????? printk("%s.\n",env->envp[i]);
??????????? i ++;
??????? }

??????? return 0;
??? }

??? static struct kset_uevent_ops uevent_ops =
??? {
??????? .filter = kset_filter,
??????? .name = kset_name,
??????? .uevent = kset_uevent,
??? };


??? static int __init kset_test_init(void)
??? {
??????? int ret = 0;

??????? printk("kset test init!\n");

??????? /* 創建并注冊 kset_p */
??????? kset_p = kset_create_and_add("kset_p",&uevent_ops,NULL);

??????? /* 添加 kset_c 到 kset_p */
??????? kobject_set_name(&kset_c.kobj,"kset_c");
??????? kset_c.kobj.kset = kset_p;

??????? /* 對于較新版本的內核,在注冊 kset 之前,需要 ?
???????????? * 填充 kset.kobj 的 ktype 成員,否則注冊不會成功 */
??????? kset_c.kobj.ktype = &ktype;
??????? ret = kset_register(&kset_c);

??????? if(ret)
??????????? kset_unregister(kset_p);

??????? return 0;
??? }

??? static void __exit kset_test_exit(void)
??? {
??????? printk("kset test exit!\n");
??????? kset_unregister(kset_p);
??????? kset_unregister(&kset_c);

??? }

??? module_init(kset_test_init);
??? module_exit(kset_test_exit);




總結

以上是生活随笔為你收集整理的linux设备驱动模型之 kset原理与实例分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久久久噜噜噜亚洲熟女综合 | 恶虐女帝安卓汉化版最新版本 | 国产精品高潮呻吟久久av野狼 | 波多野结衣小视频 | 男男肉耽高h彩漫 | 日本乱子伦 | 黑人一级黄色片 | 久久77777| 欧美激情图 | 欧美色图亚洲视频 | 日韩欧美中出 | 免费污片网站 | 两女双腿交缠激烈磨豆腐 | 国产吃瓜黑料一区二区 | 欧美日韩啪啪 | 亚州综合网 | 日韩欧美一卡 | www插插插无码免费视频网站 | 欧美福利片在线观看 | 国产精品久久久久影院色老大 | 狠狠操天天操 | 一区两区小视频 | 久草手机在线 | 日韩欧美一区二区在线 | 亚洲AV无码精品国产 | 另类中文字幕 | 中文字幕久久精品 | 欧美日韩一区二区三区在线 | 日本在线视频中文字幕 | 国产又粗又猛又爽又黄无遮挡 | 亚洲欧美v| 国内久久久久 | 先锋影音色 | 欧美在线色视频 | 精品久久国产 | 伊人精品视频在线观看 | 黄色的网站免费看 | 日本美女视频网站 | 欧美黄色三级视频 | 亚洲一卡二卡在线观看 | 国产chinese | 91伊人 | 熟妇高潮一区二区三区在线播放 | 亚洲欧美精品一区二区 | 成人在线观看av | 欧美视频免费看 | 第一区免费在线观看 | 美国少妇性做爰 | 成人av电影天堂 | 久久天天综合 | 久久网站av| 色av一区二区三区 | 欧美一及片 | 黑人性视频| 免费看a| 秋霞av在线 | 老熟妇仑乱一区二区av | 亚洲av人无码激艳猛片服务器 | 在线日韩一区二区 | 中文字幕在线第一页 | 男男做爰猛烈啪啪高 | 亚洲最大的成人网 | 134vcc影院免费观看 | 婷婷久 | 亚洲乱码一区二区 | 日韩毛片一区二区三区 | 欧美国产成人在线 | 日韩在线中文 | 拔萝卜91| 欧美一区二区黄片 | 国产一级二级三级在线 | 国产一区二区三区乱码 | 日韩欧美亚 | 国产精品久久久久久久久免费看 | se综合 | 国产aaaaa毛片 | 欧美a级在线免费观看 | 亚洲国产精品尤物yw在线观看 | 海量av资源 | 性做久久久久久久久久 | xxxx.国产 | 国产精品伦一区二区 | 久久福利片 | 中文字幕亚洲一区二区三区 | 黄色高清视频 | 在线播放视频高清在线观看 | 亚洲男女一区二区三区 | av日韩一区 | 国产在线观看你懂的 | 国产一区欧美二区 | 天天操夜夜操 | 无码人妻精品一区二区蜜桃色欲 | 超碰人人网| 国产露脸150部国语对白 | 深田咏美av在线 | 中文字幕亚洲高清 | 国产字幕侵犯亲女 | 欧美视频一二三区 | 日韩av专区 |