簡體   English   中英

C代碼,為什么將地址0xFF00強制轉換為結構?

[英]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.

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