Jak*_*nds 5 c linux memory size mmap
请告诉我,为什么我的简单应用程序无法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);
...
}
Run Code Online (Sandbox Code Playgroud)
可能您只是没有写入的权利/dev/mem
。这可能不是您想要的,将所有低端物理内存映射到您的地址空间。
查看shm_open
打开内存段或MAP_ANONYMOUS
匿名映射。
编辑:
执行以下操作man mem
来了解/dev/mem
设备节点的含义:
mem 中的字节地址被解释为物理内存地址。对不存在位置的引用会导致返回错误。
如果您想映射到设备节点以获得内存段,您应该使用/dev/zero
,但现在我上面描述的工具应该足够了。
那么不要,真的不要,以 root 权限运行这样的代码,除非你真的知道自己在做什么。写入物理内存并覆盖内核和用户空间数据和程序只会导致灾难。
mmap 在系统上以页面大小的倍数工作。如果您在 i386/amd64 或实际上大多数现代 CPU 上执行此操作,则这将是 4096。
在我系统上的 mmap 手册页中,它说:“偏移量必须是 sysconf(_SC_PAGE_SIZE) 返回的页面大小的倍数。”。在某些系统上,由于历史原因,长度参数可能不是页面大小的倍数,但在这种情况下 mmap 无论如何都会四舍五入到整页。
归档时间: |
|
查看次数: |
2374 次 |
最近记录: |