ورود/ایجاد حساب کاربری
   منوی اصلی
· خانه
· لیست کاربران
· جستجو
· آمار مشاهدات
· آرشیو مقالات


- شرح
· راهنمای نویسندگان
· درباره ما

   همکاری با نشریه
در صورتی که مایل به همکاری با نشریه هستید، می‌توانید در لیست پستی نشریه عضو شده و در جریان امور قرار گیرید. برای اطلاعات بیشتر، اینجا کلیک کنید.

   کاربران
سردبیر
هیچ مدیر کمکی حاضر
همکاران
هیچ مدیر کمکی حاضر
اعضا:
جدیدترین:جدید امروز:0
جدیدترین:جدید دیروز:0
جدیدترین:مجموع:2471
جدیدترین:جدیدترین:
ufumenarayu
اعضا:حاضر
اعضا:اعضا:0
مهمان‌ها:مهمان‌ها:3
مجموع:مجموع:3
کاربران حاضر
هیچ کاربر حاضری وجود ندارد

   ورود کاربران




 


 برای ورود مشکل دارید؟
 ثبت نام کاربران جدید

ماژول نویسی برای هسته لینوکس (قسمت ششم)

(645 مجموع کلمات موجود در متن)
(5991 بار مطالعه شده است)  نسخه چاپی

ماژول نویسی برای هسته لینوکس (قسمت ششم)


ثبت (register) یک دستگاه در هسته

همان طور که در قسمت قبل بحث کردیم، دستگاه‌های کاراکتری از طریق فـــایل‌های دستگاه کــه معمولا در dev/ قرار می‌گیــرند قــابل دسترسی هستند. در قسمت قبــل به این موضوع نیز پرداختیم که عدد اصلی هــر فایل دستگاه نشان می‌دهد که دستگاه توسط چه راه اندازی کنترل شده و عــدد فـــرعی تــوسط خود راه انداز بــرای تمایز بین دستگاه‌های تحت کنترل خود به کار می‌رود.

اضافه کردن یک راه انداز به سیستم به معنی ثبت آن در هسته است. مترادف این جمله آن است کــه در هنــگام شروع به کار ماژول (initialization)، به آن یــک عــدد اصلی نسبت داده شــود. شما می‌توانید این کــار را بـــا استـــفاده از تابع register_chrdev که در <linux/fs.h> تعریف شده است انجام دهید:

int register_chrdev(unsigned int major, const char *name,

struct file_operations fops);

unsigned int major عـــدد اصلی مورد درخواست و const char *name نام دستگاه شما اســت کــه در proc/devices/ ظاهر خواهد شد و struct file_operations *fops نیز اشاره‌گــر بــه سـاختار داده file_operations مورد استفاده راه انداز هستند. اگر مقدار بازگشتی این تابع منفی باشد ثبت دستگاه در هسته موفقیت آمیز نبوده است.

به این نکته توجه داشته باشید که ما عدد فرعی‌ای بـــه ایــن تابع پاس نکردیم چون که این موضوع برای هسته اهمیتی ندارد و ماژول خود از ان استفاده می‌کند.

سوال بسیار مهمی‌کــه ممکن است مطــرح شــود این است که چگونه عدد اصلی ای به تابع register_chrdev بدهیم و مطمئن باشیم که قبلا توسط راه انداز دیگری اختیار نشده است؟

آسان‌ترین راه برای ایــن کار رجــوع بــه فایل linux/Documentation/devices.txt از کد منبع هسته لینوکس و انتخاب یک عدد رزرو نشده است. مطمئنا این راه بدترین راه است چــون هیـــچ اطمینانی در قابـــل استفاده بودن آن عــدد اصــلـی نمی‌دهد. بهترین راه آنست کــه شما از خود هسته بخواهید که به صورت دینامیک یک عدد اصلی در اختیار شما بگذارد. اگر ورودی اول تابع register_chrdev که همان unsigned int major است را صفر قرار دهید، هستـه یک عدد اصلی را به عنوان مقدار بازگشتی تابع register_chrdev به شما باز می‌گرداند.


خروج (unregister) یک دستگاه از هسته

ما نمی‌توانیم اجازه دهیم که هر هنگام یک ماژول هسته rmmod شــود. اگــر فایل دستگاه توسط یک پروسه بــاز شـده باشد و مــا مــاژول را از هسته خارج کنیم، آن پروسه بـه آن قسمت از حافظه که آدرس آن تــابــع از راه انـــداز است، دسترسی داشته و می‌تواند آن تابع را صدا نماید. اگر خیلی خوش شانس باشیم و کــد جدیدی در آن آدرس load نشده باشد، فقط یک پیغام خطا دریافت خواهیم کرد. ولــی اگـر خیلی خوش شانس نباشیم و ماژول جدیدی در آن ادرس load شده باشد، به این معنی است که در میــان تابع جدیدی از هستــه خــواهیم پرید. نتیجه این کار به هیچ وجه قابل پیش بینی نیست ولی در اکثر موارد اتفاق‌های نسبتا ناگواری در سیستم به بار می‌آید.

معمولا برای اینکه شما اجازه انجام کاری را ندهید، یک پیغام خطا (یک عدد منفی) توسط آن تابع انجام دهنده کــار بر خواهید گردانــد. در مــورد تابع cleanup_module ایــن کار ممکن نیست، چـون ایــن تــابــع void بـر می‌گرداند (چیزی بر نمی‌گرداند). راه متداول این کار وجود یک شمارنده در ماژول است کـه تعداد پروسس‌هایی که از ماژول استفاده می‌کنند را نگه می‌دارد. شما می‌توانید مقدار این شمارنده را در سومین فیلد proc/modules/ مشاهده کنیــد. اگـر این مقدار غیر صفر باشد دستور rmmod با شکست مواجه خواهد شد.

توجه داشته باشیــد کــه شما نبایستی این شمـارنده را در cleanup_module چک نمایید بدلیل اینکه این ارزیابی توسط تابع سیستمی‌sys_delete_module که در linux/module.c تعریف شده است بـــرای شمـــا انــجــام می‌شـــود. شـمــا نمی‌توانید از این تابع بــه طور مستقیم استفــاده نمایید امــا توابعی در <linux/modules.h> تعریف شده است که اجازه افزایش، کاهش و مشاهده این شمارنده را می‌دهد. به عنوان مثال:

try_module_get(THIS_MODULE)

که یک واحد شمارنده را زیاد می‌کند و

try_module_get(THIS_MODULE)

که یک واحد شمارنده را کاهش می‌دهد.

نکته بسیار مهم این است که مقدار این شمارنده بایستی همیشه صحیح نگه داشته شود. اگر این مقدار خراب شود به هیچ عنوان نمی‌توان ماژول را unload کرد. در این مرحله هیچ کاری به جز reboot نمی‌توان کرد.


خلاصه : در قسمت پیش و ایــن قسمت با دو ساختــار داده file_operations و file و اهمیت آنها آشنــا شــدیـم و نحوه مقدار دهی آنــها را نیز فرا گرفتیم. در ادامه با استفاده از تابع register_chrdev به ثبت یک راه انداز در هسته پرداختیم و در انـتـها به بعضی از نکات در خروج ماژول از هسته پرداختیم.

در قسمت اینده یک مثال از یک راه انداز را به طور کامل بررسی خواهیم کرد.


ترجمه و تکمیل : سعید تقویs.taghavi@ece.ut.ac.ir

PDF Version

منابع :

1) http://www.tldp.org/LDP/lkmpg/2.6/html

2) http://www.linuxhq.com/guides/LKMPG/mpg.html

تمامی مطالب و مقالات این سایت تحت مجوز GNU FDL قرار دارند. بنابراین کپی و ایجاد تغییر در آنها مطابق شرایط این مجوز آزاد می‌باشد.