mmap函数

关于IO端口
几乎每一种外设都是通过读写设备上的寄存器来进行的。外设寄存器也称为“I/O端口”,通常包括:控制寄存器、状态寄存器和数据寄存器三大类,而且一个外设的寄存器通常被连续地编址。

CPU对外设IO端口物理地址的编址方式有两种:

一种:I/O映射方式(I/O-mapped),

另一种:内存映射方式(Memory-mapped)。而具体采用哪一种则取决于

CPU的体系结构。
有些体系结构的CPU(如,PowerPC、m68k等)通常只实现一个物理地址空间(RAM)。在这种情况下,外设I/O端口的物理地址就被映射到CPU的单一物理地址空间中,而成为内存的一部分。此时,CPU可以象访问一个内存单元那样访问外设I/O端口,而不需要设立专门的外设I/O指令。这就是所谓的“内存映射方式”(Memory-mapped)。而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间,称为“I/O地址空间”或者“I/O端口空间”。这是一个与CPU的RAM物理地址空间不同的地址空间,所有外设的I/O端口均在这一空间中进行编址。CPU通过设立专门的I/O指令(如X86的IN和OUT指令,linux 的outb,inb等,后面代码有用到)来访问这一空间中的地址单元(也即I/O端口)。这就是所谓的“I/O映射方式”(I/O-mapped)。

与RAM物理地址空间相比,I/O地址空间通常都比较小,如x86 CPU的I/O空间就只有64KB(0-0xffff)。这是“I/O映射方式”的一个主要缺点。Linux采用内存映射方式。我们通过上面的知识联系一下网卡的驱动:也就是说网卡的IO 端口的物理地址被映射到CPU的物理地址上,即上面说的“网卡在CPU的存储空间上接BANK4,即0x08000000”。


#include <sys/mman.h>
void *mmap(void *start,  size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *start,  size_t length); munmap执行相反的操作,删除特定地址区域的对象映射。
条件:

mmap映射必须以PAGE_SIZE()为单位,内存也只能以页为单位进行映射;面向流的设备不能进行mmap,mmap的实现和硬件有关。若要映射的地址范围不是PAGE_SIZE()的整数倍,那么要先进行内存对齐操作,强行以PAGE_SIZE的整数倍进行映射。

参数:

start:映射区的开始地址,设置为0时,表示是由系统决定开始地址。

length:映射区的长度;

prot:期望内存的保护标志,不能与文件的打开模式冲突;

flags:指定映射对象的类型,映射选项和映射页是否可以共享。

offset:被映射对象内容的起点。


操作:

mmap操作提供了一种机制,让用户程序直接访问设备内存,比用户空间和内核空间之间拷贝数据的方式,效率高。

系统调用:

mmap系统调用使进程之间通过映射同一普通文件实现共享内存。普通文件被映射到进程内存后,进程就可以像访问普通内存一样对文件进行操作,不需要open、write、read等操作。系统调用mmap共享内存的两种方式:

1.使用普通文件提供的内存映射:适用于任何进程之间,此时需要打开一个文件或创建一个文件,然后再调用mmap。

fd=open(name,flag,mode);

if(fd<0)

……

ptr=mmap(NULL,len, PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0);


2.使用特殊文件提供匿名内存映射:

适用于具有亲缘关系之间的进程,由于父子进程之间的特殊关系,先在父进程中调用mmap,再调用fork;在fork后,子进程继承父进程匿名映射后的内存空间,同样也继承mmap的返回值,这样父子进程之间就可以在映射区域进行通信了。












#include <sys/mman.h>
void *mmap(void *start,  size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *start,  size_t length);










#include <sys/mman.h>
void *mmap(void *start,  size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *start,  size_t length);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值