Globalmem character device driver implementation under Linux 3.0.35

Source: Internet
Author: User

1, Makefile

kdir=/home/xxx/s-linux-3.0.  * PWD: pwd ) # kernel Modulesobj-M: = globalmem.omodules    :Make-C $ (kdir) m= $ (PWD) Modulesclean :    rm -rf *.o *.ko *.mod.c *.markesr *.order *. Symvers. Phony:modules Clean

2, GLOBALMEM.C

#include <linux/module.h>#include<linux/types.h>#include<linux/fs.h>#include<linux/errno.h>#include<linux/mm.h>#include<linux/sched.h>#include<linux/init.h>#include<linux/cdev.h>#include<linux/slab.h>#include<asm/io.h>#include<asm/system.h>#include<asm/uaccess.h>#defineGlobalmem_size 0x1000//4KB//Create device node in the board side.//mknod/dev/globalmem C 0#defineGlobalmem_major 120//Preset Major number//Define IOCTL cmd#defineGlobalmem_magic 0x01#defineMem_clear _io (globalmem_magic, 0)Static intGlobalmem_major =Globalmem_major;//globalmem structstructGlobalmem_dev {structCdev Cdev;//Cdev structUnsignedCharMem[globalmem_size];//Global Memory};structGlobalmem_dev *GLOBALMEM_DEVP;//device struct InstanceintGlobalmem_open (structInode *inode,structFile *Filp) {        //set device struct pointer to file Privatedata pointerFilp->private_data =GLOBALMEM_DEVP; return 0;}intGlobalmem_release (structInode *inode,structFile *Filp) {    return 0;}Staticssize_t Globalmem_read (structFile *filp,Char__user *buf, size_t size, loff_t*PPOs) {unsignedLongp = *PPOs; unsignedintCount =size; intRET =0; structGlobalmem_dev *dev = filp->private_data;//get device struct pointer//Analysis and get valid read length    if(P >= globalmem_size)//Overflow        return 0; if(Count > Globalmem_size-p)//count is too largeCount = globalmem_size-p; //kernel buf-user buf    if(Copy_to_user (BUF, (void*) (Dev->mem +p), (count)) RET= -Efault; Else {        *ppos + =count; RET=count; PRINTK (Kern_info"read%d bytes from%ld\n", Count, p); }    returnret;}Staticssize_t Globalmem_write (structFile *filp,Const Char__user *buf, size_t size, loff_t*PPOs) {unsignedLongp = *PPOs; unsignedintCount =size; intRET =0; structGlobalmem_dev *dev = filp->private_data;//get device stuct pointer//Analysis and get valid write length    if(P >= globalmem_size)//Write Overflow        return 0; if(Count > Globalmem_size-p)//write count is too largeCount = globalmem_size-p; //user buf-Kernel buf    if(Copy_from_user (Dev->mem +p, buf, Count)) RET= -Efault; Else {        *ppos + =count; RET=count; PRINTK (Kern_info"written%d bytes from%ld\n", Count, p); }    returnret;}Staticloff_t Globalmem_llseek (structFile *filp, loff_t offset,intorig) {loff_t ret=0; Switch(orig) { Case 0://From the file head            if(Offset <0|| ((unsignedint) Offset >globalmem_size)) {ret= -EINVAL;  Break; } FILP->f_pos = (unsignedint) offset; RET= filp->F_pos;  Break;  Case 1://From current position            if((Filp->f_pos + offset) > Globalmem_size | | (Filp->f_pos + offset) <0) {ret= -EINVAL;  Break; } FILP->f_pos + =offset; RET= filp->F_pos;  Break; }    returnret;}Static LongGlobalmem_ioctl (structFile *filp, unsignedintCMD, unsignedLongArg) {    structGlobalmem_dev *dev = filp->private_data;//get device stuct pointer        Switch(cmd) { CaseMem_clear:memset (Dev->mem,0, globalmem_size); PRINTK (Kern_info"Globalmem is set to zero\n");  Break; default:            return-einval;//Not supported    }    return 0;}//file Operations structStatic Const structFile_operations Globalmem_fops ={. Owner=this_module,. Llseek=Globalmem_llseek,. Read=Globalmem_read,. Write=globalmem_write,. Unlocked_ioctl=globalmem_ioctl,. Open=Globalmem_open,. Release=Globalmem_release,};//init and add cdev structStatic voidGlobalmem_setup_cdev (structGlobalmem_dev * Dev,intindex) {    interr; intDevno = MKDEV (Globalmem_major,0); Cdev_init (&dev->cdev, &globalmem_fops); Err= Cdev_add (&dev->cdev, Devno,1); if(Err) printk (Kern_notice"Error%d adding Globalmem", err);}//globalmem device init functionintGlobalmem_init (void){    intresult; dev_t Devno= MKDEV (Globalmem_major,0); //Apply Globalmem Device kernel region    if(globalmem_major) result= Register_chrdev_region (Devno,1,"Globalmem"); Else {            //get major No dynamicallyresult = Alloc_chrdev_region (&devno,0,1,"Globalmem"); Globalmem_major=MAJOR (DEVNO); }    if(Result <0)        returnresult; //apply device struct memoryGLOBALMEM_DEVP = Kmalloc (sizeof(structGlobalmem_dev), Gfp_kernel); if(!GLOBALMEM_DEVP) {Result= -Enomem; GotoFail_malloc; } memset (GLOBALMEM_DEVP,0,sizeof(structGlobalmem_dev)); Globalmem_setup_cdev (GLOBALMEM_DEVP,0); return 0; Fail_malloc:unregister_chrdev_region (Devno,1); returnresult;}//Globalmem device Exit FunctionvoidGlobalmem_exit (void){    //del cdev structCdev_del (&globalmem_devp->Cdev); //Free device struct memoryKfree (GLOBALMEM_DEVP); //Unregister device regionUnregister_chrdev_region (MKDEV (Globalmem_major,0),1); }module_param (Globalmem_major,int, S_irugo); Module_init (Globalmem_init); Module_exit (Globalmem_exit); Module_author ("TT <[email protected]>"); Module_license ("Dual BSD/GPL");

Globalmem character device driver implementation under Linux 3.0.35

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.