如何使用内核模块直接访问保留内存?

时间:2015-06-30 14:24:26

标签: c linux memory-management linux-kernel

我正在尝试将操作系统(Ubuntu Server 15.04)限制为某种内存使用情况,并保留其余部分但写入内核模块以读取/写入保留内存。我想出了如何使用内核参数“mem = 4G memmap = 4G @ 0 memmap = 4G $ 4G”来限制使用/预留内存(OS为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?

1 个答案:

答案 0 :(得分:4)

好的,所以我想我解决了。事实证明我只是不明白mmap是如何工作的,我想如果它在保留的内存中,内核对写/读/ dev / mem没有限制。下面是两个程序,它们将写入我在内存中的保留位置并从中读取。

写下“Hello World!”:

    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>

    #define RESERVED_MEMORY_OFFSET  0x100000000     /* Offset is 4GB */

    int main() {
            int fd;
            char *reserved_memory;
            char *buffer = "Hello World!";

            fd = open("/dev/mem", O_RDWR | O_SYNC):
            /* Returns a pointer to the 4GB point in /dev/mem - the start of my reserved memory. Only mapping 4096 bytes. */
            reserved_memory = (char *) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, RESERVED_MEMORY_OFFSET);
            if (reserved_memory == MAP_FAILED) {
                    printf("Failed to creating mapping.\n");
                    printf("ERRNO: %s\n", strerror(errno));
                    return -1;
            }
            sprintf(reserved_memory, "%s", buffer);
            return 0;
    }

从保留存储器的开头读取:

    #include <errno.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mman.h>

    #define RESERVED_MEMORY_OFFSET  0x100000000     /* Offset is 4GB */

    int main() {
            int fd;
            char *reserved_memory;
            char buffer[13];

            fd = open("/dev/mem", O_RDWR | O_SYNC):
            /* Returns a pointer to the 4GB point in /dev/mem - the start of my reserved memory. Only mapping 4096 bytes. */
            reserved_memory = (char *) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, RESERVED_MEMORY_OFFSET);
            if (reserved_memory == MAP_FAILED) {
                    printf("Failed to creating mapping.\n");
                    printf("ERRNO: %s\n", strerror(errno));
                    return -1;
            }
            snprintf(buffer, 13, "%s", reserved_memory);
            printf("%s\n", buffer);
            return 0;
    }

特别感谢@ knm241!