5

私の単純なアプリケーションが小さいサイズのメモリを mmap できない理由を教えてください。

そして、なぜそのような特定の境界 - 257UL?

// #define MAP_SIZE 256UL or below - fail
// #define MAP_SIZE 257UL - ok

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

int main(int argc, char **argv) {
    int fd;
    void *map_base, *virt_addr;
    unsigned long read_result, writeval;
    off_t target = strtoul("0x00002000", 0, 0);

    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
    printf("/dev/mem opened.\n");
    fflush(stdout);

    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
    if(map_base == (void *) -1) FATAL;
    printf("Memory mapped at address %p.\n", map_base);
    fflush(stdout);
...
}
4

2 に答える 2

3

mmap は、システムのページ サイズの倍数で機能します。i386/amd64 または実際に最新のほとんどの CPU でこれを実行している場合、これは 4096 になります。

私のシステムの mmap の man ページには、「オフセットは、sysconf(_SC_PAGE_SIZE) によって返されるページ サイズの倍数でなければなりません」と書かれています。一部のシステムでは、歴史的な理由から長さの引数がページ サイズの倍数ではない場合がありますが、その場合でも mmap はページ全体に切り上げます。

于 2012-10-10T09:45:23.200 に答える