Monday 26 May 2014

Write sample character driver, allocate buffer in open call and free buffer in release call o Allocation using page API o Allocation using kmalloc api o Allocation using vmalloc• Write sample character driver, use the above buffer in read and write call • Write sample character driver, implement IOCTL command to allocate buffer • Write sample character driver, implement IOCTL command to allocate buffer using kmalloc o Implement IOCTL command to read data from user space into allocated kernel buffer o Implement IOCTL command to write data from the kernel buffer into user buffer • Write sample character driver allocate buffer in open call and store it into file->private_data pointer. o Use the private_data pointer inside read() and write() call

Assignment 11

• Write sample character driver, allocate buffer in open call and free buffer in release call
o Allocation using page API
o Allocation using kmalloc api
o Allocation using vmalloc• Write sample character driver, use the above buffer in read
and write call
• Write sample character driver, implement IOCTL command to allocate buffer
• Write sample character driver, implement IOCTL command to allocate buffer using
kmalloc
o Implement IOCTL command to read data from user space into allocated kernel buffer
o Implement IOCTL command to write data from the kernel buffer into user buffer
• Write sample character driver allocate buffer in open call and store it into
file->private_data pointer.
o Use the private_data pointer inside read() and write() call


driver.c

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/capability.h>
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include<linux/vmalloc.h>
#include<linux/slab.h>
char *bufk,*bufk1,*bufk2,*bufkioct;
//ioctl
#define SAMPLE_IOCTL_MAGIC_NUMBER 'K'
#define SAMPLE_IOCTL_CMD_1 \
_IOR(SAMPLE_IOCTL_MAGIC_NUMBER, 1, char )
#define SAMPLE_IOCTL_CMD_2 \
_IOW(SAMPLE_IOCTL_MAGIC_NUMBER, 2, char)
#define SAMPLE_IOCTL_CMD_3 \
_IO(SAMPLE_IOCTL_MAGIC_NUMBER, 3)
static ssize_t sample_char_read(struct file * file, char __user * buf, size_t count, loff_t
*ppos)
{
//passing data between user and kernel space
copy_to_user(buf,bufk,count);
buf=buf+20;
copy_to_user(buf,bufk1,count);
buf=buf+20;
copy_to_user(buf,bufk2,count);
buf=buf+20;
copy_to_user(buf,file->private_data,count);
return 0;
}
static ssize_t sample_char_write(struct file *filp, const char *buf, size_t size, loff_t
*offp)
{
copy_from_user(bufk,buf,size);
buf=buf+20;
copy_from_user(bufk1,buf,size);
buf=buf+20;
copy_from_user(bufk2,buf,size);
buf=buf+20;
copy_from_user(filp->private_data,buf,size);
printk("free_pages value=%s\n",bufk);
printk("kmalloc value=%s\n",bufk1);
printk("vmalloc value=%s\n",bufk2);
printk("private data=%s\n",filp->private_data);
return size;
}
//ioctl for data transfer
int sample_char_ioctl (struct file *filp, unsigned int cmd, void* arg, void* arg1)
{
char *p=(char*)arg;
printk("sample_char_ioctl\n");
switch (cmd)
{
case SAMPLE_IOCTL_CMD_1:
bufkioct="ronak";
copy_to_user(p,bufkioct,10);
printk("sample_char_ioctl_1 done\n");
break;
case SAMPLE_IOCTL_CMD_2:
copy_from_user(bufkioct,p,10);
printk("sample_char_ioctl_2 done\n");
break;
case SAMPLE_IOCTL_CMD_3:
bufkioct=(char*)kmalloc(20,GFP_ATOMIC);
printk("sample_char_ioctl_3 done\n");
break;
}
}
int sample_char_open(struct inode *inode, struct file *filp)
{
gfp_t t1;
printk("sample_char_open\n");
//dynamic memory allocation in kernel
bufk=(char*)__get_free_pages(t1,1);
bufk1=(char*)kmalloc(20,GFP_ATOMIC);
bufk2=(char*)vmalloc(20);
filp->private_data=kmalloc(20,GFP_ATOMIC);
return 0;
}
int sample_char_release(struct inode *inode, struct file *filp)
{
free_pages(bufk,1);
kfree(bufk1);
vfree(bufk2);
printk("sample_char_release\n");
return 0;
}
static struct file_operations sample_char_fops = {
read: sample_char_read,
write: sample_char_write,
open: sample_char_open,
release: sample_char_release,
unlocked_ioctl:sample_char_ioctl,
};
#define sample_major_number 89
#define max_minors 1
static struct cdev char_cdev;
static dev_t dev;
int init_module(void)
{
int ret = 0;
dev = MKDEV(sample_major_number, 0);
printk("\nLoading the sample char device driver\n");
ret = register_chrdev_region(dev, max_minors, "sample_char");
if (ret)
{
printk("register_chrdev_region Error\n");
goto error;
}
cdev_init(&char_cdev, &sample_char_fops);
ret = cdev_add(&char_cdev, dev, max_minors);
if (ret)
{
printk("cdev_add Error\n");
goto error_region;
}
return 0;
error_region:
unregister_chrdev_region(dev, max_minors);
error:
return ret;
}
void cleanup_module(void)
{
cdev_del(&char_cdev);
unregister_chrdev_region(dev, max_minors);
printk("\nUnloading the sample char device driver\n");
}


test.c

// String reversal done by device driver
#include<unistd.h>
#include<stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h> // for memset and strlen
#include<time.h>
#include <sys/ioctl.h>
#define SAMPLE_IOCTL_MAGIC_NUMBER 'K'
#define SAMPLE_IOCTL_CMD_1 \
_IOR(SAMPLE_IOCTL_MAGIC_NUMBER, 1, char )
#define SAMPLE_IOCTL_CMD_2 \
_IOW(SAMPLE_IOCTL_MAGIC_NUMBER, 2, char )
#define SAMPLE_IOCTL_CMD_3 \
_IO(SAMPLE_IOCTL_MAGIC_NUMBER, 3)
int main(int argc ,char *argv[])
{
char arrioct[10];
char arr[4][20];
int g,size;
strcpy(arr[0],"free");
strcpy(arr[1],"kmaloc");
strcpy(arr[2],"vmalloc");
strcpy(arr[3],"private");
strcpy(arrioct,"");
int fp = open("/dev/sample", O_RDWR);
if(fp<0)
{
perror("not sucess");
}
g=write(fp,arr,20);
if(g<0)
{
perror("error write");
}
bzero(arr,80);
g=read(fp,arr,20);
if(g<0)
{
perror("error read");
}
printf("free_pages value=%s\n",arr[0]);
printf("kmalloc value=%s\n",arr[1]);
printf("vmalloc value=%s\n",arr[2]);
printf("private=%s\n",arr[3]);
size=sizeof(arrioct);
ioctl(fp,SAMPLE_IOCTL_CMD_3);
ioctl(fp,SAMPLE_IOCTL_CMD_2,&arrioct);
bzero(arrioct,10);
ioctl(fp,SAMPLE_IOCTL_CMD_1,&arrioct);
printf("Read Value is =%s\n",arrioct);
}
Output :
@ubuntu:~/assign11$ sudo insmod char.ko
@ubuntu:~/assign11$ sudo mknod /dev/sample_char c 249 0
@ubuntu:~/assign11$ sudo chmod 777 /dev/sample_char
@ubuntu:~/assign11$ make test

cc -o test test.c

@ubuntu:~/assign11$ ./test
free_pages value=free
kmalloc value=kmaloc
vmalloc value=vmalloc
private=private
Read Value is =ronak
dmesg
[ 4350.276892] sample_char_open
[ 4350.276921] free_pages value=free
[ 4350.276926] kmalloc value=kmaloc
[ 4350.276930] vmalloc value=vmalloc
[ 4350.276934] private data=private
[ 4350.277056] sample_char_ioctl
[ 4350.277059] sample_char_ioctl_3 done
[ 4350.277063] sample_char_ioctl
[ 4350.277066] sample_char_ioctl_2 done
[ 4350.277070] sample_char_ioctl
[ 4350.277073] sample_char_ioctl_1 done
[ 4350.277174] sample_char_release 

No comments: