首先MMU(Memory Management Unit)它是一块硬件单元,通常集成在CPU 或 SoC 中。主要功能是把“虚拟地址”转换为“物理地址”
mmap(memory map)它是操作系统内核提供的一个系统调用/软件机制。用于将一个文件或设备缓冲区映射到进程的虚拟地址空间里
可以直观的看出来前者是硬件后者是软件上的机制,更关键的是MMU是介于硬件层与内核层之间的,而mmap是介于应用层与内核层之间的。它们所负责的位置不同。

MMU
MMU通常并不是你在板子上能找到的独立芯片,而是作为处理器(CPU/SoC)内核里集成的一块电路逻辑单元:集成在 CPU/SoC 内。在现代 x86、ARM、RISC‑V 等架构里,MMU 是 CPU 核心的一部分。它和算术逻辑单元、缓存(L1/L2/L3)一起,都是硅片(Silicon)上同一颗芯片(SoC)内部电路
操作系统在内存中构建并维护好“虚拟页 → 物理页框”映射的多级页表MMU 硬件 从一个特殊寄存器(TTBR/CR3)拿到页表根地址,再按虚拟地址的各段位做多级索引,最终得到对应的物理页框号,中途结果缓存在 TLB 中,从而实现地址转换。
mmap
mmap 是用户态与文件/设备打交道的映射接口,借助 MMU 做页表映射 。
讲到mmap,最重要是的知道它干了什么,它最大的作用是让我们的线程、进程运行时,大大减少了我们数据拷贝的次数,提高了系统的实时性和效率。
对于文件,内核会将文件内容按页(4 KiB 一页)加载到页缓存,执行 mmap(fd, length, prot, flags, fd, 0) 时,内核不会马上做任何数据拷贝,而是记录一个映射关系:把进程的虚拟地址区间 [addr, addr+length) 映射到文件页缓存对应的物理页上。进程首次访问映射区时(读或写),会触发一次缺页中断
内核在缺页处理函数里:如果对应页已在页缓存,就直接把该物理页的页框(frame)分配给进程的页表;如果不在页缓存,就先从磁盘/外设载入到页缓存,再建立映射。
从此以后,用户空间对映射区域的内存读写,就直接走 CPU 的常规读写路径,经由 MMU → TLB,访问那块已经映射的物理页,不会再经过 read()/write() 系统调用路径,也就省去了两次拷贝。
下面是mmap部分代码示例,分别是应用层与内核层的关键函数
//应用层中mmap映射函数
fd = open("/dev/led", O_RDWR);//打开设备文件,内核就能获取设备文件的索引节点,填充inode结构
if(fd<0){
printf("open error,fd = %d\n",fd);
return -1;
}
buffer = (char *)malloc(1024);
memset(buffer, 0, 1024);
mapBuf = mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);//内存映射,会调用驱动的mmap函数
strcpy(mapBuf, "test data for mmap");//向映射段写数据
memset(buffer, 0, 1024); //清空,避免误判
strcpy(buffer, mapBuf); //从映射段读取数据
printf("read data is %s\n", buffer);//如果读与写一致,说明映射成功
munmap(mapBuf, 1024);//解除映射
free(buffer);
//内核层中mmap映射函数
static int device_mmap(struct file *file, struct vm_area_struct *vma)
{
vma->vm_flags |= VM_IO;//表示对设备IO空间的映射
vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP);//标志该内存区不能被换出,在设备驱动中虚拟页和物理页的关系应该是长期的,应该保留起来,不能随便被别的虚拟页换出
if(remap_pfn_range(vma,//虚拟内存区域,即设备地址将要映射到这里
vma->vm_start,//虚拟空间的起始地址
virt_to_phys(buf)>>PAGE_SHIFT,//与物理内存对应的页帧号,物理地址右移12位
vma->vm_end - vma->vm_start,//映射区域大小,一般是页大小的整数倍
vma->vm_page_prot))//保护属性,
{
return -EAGAIN;
}
return 0;
注意这个过程没有“新开辟一块内存”
驱动里通常已经通过 kmalloc/dma_alloc_coherent、或者是 MMIO 的物理基址(BAR)准备好了一段物理内存。mmap 并不额外分配新的页;它只是把这些已有的物理页,映射(map)到用户进程的页表中。
19

被折叠的 条评论
为什么被折叠?



