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

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会报错

驱动模型小节已经完成。水平有限,时间仓促,肯定有诸多错误,若影响读者有什么疑问,大家一起讨论学习。
有烟吗?我想抽一根。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可夫小子

感谢大佬!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值