[英]C code, why is address 0xFF00 being cast to a struct?
我試圖了解一些用C編寫的USB Wi-Fi適配器的Linux內核驅動程序代碼。 文件/drivers/net/wireless/rtl818x/rtl8187/dev.c
1456
/drivers/net/wireless/rtl818x/rtl8187/dev.c
(以防萬一有人想參考內核代碼獲取上下文信息)讀取:
priv->map = (struct rtl818x_csr *)0xFF00;
我很好奇這里正確的操作數在做什么- (struct rtl818x_csr *)0xFF00;
。 我一直將此解釋為說“將廣播內存地址0xFF00
設置為rtl818x_csr
類型,然后將其分配給priv->map
”。 如果我的解釋是正確的,那么內存地址0xFF00
有什么特別之處,以至於驅動程序可以可靠地告知其后的內容將始終位於該地址? 我很好奇的另一件事是0xFF00只有16位。 如果它正在轉換內存地址,我期望32/64位。
任何人都可以弄清楚這行代碼中到底發生了什么嗎? 我想我對C語法的理解存在缺陷。
在驅動程序中,將絕對地址強制轉換為指向結構的指針是將設備的(內存映射)寄存器作為普通C結構訪問的常見方法。
使用0xff00
因為C不會對數字進行符號擴展。
0xFF00
是系統IO地址空間中的地址。 如果您查看代碼,則永遠不會直接取消引用地址,而是通過IO功能訪問該地址。
例如在通話中
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
RTL818X_EEPROM_CMD_CONFIG);
然后調用Linux內核底層IO功能。
地址被強制轉換為指向結構的指針,以訪問地址的偏移量,例如:
0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD)
請注意,在上面的rtl818x_iowrite8
調用中,由於&
運算符,在傳遞&priv->map->EEPROM_CMD
參數時,不會發生取消引用,只會計算地址+偏移量。 所述非關聯化withtin稱為內的內部低級別功能進一步實現rtl818x_iowrite8
。
您必須從設備角度考慮這一點。
從rtl8187器件映射的地址空間內的地址0xFF00開始是一個存儲器范圍,該存儲器范圍包含信息的結構與此處定義的rtl818x_csr結構相同。
因此,在邏輯上映射該區域之后,您就可以開始在其上進行總線讀寫操作來控制設備。 就像這里 (由於我沒有足夠的名聲來發布三個以上的鏈接,還不得不削減兩個超鏈接,但是你明白了)。 這些只是幾個例子。 如果您閱讀了整個文件,則隨處可見讀寫。
為了理解該結構的外觀以及為什么使用0xFF00代替0xBEEF或0xDEAD,您必須查閱該器件的數據表。
因此,如果您要開始查看內核代碼,特別是設備驅動程序,則不僅需要代碼。 您還將需要數據表或規格。 這可能很難找到(請參閱大量的電子郵件主題和文章,向供應商索取開放文檔)。
無論如何,我希望我回答了你的問題。 駭客入侵!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.