ماژول نویسی برای هسته لینوکس (قسمت هفتم)
در دو قسمت پیشین با مفاهیم ابتدایی دستگاههای کاراکتری آشنا شدیم و نحوه ثبت این گونه دستگاهها در هسته را متوجه شدیم . در این قسمت مطالبی را که در دو قسمت قبل فرا گرفتیم در ساده ترین مثال بررسی مینماییم.
کد ایـن مثــال را که حــاوی توضیحات تقریبا کامــلی است، میتوانید از اینجا بــدست آورید. پـس از کـامـپـایل مـــاژول از دستور زیر برای وارد کردن این ماژول در هسته استفاده کنید:
# insmod ./chardev.koاگـــر اکنون به انتهای فایل var/log/messages/ بروید مشاهده میکنید کــه هسته به صورت دینامیک به ماژول شما یک عدد اصلی اختصاص داده است . با استفاده از راهنماییای کــه در ایــن فــایـل شــده، دســتـور mknod را بــرای ایـجـاد dev/chardev/ بــه صورت ذکــر شده اجرا کنید. اکنــون راه انداز شما قابــل استفاده است. میتوانید آن را باز کنید، از آن بخوانید و در آن بنویسید.
برای خواندن از این دستگاه کاراکتری به صورت زیر عمل کنید:
# cat /dev/chardev
و یا برای نوشتن عبارتی مثلا “Hello” در آن به صورت زیر عمل کنید:
# echo “Hello” > /dev/chardevهمان گونه که ذکر شد توضیحات کامل این مثال در کد مثال به صورت comment آمده است. در زیر بــه دو نـکتــه از ایــن مثال اشاره کرده و در نهایت بحث این مثال را با یک سوال به پایان میبریم.
۱) در تابع device_read همان طــور کــه مشـاهده میکنید از تابع put_user استفاده شده است. بـه طور کلی هر پروسس دارای یک بافر در فضای کاربر است و هـر ماژول نیز دارای یک بافر در فضای هسته است. عملی که این تابع و توابع مشابه آن انجام میدهند، اطلاعات را بــه صـــورت کامــلا محافظت شده بین این بافرها جابجا میکنند.
۲) همان طور که در تابع device_write میبینید، ایـن تابع عملی انجام نمیدهد. شما میتوانید این تابع را به هر صورتی که میخواهید تغییر دهید. به عنوان مثال میتوانید بــا دانستــن ساختار سخت افزاری مودم خود این تابع را پیاده سازی کرده و بدین ترتیب اطلاعات خود را در مودم خـود بنویسید. البته برای خواندن از مودمتان باید تابع device_read را با توجه به ساختار مودمتان تغییر دهید.
سوال: اکنون در کد مثال خط زیر را پیدا کنید:
static char msg[BUF_LEN];
و به صورت زیر تغییر دهید:
static char *msg;
یعنی در حقیقت برای اشاره گر بافر ماژول فضایی در نظر نگیرید. حــال دوباره مـاژول را در هسته وارد کرده و عملیات cat را انجام دهید. مشــاهده میکنید کــه بـه پیغام segmentation fault برخورد خواهید کرد. در صـورتی که در چند قسمت قبل گفتیم که اگر ماژول دچار seg fault شود هسته دچـــار seg fault خواهد شد. بـــا تــوجـه به این نکات این مساله را توجیه کنید. پاسخهای خود را به e-mail بنده که در انتهای این مقاله است بفرستید و جواب صحیح را دریافت دارید.
در اینجا این قسمت به پایان میرسد. در قسمت بعدی ادامه مطالب ماژول نویسی برای هسته لینوکس را از نگاهی جدیدتر پی خواهیم گرفت.
در دو قسمت پیشین با مفاهیم ابتدایی دستگاههای کاراکتری آشنا شدیم و نحوه ثبت این گونه دستگاهها در هسته را متوجه شدیم . در این قسمت مطالبی را که در دو قسمت قبل فرا گرفتیم در ساده ترین مثال بررسی مینماییم.
کد ایـن مثــال را که حــاوی توضیحات تقریبا کامــلی است، میتوانید از اینجا بــدست آورید. پـس از کـامـپـایل مـــاژول از دستور زیر برای وارد کردن این ماژول در هسته استفاده کنید:
# insmod ./chardev.koاگـــر اکنون به انتهای فایل var/log/messages/ بروید مشاهده میکنید کــه هسته به صورت دینامیک به ماژول شما یک عدد اصلی اختصاص داده است . با استفاده از راهنماییای کــه در ایــن فــایـل شــده، دســتـور mknod را بــرای ایـجـاد dev/chardev/ بــه صورت ذکــر شده اجرا کنید. اکنــون راه انداز شما قابــل استفاده است. میتوانید آن را باز کنید، از آن بخوانید و در آن بنویسید.
برای خواندن از این دستگاه کاراکتری به صورت زیر عمل کنید:
# cat /dev/chardev
و یا برای نوشتن عبارتی مثلا “Hello” در آن به صورت زیر عمل کنید:
# echo “Hello” > /dev/chardevهمان گونه که ذکر شد توضیحات کامل این مثال در کد مثال به صورت comment آمده است. در زیر بــه دو نـکتــه از ایــن مثال اشاره کرده و در نهایت بحث این مثال را با یک سوال به پایان میبریم.
۱) در تابع device_read همان طــور کــه مشـاهده میکنید از تابع put_user استفاده شده است. بـه طور کلی هر پروسس دارای یک بافر در فضای کاربر است و هـر ماژول نیز دارای یک بافر در فضای هسته است. عملی که این تابع و توابع مشابه آن انجام میدهند، اطلاعات را بــه صـــورت کامــلا محافظت شده بین این بافرها جابجا میکنند.
۲) همان طور که در تابع device_write میبینید، ایـن تابع عملی انجام نمیدهد. شما میتوانید این تابع را به هر صورتی که میخواهید تغییر دهید. به عنوان مثال میتوانید بــا دانستــن ساختار سخت افزاری مودم خود این تابع را پیاده سازی کرده و بدین ترتیب اطلاعات خود را در مودم خـود بنویسید. البته برای خواندن از مودمتان باید تابع device_read را با توجه به ساختار مودمتان تغییر دهید.
سوال: اکنون در کد مثال خط زیر را پیدا کنید:
static char msg[BUF_LEN];
و به صورت زیر تغییر دهید:
static char *msg;
یعنی در حقیقت برای اشاره گر بافر ماژول فضایی در نظر نگیرید. حــال دوباره مـاژول را در هسته وارد کرده و عملیات cat را انجام دهید. مشــاهده میکنید کــه بـه پیغام segmentation fault برخورد خواهید کرد. در صـورتی که در چند قسمت قبل گفتیم که اگر ماژول دچار seg fault شود هسته دچـــار seg fault خواهد شد. بـــا تــوجـه به این نکات این مساله را توجیه کنید. پاسخهای خود را به e-mail بنده که در انتهای این مقاله است بفرستید و جواب صحیح را دریافت دارید.
در اینجا این قسمت به پایان میرسد. در قسمت بعدی ادامه مطالب ماژول نویسی برای هسته لینوکس را از نگاهی جدیدتر پی خواهیم گرفت.
+ نوشته شده توسط امیرحسین عربی زاده در جمعه یازدهم خرداد 1386 و ساعت
15:44 |


