2015-06-30 63 views
4

我试图限制操作系统(Ubuntu服务器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?

+0

你确定你正确使用'mmap'吗?看起来它正在返回一个错误(-1数字值),因为您正在请求映射从偏移量4096开始的4GiB区域,并根据您的问题系统没有4GiB + 4096Byte内存(因为您分割为4GiB)。也许你换了第二个和最后一个参数?此外,我不知道/ dev/mem是否可以用来访问整个(内存)地址空间,或者只是可用RAM占用的部分。 –

+0

@ knm241我刚刚添加了一个检查mmap的返回值,它看起来像是失败了。好决定!我想我不明白偏移参数是什么。我认为这是物理地址开始在4GB点(保留内存的开始)的地方。 – smbullet

+0

'/ dev/mem'是一个文件。读取第一个字节意味着读取物理地址0x0,读取第二个字节意味着读取0x1,读取第100个字节意味着读取地址0x63。 'offset'参数告诉'mmap'哪个字节开始读取'/ dev/mem'。所以如果你想从4GiB开始映射内存,偏移量必须是0x100000000。第二个参数是你想映射多少字节,可以是4096. –

回答

3

好吧,所以我想我解决了它。原来我只是不明白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!