Linux device-Driven development paradigm, Linux driver example, Linux device driver Detailed example example Song Baohua version of the CD-ROM driver source code, test compilation through the introduction of learning to use __php

Source: Internet
Author: User
/*======================================================================
A Globalmem Driver As an example of char device drivers
There are two same globalmems in this driver
This example was to introduce the function of File->private_data

The initial developer of the original code is Baohua Song
<author@linuxdriver.cn>. All Rights Reserved.
======================================================================*/
#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 <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>


#define GLOBALMEM_SIZE 0x1000/* Global Memory Maximum 4K bytes */
#define MEM_CLEAR 0x1/* Clear 0 global Memory * *
#define GLOBALMEM_MAJOR 254/* Preset GLOBALMEM main device number * *


static unsigned int globalmem_major = globalmem_major;
/*GLOBALMEM Equipment Structure Body * *
struct GLOBALMEM_DEV
{
struct Cdev Cdev; /*CDEV Structure Body * *
unsigned char mem[globalmem_size]; /* Global Memory * *
};


struct Globalmem_dev *globalmem_devp; /* Device Structure body pointer * *
/* File Open function/*
int Globalmem_open (struct inode *inode, struct file *filp)
{
/* Assign the device structure pointer to the file private data pointer.
struct Globalmem_dev *dev;

dev = container_of (inode->i_cdev,struct globalmem_dev,cdev);
Filp->private_data = Dev;
return 0;
}
/* File Release function/*
int globalmem_release (struct inode *inode, struct file *filp)
{
return 0;
}


/* IOCTL Device control function * *
static int globalmem_ioctl (struct inode *inodep, struct file *filp, unsigned
int cmd, unsigned long arg)
{
struct Globalmem_dev *dev = filp->private_data;/* Obtain the device structure body pointer */


Switch (CMD)
{
Case Mem_clear:
memset (dev->mem, 0, globalmem_size);
PRINTK (kern_info "Globalmem is set to zero\n");
Break


Default
Return-einval;
}
return 0;
}


/* Read function * *
Static ssize_t globalmem_read (struct file *filp, char __user *buf, size_t size,
loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct Globalmem_dev *dev = filp->private_data; /* Get the device structure body pointer/*


/* Analyze and obtain valid write length * *
if (P >= globalmem_size)
return count? -enxio:0;
if (Count > Globalmem_size-p)
Count = globalmem_size-p;


/* Kernel space-> User space * *
if (Copy_to_user (buf, (void*) (Dev->mem + P), count)
{
ret =-Efault;
}
Else
{
*ppos + = count;
ret = count;

PRINTK (kern_info "read%d bytes (s) from%lu\n", Count, p);
}


return ret;
}


/* Write function * *
Static ssize_t globalmem_write (struct file *filp, const char __user *buf,
size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct Globalmem_dev *dev = filp->private_data; /* Get the device structure body pointer/*

/* Analyze and obtain valid write length * *
if (P >= globalmem_size)
return count? -enxio:0;
if (Count > Globalmem_size-p)
Count = globalmem_size-p;

/* User space-> kernel space * *
if (Copy_from_user (Dev->mem + p, buf, Count))
ret =-Efault;
Else
{
*ppos + = count;
ret = count;

PRINTK (kern_info "written%d bytes (s) from%lu\n", Count, p);
}


return ret;
}


/* Seek file positioning function * *
Static loff_t globalmem_llseek (struct file *filp, loff_t offset, int orig)
{
loff_t ret = 0;
Switch (orig)
{
Case 0:/* Relative to file start position offset *
if (Offset < 0)
{
ret =-einval;
Break
}
if ((unsigned int) offset > globalmem_size)
{
ret =-einval;
Break
}
Filp->f_pos = (unsigned int) offset;
RET = filp->f_pos;
Break
Case 1:/* Relative file Current position offset */
if ((Filp->f_pos + offset) > Globalmem_size)
{
ret =-einval;
Break
}
if ((Filp->f_pos + offset) < 0)
{
ret =-einval;
Break
}
Filp->f_pos + = offset;
RET = filp->f_pos;
Break
Default
ret =-einval;
Break
}
return ret;
}


/* File operation structure Body * *
static const struct File_operations Globalmem_fops =
{
. Owner = This_module,
. Llseek = Globalmem_llseek,
. Read = Globalmem_read,
. write = Globalmem_write,
. IOCTL = Globalmem_ioctl,
. open = Globalmem_open,
. Release = Globalmem_release,
};


/* Initialize and register cdev*/
static void Globalmem_setup_cdev (struct globalmem_dev *dev, int index)
{
int err, Devno = Mkdev (globalmem_major, index);


Cdev_init (&dev->cdev, &globalmem_fops);
Dev->cdev.owner = This_module;
Dev->cdev.ops = &globalmem_fops;
Err = Cdev_add (&dev->cdev, Devno, 1);
if (ERR)
PRINTK (kern_notice "Error%d adding led%d", err, index);
}


/* Device driver Module loading function * *
int globalmem_init (void)
{
int result;
dev_t Devno = Mkdev (globalmem_major, 0);


/* Apply for equipment number * *
if (globalmem_major)
result = Register_chrdev_region (Devno, 2, "Globalmem");
else/* Dynamic Request device Number * *
{
result = Alloc_chrdev_region (&devno, 0, 2, "Globalmem");
Globalmem_major = Major (Devno);
}
if (Result < 0)
return result;

/* Dynamic request 2 device Structure of memory * *
GLOBALMEM_DEVP = Kmalloc (2*sizeof (struct Globalmem_dev), gfp_kernel);
if (!GLOBALMEM_DEVP)/* Request failed * *
{
result =-Enomem;
Goto Fail_malloc;
}
memset (GLOBALMEM_DEVP, 0, 2*sizeof (struct globalmem_dev));

Globalmem_setup_cdev (&globalmem_devp[0], 0);
Globalmem_setup_cdev (&globalmem_devp[1], 1);
return 0;


Fail_malloc:unregister_chrdev_region (Devno, 1);
return result;
}


/* Module Unload function * *
void Globalmem_exit (void)
{
PRINTK (kern_info "Good bye,mem!\n");
Cdev_del (& (Globalmem_devp[0].cdev));
Cdev_del (& (Globalmem_devp[1].cdev)); /* Logoff cdev*/
Kfree (GLOBALMEM_DEVP); /* release device structure inside the deposit * *
Unregister_chrdev_region (Mkdev (globalmem_major, 0), 2); /* Release Device number * *
}


Module_author ("Song Baohua");
Module_license ("Dual BSD/GPL");


Module_param (globalmem_major, int, s_irugo);


Module_init (Globalmem_init);
Module_exit (Globalmem_exit);

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.