前言
Linux 编程中,大多数的场景,数据的交换,不论读还是写都要经过两次数据拷贝过程:用户和内核,内核和硬件物理内存
如果数据的访问量比较小,两次的数据拷贝对系统性能影响几乎可以忽略不计
如果数据的访问比较大,两次的数据拷贝势必影响系统性能
数据的操作的规律是源要不是用户或者硬件,目的要不是硬件或者用户,而内核仅仅作为一个缓冲,所以用户到内核的数据拷贝是多余的,如果让用户在用户空间访问硬件设备的物理内存,即可将两次数据拷贝变成一次数据拷贝
以下设备的数据量的访问比较大:摄像头,声卡,显卡,LCD等
如何让用户在用户空间访问到硬件设备的物理地址呢?将数据的拷贝由2次变成1次,加快数据的访问速度呢?
利用大名鼎鼎的mmap机制。
作为驱动层,如果我们所涉及的驱动设备数据的量比较大,我们在驱动层,最好根据需要,去支持mmap机制,将设备物理地址映射到用户空间的虚拟地址上,一旦映射完毕,对设备的访问将来都放在用户空间来进行
回顾mmap系统调用的使用:
void *addr;
fd = open("a.txt", ...);
addr = mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
memcpy(addr, "hello,world", 12);
作用:将文件a.txt(硬盘物理信息)映射到用户3G虚拟地址空间中的MMAP虚拟内存映射区中,一旦映射完毕将来访问用户的这块虚拟内存就是在访问对应的物理地址(物理内存),不再经过内核的数据拷贝,加快文件的访问速度。
第一个实参0:告诉内核,请在当前进程的3G虚拟地址空间的MMAP内存映射区中找一块空闲的虚拟内存用来映射文件
第二个实参0x1000:空闲的用户虚拟内存的大小,必须是页面大小的整数倍
返回值addr:内核将内核帮你找的那块空闲虚拟内存区域的首地址返回到用户空间,将来用户在用户空间访问这块虚拟内存就是在访问硬件的物理地址
这样的操作,就会绕过