⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev.c

📁 在Linux下实现文件的拷贝
💻 C
字号:
#ifndef __KERNEL__#  define __KERNEL__    //按内核模块编译#endif#ifndef MODULE#  define MODULE                //设备驱动程序模块编译#endif#define DEVICE_NAME "MyDev"     #define OPENSPK 1#define CLOSESPK 2                                                                                      //必要的头文件#include <linux/module.h>        /*同kernel.h,最基本的内核模块头文件*/#include <linux/kernel.h>  //同module.h,最基本的内核模块头文件#include <linux/sched.h>  //这里包含了进行正确性检查的宏#include <linux/fs.h>     //文件系统所必需的头文件#include <asm/uaccess.h>  //这里包含了内核空间与用户空间进行数据交换时的函数宏#include <asm/io.h>      //I/O访问int my_major=0;                 //主设备号static int Device_Open=0;static char Message[]="This is from device driver";char *Message_Ptr;int my_open(struct inode *inode, struct file *file){//每当应用程序用open打开设备时,此函数被调用  printk ("\ndevice_open(%p,%p)\n", inode, file);  if (Device_Open)    return -EBUSY;      //同时只能由一个应用程序打开  Device_Open++;  MOD_INC_USE_COUNT;    //设备打开期间禁止卸载  return 0;}static void  my_release(struct inode *inode, struct file *file){//每当应用程序用close关闭设备时,此函数被调用  printk ("\ndevice_release(%p,%p)\n", inode, file);  Device_Open --;  MOD_DEC_USE_COUNT;    //引用计数减1}ssize_t  my_read (struct file *f,char *buf,int size,loff_t off){//每当应用程序用read访问设备时,此函数被调用    int bytes_read=0;       #ifdef DEBUG    printk("\nmy_read is called. User buffer is %p,size is %d\n",buf,size);#endifif (verify_area(VERIFY_WRITE,buf,size)==-EFAULT)     return -EFAULT;        Message_Ptr=Message;        while(size && *Message_Ptr)        {                       if(put_user(*(Message_Ptr++),buf++))    //写数据到用户空间                       return -EINVAL;                size --;                bytes_read++;        }        return bytes_read; }ssize_t my_write (struct file *f,const char *buf, int size,loff_t off){//每当应用程序用write访问设备时,此函数被调用    int i;        unsigned char uc;#ifdef DEBUG    printk("\nmy_write is called. User buffer is %p,size is %d\n",buf,size);#endifif (verify_area(VERIFY_WRITE,buf,size)==-EFAULT) return -EFAULT;        printk("\nData below is from user program:\n");        for (i=0;i<size;i++)                if(!get_user(uc,buf++)) //从用户空间读数据                        printk("%02x ",uc);        return size; }int my_ioctl(struct inode *inod,struct file *f,unsigned int arg1,unsigned int arg2){//每当应用程序用ioctl访问设备时,此函数被调用#ifdef DEBUG    printk("\nmy_ioctl is called. Parameter is %p,size is %d\n",arg1);#endif        switch (arg1){        case OPENSPK:                printk("\nNow,open PC's speaker.\n");                outb(inb(0x61)|3,0x61); //打开计算机的扬声器                break;        case CLOSESPK:                printk("\nNow,close PC's speaker.");                outb(inb(0x61)&0xfc,0x61);//关闭计算机的扬声器                break;}}        struct file_operations my_fops = {    NULL,          /* lseek */    my_read,    my_write,          NULL,          NULL,          my_ioctl,          NULL,          my_open,          my_release,        /* nothing more, fill with NULLs */};int init_module(void){//每当装配设备驱动程序时,系统自动调用此函数    int result;    result = register_chrdev(my_major,DEVICE_NAME,&my_fops);     if (result < 0) return result;    if (my_major == 0)                         my_major = result;           printk("\nRegister Ok. major-number=%d\n",result);          return 0;}void cleanup_module(void){//每当卸载设备驱动程序时,系统自动调用此函数    printk("\nunload\n");                unregister_chrdev(my_major, DEVICE_NAME);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -