【问题标题】:Is it possible to get the Linux source code for mmap and the Windows source code for MapViewOfFile?是否可以获得 mmap 的 Linux 源代码和 MapViewOfFile 的 Windows 源代码?
【发布时间】:2011-05-27 16:22:53
【问题描述】:

Goog 下午,我最近下载了 www.kernel.org 主线 2.6.39 Linux 内核源码发行版。我们正在寻找 void mmap(void start , size_t length, int prot, int flags, int fd, off_t offset) 的 Linux 源代码。在我们解压 tar.bz2 发行版后,我们发现了一个 mmap.c 文件,其中包含内存映射源代码。 但是,我们无法在 mmap.c 中找到 void mmap(void start , size_t length, int prot, int flags, int fd, off_t offset) 的 Linux 源代码。 是否有任何 Linux 工程师或管理员知道我们从哪里获得 void mmap(void start , size_t length, int prot, int flags, int fd, off_t offset) 的 Linux 源代码? 此外,我们对 MapViewOfFile 的 Windows 源代码感兴趣。我知道这有点牵强,因为 Microsoft 操作系统源代码不在开源域中。 如果有人想知道为什么我们需要这个源代码,我们正在尝试使用 32 位架构上的缓存内存映射文件实现来优化 C++ 去重程序原型的运行时性能。我们想了解如何使用 mmap 和 MapViewOfFile 来优化原型的运行时性能?谢谢。

【问题讨论】:

  • 对于 Windows,我可能会查看 Wine 源代码。
  • @David:不,它只会调用mmap。另一方面,ReactOS...
  • @David Heffernan。谢谢你的回答。
  • @Ben Voight。感谢您的帮助。

标签: c++ windows linux-kernel


【解决方案1】:

从安卓源代码拉取;

#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

【讨论】:

  • 感谢您的回答。这是否意味着 mmap2 仅用于 Android 的汇编语言?那是不可能获得 void *mmap(void start , size_t length, int prot, int flags, int fd, off_t offset) 的 Linux C 代码吗?谢谢。
  • @Frank Linux 版本将成为正在使用的 libc 库的一部分。大多数发行版使用 glibc。所以你需要检查它的来源。 ftp.gnu.org/gnu/glibc/glibc-2.9.tar.gz 在撰写本文时拥有最新的发布版本。您要查找的文件是 sysdeps/unix/sysv/linux/i386/mmap.S(适用于 x86)。是的,实际代码是在 ASM 中完成的。这是为了展示一个更简化的版本。
  • #onteria_,谢谢您的回答。今天晚上我将开始接受答案。我刚下载。 ftp.gnu.org/gnu/glibc/glibc-2.9.tar.gz 并找到 mmap.S。你知道 mmap.s 与 mmap.c 中的 linux 内核源代码有什么关系吗?感谢您的帮助。
【解决方案2】:

要获得 Win32 MapViewOfFile 实施,您必须支付昂贵的订阅费用,签署合法的保密协议等。

linux mmap 是公开可读的。但是,您应该知道有两个部分:glibc 中的mmap 函数,以及内核中的匹配系统调用,所有有趣的位都在其中。您显示的签名是针对 glibc 函数的,不要指望系统调用具有完全相同的参数。

但你可以“了解如何使用mmapMapViewOfFile”而不需要阅读实现。

【讨论】:

  • @Ben Voight,谢谢您的回答。 wg刚下载了一个glibc发行版,ftp.gnu.org/gnu/glibc/glibc-2.9.tar.gz,在*.h头文件或*.c源文件中找不到mmap函数。你知道我们在哪里可以找到 glibc 发行版中的 linux mmap 函数吗?谢谢。
  • @Frank:它是一个自动生成的包装器,除了打包参数并进行系统调用之外什么都不做。内核中的mmap.c 是完成所有工作的地方。我只提到了 glibc 层,因为它改变了参数。
  • @Ben Voight,谢谢您的回答。你知道我们在哪里可以找到自动生成的包装器,它打包参数并对内核 mmap.c 进行系统调用。谢谢您的帮助。我将在本周末开始接受答案。
  • @Frank:查看makefile,它位于sysdeps / unix / sysv / linux / syscall-list.h。此文件由 glibc 构建过程生成,下载中不存在。
  • @Ben Voight,谢谢您的回答。今晚我会尝试构建 glibc 库,
【解决方案3】:

对于MapViewOfFile,我会检查Winbase.h,但它可能只是声明,否则您将不得不求助于逆向工程,这在大多数国家/地区被认为是非法的。

我找到了一篇关于 MMAP 及其工作原理的广泛文章 here。也许这有帮助。

【讨论】:

  • 我没有否决您的评论。如果我们能找到更多关于 Linux void *mmap(void start , size_t length, int prot, int flags, int fd, off_t offset)?我们计划首先在 Linux 上进行原型设计。谢谢,
【解决方案4】:

我的直接猜测是,试图弄清楚如何从源代码到函数更好地使用这些可能(充其量)是一种非常迂回的方式来获得很多东西。特别是,您可能需要查看更多/其他代码才能在任何地方获得很多。当您深入了解时,mmap/MapViewOfFile 本身的代码可能提供的帮助很少(充其量),而其他代码(例如文件系统驱动程序和文件缓存中的代码)可能更有意义。

当您深入了解时,mmap 和 MapViewOfFile 的工作相对简单:设置页面描述符,将一系列虚拟地址映射到某个文件的某些部分。

在您尝试访问其中一个页面之前,不会发生太多其他/更多事情。这将触发“不存在”故障。故障处理程序将使用 I/O 子系统从磁盘中读取相应的数据,并返回让原始指令执行。仍然不是很有趣。

至少从优化的角度来看,有趣的地方在于 I/O 子系统内部。这可能(例如)跟踪页面错误的历史,并使用它来预测可能很快需要哪些页面(如果需要,则在错误发生之前发出对预测页面的读取)。

然而,mmap/MapViewOfFile 的源代码最多不会直接指向您可能关心的 I/O 子系统部分(事实上,它们可能在这方面)。

【讨论】:

  • 感谢您的回答。我猜你说的是 mmap 最有趣的部分是在 I/O 子系统代码中。谢谢您的帮助。今天晚上我将开始接受答案。
  • @Frank:是的,但是所涉及的 I/O 子系统代码根本不是 mmap 的一部分。 mmap 只是设置页面描述符。
  • 感谢您的回答。我猜你说的是不可能读取内核 mmap.c 使用的 I/O 子系统代码。谢谢。
  • @Frank:不,我是说 mmap.c 根本不会直接使用相关代码。 “页面不存在”故障的故障处理程序将。代码在那里并且可以阅读(至少在 Linux 中),但不会有任何东西直接从 mmap.c 引导到您关心的部分(它不会直接调用任何有趣的东西)。
  • 感谢您的回答。感谢您的澄清。
【解决方案5】:

有趣,但我也需要 mmap 源... :)

到目前为止,我只能在 NetBSD 上找到答案。 Based on this comment:

  • libc 函数在src/lib/libc/sys/mmap.c
  • 对应的核函数在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,但您可以将其替换为任何其他版本。

问候。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    相关资源
    最近更新 更多