linux驱动学习示例

来源:互联网 发布:淘宝 企业店铺转让 编辑:程序博客网 时间:2024/06/11 19:32


driver.c

#include <linux/init.h>#include <linux/kernel.h>//  /usr/src/linux-headers-4.13.0-17#include "linux/module.h"#include <linux/types.h>#include <linux/fs.h> //file_operations#include <linux/cdev.h> //cdev#include <linux/slab.h> //kmalloc kfree#include <linux/uaccess.h> //copy_to_user copy_from_user#include <linux/ip.h>#include <linux/tcp.h>#include <linux/netfilter_ipv4.h>#include <linux/netfilter.h>#include <linux/sched.h>#include <linux/nsproxy.h>#include <net/net_namespace.h> //init_net变量在其中/******************************* Define Constant Macro ******************/#ifndef DEVICE_NAME#define DEVICE_NAME "KeyboardTouches"#endif#ifndef MINOR_COUNT#define MINOR_COUNT 1#endif#ifndef RECV_SIZE#define RECV_SIZE  512#endif/*******************************回调函数声明*********************************/ssize_t fileRead(struct file *pFile,char __user *buffer,size_t count,loff_t *offset);ssize_t fileWrite(struct file *pFile,const char __user *buffer,size_t count,loff_t *offset);struct file_operations fop= {.owner=THIS_MODULE,.llseek=NULL,.open=NULL,//.ioctl=NULL,.release=NULL,.read=fileRead,.write=fileWrite,.release=NULL};/**************************变量定义*************************/char *recvBuffer=NULL;int result=0;static struct nf_hook_ops nfhop;struct cdev device;dev_t deviceNo;struct net_device *nd;/************************** Function: filterSocket******************************/unsigned int filterSocket(void *priv,struct sk_buff *skb,const struct nf_hook_state *state){  printk(KERN_INFO "%s execute in driver:%s .\n",__FUNCTION__,DEVICE_NAME);  //无条件丢包,阻断一切与外界的联系  return NF_DROP;}int fileOpen(struct inode *node,struct file *pFile){  return 0;}/******************************* Function: fileRead**************************/ssize_t fileRead(struct file *pFile,char __user *buffer,size_t count,loff_t *offset){  result=copy_to_user(buffer,recvBuffer,count);  if (result<0) {    //只有加了换行符之后才能立刻在控制台输出    printk(KERN_INFO "Read buffer from device failed with error code:%d\n",result);    return result;  }  return 0;}/******************************   Function: fileWrite ***********************/ssize_t fileWrite(struct file *pFile,const char __user *buffer,size_t count,loff_t *offset){  if (count>=RECV_SIZE) {    printk_deferred(KERN_ALERT "Write to device data quantity (%d Bytes) is more than recieve buffer size (%d Bytes).\n",count,RECV_SIZE);    return 0;  }  printk(KERN_ALERT "Write length:%ld\n",count);  result=copy_from_user(recvBuffer,buffer,count);  if (result<0) {    printk(KERN_INFO "Write to device failed with error code:%d\n",result);    return result;  }  return 0;}/******************************** Function: fileClose ***********************/int fileClose(struct inode *node,struct file *pFile){  return 0;}/****************************** Function: startDriver **********************/static int __init startDriver(void){  //初始化nfhop  recvBuffer=kmalloc(RECV_SIZE,GFP_KERNEL);  //申请设备号  result=alloc_chrdev_region(&deviceNo,0,MINOR_COUNT,DEVICE_NAME);  if (result<0) {    printk(KERN_INFO "Allocate character device number failed!\n");    return result;  }  printk(KERN_INFO "Allocate device suceeded! Master: %d, Slave:%d\n",MAJOR(deviceNo),MINOR(deviceNo));  //对设备与文件操作进行绑定  cdev_init(&device,&fop);  //对设备与dev_t进行绑定  result=cdev_add(&device,deviceNo,MINOR_COUNT);  if (result<0) {    //注册字符设备    unregister_chrdev_region(deviceNo,MINOR_COUNT);    printk(KERN_INFO "Add device to system failed! Unregister Master: %d, Slave:%d\n",MAJOR(deviceNo),MINOR(deviceNo));    return result;  }  //注册网络钩子进行丢包操作  //获得当前网卡设备,这里的名称可以通过ifconfig获得,此处为enp8s0  nd=dev_get_by_name(current->nsproxy->net_ns, "enp8s0"); //current->nsproxy->net_ns用&init_net代替也是可以的  printk(KERN_INFO "Get net device %s in kernel.\n",nd->name);  //配置钩子  nfhop.hook=filterSocket;  nfhop.pf=PF_INET;  nfhop.hooknum=NF_INET_PRE_ROUTING,  nfhop.priority=NF_IP_PRI_FIRST;  nfhop.dev=nd;  //注册网络钩子  nf_register_net_hook(current->nsproxy->net_ns,&nfhop);  printk(KERN_INFO "the driver %s is started.\n",__FUNCTION__);  return 0;}/******************************* Function: exitDriver **************************/static void __exit exitDriver(void) {  nf_unregister_net_hook(current->nsproxy->net_ns,&nfhop);  //释放堆上的内存防止泄漏  if (recvBuffer!=NULL) {    kfree(recvBuffer);  }  //删除设备  cdev_del(&device);  //回收设备号  unregister_chrdev_region(deviceNo,MINOR_COUNT);  printk(KERN_INFO "the driver %s  exited.\n",__FUNCTION__);}/**************************** 例行公事 *******************************************/module_init(startDriver);module_exit(exitDriver);MODULE_LICENSE("GPL");MODULE_AUTHOR("MOU MOU MOU");

Makefile

ifneq ($(KERNELRELEASE),)obj-m +=driver.oelseKDIR = /lib/modules/$(shell uname -r)/builddefault:$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modulesendifclean:rm -rf *.o *.ko *.modrm -rf .temp.versionsrm *.orderrm -f .driver.o.cmdrm -f .driver.ko.cmdrm -f .driver.mod.o.cmdrm -f driver.mod.c



原创粉丝点击