- 论坛徽章:
- 1
|
写了个简单的设备,想将设备的内存映射到用户空间,内核代码如下,- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/fs.h>
- #include <linux/mm.h>
- #include <asm/io.h>
- #define DEV_MAP_NAME "dev_map"
- #define DEV_MAP_MAJOR 100
- static int dev_open(struct inode * inode, struct file *filp);
- static int dev_mmap(struct file *filp, struct vm_area_struct *vma);
- static int dev_release(struct inode *inode, struct file *filp);
- char * buf_addr;
- char buf[] = "hello world";
- struct file_operations dev_fops = {
- .owner = THIS_MODULE,
- .open = dev_open,
- .mmap = dev_mmap,
- .release = dev_release,
- };
- int __init map_kernel_space_init(void)
- {
- int ret;
- ret = register_chrdev(DEV_MAP_MAJOR, DEV_MAP_NAME, &dev_fops);
- if (ret < 0) {
- printk(KERN_ERR "register_chrdev failed\n");
- return ret;
- }
- return 0;
- }
- void __exit map_kernel_space_exit(void)
- {
- unregister_chrdev(DEV_MAP_MAJOR, DEV_MAP_NAME);
- printk(KERN_DEBUG "exit...");
- }
- static int dev_open(struct inode *inode, struct file *filp)
- {
- buf_addr = (char *)kmalloc(1024, GFP_KERNEL);
- if (buf_addr == NULL)
- printk(KERN_ERR "kmalloc error");
- memcpy(buf_addr, buf, sizeof(buf));
- return 0;
- }
- static int dev_mmap(struct file *filp, struct vm_area_struct *vma)
- {
- int ret;
- printk(KERN_DEBUG "begin remap_pfn_range...");
- ret = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)buf_addr) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, PAGE_SHARED);
- printk(KERN_DEBUG "after remap_pfn_range");
- if (ret != 0) {
- printk(KERN_ERR "remap_pfn_range failed\n");
- return -EAGAIN;
- }
- return 0;
- }
- static int dev_release(struct inode *inode, struct file *filp)
- {
- return 0;
- }
- module_init(map_kernel_space_init);
- module_exit(map_kernel_space_exit);
复制代码 用户空间代码如下:- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/mman.h>
- #include <fcntl.h>
- int main()
- {
- int fd;
- fd = open("./dev_map", O_RDWR);
- if (fd < 0) {
- perror("open failed");
- return -1;
- }
- char *addr = NULL;
- addr = mmap(NULL, 12, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap failed");
- return -1;
- }
- printf("%s\n", addr);
- printf("string len = %u\n", strlen(addr));
- return 0;
- }
复制代码 编译后,加载模块,多次运行用户空间程序,发现打印出的内容总是变化,这是怎么回事?
还有,我这样实现的对吗?没有找到太多合适的remap_pfn_range()的例子,求大婶指导 |
|