2015-06-30 62 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!