? 明確:mmap就是完成物理地址映射到用戶虛擬地址用的
?明確:用戶3G虛擬地址空間劃分:
??? ? ?0x00000000-------------------------------------------------------0xBFFFFFFF
??? ? ? ? ? ? ? ?代碼段 ?數據段 ?BSS段 ?堆區 ? MMAP虛擬內存區 ? ? ?棧區
??? ??? ??? ??? ??? ??? ??? ??? ??? ? ? ----><------ ? ? ? ? ? ?<----
函數原型:?
?void *mmap(void *addr, size_t length,?
??? ??? ? int prot, int flags,
int fd, off_t offset);
?函數功能:將物理地址空間映射到用戶虛擬內存空間上
??? ??? ? ?將物理地址映射到用戶虛擬地址
??? ??? ? ?老王課程這么講:將文件映射到用戶虛擬地址空間上
??? ??? ? ?文件對應硬件外設,外設通過物理地址訪問
??? ??? ? ?linux系統不允許訪問物理地址,利用mmap映射不得了
?參數:
? addr:給NULL,讓linux內核幫你在用戶虛擬內存區域找一塊
??? ? 空間內存用來映射物理地址
?length:讓linux內核幫你找的空閑用戶虛擬內存的大小
??? ??? ?切記:大小必須是頁面大小(4KB)的整數倍
?prot:描述內核幫你找的空閑用戶虛擬內存的訪問權限
??? ? 一般指定為:PROT_READ|PROT_WRITE
? flags:其余屬性,一般指定為:MAP_SHARED
? fd:硬件外設
?offset:偏移量,一般給0
?返回值:linux內核將空閑的用戶虛擬內存的首地址進行返回
??? ??? ?這個起始用戶虛擬地址同樣也是4KB整數倍
?
?參考代碼:
?void *addr;
?int fd = open("a.txt", O_RDWR);
?addr = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE,?
??? ??? ??? ?MAP_SHARED, fd, 0);
?說明:將文件a.txt映射到以addr起始的用戶虛擬內存上
??? ? ?將來訪問映射的用戶虛擬內存就是訪問文件
?
?//向映射的用戶虛擬內存拷貝字符串數據
本質是向文件a.txt寫入數據
?memcpy(addr, "hello,world", 12);
2.1.應用程序調用mmap,首先跑到C庫的mmap函數定義
2.2.C庫的mmap函數作兩件事:
1.保存mmap系統調用號到r7寄存器
2.調用swi/svc指令觸發軟中斷異常
2.3.一旦觸發軟中斷異常,CPU核立馬處理軟中斷異常
2.4.最后進程跑到內核空間繼續運行,跑到軟中斷異常的入口地址
運行,做如下事情:
1.調用軟中斷異常處理函數,而此函數做兩件事:
?1.從r7寄存器中取出mmap系統調用號
??? ?2.以mmap系統調用號為下標在內核的系統調用表中
??? ? ?找到mmap對應的內核函數sys_mmap,而內核的
??? ? ?sys_mmap做三件事:
??? ? ?1.內核的sys_mmap首先在當前進程的3G虛擬地址空間中
??? ? ? ?找一塊空閑的用戶虛擬內存,將來用于和物理地址
??? ??? ?做映射
??? ? ?2.一旦找到空閑的用戶虛擬內存,并且用戶mmap本身
??? ? ? ?也給用戶虛擬內存指定了一堆的屬性(大小,權限等)
??? ??? ?所以內核用struct vm_area_struct數據結構定義
??? ??? ?初始化一個對象來描述空閑的用戶虛擬內存的屬性
??? ? ? ?struct vm_area_struct {
??? ??? ??? ?unsigned long vm_start; //空間用戶虛擬內存的起始地址
??? ??? ??? ??? ??? ??? ??? ??? ??? ?//等于mmap的返回值addr
??? ??? ??? ?unsigned long vm_end; //結束地址=vm_start+大小?
??? ??? ??? ?pgprot_t vm_page_prot; //等于mmap傳遞的PROT_READ|PROT_READ|PROT_WRITE
??? ??? ??? ?unsigned long vm_flags;?? ?//等于mmap傳遞的MAP_SHARED
??? ??? ??? ?unsigned long vm_pgoff;?? ? //等于mmap傳遞的0
??? ??? ??? ?...
??? ??? ?};
??? ? ?3.最后內核的sys_mmap調用底層驅動的mmap接口
? 并且內核sys_mmap將第2步創建的對象的地址
? 也傳遞給底層驅動的mmap接口
??? ??? ?
3.底層驅動mmap執行完畢,進程返回,至此mmap調用結束 ??
struct file_operations {
??? ?int (*mmap) (struct file *file,?
??? ??? ??? ??? ?struct vm_area_struct *vma);
};
接口功能:永遠只能唯一做一件事:將已知的物理地址和已知的
??? ??? ?用戶虛擬地址做映射,類似:媒婆
??? ??? ?由于用戶虛擬地址在用戶空間,所以將來訪問操作
??? ??? ?都是在應用程序完成,而不是在內核驅動完成
??? ??? ?訪問映射的用戶虛擬地址就是在訪問物理地址
file:跟fd親戚關系
vma:指向內核sys_mmap創建的一個對象,此對象來描述空閑的
用戶虛擬內存的各種屬性,將來底層驅動mmap接口利用
此指針可以獲取到用戶虛擬內存的屬性:
vma->vm_start //獲取起始用戶虛擬地址
vma->vm_end?
vma->vm_flags
vma->vm_page_prot
...
問:底層驅動的mmap接口到底如何最終完成映射呢?
因為已知物理地址可以看手冊獲取到
已知的用戶虛擬地址通過vma指針能夠獲取到
如何將兩者關聯在一起呢?
萬事俱備只欠東風
答:只需調用以下函數完成關聯映射:
int remap_pfn_range(struct vm_area_struct *vma,?
??? ??? ??? ??? ??? ?unsigned long addr,
??? ??? ??? ??? ??? ?unsigned long pfn,?
??? ??? ??? ??? ??? ?unsigned long size,?
??? ??? ??? ??? ??? ?pgprot_t prot);
函數功能:完成最終的地址映射
vma:傳遞內核sys_mmap創建的對象地址
??? ? ?也就是傳遞驅動mmap接口的第二個參數
addr:傳遞空閑的用戶虛擬內存的首地址
也就是傳遞vma->vm_start
pfn:傳遞起始的物理地址>>12
??? ? ? 切記:此物理地址大小必須是4KB(0x1000)整數倍
??? ? ? 例如:
??? ??? ??? ?0xC001C000>>12:合法
??? ??? ??? ?0xC001C004>>12:不合法
size:傳遞映射的用戶虛擬內存的大小
? 也就是傳遞:vma->vm_end - vma->vm_start?
prot:傳遞用戶虛擬內存的訪問權限
??? ? ? ?也就是傳遞:vma->vm_page_prot
案例:利用mmap實現開關燈操作
參考代碼:day09/1.0
什么時候用:read,write,ioctl
什么時候用: mmap
4.1.read,write,ioctl數據操作流程
? 對設備讀操作:read,ioctl
??? ?數據流:硬件寄存器----->內核緩沖區------->用戶緩沖區
??? ??? ??? ??? ? ?gpio_get_value ? ? copy_to_user
?對設備寫操作:write,ioctl
??? ?數據流:用戶緩沖區----->內核緩沖區------->硬件寄存器?
??? ??? ??? ??? ??? ?copy_from_user ? ?gpio_set_value
??? ??? ??? ??? ??? ?
?結論:read,write,ioctl數據操作勢必要經過兩次數據拷貝:
用戶-內核->硬件
硬件->內核->用戶?
4.2.mmap數據操作流程:
? 對設備讀操作: 應用程序直接以指針形式讀取寄存器
??? ??? ??? ? ? data = *gpiocout;
? 對設備寫操作: 應用程序直接以指針的形式寫入寄存器?? ?
??? ??? ??? ? ? *gpiocout &= ~(1<< 12);
?結論:mmap數據操作只需一個數據拷貝:
??? ? ?用戶->硬件
??? ? ?硬件->用戶
??? ? ?
4.3.終極結論:
? 1.如果用戶對硬件操作訪問的數據量比較小,read,write,ioctl
的兩次數據拷貝對系統性能肯定有影響,但是這種影響幾乎
可以忽略不計,如果操作的數據量比較大,兩次數據拷貝
性能的影響是致命的,例如:攝像頭,LCD顯示屏,聲卡等
?2.如果訪問操作的數據量比較大,用read,write,ioctl勢必
影響系統的性能,務必采用mmap,將兩次數據拷貝變成一次
提供系統的性能效率
?3.由于mmap在使用的時候,分配的用戶虛擬內存必須是4KB的
整數倍,如果操作的數據量比較小,此時還用mmap
即使提高了系統的性能(幾乎體會不到),反而是浪費了
寶貴的內存資源
你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
網頁題目:驅動學習筆記9用戶空間地址映射mmap,應用程序直接用指針操作寄存器-創新互聯
當前URL:http://www.2m8n56k.cn/article2/ceggic.html
成都網站建設公司_創新互聯,為您提供關鍵詞優化、網站設計公司、標簽優化、服務器托管、網站內鏈、搜索引擎優化
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯