第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 《深入Linux设备驱动程序内核机制》中的mmap_demo.c例程

《深入Linux设备驱动程序内核机制》中的mmap_demo.c例程

时间:2021-09-11 20:12:26

相关推荐

《深入Linux设备驱动程序内核机制》中的mmap_demo.c例程

驱动代码如下:

1 #include <linux/module.h> 2 #include <linux/kernel.h> 3 #include <linux/types.h> 4 #include <linux/init.h> 5 #include <linux/errno.h> 6 #include <linux/sched.h> 7 8 #include <linux/device.h> 9 #include <linux/cdev.h> 10 #include <linux/fs.h> 11 #include <linux/fcntl.h> 12 #include <linux/gfp.h> 13 #include <linux/string.h> 14 #include <linux/mm_types.h> 15 #include <linux/mm.h> 16 #include <linux/highmem.h> 17 #include <linux/timer.h> 18 19 #include <asm/io.h> 20 #include <asm/system.h> 21 #include <asm/uaccess.h> 22 23 #define KSTR_DEF "Hello world from kernel virtual space" 24 25 static struct cdev *pcdev; 26 static dev_t ndev; 27 static struct page *pg; 28 static struct timer_list timer; 29 30 static void timer_func(unsigned long data) 31 { 32 printk("timer_func:%s\n",(char *)data); 33 timer.expires = jiffies + HZ*10; 34 add_timer(&timer); 35 } 36 37 static int demo_open(struct inode *inode,struct file *filp) 38 { 39 return 0; 40 } 41 42 43 static int demo_release(struct inode *inode,struct file *filp) 44 { 45 return 0; 46 } 47 48 static int demo_mmap(struct file *filp,struct vm_area_struct *vma) 49 { 50 int err = 0; 51 unsigned long start = vma->vm_start; 52 unsigned long size = vma->vm_end - vma->vm_start; 53 54 err = remap_pfn_range(vma,start,vma->vm_pgoff,size,vma->vm_page_prot); 55 printk("vma->vm_pgoff = 0x%x\n",vma->vm_pgoff); 56 return err; 57 } 58 59 static struct file_operations mmap_fops = 60 { 61 .owner = THIS_MODULE, 62 .open = demo_open, 63 .release= demo_release, 64 .mmap = demo_mmap, 65 }; 66 67 static demo_map_init(void) 68 { 69 int err = 0; 70 char *kstr; 71 72 pg = alloc_pages(GFP_HIGHUSER,0); 73 SetPageReserved(pg); 74 75 kstr = (char *)kmap(pg); 76 strcpy(kstr,KSTR_DEF); 77 printk("kpa = 0x%x,kernel string = %s\n",page_to_phys(pg),kstr); 78 79 pcdev = cdev_alloc(); 80 cdev_init(pcdev,&mmap_fops); 81 alloc_chrdev_region(&ndev,0,1,"mmap_dev"); 82 printk("major = %d,minor = %d\n",MAJOR(ndev),MINOR(ndev)); 83 pcdev->owner = THIS_MODULE; 84 cdev_add(pcdev,ndev,1); 85 86 init_timer(&timer); 87 timer.function = timer_func; 88 timer.data = (unsigned long)kstr; 89 timer.expires = jiffies + HZ*10; 90 add_timer(&timer); 91 92 return err; 93 } 94 95 static void demo_map_exit(void) 96 { 97 del_timer_sync(&timer); 98 cdev_del(pcdev); 99 unregister_chrdev_region(ndev,1);100 kunmap(pg);101 ClearPageReserved(pg);102 __free_pages(pg,0);103 }104 105 module_init(demo_map_init);106 module_exit(demo_map_exit);

Makefile

1 export ARCH=x86 2 export CROSS_COMPILE=3 obj-m := mmap_demo.o 4 KERNELDIR := /lib/modules/$(shell uname -r)/build 5 PWD := $(shell pwd) 6 7 default: 8 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 9 clean:10 rm -f *.o *.ko *.mod.*

注意上面两行,由于我的机器上配置了arm交叉编译,ARCH/CROSS_COMPILE进行了配置,如果编译x86的ko,必须取消之,否则总是提示.h之类的奇怪错误。

应用程序:

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 #include <unistd.h> 8 #include <sys/mman.h> 9 10 #define MAP_SIZE 409611 #define USTR_DEF "String changed from User Space"12 13 int main(int argc,char *argv[])14 {15 int fd;16 char *pdata;17 18 if(argc <= 1)19 {20 printf("Usage: main devfile pamapped\n");21 return 0;22 }23 fd = open(argv[1],O_RDWR|O_NDELAY);24 if(fd < 0)25 return -1;26 pdata = (char *)mmap(0,MAP_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,27 fd,strtoul(argv[2],0,16));28 printf("UserAddr = %p,Data from kernel:%s\n",pdata,pdata);29 printf("Writing a string to the kernel space...");30 strcpy(pdata,USTR_DEF);31 printf("Done\n");32 munmap(pdata,MAP_SIZE);33 close(fd);34 return 0;35 }

特别注意

mmap最后一个参数:

void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);

offset: 映射文件的位置,一般从头开始。而在设备文件中,表示映射物理地址的起始地址;

kpa = 0x790a4000,kernel string = <NULL>major = 248,minor = 0timer_func:Hello world from kernel virtual spacetimer_func:Hello world from kernel virtual spacevma->vm_pgoff = 0x790a4//vm_pgoff表示的是物理地址偏移

timer_func:String changed from User Space

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。