ldd3-3-scull.1设备的加载卸载

/***************************************************************************************************
                                            scull模块加载卸载
实验步骤:
    #make
    #insmod scull2.ko
    #gcc user2.c
    #./a.out        看返回是成功还是失败即可。
    #rmmod scull2

    注,都在root权限下进行。 若make报找不到函数,是版本问题。需要换函数即可。
    张永辉 2012年10月9日
***************************************************************************************************/

/***************************************************************************************************
                                    用户使用函数
user2.c
***************************************************************************************************/
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>

int main(void)
{
    int fd, num,ret;

    fd = open("/dev/scull0", O_RDWR, S_IRUSR | S_IWUSR);
    printf("fd = %d \n",fd);

    if (fd != -1 )
    {
        printf("scull0 Device open secuss !\n");
       
        close(fd);
    }else
    {
        printf("scull0 Device open failure !\n");
    }
    return 0;
}

/***************************************************************************************************
                                        scull2.h
***************************************************************************************************/
#ifndef _SCULL_H_
#define _SCULL_H_
/***************************************************************************************************
                                    常量定义
***************************************************************************************************/
#ifndef     SCULL_MAJOR
    #define SCULL_MAJOR 0           //dynamic major by default 缺省的主设备号
#endif

#ifndef     SCULL_NR_DEVS
    #define SCULL_NR_DEVS 4         // scull0 1 2 3
#endif

#ifndef     SCULL_QUANTUM           //量子大小,单位字节
    #define SCULL_QUANTUM 400
#endif

#ifndef     SCULL_QSET              //量子集大小
    #define SCULL_QSET    100
#endif
/***************************************************************************************************
                                    数据结构定义
***************************************************************************************************/
/*                                  scull 数据模型
    是一个结构,见下表。

scull_qset是一个链表结构
    一个指针指向下一个结构。
    一个指针指向一个量子集。
        量子集是n=1000个指针的数组,每个指针指向一块内存,此内存有m=4000字节大。一块内存即是以个量子。
两模型如下:*/
struct scull_qset
{
    void **data;
    struct scull_qset *next;
};

struct scull_dev {
    struct scull_qset *data;  // Pointer to first quantum set   指向第一个 scull_qset结构
    int quantum;              // the current quantum size       一个量子的大小,  默认4000
    int qset;                 // the current array size         一个量子集的个数,默认1000
    unsigned long size;       // amount of data stored here     保存了的数据总数
    unsigned int access_key;  // used by sculluid and scullpriv
    struct semaphore sem;     // mutual exclusion semaphore     信号量
    struct cdev cdev;         // Char device structure          设备
};

/***************************************************************************************************
                                    全局变量声明
***************************************************************************************************/
//声明在 scull.c 的全局变量

/***************************************************************************************************
                                    函数声明
***************************************************************************************************/
//-------------------------------file_operations 操作函数声明---------------------------------------
    //-------------------------------供调用的函数声明-----------------------------------------------
//**************************************************************************************************
#endif

/***************************************************************************************************
                                            scull2.c
***************************************************************************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>               /* everything...    */
#include <linux/kernel.h>
#include <asm/uaccess.h>            /* copy_*_user      */
#include <linux/cdev.h>             //cdev
#include <linux/types.h>            /* size_t           */
#include <linux/slab.h>             /* kmalloc()        */
#include <linux/device.h>           //class_create

//#include <linux/moduleparam.h>
#include <linux/errno.h>            /* error codes      */
#include <linux/proc_fs.h>
//#include <linux/fcntl.h>          /* O_ACCMODE        */
//#include <linux/seq_file.h>
//#include <asm/system.h>           /* cli(), *_flags   */


#include "scull2.h"
MODULE_LICENSE("Dual BSD/GPL");
/***************************************************************************************************
                            全局变量声明
***************************************************************************************************/

dev_t   scull_num;                              //  设备号
int     scull_major     =   SCULL_MAJOR;        //主设备号   scull.h #define=0
int     scull_minor     =   0;                  //次设备号

int     scull_quantum   =   SCULL_QUANTUM;      //量子大小 = 400
int     scull_qset      =   SCULL_QSET;         //量子集大小 = 100

struct  scull_dev       *scull_devices=NULL;    //在 scull_init_module 分配的设备存储区
static  struct class    *scull_class=NULL;

/***************************************************************************************************
                            file_operations 函数实现
***************************************************************************************************/
static ssize_t scull_read(struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
    return 0;
}
static ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
    return 0;
}

//初始化设备的file_operations结构体,必须的。  此结构
struct file_operations scull_fops =
{
    .read =     scull_read,
    .write =    scull_write,
   
};

/***************************************************************************************************
                            注册和注销模块
***************************************************************************************************/
static int scull_init_module(void)
{
    int result;
    printk(KERN_WARNING "scull2 initing ... \n");

    //------------------注册设备号:scull2----------------------------------------------------------
    result = alloc_chrdev_region(&scull_num, scull_minor, 1,"scull2");
    if(result < 0)
    {
        printk(KERN_WARNING "alloc_chrdev_region error \n");
        return result;
    }
    scull_major = MAJOR(scull_num);
    printk(KERN_WARNING "scull_num = %d \n",scull_num);
    printk(KERN_WARNING "scull_major = %d \n",scull_major);

    //分配存储空间给scull_devices, 也给dev分配了空间。
    scull_devices =  kmalloc( 1*sizeof(struct scull_dev), GFP_KERNEL);
    if (!scull_devices)
    {
        printk(KERN_WARNING "kmalloc scull_devices error");
        result = -ENOMEM;
        goto err1;
    }
    memset(scull_devices, 0, 1 * sizeof(struct scull_dev));     //初始化空间

    //------------------初始化cdev并添加到系统------------------------------------------------------
    cdev_init(&scull_devices->cdev, &scull_fops);
    scull_devices->cdev.owner = THIS_MODULE;

    result = cdev_add(&scull_devices->cdev, scull_num, 1);
    if (result)
    {
        printk(KERN_NOTICE "cdev_add error! \n");
        goto err2;
    }
    //-------------------创建设备节点---------------------------------------------------------------
    scull_class = class_create(THIS_MODULE, "scull_class2");//在/sys目录下建立了一个scull_class2的目录
    if (IS_ERR(scull_class))
    {
        printk(KERN_INFO "gvar_class2 create error\n");
        goto err3;
        //class_destroy(gvar_class);
    }

    class_device_create(scull_class,NULL,scull_num,NULL,"scull" "%d", MINOR(scull_num));
    if(0)
    {   printk(KERN_INFO "device_create error\n");
        goto err4;
        //class_device_destroy()
    }

    printk(KERN_INFO "create device suess !\n");
    return 0;
    //------------------失败处理:所有操作将回退----------------------------------------------------
    err4:
        class_destroy(scull_class);
    err3:
        cdev_del(&scull_devices->cdev);
    err2:
        kfree(scull_devices);
    err1:
        unregister_chrdev_region(scull_num,1);
    return result;
}

static void scull_cleanup_module(void)
{
    class_device_destroy(scull_class,scull_num);
    if(scull_class != NULL)
    {
        class_device_destroy(scull_class, scull_num);
        class_destroy(scull_class);
    }

    if(&scull_devices->cdev != NULL)
    {
        cdev_del(&scull_devices->cdev);
    }

    unregister_chrdev_region(scull_num,1);
    printk(KERN_WARNING "scull goodbye! \n");
}

module_init(scull_init_module);
module_exit(scull_cleanup_module);


 

obj-m := scull2.o                                    #模块编译的目标必须以obj-m 这样的形式指出
KERNELDIR ?= /lib/modules/$(shell uname -r)/build       #模块的编译必须指定内核源代码的路径

PWD := $(shell pwd)
modules:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules            #本行开头必须使用 Tab 键
modules_install:
 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clearn:
 rm -rf *.o *.ko *mod.o [mM]odule* .*.cmd .tmp_versions


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值