簡體   English   中英

如何在 Linux 中調用 mmap() 時獲取設備中某個字段的偏移量

[英]How to get the offset of a field within a device in Linux when calling mmap()

我目前正在 Linux 設備驅動程序中實現mmap()

基本上,假設已經定義了一個名為data的結構。 我的設備結構定義如下,

struct test_dev{
    struct cdev cdev;
    struct mutex lock;
    struct data *data;
};

在設備的open()方法中,通過調用 vmalloc() 分配data 假設我想讓用戶調用mmap()映射到數據字段,用戶需要知道data字段的offset

int fd = open("/dev/testdev", O_RDWR);
int ret = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);

試圖找到data的偏移量時我被卡住了。

我查看了 mmap() 的聯機幫助頁,它說

文件映射的內容(與匿名映射相反;請參閱下面的 MAP_ANONYMOUS)使用從文件描述符 fd 引用的文件(或其他對象)中的偏移偏移量開始的長度字節進行初始化。

Q1:由於data域是用vmalloc()分配的,在high memory,而test_dev結構是用kmalloc()分配的,在low memory,addr(data) - addr(test_dev)小於0,所以,我們不能以這種方式計算偏移量。 我可以知道是否有另一種方法來獲取offset ,以便用戶可以將此offset用於mmap()data字段?

Q2:如果改為使用kmalloc()分配data字段, vmalloc()方法之間會有什么區別嗎?

Linux Device Drivers 中,它指出kmalloc()返回的內存地址也是虛擬地址,並且位於低內存中。 我不確定使用“addr(data) - addr(test_dev)”是否有效。 根據我自己的理解,它不太可能起作用。

此外,由於kmalloc() kmalloc()是內核中為小於頁面大小的對象分配內存的正常方法,因此在實現mmap()時,我們可能不會選擇映射到kmalloc()返回的地址,因為mmap () 映射到頁面邊界。

偏移量將傳遞給您在設備驅動程序中編寫的 mmap 處理程序。 您可以將其視為任意的off_t參數,表示您想要的任何內容。 只需忽略它並始終 mmap data 或者將其用作data開頭的偏移量,這可能是您的驅動程序最正確的語義。

您在驅動程序初始化時使用 kmalloc() 的結構與 mmap 無關。 offset不是從此結構開始的偏移量。

要 mmap vmalloc 內存,您需要獲取每個頁面,因為它們不連續,並將其添加到 vma。 請參閱vmalloc_to_pagevm_insert_page

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM