实验探究 ioremap
生活随笔
收集整理的這篇文章主要介紹了
实验探究 ioremap
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
版權(quán)聲明:歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處 http://blog.csdn.net/lizuobin2/
? ? ioremap 寫驅(qū)動(dòng)最常用的函數(shù)之一,但是對(duì)它始終一知半解,看了內(nèi)核關(guān)于這部分的代碼,功力不夠也是一頭霧水。本文通過實(shí)驗(yàn)的方法,了解 ioremap 到底干了些啥,本文獻(xiàn)給那些看不懂內(nèi)核源代碼,還想知道 ioremap 能干些什么,干了些什么的同學(xué)。
? ? 實(shí)驗(yàn)方法:
? ??? ??點(diǎn)燈實(shí)驗(yàn),LED接在GPB5~8,因此需要使用 gpbcon 配置,gpbdat 輸出高低。? ??? ??? ??gpbcon ?0x56000010
? ??? ??? ??gpbdat ?0x56000014
? ??下面,嘗試了各種 ioremap 的方法測(cè)試,點(diǎn)燈 關(guān)燈 是否正常,點(diǎn)燈正常代表寄存器訪問沒問題。
1、字節(jié)映射還是頁映射?
? ??gpbcon = (volatile unsigned long *)ioremap(0x56000010, 1);
? ??gpbdat = gpbcon + 1;
? ??測(cè)試結(jié)果,點(diǎn)燈正常,雖然只映射一個(gè)字節(jié),但是 gpbcon、gpbdat 使用虛擬地址時(shí)可以訪問到物理地址,因此是頁映射。
2、同一頁的 映射的物理地址之前的地址是否也映射了?
? ??gpbdat = (volatile unsigned long *)ioremap(0x56000014, 1);
? ??gpbcon = gpbdat - 1;
? ??測(cè)試結(jié)果,點(diǎn)燈正常,雖然只映射了1個(gè)字節(jié),但是之前的地址也可以訪問到對(duì)應(yīng)的物理地址,因此,該物理地址所在的頁,全都都進(jìn)行了映射。
3、同一頁內(nèi),重復(fù)映射會(huì)怎樣?
? ??gpbcon = (volatile unsigned long *)ioremap(0x56000010, 1);
? ??gpbdat = (volatile unsigned long *)ioremap(0x56000014, 1);
? ??temp = ? (volatile unsigned long *)ioremap(0x56000014, 1);
? ??printk("gpbcon: %x\n", gpbcon);
? ??printk("gpbdat: %x\n", gpbdat);
? ??printk(" ?temp: %x\n", ? temp);
? ??輸出:
? ??? ??gpbcon: c483c010
? ??? ??gpbdat: c4840014 ?
? ??? ??temp: ? c4844014
? ??測(cè)試結(jié)果:
? ??? ??程序依舊正常運(yùn)行,但是輸出的 gpbcon、gpbdat 虛擬地址不連續(xù)!即使是相同的物理地址 ioremap 得到的虛擬地址不相等。
? ??1、那么,gpbcon + 1 也就是 c483c014 是不是也對(duì)應(yīng)于 gpbdat的物理地址呢?
? ??? ??gpbcon = (volatile unsigned long *)ioremap(0x56000010, 1);
? ??? ??gpbdat = (volatile unsigned long *)ioremap(0x56000014, 1);
? ??? ??temp = ? (volatile unsigned long *)ioremap(0x56000014, 1);
? ??? ??printk("gpbcon: %x\n", gpbcon);
? ??? ??printk("gpbdat: %x\n", gpbdat);
? ??? ??printk(" ?temp: %x\n", ? temp);
? ??? ??gpbdat_temp = gpbcon + 1;
? ??測(cè)試 虛擬地址gpbdat_temp 、gpbdat 是不是都能訪問到 gpbdat 的物理地址。?
? ??輸出:
? ??? ??gpbcon: c484a010
? ??? ??gpbdat: c484e014 ?
? ??? ??temp: ? c4852014
? ??測(cè)試結(jié)果:
? ??1、神奇,程序正常運(yùn)行,也就是說通過 虛擬地址 c484e014 或者(c484a010 + 4) 都能訪問到 gpbdat 的物理地址!
? ??因此,如果兩個(gè)物理地址位于同一頁,我們是沒必要去兩次ioremap的,1次就夠了,而且兩次會(huì)浪費(fèi)掉一頁虛擬空間。
? ??2、 推理,我通過ioremap temp 得到的虛擬地址也可以訪問到 gpbdat 的物理地址。
? ??? ??我通過ioremap temp 得到的虛擬地址 -4 也可以訪問到 gpbcon 的物理地址。
4、重復(fù)映射了,如何iounmap ?
? ??gpbcon = (volatile unsigned long *)ioremap(0x56000010, 1);
? ??gpbdat = (volatile unsigned long *)ioremap(0x56000014, 1);
? ??temp = ? (volatile unsigned long *)ioremap(0x56000014, 1);
? ??printk("gpbcon: %x\n", gpbcon);
? ??printk("gpbdat: %x\n", gpbdat);
? ??printk(" ?temp: %x\n", ? temp);
? ??iounmap(gpbcon);
? ??iounmap(gpbdat);
? ??iounmap(temp);
? ??測(cè)試:程序正常,沒有崩潰。
? ??? ??ioremap 可以有多個(gè)虛擬地址對(duì)應(yīng)于一個(gè)物理地址,iounmap時(shí)相互不受影響。
? ??猜測(cè):iounmap(gpbcon + n);保證(gpbcon + n 與 gpbcon在同一頁)應(yīng)該也可以釋放掉gpbcon,沒有測(cè)試。
結(jié)論:
? ??1、ioremap 按照頁大小進(jìn)行映射,而且是 整頁 。
? ??2、ioremap 允許對(duì)一個(gè)物理地址進(jìn)行多次映射,而且分配的虛擬空間地址各不相同(多個(gè)虛擬地址對(duì)應(yīng)于同一個(gè)物理地址)。而且,ioumap相互不影響。
曾經(jīng)疑惑的那些問題:
? ??1、我要是用一個(gè)寄存器,4個(gè)字節(jié)
? ??? ??ioremap(0x56000010, 1);
? ??? ??ioremap(0x56000010, 4);
? ??都能用?顯然,都能用~頁映射,該物理地址所在的頁,已經(jīng)全部被映射了。
? ??2、兩個(gè)驅(qū)動(dòng)程序,都要用到同一個(gè)寄存器,兩次Ioremap,iounmap,會(huì)不會(huì)沖突啊?
? ??? ??顯然經(jīng)過上邊的實(shí)驗(yàn),它們各自ioremap得到的虛擬地址不同,iounmap時(shí)只是把各地的虛擬地址釋放了而已,相互不會(huì)產(chǎn)生影響。
總結(jié)
以上是生活随笔為你收集整理的实验探究 ioremap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux设备模型之Class
- 下一篇: 内核request_mem_region