从应用层的mmap到驱动层的mmap

来源:互联网 发布:网络社交平台的特点 编辑:程序博客网 时间:2024/04/30 22:58

吐舌头应用层

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <strings.h>#include <sys/mman.h>int main(int argc, char **argv){if(2 != argc){printf("Usage: %s <file>\n", argv[0]);return 0;}int fd = open(argv[1], O_RDWR);if(-1 == fd){perror("open");return -1;}// 将fd代表的设备文件映射到用户虚拟地址空间char *q = mmap(NULL, 10240, PROT_WRITE|PROT_READ , MAP_SHARED, fd, 0);if( MAP_FAILED == q){perror("mmap");return -1;}int *p = (int*)(q+0x0c44);while(1){*p = 1<<7;sleep(1);sync();*p &= ~(1<<7);sleep(1);sync();}close(fd);}

吐舌头驱动层

#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/version.h>#include <asm/io.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/slab.h>#include <asm/uaccess.h> #include <linux/highmem.h> #include <asm/kmap_types.h>MODULE_LICENSE("Dual BSD/GPL");MODULE_DESCRIPTION("a simple driver example!");typedef struct leddat{int *baseaddr;int pin;}LEDDAT; struct led{dev_t num;struct cdev *mycdev;LEDDAT leds[4];}MYLED;static int myled_open(struct inode *inodep, struct file *filep){int i = 4;printk("led open called\n");MYLED.leds[0].baseaddr = ioremap(0x11000c40, 8);MYLED.leds[0].pin = 7;MYLED.leds[1].baseaddr = ioremap(0x11000c20, 8);MYLED.leds[1].pin = 0;MYLED.leds[2].baseaddr = ioremap(0x114001E0, 8);MYLED.leds[2].pin = 4;MYLED.leds[3].baseaddr = ioremap(0x114001E0, 8);MYLED.leds[3].pin = 5;//*MYLED.gpx2con = *MYLED.gpx2con &~(0xf<<28)  |   1<<28;while(i--)iowrite32((ioread32(MYLED.leds[i].baseaddr)&~(0xf<<(MYLED.leds[i].pin*4))) | 1<<(MYLED.leds[i].pin*4) ,MYLED.leds[i].baseaddr);return 0;}char buf[100] = {"hello"};static ssize_t myled_read (struct file *f, char __user *p, size_t n, loff_t *off){if(copy_to_user(p, buf, 5)){return -EFAULT;}return 5;}static ssize_t myled_write (struct file *f, const char __user *p, size_t n, loff_t *off){if(copy_from_user(buf, p, n)){return -EFAULT;}return n;}#define ON   _IOW('L', 0, int)#define OFF  _IOW('L', 1, int)#define XXX  _IOW('L', 2, int)static long myled_ioctl(struct file *f, unsigned int cmd, unsigned long arg){int *dataaddr = MYLED.leds[arg].baseaddr+1;int pin = MYLED.leds[arg].pin;switch(cmd){case ON:iowrite32((ioread32(dataaddr) | 1<<pin ), dataaddr);break;case OFF:iowrite32((ioread32(dataaddr) & ~(1<<pin)) ,dataaddr);break;case XXX:printk("unknow cmd\n");break;}return 0;}static int myled_release(struct inode *inodep, struct file *filep){int i = 4;printk("led closed\n");while(i--)iounmap(MYLED.leds[i].baseaddr);return 0;}int myled_mmap(struct file *f, struct vm_area_struct *vma){// 以页对其映射return remap_pfn_range(vma, vma->vm_start, 0x11000000>>PAGE_SHIFT, vma->vm_end-vma->vm_start, vma->vm_page_prot);}struct file_operations myops = {.owner = THIS_MODULE,.open = myled_open,.unlocked_ioctl  = myled_ioctl,.read = myled_read,.write = myled_write,.mmap = myled_mmap,.release = myled_release};static int __init mymodule_init(void){int ret = 0;printk("led module in\n");//request dev numret = alloc_chrdev_region(&MYLED.num, 0, 1, "leddddddddddd");if(ret){printk("devnum alloc fail!\n");return ret;}printk("num: %d\n", MAJOR(MYLED.num) );//create cdev objectMYLED.mycdev =  cdev_alloc();if(NULL==MYLED.mycdev){printk("alloc cdev fail!\n");goto cdev_alloc_out;}//init cdev opscdev_init(MYLED.mycdev,  &myops);MYLED.mycdev->owner = THIS_MODULE;//register cdev into kernelret = cdev_add(MYLED.mycdev, MYLED.num, 1);if(ret){printk("add cdev fail!\n");goto cdev_add_out;}return 0;cdev_add_out:kfree(MYLED.mycdev);cdev_alloc_out:unregister_chrdev_region(MYLED.num, 1);return ret;}static void __exit mymodule_exit(void){//unregister cdev from kernelcdev_del(MYLED.mycdev);//release cdev objectkfree(MYLED.mycdev);//release dev numunregister_chrdev_region(MYLED.num, 4); printk("led module release\n");}module_init(mymodule_init);module_exit(mymodule_exit);





0 0
原创粉丝点击