二、使用mmap将物理地址映射到进程的虚拟地址空间
mmap(2)
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
功能:将文件或设备映射到内存
参数:
addr:指定了映射区域的起始地址(虚拟地址)
通常是NULL:地址由内核来决定
length:指定了映射区域的长度
prot:期望的内存保护标志,不能与文件的打开模式冲突。是以下的某个值,
可以通过or运算合理地组合在一起:
PROT_EXEC Pages may be executed.//页内容可以被执行
PROT_READ Pages may be read.//可被读
PROT_WRITE Pages may be written.//可被写
或者只选择下面标志:
PROT_NONE Pages may not be accessed.//页不可访问
flags:指定映射对象的类型,映射选项和映射页是否可以共享。它的值可以是一个或者多个以下位的组合体
(二选一)
MAP_SHARED:对映射区域的更新给其他进程看,也同步到下层的更新
MAP_PRIVATE:对映射区域的更新不给其他进程看,也不同步到下层的更新
也可以同时加上下面:
MAP_ANONYMOUS:匿名映射,映射区域的内容被初始化为0,不与任何文件相关,如果指定了这个参数,fd和offset被忽略
fd:文件描述符,其值也可以设置为-1,此时需要指定flags参数中的MAP_ANON,表明进行的是匿名映射。
offset:文件的起始位置
返回值:成功执行时,mmap()返回被映射区的指针,失败时,mmap()返回MAP_FAILED[其值为(void *)-1]
int munmap(void *addr, size_t length);
功能:解除文件到内存的映射
参数:
addr:mmap(2)的返回值
length:指定了映射区域的长度
返回值:
成功代表0,失败代表-1
举例说明:将物理地址映射到进程的虚拟地址空间,然后对虚拟空间进行操作(mmap.c)
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
int main(void) {
//将物理地址映射到虚拟地址
//物理地址是操作系统选择的
int prot = PROT_WRITE | PROT_READ;
int flags = MAP_PRIVATE | MAP_ANONYMOUS;//这两行是为了让长度短一点
void *p = mmap(NULL, 1024, prot, flags, -1, 0); //因为mmap的返回值就是void *类型的
if(p == MAP_FAILED) {
perror("map");
return -1;
}
//映射正确
//解除映射
strcpy(p, "hellow");
printf("%s\n", (char *)p);
munmap(p, 1024);
return 0;
}
命令: tarena@ubuntu:~/day/day26$ gcc mmap.c
命令: tarena@ubuntu:~/day/day26$ ./a.out
结果: hellow
补充: linux下一切皆文件,包括各个设备
【C语言】【unix c】使用mmap将物理地址映射到进程的虚拟地址空间
最新推荐文章于 2024-07-28 20:00:00 发布