2012-08-01 27 views
7

मैं यूएसबी वाई-फाई एडाप्टर के लिए सी में लिखे गए कुछ लिनक्स कर्नेल ड्राइवर कोड को समझने की कोशिश कर रहा हूं। फ़ाइल /drivers/net/wireless/rtl818x/rtl8187/dev.c (बस में मामला किसी संदर्भ के लिए कर्नेल कोड का उल्लेख करना चाहता था) में लाइन 1456 पढ़ता है:सी कोड, पता 0xFF00 एक संरचना में डाला जा रहा है क्यों?

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

मैं क्या बिल्कुल सही संकार्य यहाँ क्या कर रहा है के बारे में उत्सुक हूँ - (struct rtl818x_csr *)0xFF00;। मैं इसे rtl818x_csr टाइप करने के लिए "कास्ट मेमोरी एड्रेस 0xFF00 कहने के रूप में व्याख्या कर रहा हूं और फिर इसे priv->map पर असाइन करें"। अगर मेरी व्याख्या सही है, तो स्मृति पता 0xFF00 के बारे में इतना खास क्या है कि चालक विश्वसनीय रूप से बता सकता है कि इसके बाद क्या होगा यह हमेशा इस पते पर होगा? दूसरी बात यह है कि मैं उत्सुक हूं कि 0xFF00 केवल 16-बिट्स है। अगर मैं स्मृति पता कास्टिंग कर रहा था तो मुझे 32/64-बिट्स की उम्मीद होगी।

कोई भी इस कोड की लाइन में क्या हो रहा है, यह स्पष्ट कर सकता है? मुझे लगता है कि सी वाक्यविन्यास की मेरी समझ में एक दोष है।

+0

ऐसा लगता है कि RTL818x चिपसेट के लिए नियंत्रण/स्थिति रजिस्टर 0xFF00 को संबोधित करने के लिए स्मृति-मैप किया गया है। –

उत्तर

2

किसी संरचना के लिए पॉइंटर को एक पूर्ण पता कास्टिंग करना सामान्य सी संरचना के रूप में डिवाइस के (मेमोरी मैप किए गए) रजिस्टरों तक पहुंचने के लिए ड्राइवरों में एक आम तरीका है।

0xff00 का उपयोग करता है क्योंकि सी संख्याओं का साइन एक्सटेंशन नहीं करता है।

+0

यह संरचना के लिए नहीं बल्कि एक सूचक के लिए एक कलाकार है। –

2

0xFF00 सिस्टम के आईओ पता स्थान में एक पता है। यदि आप कोड में देखते हैं, तो पता कभी भी सीधे संदर्भित नहीं किया जाता है लेकिन आईओ कार्यों के माध्यम से उपयोग किया जाता है।

उदाहरण के लिए

, कॉल

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

जो तब कॉल लिनक्स कर्नेल निम्न स्तर आईओ कार्यों में।

पते में एक struct के लिए सूचक को डाला जाता है पता है, उदाहरण के यहां से ऑफसेट करने के लिए पहुँच प्रदान करने के:

0xFF00 + offsetof(struct rtl818x_csr, EEPROM_CMD) 

नोट ऊपर rtl818x_iowrite8 कॉल में, कोई भिन्नता होती है कि जब &priv->map->EEPROM_CMD तर्क क्योंकि गुजर & ऑपरेटर का, केवल पता + ऑफसेट की गणना की जाती है। rtl818x_iowrite8 के अंदर बुलाए गए आंतरिक निम्न स्तर के कार्यों के साथ अव्यवस्था को आगे बढ़ाया जाता है।

2

आपको इसे डिवाइस के दृष्टिकोण से देखना होगा।

rtl8187 डिवाइस के लिए मैप किए गए पता स्थान के अंदर पता 0xFF00 से शुरू करना एक स्मृति सीमा है जो आरटीएल 818x_csr संरचना here परिभाषित की गई जानकारी को उसी तरह संरचित करती है।

तो जब आप उस क्षेत्र को तार्किक रूप से मानचित्रित करते हैं तो आप बस को पढ़ना शुरू कर सकते हैं और डिवाइस को नियंत्रित करने के लिए लिख सकते हैं। here की तरह (दो और हाइपरलिंक्स को काटना पड़ा क्योंकि मेरे पास 3 से अधिक पोस्ट करने के लिए आवश्यक प्रतिष्ठा नहीं है, लेकिन आपको बिंदु मिल गया है)। ये केवल कुछ उदाहरण हैं। यदि आप पूरी फाइल पढ़ते हैं तो आप देखेंगे और लिखते हैं हर जगह छिड़कते हैं।

यह समझने के लिए कि वह संरचना उस तरह क्यों दिखती है और 0xFEEF या 0xDEAD के बजाय 0xFF00 का उपयोग क्यों किया जाता है, आपको उस डिवाइस के लिए डेटाशीट से परामर्श करना होगा।

तो यदि आप कर्नेल कोड और विशेष रूप से डिवाइस ड्राइवरों को देखना शुरू करना चाहते हैं, तो आपको केवल कोड से अधिक होना होगा।आपको डेटाशीट या विनिर्देशों की भी आवश्यकता होगी। यह ढूंढना मुश्किल हो सकता है (ईमेल थ्रेड के गज़लिया देखें और विक्रेताओं से खुले दस्तावेज की मांग करने वाले लेख देखें)।

वैसे भी, मुझे उम्मीद है कि मैंने आपके प्रश्न का उत्तर दिया है। हैप्पी हैकिंग!