4

我會在用戶應用程序中使用malloc分配內存,並通過字符驅動程序接口發送malloc返回地址到內核模塊。我們可以在內核模塊中使用virt_to_phys作爲用戶空間內存嗎?

我會爲腳內核模塊中使用get_user_pages_fast該內存的頁面。

我可以使用virt_to_phys度日malloc返回的地址。 它有效嗎?如果沒有,那我該如何獲得適當的物理地址?

我的目標是讓用戶空間分配內存的物理地址。 我將傳輸大小限制爲pagesize(4KB)。

+0

您是否需要實際的物理地址或DMA地址?您可以在固定頁面上使用'dma_map_page()',或者如果您已經從固定頁面創建了分散 - 收集列表,則可以使用'dma_map_sg()。如果你想讓CPU訪問頁面,你可以使用'kmap_atomic()'獲得頁面的內核虛擬地址。請注意,使用'kmap_atomic()'映射的頁面需要按照與映射順序完全相反的順序進行取消映射。 –

回答

0

該程序將幫助您直接訪問物理內存。想法是mmap/dev/mem(RAM)

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

int main(int argc, char *argv[]) { 
    if (argc < 3) { 
     printf("Usage: %s <phys_addr> <offset>\n", argv[0]); 
     return 0; 
    } 

    off_t offset = strtoul(argv[1], NULL, 0); 
    size_t len = strtoul(argv[2], NULL, 0); 

    // Truncate offset to a multiple of the page size, or mmap will fail. 
    size_t pagesize = sysconf(_SC_PAGE_SIZE); 
    off_t page_base = (offset/pagesize) * pagesize; 
    off_t page_offset = offset - page_base; 

    int fd = open("/dev/mem", O_SYNC); 
    unsigned char *mem = mmap(NULL, page_offset + len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, page_base); 
    if (mem == MAP_FAILED) { 
     perror("Can't map memory"); 
     return -1; 
    } 

    size_t i; 
    for (i = 0; i < len; ++i) 
     printf("%02x ", (int)mem[page_offset + i]); 

    return 0; 
} 

幸得Accessing physical address from user space

1

,你不行,virt_to_phys 內核虛擬地址轉換成物理地址。存在3(或4)在linux類型的地址:

  • 內核虛擬地址:其是物理地址+/-偏移(PAGE_OFFSET)。
  • 內核物理地址:實際物理地址(由__pa或virt_to_phys功能獲得)。
  • 用戶虛擬地址:翻譯到物理地址的過程的頁表內。

注意,頁表「佈局」取決於處理器的架構,所以你需要實現一個軟件頁錶行走對應於你的工作的架構。

而最後一個字,第4種存在的地址是:

  • 總線地址:這是一個地址由設備所看到。
1

malloc返回用戶虛擬地址。所以我認爲你不能使用驅動程序裏面的malloc返回的地址。

virt_to_phys:返回的物理地址是給定內存地址的物理(CPU)映射。只有在通過kmalloc直接映射或分配的地址上使用此函數纔有效。這意味着它被內核用來將內核虛擬地址(不是用戶虛擬地址)轉換爲物理地址

相關問題