【发布时间】:2015-06-30 14:24:25
【问题描述】:
我正在尝试将操作系统(Ubuntu Server 15.04)限制为一定的内存使用量并保留其余部分,但编写一个内核模块来读取/写入保留的内存。我想出了如何使用内核参数“mem=4G memmap=4G@0 memmap=4G$4G”来限制使用/保留内存(操作系统为 4GB,保留 4GB,在 4GB 处拆分)但我不知道如何对保留内存的 DMA 与内核模块一起使用。我想只创建一个 proc 文件,但我不确定您是否可以在操作系统分配的内存之外创建一个。
有什么建议吗?谢谢!
编辑:这是为了研究,所以它不需要“很好”
更新: 也许我不需要编写内核模块。我刚刚找到了这个,我要试一试: http://elinux.org/Memory_Management#Reserving_.28and_accessing.29_the_top_of_memory_on_startup
更新: 我尝试了上面的链接,但每当我尝试写作时都会出现段错误。这是我的代码:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mann.h>
#define RESERVED_MEMORY_SIZE 0x100000000
int main() {
int fd;
char *reserved_memory;
fd = open("/dev/mem", O_RDWR | O_SYNC);
reserved_memory = (char *) mmap(0, RESERVED_MEMORY_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 4096);
reserved_memory[0] = 'a';
return 0;
}
dmesg 显示:
a.out[1167]: segfault at ffffffffffffffff ip 00000000004005d7 sp 00007ffeffccbd80 error 7 in a.out[400000+1000]
为了好玩,我尝试了 reserved_memory[1]:
a.out[1180]: segfault at 0 ip 00000000004005db sp 00007ffc388d77b0 error 6 in a.out[400000+1000]
我将研究这些消息的格式,以便弄清楚它在告诉我什么。
更新:
我发现这个问题是由与我有相同问题的人提出的,但唯一的解决方案似乎是内核重建。我将尽量避免这种情况,所以也许我最好的选择是再次自定义内核模块。 accessing mmaped /dev/mem?
【问题讨论】:
-
您确定您使用的
mmap正确吗?当您请求从偏移量 4096 开始映射 4GiB 区域时,它似乎返回错误(-1 数值),并且根据您的问题,系统没有 4GiB+4096Byte 内存(因为您拆分为 4GiB)。也许你交换了第二个和最后一个论点?另外我不知道 /dev/mem 是否可用于访问整个(内存)地址空间或仅用于访问可用 RAM 占用的部分。 -
@knm241 我刚刚添加了对 mmap 的返回值的检查,看起来它失败了。好决定!我想我不明白偏移参数是什么。我认为那是物理地址开始的地方,它将在 4GB 点(保留内存的开始)。
-
/dev/mem是一个文件。读第一个字节就是读物理地址0x0,读第二个字节就是读0x1,读第100个字节就是读地址0x63。offset参数告诉mmap从哪个字节开始读取/dev/mem。所以如果要从4GiB开始映射内存,偏移量必须是0x100000000。第二个参数是要映射多少字节,可以是4096。 -
好的,有道理。我将该行更改为
reserved_memory = (char *) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0x100000000);,但仍然无法映射。 -
查看here 以获取可能的错误列表。包含
errno.h标头并打印errno左值的值(即printf("%d\n", errno)。我的猜测是您无法映射操作系统不知道的内存。
标签: c linux memory-management linux-kernel