[英]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_page
和vm_insert_page
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.