linux设备驱动开发入门


linux设备驱动开发入门

1.linux内核模块开发入门

基本步骤

1
2
graph LR;
a(编写内核模块代码)-->b(修改该目录下的Kconfig文件和Makefile)-->c(运行内核模块)
1.实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <linux/kernel.h>
#include <linux/module.h>
/*
__init 和__exit为两个宏
*/
// EXPORT_SYMBOL(gx);(声明符号表,使得该变量或者函数可以被其他模块调用)
int a = 1;
char *b = "hello";
int c[5] = {1,2,3,4,5};
module_param(a,int,0664);//内核模块传参,传参后内核函数可以直接使用这些参数
module_param(b,charp,0664);
module_param(c,int,NULL,0664);
int __init my_init(void)
//init函数必须为int类型
{
printk("just a test for linux kernel module test!\n");
printk("my init linux kernel module is running!\n");
return 0;
}
void __exit my_exit(void)
{
//exit函数必须为void类型
printk("just a test for linux kernel module test!\n");

}
module_init(my_init);
//当该内核模块插入时将会执行my_init函数
module_exit(my_exit);
//当该内核模块移除时将会执行my_exit函数
MODULE_LICENCE("GPL");//指定模块的开源协议
MODULE_AUTHOR("bugprogram-git");//指定模块的作者
MODULE_DESCRIPTION("just a kernel module test");//指定内核模块的详细信息
MODULE_ALIAS("mymodule");//指定模块的别名
//这些MODLE_*的本质其实是定义在static字符数组用于存放指定字符串内容,这些字符串内容链接时存放在.modinfo字段,可以用modinfo命令来查看这些模块信息,用法
modinfo $(MODULE_NAME)//查看某个模块的信息

2.修改模块代码所在的目录的Kconfig文件

1
2
3
4
config MY_MODULE
tristate "this is the linux kernel moule for test"
help
just a test

3.修改该目录下的Makefile文件

1
2
obj-$(CONFIG_MY_MODULE)         += module.o
#(这里的module.o要和.c文件的文件名一致,MY_MODULE要和Kconfig文件里面的指定一致)

4.运行内核模块

1
2
3
4
5
dmesg -C    #清除内核已打印的信息
dmesg #查看内核打印信息
lsmod#显示当前系统已经载入的模块
insmod#将某个模块运行
dmesg#查看内核打印信息

5.linux设备驱动开发

linux内核用设备号来区分不同的设备,设备号是一个32位的无符号整数,dev_t类型,而且设备号可以分为两个部分,

  • 1.主设备号

    占12位

  • 2.次设备号

    占20位

    常用的api

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    MAJOR(dev_t dev);
    //获取设备号的主设备号
    MINOR(dev_t dev);
    //获取设备的次设备号
    MKDEV(int major,int minor);
    //创建一个设备
    int register_chrdev_region(dev_t from,unsigned count,char *name);
    //手动注册一个设备到内核
    int alloc_chrdev_regionda(dev_t *dev,unsigned baseminor,unsigned count,const char *name);

    //只需要主次设备号和fops即可注册设备
    int __register_chrdev(unsigned int major, unsigned int baseminor,
    unsigned int count, const char *name,
    const struct file_operations *fops)
    void unregister_chrdev_region(dev_t from,unsigned count);
    //注销一个设备
    //动态注册一个设备到内核中
    //分配成功后会在/proc/devices中查看到设备号对应的设备名称
    cdev_alloc(void);
    cdev_init(struct cdev *dev,struct file_operations *fops);
    cdev_add(struct cdev *dev,dev_t devnum,unsigned int count);
    cdev_del(struct cdev *dev);
    //将数据从内核空间拷贝到用户空间
    unsigned long copy_to_user(void __user *to,const void *from,unsigned long n);
    unsigned long copy_from_user(void *to,void *from,unsigned long n);

    基本步骤

    1
    2
    graph LR;
    a(申请设备号)-->b(注册设备号)-->c(设置设备对应的file_ops)-->d(将其加入到内核的链表中)

文章作者: 404NotFound
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 404NotFound !
评论
  目录