2012-08-01 6 views
7

Próbuję zrozumieć niektóre kod sterownika jądra Linux napisany w C dla karty USB Wi-Fi. Linia w pliku /drivers/net/wireless/rtl818x/rtl8187/dev.c1456 (na wszelki wypadek, gdyby ktoś chciał odnieść się do kodu jądra dla kontekstu) brzmi:Kod C, dlaczego adres 0xFF00 jest przesyłany do struktury?

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

Jestem ciekaw, co dokładnie prawy argument jest tu robi - (struct rtl818x_csr *)0xFF00;. Interpretowałem to jako mówiąc "adres pamięci wylewki o adresie 0xFF00 jako typu rtl818x_csr, a następnie przypisz go do priv->map". Jeśli moja interpretacja jest prawidłowa, co jest takiego szczególnego w adresie pamięci 0xFF00, że kierowca może niezawodnie stwierdzić, że to, o co chodzi, będzie zawsze pod tym adresem? Inną ciekawostką jest to, że 0xFF00 ma tylko 16 bitów. Oczekiwałbym 32/64-bitów, jeśli przesyła adres pamięci.

Czy ktoś może dokładnie wyjaśnić, co się dzieje w tym wierszu kodu? Wyobrażam sobie, że w moim zrozumieniu składni C jest błąd.

+0

Wygląda na to, że rejestr sterowania/stanu mikroukładu RTL818x jest odwzorowany w pamięci na adres 0xFF00. –

Odpowiedz

2

Przesyłanie bezwzględnego adresu do wskaźnika do struktury jest powszechnym sposobem uzyskiwania dostępu do rejestrów (odwzorowanych w pamięci) urządzenia jako normalnej struktury C.

Korzystanie z 0xff00 działa, ponieważ C nie robi podpisania rozszerzenie numerów.

+0

To nie jest rzutowanie na strukturę, ale na wskaźnik. –

2

to adres w przestrzeni adresowej IO systemu. Jeśli zajrzysz do kodu, adres nie zostanie nigdy bezpośrednio odwołany, ale uzyska się dostęp poprzez funkcje IO.

Na przykład w zaproszeniu

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

które następnie wywołuje jądra Linux niskopoziomowych funkcji IO.

Adres odlewa się do wskaźnika do struktury w celu umożliwienia dostępu do offsetu z adress, przykład tutaj:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD) 

Należy pamiętać, że w zaproszeniu rtl818x_iowrite8 powyżej, nie dereference występuje po minięciu &priv->map->EEPROM_CMD argumentu, ponieważ operatora &, obliczany jest tylko adres + przesunięcie. Dereferencja jest dalej osiągana dzięki wewnętrznym funkcjom niskiego poziomu określanym wewnątrz rtl818x_iowrite8.

2

Musisz wziąć to pod uwagę z punktu widzenia urządzenia.

Począwszy od adresu 0xFF00 w przestrzeni adresowej zamapowanej dla urządzenia rtl8187 jest zakres pamięci zawierający informacje o strukturze zdefiniowanej w ten sam sposób co struktura rtl818x_csr zdefiniowana jako here.

Po logicznym odwzorowaniu tego regionu można rozpocząć wykonywanie odczytów magistrali i zapisywanie na nim w celu sterowania urządzeniem. Tak jak here (musiałem wyciąć jeszcze dwa hiperlinki, ponieważ nie mam reputacji koniecznej do opublikowania więcej niż 3, ale masz rację). To tylko kilka przykładów. Jeśli przeczytasz cały plik, zobaczysz, że odczyty i zapisy są posypywane wszędzie.

Aby zrozumieć, dlaczego ta struktura wygląda w ten sposób i dlaczego 0xFF00 jest używany zamiast 0xBEEF lub 0xDEAD, musisz zapoznać się z arkuszem danych dla tego urządzenia.

Jeśli więc chcesz zacząć przeglądać kod jądra, a zwłaszcza sterowniki urządzeń, będziesz musiał mieć więcej niż tylko kod.Będziesz także potrzebował arkusza danych lub specyfikacji. Może to być raczej trudne do znalezienia (patrz gazele wiadomości e-mail i artykuły zachęcające do otwarcia dokumentacji od dostawców).

W każdym razie, mam nadzieję, że odpowiedziałem na twoje pytanie. Happy hacking!

Powiązane problemy