• linux驱动开发手记【2】


    1、/dev目录下,主设备号和次设备号。ls -l可以通过第一个字母是c或者b区分是字符设备或者是块设备。主设备号标识设备对应的驱动程序。

    2、分配设备编号:

    如果我们提前明确知道所需要的设备编号,则使用

    int  register_chrdev_region(dev_t first,unsigned int count,char * name);

    否则,使用动态分配函数

    int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name);

    3、释放设备编号

    一般,该函数在模块的清除函数中调用

    void unregister_chrdev_region(dev_t first,unsigned int count);
    

    注意:驱动程序应该始终使用alloc_chrdev_region而不是register_chrdev_region函数

    4、需要学习:awk工具和grep命令

    (1)IBM awk教程


    5、分配主设备号的最佳方式:默认采用动态分配,同时保留在加载甚至是编译时指定主设备号的余地。

    // 获取主设备号  
        if(scull_major){  
            dev = MKDEV(scull_major,scull_minor);  
            result = register_chrdev_region(dev,scull_nr_devs,"scull");  
        }else{  
            result = alloc_chrdev_region(&dev,scull_minor,scull_nr_devs,"scull");  
            scull_major = MAJOR(dev);  
        }  
        if(result < 0){  
            printk(KERN_WARNING "scull: can't get major %d /n", scull_major);  
            return result;  
        }  

    6、一些重要的数据结构:file_operations、file和inode,这些数据结构都定义在<linux/fs.h>中

    (1)scull实现file_operations其中的几个最重要的

    // scull设备的文件操作  
    struct file_operations scull_fops = {  
        .owner =    THIS_MODULE,  
        .llseek =   scull_llseek,  
        .read =     scull_read,  
        .write =    scull_write,  
        /*.ioctl =  scull_ioctl,*/  
        .open =     scull_open,  
        .release =  scull_release,  
    };

    (2)file结构代表一个打开的文件描述符

    (3)inode在内部表示文件,i节点

    补推荐直接操作i_rdev,应该使用这两个宏操作获取主设备号和次设备号:

    unsigned int iminor(struct inode *inode);
    unsigned int imajor(struct inode *inode);

    7、(1)open和release

    •            小技巧:container_of的使用。案例:我们通常不需要cdev结构本身,而是需要包含cdev结构的scull_dev结构。由结构体中的成员指针获得结构体的指针。
    •            驱动程序如何才能知道一个打开的设备文件要被真正关闭呢?答:并不是每个close系统调用都会引起对release方法的调用。

    (2)scull的内存使用

    linux内核中用于内存管理的两个核心函数。定义在<linux/slab.h>中

    void *kmalloc(size_t size, int flags);
    void kfree(void *ptr);

    read和write是站在用户空间的角度说的。


    8、一篇IBM开发者社区的文章:linux内核剖析

    9、linux网站,上面有初、中、高等linux教程:linux之家

    10、scull模块全部代码(含注释):基本scull模块代码

    11、编译测试,未实验成功。不过,找到一篇文章点击打开链接,详细介绍了每一个可能的错误和解决方法;

    其中有个错误:‘SPIN_LOCK_UNLOCKED’未声明(不在函数内),在这篇文章中解决了(点击打开链接


    12、scull终于编译通过后,进行了如下实验:

    (1)利用scull_load安装驱动;

    (2)用ls -l /dev/scull查看安装的设备。


    (3)使用cp命令测试


    (4)使用输入/输出重定向测试


    点击打开链接

    (5)使用free命令查看内存变化【未完】

    (6)验证每次读写一个量子【未完】

    13、学习使用strace工具

    (1)strace:用来跟踪进程执行时的系统调用和所接收的信号

    (2)使用strace和gdb调试程序

  • 相关阅读:
    调试 Android* x86 应用程序的方法以及要使用的工具
    android 获取手机信息工具类
    Android 布局自适应屏幕
    php &amp; 和 &amp;amp; (主要是url 问题)
    系统的BIOS与系统安装
    ios的设计原则
    POJ 2409 Let it Bead(Polya简单应用)
    鸿学金信风控具体介绍
    Linux高性能server编程——I/O复用
    WCF问题集锦:未依照DataMember定义的名称序列化对象
  • 原文地址:https://www.cnblogs.com/javaadu/p/11742692.html
Copyright © 2020-2023  润新知