All pastes #2092050 Raw Edit

Mine

public text v1 · immutable
#2092050 ·published 2011-10-20 23:58 UTC
rendered paste body
1)  module code

/* **************** LF339:1.0 s_09/lab6_misc.c **************** */
/*
 * The code herein is: Copyright the Linux Foundation, 2011
 *
 * This Copyright is retained for the purpose of protecting free
 * redistribution of source.
 *
 *     URL:    http://training.linuxfoundation.org
 *     email:  trainingquestions@linuxfoundation.org
 *
 * The primary maintainer for this code is Jerry Cooperstein
 * The CONTRIBUTORS file (distributed with this
 * file) lists those known to have contributed to the source.
 *
 * This code is distributed under Version 2 of the GNU General Public
 * License, which you should have received with the source.
 *
 */
/* 
 * Using the misc API (full solution)
 *
 * Implement your fullest driver from above with the misc API.
 *    
 * Once again a second solution is given which includes the same
 * header file previously used.
 *
@*/

#include <linux/module.h>	/* for modules */
#include <linux/fs.h>		/* file_operations */
#include <linux/uaccess.h>	/* copy_(to,from)_user */
#include <linux/init.h>		/* module_init, module_exit */
#include <linux/slab.h>		/* kmalloc */
#include <linux/miscdevice.h>
#include <linux/mm.h>

#define MYDEV_NAME "mycdrv"

static char *ramdisk;
static size_t ramdisk_size = (16 * PAGE_SIZE);

static int my_map(struct file *file, struct vm_area_struct *vma)
{
	unsigned long pfn, len; 
	printk("in my_map \n");
       /* need to get the pfn for remap_pfn_range -- either of these two follwoing methods will work */

        pfn = virt_to_phys(ramdisk + vma->vm_pgoff) >> PAGE_SHIFT;
	printk("pfn %ld \n", pfn);
	len = vma->vm_end - vma->vm_start;
	printk("length = %ld \n", len); 
        if (remap_pfn_range(vma, vma->vm_start, pfn, len, 
                                     vma->vm_page_prot)) {
		printk("remap failed \n");
                return -EAGAIN;
        }
	printk("map is done \n");
	return 0;
}
static int mycdrv_open(struct inode *inode, struct file *file)
{
	static int counter = 0;
	printk(KERN_INFO " attempting to open device: %s:\n", MYDEV_NAME);
	printk(KERN_INFO " MAJOR number = %d, MINOR number = %d\n",
	       imajor(inode), iminor(inode));
	counter++;

	printk(KERN_INFO " successfully open  device: %s:\n\n", MYDEV_NAME);
	printk(KERN_INFO "I have been opened  %d times since being loaded\n",
	       counter);
	printk(KERN_INFO "ref=%d\n", module_refcount(THIS_MODULE));

	return 0;
}

static int mycdrv_release(struct inode *inode, struct file *file)
{
	printk(KERN_INFO " CLOSING device: %s:\n\n", MYDEV_NAME);
	return 0;
}

static ssize_t
mycdrv_read(struct file *file, char __user * buf, size_t lbuf, loff_t * ppos)
{
	int nbytes, maxbytes, bytes_to_do;
	maxbytes = ramdisk_size - *ppos;
	bytes_to_do = maxbytes > lbuf ? lbuf : maxbytes;
	if (bytes_to_do == 0)
		printk(KERN_INFO "Reached end of the device on a read");
	nbytes = bytes_to_do - copy_to_user(buf, ramdisk + *ppos, bytes_to_do);
	*ppos += nbytes;
	printk(KERN_INFO "\n Leaving the   READ function, nbytes=%d, pos=%d\n",
	       nbytes, (int)*ppos);
	return nbytes;
}

static ssize_t
mycdrv_write(struct file *file, const char __user * buf, size_t lbuf,
	     loff_t * ppos)
{
	int nbytes, maxbytes, bytes_to_do;
	maxbytes = ramdisk_size - *ppos;
	bytes_to_do = maxbytes > lbuf ? lbuf : maxbytes;
	if (bytes_to_do == 0)
		printk(KERN_INFO "Reached end of the device on a write");
	nbytes =
	    bytes_to_do - copy_from_user(ramdisk + *ppos, buf, bytes_to_do);
	*ppos += nbytes;
	printk(KERN_INFO "\n Leaving the   WRITE function, nbytes=%d, pos=%d\n",
	       nbytes, (int)*ppos);
	return nbytes;
}

static loff_t mycdrv_lseek(struct file *file, loff_t offset, int orig)
{
	loff_t testpos;
	switch (orig) {
	case SEEK_SET:
		testpos = offset;
		break;
	case SEEK_CUR:
		testpos = file->f_pos + offset;
		break;
	case SEEK_END:
		testpos = ramdisk_size + offset;
		break;
	default:
		return -EINVAL;
	}
	testpos = testpos < ramdisk_size ? testpos : ramdisk_size;
	testpos = testpos >= 0 ? testpos : 0;
	file->f_pos = testpos;
	printk(KERN_INFO "Seeking to pos=%ld\n", (long)testpos);
	return testpos;
}

static const struct file_operations mycdrv_fops = {
	.owner = THIS_MODULE,
	.read = mycdrv_read,
	.write = mycdrv_write,
	.open = mycdrv_open,
	.release = mycdrv_release,
	.llseek = mycdrv_lseek,
	.mmap = my_map,
};

static struct miscdevice my_misc_device = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = MYDEV_NAME,
	.fops = &mycdrv_fops,
};

static int __init my_init(void)
{
	ramdisk = kzalloc(ramdisk_size, GFP_KERNEL);
	printk("ramdisk %p \n", ramdisk);
	if (misc_register(&my_misc_device)) {
		printk(KERN_WARNING "Culdn't register device misc, "
		       "%d.\n", my_misc_device.minor);
		return -EBUSY;
	}


	printk("ramdisk[0]=%d, ramdisk[1]=%d, ramdisk[8191]=%d, ramdisk[8192]=%d \n",
		ramdisk[0], ramdisk[1], ramdisk[8191], ramdisk[8192]);


	printk(KERN_INFO "\nSucceeded in registering character device %s\n",
	       MYDEV_NAME);
	return 0;
}

static void __exit my_exit(void)
{
	int i;
	misc_deregister(&my_misc_device);
	printk(KERN_INFO "\ndevice unregistered\n");
	//printk("info in ramdisk %s \n", ramdisk);
	printk("ramdisk[0]=%d, ramdisk[1]=%d, ramdisk[8191]=%d, ramdisk[8192]=%d \n",
		ramdisk[0], ramdisk[1], ramdisk[8191], ramdisk[8192]);

	kfree(ramdisk);
}

module_init(my_init);
module_exit(my_exit);

MODULE_AUTHOR("Jerry Cooperstein");
MODULE_LICENSE("GPL v2");



2) test code

/* **************** LF339:1.0 s_18/lab1_ioctl_data_test.c **************** */
/*
 * The code herein is: Copyright the Linux Foundation, 2011
 *
 * This Copyright is retained for the purpose of protecting free
 * redistribution of source.
 *
 *     URL:    http://training.linuxfoundation.org
 *     email:  trainingquestions@linuxfoundation.org
 *
 * The primary maintainer for this code is Jerry Cooperstein
 * The CONTRIBUTORS file (distributed with this
 * file) lists those known to have contributed to the source.
 *
 * This code is distributed under Version 2 of the GNU General Public
 * License, which you should have received with the source.
 *
 */
/*
 * Using ioctl's to pass data (User-space application)
 @*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <sys/mman.h>

struct my_data {
	int i;
	long x;
	char s[256];
} my_data;

#define MYIOC_TYPE 'k'

int main(int argc, char *argv[])
{
	int fd, rc;
	int MY_IOCTL;
	int page_size;
	int abc = 'M';
	char *nodename = "/dev/mycdrv";
	char *uptr = NULL;
	/* open the device node */

	if (argc > 1)
		nodename = argv[1];
	fd = open(nodename, O_RDWR);
	printf(" I opened the device node, file descriptor = %d\n", fd);

	page_size = getpagesize(); 
	printf("page size = %d \n", page_size);
	uptr = mmap(NULL, 2 * page_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	printf("user space ptr %p \n", uptr);
	
	//memcpy(uptr,"SATHYA", 7);
	printf("HAHA is %d \n", abc);

	memset(uptr,abc,8193);

	munmap(uptr, 2 * page_size);
	close(fd);
	

}