আইওসিটিএল লিনাক্স ডিভাইস ড্রাইভার [বন্ধ]


126

কেউ আমাকে ব্যাখ্যা করতে পারেন,

  1. কী IOCTL?
  2. এটা কি কাজে লাগে?
  3. আমি কীভাবে এটি ব্যবহার করতে পারি?
  4. আমি একইভাবে কাজ করে এমন নতুন ফাংশনটি কেন সংজ্ঞায়িত করতে পারি না IOCTL?

উত্তর:


99

একটি ioctl, যার অর্থ "ইনপুট-আউটপুট নিয়ন্ত্রণ" এক ধরণের ডিভাইস-নির্দিষ্ট সিস্টেম কল। লিনাক্সে কেবল কয়েকটি সিস্টেম কল রয়েছে (300-400), যা ডিভাইসগুলির সমস্ত অনন্য কার্যকারিতা প্রকাশ করতে যথেষ্ট নয়। সুতরাং একটি ড্রাইভার একটি আইওএসটিএল সংজ্ঞায়িত করতে পারে যা একটি ব্যবহারকারী স্থান অ্যাপ্লিকেশনটিকে আদেশ দেওয়ার জন্য অনুমতি দেয়। তবে, আইওসিটিএলগুলি খুব নমনীয় নয় এবং কিছুটা বিশৃঙ্খলাযুক্ত হওয়ার ঝোঁক রয়েছে (কয়েক ডজন "ম্যাজিক সংখ্যা" যা কেবল কাজ করে ... বা না), এবং এটিও অনিরাপদ হতে পারে, আপনি যখন কার্নেলটিতে একটি বাফারটি পাস করেন - খারাপ হ্যান্ডলিং ভেঙে যেতে পারে জিনিস সহজেই।

একটি বিকল্প হ'ল 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ব্লক ড্রাইভারের জন্য।

ভারী ব্যবহারের জন্য আরেকটি পদ্ধতি হ'ল নেটলিংক, যা একটি বিএসডি সকেট ইন্টারফেসের মাধ্যমে আপনার ড্রাইভারের সাথে কথা বলার জন্য একটি আইপিসি (আন্ত-প্রক্রিয়া যোগাযোগ) পদ্ধতি is এটি ওয়াইফাই ড্রাইভারদের দ্বারা উদাহরণস্বরূপ ব্যবহৃত হয়। তারপরে আপনি ইউজারস্পেস থেকে 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 ফাংশনগুলি সঠিক হয় (আমি কিছু ক্ষেত্রে ডাবল আন্ডারস্কোর বোঝাতে চাইছি, কিছু ক্ষেত্রে নেই I've
jcoppens

খুব ভালভাবে ব্যাখ্যা করা হয়েছে .. ধন্যবাদ! আপনি দয়া করে ড্রাইভার পাশের একটি ছোট কোড স্নিপেট দিতে পারেন যা এই আইওসিটিএল ব্যবহার করে?
আদিশ্রী

পড়ুন opensourceforu.com/2011/08/io-control-in-linux উদাহরণস্বরূপ
chandola

খুব ভাল ব্যাখ্যা করা হয়েছে। ধন্যবাদ. আমি মনে করি এটি _আইআরআর _ ইওআরডব্লিউ নয়
মোহাম্মদ স্যামি

উত্তর একটি ব্লগ পোস্ট মত।
ফ্রেড্রিক গাউস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.