答案 0 :(得分:3)
从Android源代码中提取;
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
extern void* __mmap2(void*, size_t, int, int, int, size_t);
#define MMAP2_SHIFT 12
void* mmap( void* addr, size_t size, int prot, int flags, int fd, long offset )
{
if ( offset & ((1UL << MMAP2_SHIFT)-1) ) {
errno = EINVAL;
return MAP_FAILED;
}
return __mmap2(addr, size, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT);
}
来源:mmap.c
现在,实际的__mmap2
调用具有程序集,因此它将取决于您的拱门。这是一个x86版本:
/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>
.text
.type __mmap2, @function
.globl __mmap2
.align 4
__mmap2:
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
mov 28(%esp), %ebx
mov 32(%esp), %ecx
mov 36(%esp), %edx
mov 40(%esp), %esi
mov 44(%esp), %edi
mov 48(%esp), %ebp
movl $__NR_mmap2, %eax
int $0x80
cmpl $-129, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
popl %ebp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
ret
来源:__mmap2.S
答案 1 :(得分:3)
要获得Win32 MapViewOfFile
实施,您必须支付昂贵的订阅费用,签署合法的保密协议等。
linux mmap
是公开可读的。但是,您应该知道有两个部分:glibc中的mmap
函数,以及内核中匹配的系统调用,其中所有有趣的位都是。您显示的签名是glibc函数,不要指望系统调用具有完全相同的参数。
但您可以“了解如何使用mmap
和MapViewOfFile
”,而无需阅读实施内容。
答案 2 :(得分:2)
答案 3 :(得分:2)
我的直接猜测是,试图弄清楚如何从源代码到函数更好地使用这些可能(最多)是一种非常迂回的方式来获取大部分的任何地方。特别是,您可能需要查看更多/其他代码才能获得更多功能。当你了解它时,mmap / MapViewOfFile本身的代码可能是最小的帮助(充其量),而其他代码(例如在文件系统驱动程序和文件缓存中)可能更有意义。
当你了解它时,mmap和MapViewOfFile有相对简单的工作:设置页面描述符,将一系列虚拟地址映射到某个文件的某些部分。
在您尝试访问其中一个页面之前,没有其他/更多的事情发生。这将触发“不存在”故障。故障处理程序将使用I / O子系统从磁盘读入相应的数据,并返回让原始指令执行。还不是很有趣。
至少从优化的角度来看,事情变得有趣的一点是I / O子系统内部。这可能(例如)跟踪页面错误的历史记录,并使用它来预测很快可能需要哪些页面(如果是,则在错误发生之前发出预测页面的读取)。
但是,mmap / MapViewOfFile的源代码根本不会直接导致您可能关心的I / O子系统部分(实际上,它们可能几乎完全无用)这方面)。
答案 4 :(得分:1)
很有趣,但我也需要mmap源代码......:)
到目前为止,我只能在NetBSD上找到答案。 Based on this comment:
相应的内核函数位于src/sys/uvm/uvm_map.c:
int uvm_map(struct vm_map * map,vaddr_t startp / IN / OUT * /,vsize_t size, struct uvm_object * uobj,voff_t uoffset,vsize_t align,uvm_flag_t flags)
实际链接对应于NetBSD第8版,但您可以将其替换为任何其他版本。
问候。