Linux 驱动模型初探4——汇总和拾遗

1,直接上code

#include <linux/device.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/stat.h>

#include <linux/slab.h>

#include <linux/kobject.h>

#include <linux/kdev_t.h>

//#include "./kf_device.h"

#define KFMAJOR 96

//-----\\class moduel

static struct class kf_class={

.name = "kf-class",

.owner = THIS_MODULE,

};

static int kf_class_register(void){

int ret = -1;

ret = class_register(&kf_class);

//kf_class = class_create(THIS_MODULE,"kfclass");

if(ret < 0){

printk("kf-class register error!\n");

//return kf_class_unregister(&kf_class);

}

printk("kf-class register ok!\n");

return 0;

}

static void kf_class_unregister(void){

class_unregister(&kf_class);

//class_destroy(&kf_class);

}

//------\\bus moduel

static int kf_bus_type_match(struct device *dev, struct device_driver *drv)

{

printk("enter %s\n",__func__);

return 1;

}

/*static int kf_bus_type_probe(struct device *dev){

int ret = -1;

printk("enter %s\n",__func__);

if (dev->driver->probe)

ret = dev->driver->probe(dev);

return ret;

}*/

static void kf_bus_release(struct device *dev){

//need to do

printk("%s\n",__func__);

}

static struct bus_type kf_bus_type = {

.name = "kf-bus-type",

.match = kf_bus_type_match,

//  .probe = kf_bus_type_probe,

};

static struct device kf_bus = {

.init_name = "kf-bus",

.release = kf_bus_release,

};

static int kf_bus_register(void){

int bus_ret = -1;

//kf_bus.class = &kf_class;

bus_ret = device_register(&kf_bus);

if(bus_ret < 0){

printk("bus device reister error!\n");

}

bus_ret = bus_register(&kf_bus_type);

if(bus_ret < 0){

printk("bus type reister error!\n");

}

printk("kf_bus & kf_bus_type register ok\n");

return bus_ret;

}

static void kf_bus_unregister(void){

bus_unregister(&kf_bus_type);

device_unregister(&kf_bus);

}

//-----\\device module

static void kf_device_release(struct device *dev){

printk("%s\n",__func__);

}

static struct device kf_device={

.init_name = "kf-device0",

.devt = MKDEV(KFMAJOR,1),

.release = kf_device_release,

};

static int kf_device_register(void){

int ret = -1;

//Do not point this class

//kf_device.class = &kf_class;

kf_device.bus = &kf_bus_type;

kf_device.parent = &kf_bus;

ret = device_register(&kf_device);

if(ret < 0){

printk("kf device reister error!\n");

}

printk("kf device reister ok!\n");

return ret;

}

static void kf_device_unregister(void){

device_unregister(&kf_device);

}

//------\\driver module

/*

struct kf_device_driver{

char *name;

struct device_driver driver;

};*/

static int kf_device_driver_probe(struct device *dev){

printk("enter drive probe\n");

return 0;

}

static struct device_driver kf_device_driver={

.name = "kf-device-driver",

.probe = kf_device_driver_probe,

};

static int kf_device_dirver_register(void){

int ret = -1;

kf_device_driver.bus = &kf_bus_type;

ret = driver_register(&kf_device_driver);

printk("kf_device_driver reister ok!\n");

return ret;

}

static void kf_device_dirver_unregister(void){

driver_unregister(&kf_device_driver);

}

//-----\\init func

static int __init kf_bus_init(void)

{

int com_ret;

printk(">>>kf_bus_init successed!!\n");

com_ret =kf_class_register();

com_ret = kf_bus_register();

com_ret = kf_device_register();

com_ret = kf_device_dirver_register();

if(com_ret < 0){

printk(">>>kf_bus_register error\n");

//kf_bus_unregister();

}

return 0;

}

static void __exit kf_bus_exit(void)

{

printk(">>>kf_bus_exit successed!!\n");

kf_device_dirver_unregister();

kf_device_unregister();

kf_bus_unregister();

kf_class_unregister();

}

module_init(kf_bus_init);

module_exit(kf_bus_exit);

MODULE_AUTHOR("Koffuxu");

MODULE_LICENSE("GPL");

2,现在已经insmod成功了,纵观一下sys文件系统的各个目录。bus的match成功了,会在device下面有软链接

同时,在driver中?也有软链接。

在bus目录:

在device目录:

在class目录:null。因为没有指定相关bus

3,罗嗦一下,uevent模块

两种方式通知用户层,在Android系统中,这两种方式并存着。这里可以就足够写一篇了

int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,char *envp_ext[])

方式一,

/* send netlink message 实际就是socket通信*/

netlink_broadcast_filtered(uevent_sock, skb, 0, 1, GFP_KERNEL,kobj_bcast_filter, kobj);@af_netlink.c

方式二,

/* call uevent_helper, usually only enabled during early boot 调用uevent_helper函数*/

call_usermodehelper(argv[0], argv,  env->envp, UMH_WAIT_EXEC);@kmod.c

4,UML读图(图画得不好,既然都画了,那还是贴出来吧)

所有的*_private成员与其引用的struct都是相互引用

5,device如何指定某个class?

切记,不要把device bus和stuct device dev指定在一个class,否则会重复建目录导致dev register失败!

像这样提示错误

6,如果指定了某个class(kf-class)之后,这个device就会从sys/device目录移到/sys/device/virtual/kf-class/下面

这是因为在这个函数中操作的。

device_add_class_symlinks(dev);

device_add_attrs(dev);

7,如果使用MKDEV

.devt = MKDEV(KFMAJOR,1),

8,struct device设备必须要实现release函数,否则rmmond会报错

驱动模型小节已经完成。水平有限,时间仓促,肯定有诸多错误,若影响读者有什么疑问,大家一起讨论学习。

有烟吗?我想抽一根。

时间: 2024-10-17 01:57:45

Linux 驱动模型初探4——汇总和拾遗的相关文章

Linux 驱动模型初探3——device

讲device之前,我要引入一个比喻,这个比喻来自一个学长(z2007b).driver是帅哥,device是美女,bus是红娘,bus是提供device和driver配对的场所(方法?).好吧,暂时先这样定,现在要讲的就是美女. 1,老规则,先看看struce device这个美女有哪些特性(成员)和方法 struct device { struct device *parent; struct device_private*p; struct kobject kobj; const char

Linux 驱动模型初探1——BUS

##写在前面的话## 这几篇文章是2011年,当时的老大对我提出的一个"作业".当时研究了一把,完成了第一篇BUS,老大看过之后,表示满意,要我把后面继续完成.然,世事变迁,老大离开了公司,去了其它公司.之后,我也从S公司离开了.所做的工作也有小范围的调整.近期又回到驱动这块,再看到之前的笔记,感慨万千,我决计是要完成搁浅了近3年"作业". 测试代码我已经提交到github上:https://github.com/koffuxu/kornel/tree/dev/dr

Linux 驱动模型初探2——device_driver

1,思考 device_driver也是一个kobject?,但你注意没有,在sys/目录下有bus/,有device/就是没有device_driver/,Y?为什么这么设计? 先看struct devic_driver; struct device_driver { const char *name; struct bus_type *bus; ... int (*probe) (struct device *dev); int (*remove) (struct device *dev);

浅析Linux驱动模型中的底层数据结构kobject和kset

1.kobject Linux内核用kobject来表示一个内核对象.它和Sysfs文件系统联系密切,在内核中注册到系统中的每个kobject对象在sysfs文件系统中对对应着一个文件目录.kobject数据结构通常的用法是嵌入到其对他的数据结构中(即容器,比如cdev结构),用于实现内核对该类数据结构对象的管理.这些数据结构(容器)通过kobject连接起来,形成了一个树状结构. 它在源码中的定义为: /*<include/linux/kobject.h>*/ struct kobject

Linux驱动模型解析bus之platform bus

这是内核启动之后要调用的驱动模型的开始代码: drivers/base/init.c/** * driver_init - initialize driver model. * * Call the driver model init functions to initialize their * subsystems. Called early from init/main.c. */ void __init driver_init(void) { /* These are the core

linux内核驱动模型

linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构成内核对象集,用kset表示,内核对象集也包含自己的内核对象,从而组成层次化的结构.2.用sysfs文件系统导出到用户空间.内核中的所有内核对象组织成树状,以对象属性为叶子.通过sysfs文件系统,将用户空间对文件的读写操作转化为对内核对象属性的显示和保存方法.从而导出内核对象信息,并提供配置接口.

转 Linux设备模型 (1)

作者:wwang 出处:http://www.cnblogs.com/wwang 本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接. 随着计算机的周边外设越来越丰富,设备管理已经成为现代操作系统的一项重要任务,这对于Linux来说也是同样的情况.每次Linux内核新版本的发布,都会伴随着一批设备驱动进入内核.在Linux内核里,驱动程序的代码量占有了相当大的比重.下图是我在网络上搜索到的

Linux 设备模型基本概念

1.设备模型引入 Linux 2.6内核最初为了应付电源管理的需要,提出了一个设备模型来管理所有的设备.在物理上,外设之间是有一种层次关系的,比如把一个U盘插到笔记本上,实际上这个U盘是接在一个USB Hub上,USB Hub又是接在USB 2.0 Host Controller (EHCI)上,最终EHCI又是一个挂在PCI Bus上的设备.这里的一个层次关系是:PCI->EHCI->USB Hub->USB Disk.如果操作系统要进入休眠状态,首先要逐层通知所有的外设进入休眠模式,

Linux 驱动之 platform 驱动模型总结 (基于tiny210 平台 LED 驱动)

1.概述 在一般情况下,2.6内核中已经初始化并挂载了一条platform总线在sysfs文件系统中.那么我们编写platform模型驱动时,需要完成两个工作:1:实现platform驱动 2:实现platform设备,然而在实现这两个工作的过程中还需要实现其他的很多小工作,在后面介绍.platform模型驱动的实现过程核心架构就很简单,如下所示. platform驱动模型三个对象:platform总线.platform设备.platform驱动. platform总线对应的内核结构:struc