简体   繁体   English

无法将设备映射到内存

[英]Unable to map device into memory

I'm attempting to map an sg device, eg /dev/sg1, into memory using mmap(). 我正在尝试使用mmap()将sg设备(例如/ dev / sg1)映射到内存中。 I did not write this code but inherited it. 我没有编写此代码,但继承了它。 The relevant code is: 相关代码为:

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);
}

This code consitently errors out with ENOMEM and perror() prints, "Cannot allocate memory." 这段代码使ENOMEM出现错误,并且perror()打印出“无法分配内存”。 I've read some earlier posts here from individuals having similar issues with mmap(). 我从这里阅读过一些以前的帖子,这些帖子来自与mmap()有类似问题的个人。 As far as I know, I have enough RAM. 据我所知,我有足够的内存。 My system has 6gb (though only 4 should be accessible to this system since is a 32-bit kernel). 我的系统有6gb(尽管由于是32位内核,所以该系统只能访问4gb)。 I saw other posters showing memory stats. 我看到其他海报显示了内存状态。 Here's what I can find: 这是我可以找到的:

[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

The swap space seems to be about normal. 交换空间似乎正常。 From what I recall, it's standard to make the swap space equal to your physical memory size (which it is for a 32-bit kernel). 我记得,使交换空间等于您的物理内存大小(对于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

Some interesting data from sysctl: 来自sysctl的一些有趣的数据:

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

I'm at a loss for why I'm out of memory. 我不知为什么我内存不足。 Although I've not used this particular POSIX call before, if I understand it correctly, I'm asking to map a region of approximately 1mb into memory from the device /dev/sg1. 尽管我以前没有使用过这个特殊的POSIX调用,但是如果我理解正确的话,我要求从设备/ dev / sg1将大约1mb的区域映射到内存中。 It would seem that I should be able to do so. 看来我应该能够这样做。 Please help me to understand what I'm missing. 请帮助我了解我所缺少的。

Oh, I also looked at /proc/[PID]/maps for this process when the error occurs but the file is zero length. 哦,当错误发生但文件长度为零时,我也查看了/ proc / [PID] / maps进行此过程。

Thanks, Andy 谢谢,安迪

I think you are getting the error not because you're out of address space/memory in your process, but because the mmap call is trying to allocate 1MB of the "reserved buffer" in the kernel, but the default is most likely less than 1MB. 我认为您收到错误不是因为您的进程空间不足,而是因为mmap调用试图在内核中分配1MB的“保留缓冲区”,但是默认值很可能小于1MB。 From http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/mmap.html : http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/mmap.html

The 'length' argument should be less than or equal to the size of the reserved buffer associated with 'sg_fd'. “长度”参数应小于或等于与“ sg_fd”关联的保留缓冲区的大小。 If it exceeds the reserved buffer size (after 'length' has been rounded up to a page size multiple) then MAP_FAILED is returned and ENOMEM is placed in errno. 如果超过保留的缓冲区大小(在将“长度”舍入为页面大小的倍数后),则返回MAP_FAILED并将ENOMEM放置在errno中。

I think you need to set the size of the buffer using the ioctl flag SG_SET_RESERVED_SIZE. 我认为您需要使用ioctl标志SG_SET_RESERVED_SIZE设置缓冲区的大小。

See also: http://sg.danny.cz/sg/s_packet.html#mmap_notes 另请参阅: http : //sg.danny.cz/sg/s_packet.html#mmap_notes

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM