0

我正在尝试使用 mmap() 将 sg 设备(例如 /dev/sg1)映射到内存中。我没有编写此代码,而是继承了它。相关代码为:

uint8_t *pRegion = NULL;
int fd = open("/dev/sg1", O_RDWR | O_NONBLOCK);
pRegion = mmap(0, 1048576, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if((void*)-1 == pRegion) {
    perror("mmap error");
    exit(1);
}

此代码始终使用 ENOMEM 出错,并且 perror() 打印“无法分配内存”。我在这里阅读了一些与 mmap() 有类似问题的人的早期帖子。据我所知,我有足够的内存。我的系统有 6gb(虽然这个系统应该只能访问 4gb,因为它是 32 位内核)。我看到其他显示内存统计数据的海报。这是我能找到的:

[andy@andylnx gcc_bin-32]$ free -m
             total       used       free     shared    buffers     cached
Mem:          6077        307       5770          0         30        102
-/+ buffers/cache:        174       5903
Swap:         4095          0       4095

交换空间似乎是正常的。据我所知,使交换空间等于您的物理内存大小(对于 32 位内核)是标准的。

[andy@andylnx gcc_bin-32]$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 47487
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 20000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

来自 sysctl 的一些有趣数据:

vm.max_map_count = 65530
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 33554432

我不知道为什么我没有记忆了。虽然我之前没有使用过这个特定的 POSIX 调用,但如果我理解正确的话,我要求将大约 1mb 的区域从设备 /dev/sg1 映射到内存中。看来我应该能够做到。请帮助我了解我所缺少的。

哦,当错误发生但文件长度为零时,我还查看了此进程的 /proc/[PID]/maps 。

谢谢,安迪

4

1 回答 1

1

我认为您收到错误不是因为您的进程中的地址空间/内存不足,而是因为 mmap 调用试图在内核中分配 1MB 的“保留缓冲区”,但默认值很可能小于1MB。来自 http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/mmap.html

'length' 参数应小于或等于与 'sg_fd' 关联的保留缓冲区的大小。如果它超过了保留的缓冲区大小(在“长度”向上舍入到页面大小的倍数之后),则返回 MAP_FAILED 并将 ENOMEM 放入 errno 中。

我认为您需要使用 ioctl 标志 SG_SET_RESERVED_SIZE 设置缓冲区的大小。

另见: http ://sg.danny.cz/sg/s_packet.html#mmap_notes

于 2013-08-27T00:06:06.617 回答