Write the CMOS driver module step by step
Let's implement a char driver to access the system CMOS.
The first step is to create a device module, which is the simplest, similar to the previous Hello World module.
/************************************************************code writer : EOFcode date : 2014.08.15code file : cmos_demo.ce-mail:[email protected]code purpose:This code is a demo for how to build a CMOS-driverstep by step.If there is something wrong with my code, please touchme by e-mail. Thank you.************************************************************/#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/fs.h>#include <linux/init.h> #include <linux/cdev.h> #include <linux/slab.h> /* kmalloc() */#include <linux/kernel.h> /* printk */#include <linux/device.h>#include <linux/ioport.h>#include <linux/kdev_t.h>int cmos_major = 0;//defualtint cmos_minor = 0;module_param(cmos_major,int,S_IRUGO);module_param(cmos_minor,int,S_IRUGO);//static dev_tcmos_dev_number;/* Allocated device number */struct class*cmos_class;/* Tie with the device model */#define NUM_CMOS_BANKS2#define CMOS_BANK_SIZE(0xFF*8)#define DEVICE_NAME"Jason_cmos"#define CMOS_BANK0_INDEX_PORT0x70#define CMOS_BANK0_DATA_PORT0x71#define CMOS_BANK1_INDEX_PORT0x72#define CMOS_BANK1_DATA_PORT0x73unsigned char addrports[NUM_CMOS_BANKS] = {CMOS_BANK0_INDEX_PORT,CMOS_BANK1_INDEX_PORT};unsigned char dataports[NUM_CMOS_BANKS] = {CMOS_BANK0_DATA_PORT,CMOS_BANK1_DATA_PORT};MODULE_AUTHOR("Jason Leaster");MODULE_LICENSE("Dual BSD/GPL");struct cmos_dev{unsigned short current_pointer; /*Current point within the bank*/unsigned int size;/*size of the bank*/int bank_number;/*Size of bank*/struct cdev cdev;char name[10];/*Name of I/O regeion*//* ... */}*cmos_devp; static struct file_operations cmos_fops = {.owner=THIS_MODULE,};int cmos_init(void){int i;dev_t dev = 0;if(alloc_chrdev_region(&dev,cmos_minor,NUM_CMOS_BANKS,DEVICE_NAME) < 0){printk(KERN_DEBUG "Can't regiester device\n");return -1;}cmos_major = MAJOR(dev);/*********I don't know what this is************/cmos_class = class_create(THIS_MODULE,DEVICE_NAME);release_region(0x70,0x8);for(i = 0;i < NUM_CMOS_BANKS;i++){cmos_devp = kmalloc(sizeof(struct cmos_dev),GFP_KERNEL);if(!cmos_devp){printk("Bad Kmalloc\n");return 1;}sprintf(cmos_devp->name,"cmos%d",i);if(!(request_region(addrports[i],2,cmos_devp->name))){printk("cmos: I/O port 0x%x is not free.\n",addrports[i]);return -EIO;}cmos_devp->bank_number = i;cdev_init(&cmos_devp->cdev,&cmos_fops);cmos_devp->cdev.owner = THIS_MODULE;if(cdev_add(&cmos_devp->cdev,(dev + i),1)){printk("Bad cdev\n");return 1;}device_create(cmos_class,NULL,(dev + i),NULL,"cmos%d",i);}printk("CMOS Driver Initialized.\n");return 0;}void cmos_cleanup(void){int i;dev_t devno = MKDEV(cmos_major,cmos_minor);cdev_del(&cmos_devp->cdev);unregister_chrdev_region(devno,NUM_CMOS_BANKS);for(i = 0;i < NUM_CMOS_BANKS;i++){device_destroy(cmos_class,MKDEV(MAJOR(devno),i));release_region(addrports[i],2);}class_destroy(cmos_class);return ;}module_init(cmos_init);module_exit(cmos_cleanup);
The implementation of open, writer, read, and release is only part of the registration module. However, it feels good ~
To be updated...
Ordinary, on the road