IOCTL लिनक्स डिवाइस ड्राइवर [बंद]


126

क्या कोई मुझे समझा सकता है,

  1. क्या है IOCTL?
  2. इसका क्या उपयोग है?
  3. मुझे इसे कैसे प्रयोग में लाना है?
  4. मैं नए फ़ंक्शन को परिभाषित क्यों नहीं कर सकता जो उसी तरह काम करता है IOCTL?

जवाबों:


99

एक ioctl, जिसका अर्थ है "इनपुट-आउटपुट कंट्रोल" एक प्रकार का डिवाइस-विशिष्ट सिस्टम कॉल है। लिनक्स (300-400) में केवल कुछ सिस्टम कॉल हैं, जो सभी अद्वितीय फ़ंक्शन उपकरणों को व्यक्त करने के लिए पर्याप्त नहीं हैं। तो एक ड्राइवर एक ioctl को परिभाषित कर सकता है जो एक यूजरस्पेस एप्लिकेशन को इसे ऑर्डर भेजने की अनुमति देता है। हालाँकि, ioctls बहुत लचीले नहीं होते हैं और उनमें थोड़ा सा अकड़न (दर्जनों "मैजिक नंबर") होते हैं, जो सिर्फ काम करते हैं ... या नहीं), और असुरक्षित भी हो सकते हैं, क्योंकि आप एक बफर को कर्नेल में पास करते हैं - खराब हैंडलिंग टूट सकती है चीजें आसानी से।

एक विकल्प sysfsइंटरफ़ेस है, जहां आप एक फ़ाइल को नीचे सेट करते हैं /sys/और पढ़ते हैं / लिखते हैं कि और ड्राइवर से जानकारी प्राप्त करने के लिए। इसे कैसे सेट किया जाए, इसका एक उदाहरण:

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

और ड्राइवर सेटअप के दौरान:

device_create_file(dev, &dev_attr_version);

तब आपके पास अपने डिवाइस के लिए एक फ़ाइल होगी /sys/, उदाहरण के लिए, /sys/block/myblk/versionएक ब्लॉक ड्राइवर के लिए।

भारी उपयोग के लिए एक और तरीका है नेटलिंक, जो एक बीएसडी सॉकेट इंटरफेस पर अपने ड्राइवर से बात करने के लिए एक आईपीसी (अंतर-प्रक्रिया संचार) विधि है। इसका उपयोग, उदाहरण के लिए, वाईफाई ड्राइवरों द्वारा किया जाता है। आप इसके बाद libnlया libnl3लाइब्रेरीज़ का उपयोग करके यूजरस्पेस से इसके साथ संवाद करते हैं।


3
यह प्रश्न आंशिक रूप से 'उत्तर' देता है।
विशाल साहू

163

ioctlसमारोह डिवाइस ड्राइवर को लागू डिवाइस पर विन्यास स्थापित करने के लिए के लिए उपयोगी है। एक प्रिंटर की तरह, जिसमें फ़ॉन्ट परिवार की जांच और सेट करने के लिए कॉन्फ़िगरेशन विकल्प ioctlहैं, वर्तमान फ़ॉन्ट प्राप्त करने के लिए फ़ॉन्ट का उपयोग किया जा सकता है और साथ ही फ़ॉन्ट को नए पर सेट किया जा सकता है। एक उपयोगकर्ता एप्लिकेशन ioctlएक प्रिंटर को एक कोड भेजने के लिए कहता है कि यह वर्तमान फ़ॉन्ट को वापस करने के लिए या नए को फ़ॉन्ट सेट करने के लिए कहता है।

int ioctl(int fd, int request, ...)
  1. fdफ़ाइल डिस्क्रिप्टर है, जो द्वारा लौटा है open;
  2. requestअनुरोध कोड है। जैसे GETFONTप्रिंटर से वर्तमान फ़ॉन्ट मिलेगा, प्रिंटर SETFONTपर फ़ॉन्ट सेट करेगा;
  3. तीसरा तर्क है void *। दूसरे तर्क के आधार पर, तीसरा मौजूद हो सकता है या नहीं भी हो सकता है, उदाहरण के लिए यदि दूसरा तर्क है SETFONT, तो तीसरा तर्क फ़ॉन्ट का नाम हो सकता है जैसे "Arial";

int requestसिर्फ एक मैक्रो नहीं है। एक उपयोगकर्ता कोड एक अनुरोध कोड और डिवाइस ड्राइवर मॉड्यूल उत्पन्न करने के लिए आवश्यक है कि डिवाइस पर कौन सा कॉन्फ़िगरेशन के साथ खेला जाना चाहिए। एप्लिकेशन अनुरोध कोड का उपयोग करके भेजता है ioctlऔर फिर डिवाइस ड्राइवर मॉड्यूल में अनुरोध कोड का उपयोग करके यह निर्धारित करता है कि किस क्रिया को करना है।

एक अनुरोध कोड में 4 मुख्य भाग होते हैं

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

यदि अनुरोध कोड SETFONTएक प्रिंटर पर फ़ॉन्ट सेट करना है, तो डेटा ट्रांसफर की दिशा उपयोगकर्ता एप्लिकेशन से डिवाइस ड्राइवर मॉड्यूल तक होगी (उपयोगकर्ता एप्लिकेशन "Arial"प्रिंटर को फ़ॉन्ट का नाम भेजता है )। यदि अनुरोध कोड है GETFONT, तो दिशा प्रिंटर से उपयोगकर्ता के आवेदन के लिए है।

अनुरोध कोड उत्पन्न करने के लिए, लिनक्स कुछ पूर्वनिर्धारित फ़ंक्शन-जैसे मैक्रोज़ प्रदान करता है।

1. _IO(MAGIC, SEQ_NO)दोनों 8 बिट, 0 से 255 हैं, उदाहरण के लिए मान लें कि हम प्रिंटर को रोकना चाहते हैं। इसके लिए डेटा ट्रांसफर की जरूरत नहीं होती है। इसलिए हम नीचे दिए गए अनुरोध कोड को जनरेट करेंगे

#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

और अब के ioctlरूप में उपयोग करें

ret_val = ioctl(fd, PAUSE_PRIN);

ड्राइवर मॉड्यूल में संबंधित सिस्टम कॉल कोड प्राप्त करेगा और प्रिंटर को रोक देगा।

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGICऔर SEQ_NOइसके बाद के संस्करण के रूप में ही हैं, और TYPEअगले तर्क के प्रकार देता है, का तीसरा तर्क याद ioctlहै void *। डब्ल्यू __IOWइंगित करता है कि डेटा प्रवाह उपयोगकर्ता एप्लिकेशन से ड्राइवर मॉड्यूल तक है। एक उदाहरण के रूप में, मान लें कि हम प्रिंटर फ़ॉन्ट को सेट करना चाहते हैं "Arial"
#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)

आगे की,

char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font); 

अब fontएक पॉइंटर है, जिसका अर्थ है कि यह एक ऐसा पता है जो सबसे अच्छा प्रतिनिधित्व करता है unsigned long, इसलिए _IOWउल्लेख का तीसरा भाग इस प्रकार है। इसके अलावा, फ़ॉन्ट का यह पता डिवाइस ड्राइवर मॉड्यूल में लागू संबंधित सिस्टम कॉल को दिया जाता है unsigned long और हमें इसे उपयोग करने से पहले इसे उचित प्रकार में डालना होगा। कर्नेल स्थान उपयोगकर्ता स्थान तक पहुंच सकता है और इसलिए यह काम करता है। अन्य दो फ़ंक्शन-जैसे मैक्रो हैं __IOR(MAGIC, SEQ_NO, TYPE)और __IORW(MAGIC, SEQ_NO, TYPE)जहां डेटा प्रवाह क्रमशः कर्नेल स्थान से उपयोगकर्ता स्थान और दोनों तरीकों से होगा।

यदि यह सहायता करता है तो कृपया मुझे इसकी जानकारी दें!


मुझे आश्चर्य है कि अगर __IOW, __IOR और __IORW उपरोक्त कार्य सही हैं (मेरा मतलब है कि कुछ मामलों में डबल अंडरस्कोर है, कुछ मामलों में नहीं। मैंने कभी भी डबल अंडरस्कोर का उपयोग नहीं किया है) ... एक स्पष्ट विवरण के लिए धन्यवाद!
jcoppens

बहुत अच्छी तरह से समझाया .. धन्यवाद! क्या आप ड्राइवर साइड का एक छोटा कोड स्निपेट दे सकते हैं जो इस ioctl का उपयोग करता है?
आदश्री

उल्लेख opensourceforu.com/2011/08/io-control-in-linux उदाहरण के लिए
चंदोला

बहुत अच्छी तरह से समझाया गया। धन्यवाद। मुझे लगता है कि यह _IOWR नहीं _IORW है
मोहम्मद समी

ब्लॉग पोस्ट की तरह उत्तर दें।
फ्रेड्रिक गॉस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.