#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