2012-08-01 78 views
7

我想了解一些用C寫的USB Wi-Fi適配器的Linux內核驅動程序代碼。在文件/drivers/net/wireless/rtl818x/rtl8187/dev.c(以防萬一有人想參考上下文的內核代碼)1456行讀取:C代碼,爲什麼地址0xFF00被轉換爲struct?

priv->map = (struct rtl818x_csr *)0xFF00; 

我很好奇究竟是什麼正確的操作是在這裏做什麼 - (struct rtl818x_csr *)0xFF00;。我一直在解釋這是說:「將內存地址0xFF00設置爲rtl818x_csr,然後將其分配給priv->map」。如果我的解釋是正確的,那麼內存地址0xFF00有什麼特別的地方,驅動程序能夠可靠地說出它後面的東西總是在這個地址?我很好奇的另一件事是0xFF00只有16位。如果它正在播放一個內存地址,我會期待32/64位。

任何人都可以澄清這一行代碼到底發生了什麼?我想我的C語法理解存在缺陷。

+0

它看起來像是RTL818x芯片組的控制/狀態寄存器存儲器映射到地址0xFF00。 – 2012-08-01 10:04:19

回答

2

將絕對地址轉換爲指向結構的指針是驅動程序以普通C結構訪問設備(內存映射)寄存器的常用方法。

使用0xff00的工作原理是因爲C沒有做數字的符號擴展。

+0

這不是對結構的轉換,而是對指針的轉換。 – 2012-08-01 10:05:22

2

0xFF00是系統的IO地址空間中的地址。如果您查看代碼,地址永遠不會直接解除引用,但可以通過IO函數訪問。

例如,在呼叫

rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, 
       RTL818X_EEPROM_CMD_CONFIG); 

然後調用Linux內核低電平IO功能。

地址被轉換爲指針結構,能由ADRESS,例如這裏獲得補償:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD) 

注意,在上面的rtl818x_iowrite8通話,傳遞&priv->map->EEPROM_CMD說法,因爲當沒有發生提領&運算符,只計算地址+偏移量。使用在rtl818x_iowrite8內部調用的內部低級函數可進一步實現解除引用。

2

你必須從設備的角度考慮這一點。

從映射到rtl8187設備的地址空間內的地址0xFF00開始,是一個內存範圍,其保存的信息結構與rtl818x_csr結構定義的here相同。

因此,邏輯映射該區域後,您可以開始在其上執行總線讀取和寫入操作來控制設備。像here(不得不減少兩個超鏈接,因爲我沒有必要的聲望超過3,但你明白了)。這些只是一些例子。如果你閱讀整個文件,你會看到讀寫遍佈各處。

爲了理解爲什麼這個結構看起來這樣,爲什麼使用0xFF00而不是0xBEEF或0xDEAD,你必須查閱該設備的數據手冊。

所以,如果你想開始看內核代碼,特別是設備驅動程序,你將不得不有更多的代碼。您還需要數據表或規格。這可能很難找到(請參閱電子郵件線索和文章向供應商徵求開放文檔的超文本)。

無論如何,我希望我回答你的問題。 快樂黑客!