LDD3 study note 3
来源:互联网 发布:cloudstack基本网络 编辑:程序博客网 时间:2024/05/01 03:02
LDD3 study note 3
-v0.1 2017.11.17 Sherlock init
这篇笔记记录驱动程序中mmap的写法,以及相关的调试过程。同样代码在:
https://github.com/wangzhou/scull.git
1. mmap
在linux用户态调用mmap函数可以把文件内容直接映射到内存,这样用户态程序可以像访问
内存一样访问文件。同样,使用mmap也可以把设备的一段IO空间映射到用户态,用户态程序
可以直接访问这个设备的寄存器。当然,要在程序驱动里添加mmap的对应支持。
2. 驱动实现
为了支持把设备的IO空间映射到用户态,驱动里要实现.mmap的回调,struct vm_area_struct
会把用户态想要映射到的用户态虚拟地址传到内核。在.mmap回调里需要把这些参数,连同
想要映射的实际物理地址传递给remap_pfn_range函数,这个函数帮助建立虚拟地址到物理
地址的映射。
下面的例子是在scull驱动里,申请了一段内核态的内存,我们可以通过下面的操作把它映射
到用户态。
int scull_mmap(struct file *file, struct vm_area_struct *vma){ unsigned long page = virt_to_phys(scull_device->mmap_memory); unsigned long start = (unsigned long)vma->vm_start; unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start); vma->vm_flags |= (VM_IO | VM_LOCKED | VM_DONTEXPAND | VM_DONTDUMP); if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, size, PAGE_SHARED)) { printk(KERN_ALERT "remap_pfn_range failed!\n"); return -1; } return 0;}
LDD3上讲,remap_pfn_range只能映射IO空间和系统保留内存,但是上面例子的mmap_memory
实际在就是用get_free_page分配的(把get_free_page换成kmalloc也是可以做映射的), 测试
的结果是用get_free_page分配的内存也是可以被映射到用户态的。所以,实际上
remap_pfn_range也可以把系统内存映射到用户态。
内核用struct vm_area_struct管理进程空间的各个虚拟地址区域。cat /proc/pid/maps
可以看到一个进程所有的虚拟地址区域。在下面的例子中,我们可以看到测试程序(read.c)
的进程的各个地址区域。可以看到调用mmap创建起来的一个地址区域/dev/scull0.
estuary:/$ cat /proc/1251/maps00400000-00401000 r-xp 00000000 00:01 882 /a.out00410000-00411000 rw-p 00000000 00:01 882 /a.outffffae624000-ffffae634000 rw-p 00000000 00:00 0 ffffae634000-ffffae764000 r-xp 00000000 00:01 629 /lib/aarch64-linux-gnu/libc-2.21.soffffae764000-ffffae773000 ---p 00130000 00:01 629 /lib/aarch64-linux-gnu/libc-2.21.soffffae773000-ffffae777000 r--p 0012f000 00:01 629 /lib/aarch64-linux-gnu/libc-2.21.soffffae777000-ffffae779000 rw-p 00133000 00:01 629 /lib/aarch64-linux-gnu/libc-2.21.soffffae779000-ffffae77d000 rw-p 00000000 00:00 0 ffffae77d000-ffffae799000 r-xp 00000000 00:01 575 /lib/aarch64-linux-gnu/ld-2.21.soffffae7a1000-ffffae7a2000 rw-s 00000000 00:01 1385 /dev/scull0ffffae7a2000-ffffae7a7000 rw-p 00000000 00:00 0 ffffae7a7000-ffffae7a8000 r--p 00000000 00:00 0 [vvar]ffffae7a8000-ffffae7a9000 r-xp 00000000 00:00 0 [vdso]ffffae7a9000-ffffae7aa000 r--p 0001c000 00:01 575 /lib/aarch64-linux-gnu/ld-2.21.soffffae7aa000-ffffae7ac000 rw-p 0001d000 00:01 575 /lib/aarch64-linux-gnu/ld-2.21.sofffff5f89000-fffff5faa000 rw-p 00000000 00:00 0 [stack]
- LDD3 study note 3
- LDD3 study note 0
- LDD3 study note 1
- LDD3 study note 2
- Mysql study note 3
- jQuery study note 3
- DOJO Study Note(3) - Dojo 事件机制
- note : A-Protect Study note
- perl study note-1
- perl study note-2
- WinCE Study Note
- The Study Note
- svn study note 1
- perl study note
- MySql study note 1
- Sed study note
- AWK study note
- SAP BW Study note
- 弘智教育-效果图10-建模最后一节课
- 【七月Python入门】 第五课面文件访问与函数式编程入门
- 打造浪漫的Android表白程序
- pandas—Dataframe操作(选取 插入 删除)
- 存储器层次结构1
- LDD3 study note 3
- 把android中图片局部区域改为透明
- C++ 双向链表简单实现通讯录
- 微信支付:“当前页面的URL未注册”
- 1.安装cocos2d-js环境(Linux)
- 汇总 Vue 中大家最爱问的高频问题
- IAR 编译 ZStack-CC2530生成 HEX 文件完全配置
- Java中的队列API——Queue
- Hash 学习