#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/cdev.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/semaphore.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/arch/irqs.h>
#include <asm/io.h>
#include <linux/version.h>
#include <asm/hardware.h>
#include <linux/delay.h>
#include <asm/arch/sep4020_hal.h>
#define DRIVE_MAJOR 165
#define DRIVE_NAME "Test drv"
typedef struct
{
dev_t dev_num ;
struct cdev cdev ;
}code_dev ;
static code_dev test_dev ;
unsigned char data_source;
unsigned char *testmap;
unsigned char *kmalloc_area;
unsigned long msize;
static int test_open(struct inode *inode , struct file *filp)
{
return 0 ;
}
static int test_close(struct inode *inode , struct file *filp)
{
return 0 ;
}
static ssize_t test_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{
if(copy_from_user(&data_source,buf,sizeof(data_source)))
{
printk("write error!\n");
}
return(sizeof(data_source));
}
static ssize_t test_read(struct file *filp, char __user *buf,size_t count,loff_t *ppos)
{
if(copy_to_user(buf,&data_source,sizeof(data_source)))
{
printk("read error!\n");
}
return(sizeof(data_source));
}
static int test_mmap(struct file *file,struct vm_area_struct *vma)
{
int ret;
ret=remap_pfn_range(vma,vma->vm_start,virt_to_phys((void *)((unsigned long)kmalloc_area))>>PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
if(ret!=0)
{
return -EAGAIN;
}
return ret;
}
static int test_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
int result;
int i;
switch(cmd)
{
case 0:
{
result=0;
}
break;
case 1:
{
result=1;
}
break ;
case 2:
{
for(i=0;i<20;i++)
{
printk("i=%d %c\n",i,*(testmap+i));
}
result=2;
}
break;
default:
return -ENOTTY;
}
return(result);
}
static struct file_operations test_fs = {
.owner = THIS_MODULE ,
.open = test_open ,
.release = test_close ,
.read = test_read ,
.write = test_write ,
.mmap = test_mmap,
.ioctl = test_ioctl
};
static int __init test_init(void)
{
unsigned int ret ;
unsigned char *virt_addr;
memset(&test_dev , 0 ,sizeof(test_dev)) ;
test_dev.dev_num = MKDEV(DRIVE_MAJOR , 0) ;
ret = register_chrdev_region(test_dev.dev_num , 1 ,DRIVE_NAME) ;
if(ret < 0)
{
return(ret) ;
}
cdev_init(&test_dev.cdev , &test_fs) ;
test_dev.cdev.owner = THIS_MODULE ;
test_dev.cdev.ops = &test_fs ;
printk("\nInit drv \n") ;
ret = cdev_add(&test_dev.cdev , test_dev.dev_num , 1) ;
if(ret < 0)
{
printk("cdev add error !\n") ;
return(ret) ;
}
testmap=kmalloc(4096,GFP_KERNEL);
kmalloc_area=(int *)(((unsigned long)testmap +PAGE_SIZE-1)&PAGE_MASK);
if(testmap==NULL)
{
printk("Kernel mem get pages error\n");
}
for(virt_addr=(unsigned long)kmalloc_area;virt_addr<(unsigned long)kmalloc_area+4096;virt_addr+=PAGE_SIZE)
{
SetPageReserved(virt_to_page(virt_addr));
}
memset(testmap,'q',100);
printk("Test drv reg success !\n") ;
return 0 ;
}
static void __exit test_exit(void)
{
printk("Test drv exit\n") ;
cdev_del(&test_dev.cdev) ;
unregister_chrdev_region(test_dev.dev_num , 1) ;
}
MODULE_LICENSE("GPL") ;
module_init(test_init) ;
module_exit(test_exit) ;
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#define max_num 4096
int main(int argc,char *argv[])
{
int fd;
int ret;
unsigned char *rwc,*rrc;
unsigned int *map;
unsigned char ** newmap;
rwc=malloc(sizeof(unsigned char));
rrc=malloc(sizeof(unsigned char));
*rwc=50;
*rrc=30;
fd=open("/dev/drvio1",O_RDWR);
if(fd<0)
{
printf("open file error!\n");
return -1;
}
ret=write(fd,rwc,sizeof(rwc));
ret=read(fd,rrc,sizeof(rrc));
printf("rwc =%d\nrrc =%d\n",*rwc,*rrc);
*rwc=10;
ret=write(fd,rwc,sizeof(rwc));
ret=read(fd,rrc,sizeof(rrc));
printf("rwc =%d\nrrc =%d\n",*rwc,*rrc);
ioctl(fd,2,0);
if((map=(unsigned int *)mmap(NULL,max_num,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED)
{
printf("mmap error!\n");
}
memset(map,'c',max_num);
strcpy(map,"Welcome");
ioctl(fd,2,0);
munmap(map,4096);
map=NULL;
close(fd);
return 0;
}
AR = ar
ARCH = arm
CC = arm-linux-gcc
#ifneq ($(KERNELRELEASE))
obj-m:= drv.o
#else
KDIR = /decard_dev/linux-v3.4.4
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
arm-linux-gcc tdrv.c -o tdrv
arm-linux-gcc tdrv1.c -o tdrv1
rm -rf *.mod.c *.mod.o *.o
rm -rf .*.ko.cmd .*.mod.o.cmd .*.o.cmd .tmp_versions
clean:
rm -rf *.o *.ko *.mod.c tdrv tdrv1
rm -rf .*.ko.cmd .*.mod.o.cmd .*.o.cmd .tmp_versions
#endif
mknod /dev/drvio1 c 165 0