将添加的系统调用写成一个内核模块_2.制作第一个驱动程序

先讲解驱动框架,然后写出first_drv驱动程序,来打印一些信息

写出first_drv驱动程序需要以下几步:

(1)写出驱动程序first_drv_open first_drv_write

(2)需要定义file_operations结构体来封装驱动函数first_drv_open first_drv_write

对于字符设备来说,常用file_operations以下几个成员:

8a7d36d05f268be89041147f97254c94.png

(3) 模块加载函数,通过函数 register_chrdev(major, “first_drv”, &first_drv_fops) 来

注册字符设备

(4)写驱动的first_drv_init 入口函数来调用这个register_chrdev()注册函数,

(5)通过module_init()来修饰入口函数,使内核知道有这个函数

(6)写驱动的first_drv_exit出口函数,调用这个unregister_chrdev()函数卸载,

(7) 通过module_exit()来修饰出口函数

(8) 模块许可证声明, 最常见的是以MODULE_LICENSE( "GPL v2" )来声明

1.首先创建first_drv.c文件

代码如下:

#include #include #include #include #include #include #include #include #include #include  /*1写出驱动程序first_drv_open first_drv_write *//* inode结构表示具体的文件,file结构体用来追踪文件在运行时的状态信息。*/static int first_drv_open(struct inode *inode, struct file *file){ printk(“first_drv_open”); //打印,在内核中打印只能用printk() return 0;}/*参数filp为目标文件结构体指针,buffer为要写入文件的信息缓冲区,count为要写入信息的长度,ppos为当前的偏移位置,这个值通常是用来判断写文件是否越界*/static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos){ printk(“first_drv_write”); //打印,在内核中打印只能用printk() return 0;} /*2定义file_operations结构体来封装驱动函数first_drv_open first_drv_write */ static struct file_operations first_drv_fops = { .owner = THIS_MODULE, //被使用时阻止模块被卸载 .open = first_drv_open,  .write = first_drv_write,  }; /*4写first_drv_init入口函数来调用这个register_chrdev()注册函数*/int first_drv_init(void){ /*3 register_chrdev注册字符设备,并设置major=111*/ /*如果设置major为0,表示由内核动态分配主设备号,函数的返回值是主设备号*/register_chrdev (111, “first_drv”, &first_drv_fops); //111:主设备号,”first_drv”:设备名/*register_chrdev作用:在VFS虚拟文件系统中找到字符设备,然后通过主设备号找到内核数组里对应的位置,最后将设备名字和fops结构体填进去*/ return 0;}/*5 module_init修饰入口函数*/module_init(first_drv_init); /*6 写first_drv_exit出口函数*/void first_drv_exit(void){unregister_chrdev (111, “first_drv”); //卸载驱动,只需要主设备号和设备名就行 }/*7 module_exit修饰出口函数*/module_exit(first_drv_exit);/*8许可证声明, 描述内核模块的许可权限,如果不声明LICENSE,模块被加载时,将收到内核被污染 (kernel tainted)的警告。*/MODULE_LICENSE( "GPL v2" );

2然后写Makefile编译脚本:

KERN_DIR = /work/system/linux-2.6.22.6 //依赖的内核目录,前提内核是编译好的 all:  make -C $(KERN_DIR) M=`pwd` modules // M=`pwd`:指定当前目录//make -C $(KERN_DIR) 表示将进入(KERN_DIR)目录,执行该目录下的Makefile//等价于在linux-2.6.22.6目录下执行: make M=(当前目录) modules// modules:要编译的目标文件  clean: make -C $(KERN_DIR) M=`pwd` modules clean rm -rf modules.orderobj-m += frist_drv.o //obj-m:内核模块文件,指将myleds.o编译成myleds.ko

3. make,编译生成frist_drv.ko文件

ca27c617d945d04c985ca988724384d1.png

4.然后开发板通过nfs网络文件系统来加载frist_drv.ko

加载之前首先通过 cat /proc/devices来查看字符主设备号111是否被占用

7647215a843a666a62d59b5928ae387e.png

然后通过 insmod first_drv.ko来挂载, 通过 cat /proc/devices就能看到first_drv已挂载好

60eb8769aca18f378ccc9f0cfea4e1b1.png

5.通过测试程序测试frist_drv模块

测试程序first_driver_text.c代码如下

#include  //调用sys目录下types.h文件#include  //stat.h获取文件属性#include #include /*输入”./first_driver_text”, agc就等于1, argv[0]= first_driver_text *//*输入”./first_driver_text on”, agc就等于2, argv[0]= first_driver_text,argv[1]=on; */int main(int argc,char **argv) {int fd1, fd2;int val=1;fd1 = open("/dev/xxx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值