ماژول نویسی برای هسته لینوکس (قسمت دوم)(661 مجموع کلمات موجود در متن) (7218 بار مطالعه شده است) 
ماژول نویسی
برای هسته لینوکس (قسمت
دوم)
در قسمــت
قبــل بـــا مــاژول هسته، نحوه load
شدن
و unload شدن
آن و مطالبی دیگر آشنا شدیم و یک ماژول
بسیار ساده نوشتیم و با مکانیزمkbuild
ان
را کامپایل کردیم.
در
این قسمت به مثال های بیشتری خواهیم
پرداخت.
مثال hello
world – قسمت
دوم
همان طور
کـــه در قسمت قبـل گفتیم بعد از هسته
2.3.13 می
توانید برای دوتابع ()init_module
و
()cleanup_module
اســـامی
دیگری اختیار کنید.
این
امکان توسـط دو مــاکــروی ()module_init
و()module_exit
که
در فایل <linux/init.h>
تعریف
شده اند میسر می گردد.
دو تـابع شروع
و پایان ماژول بایستی قبـــل از این دو
ماکرو تعریف شده باشند در غیر این صورت
خطای کامپایلر را دریافت خواهید کرد .
برای روشن
شدن این موضوع به مثال hello-2.c
توجه
کنید.
/* hello-2.c */
#include <linux/module.h> /*
needed by all modules */
#include <linux/kernel.h>/*needed
for macros like KERN_INFO,KERN_ALERT,etc */
#include <linux/init.h>/*needed
for module_init() & module_exit() */
static int __init
hello_2_init(void)
{
printk(KERN_INFO “Hello, World 2\n”);
return 0;
}
static void __exit
hello_2_exit(void)
{
printk(KERN_INFO “Goodbye, World 2\n”);
}
module_init(hello_2_init);/*sets
hello_2_init() as initialization function */
module_exit(hello_2_exit);/*sets
hello_2_exit() as termination function */
برای اینکه
این کد مانند مثال hello-1.c
مورد
کامپایل قرار گیرد کافی است در Makefile
خط
زیر را اضافه کنید:
obj-m += hello-2.o
پس
از اعمال این تغییر Makefile
به
صورت زیر خواهد بود:
obj-m += hello-1.o
obj-m += hello-2.o
All:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
Clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
ماکروهای
init__ و
exit__
ماکــروی
init__ در
مورد درایـــورهایی کـــه بــه صـورت
built-in در
هسته استفاده میشوند
باعث میشود که پس از به
اتمام رسیدن تابع init،
این تابع از حافظه خارج شده و حافظهای
کــه برای آن گرفته شده است آزاد میگـردد.
ایـن
ماکرو در مورد درایورهایی که قرار است به
صورت ماژول به هسته وارد شوند تاثیری
نخواهد داشت.
همانند init__
کـه
برای توابع init
در
نظر گرفته شده ماکروی exit__
برای
حذف فضای تابع exit
استفاده
میگـردد و برای درایور
هایی که به صورت ماژول وارد هسته می شوند
تاثیری نخواهد داشت.
این دو ماکرو
در فایل <linux/init.h>
تعریف
شدهاند و باعث گرفتن و
آزاد کردن حافظه از فضای هسته میشوند.
اگر در هنگام
بوت هسته پیغامی مانند:
Freeing unused kernel memory :
236k freed
را دریافت
کردید دلیل این موضوع استفاده از این دو
ماکرو است.
عــلت
استــفــاده از static
را
در قســمت بعد بـه تفصیل بررسی خواهیم
کرد.
مثال Hello
world – قسمت
سوم
به مانند دو
ماکروی init__
و
exit__ که
برای توابع به کار میرود،
مــاکــرویی به نام initdata__
داریم
که برای متغیرها به کار می رود و همان
تاثیرات ذکر شده در بالا برای متغیر ها
را دارد.
به
مثال ماژول hello-3.c
توجه
کنید :
/* hello-3.c */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int hello_3_data
__initdata = 3 ;
static int __init
hello_3_init(void)
{
printk(KERN_INFO “Hello, World %d\n”, hello_3_data );
return 0;
}
static void __exit
hello_3_exit(void)
{
printk(KERN_INFO “Goodbye, World 3\n”);
}
module_init(hello_3_init);
module_exit(hello_3_exit);
به مانند قبل
با اضافه کردن obj-m
+= hello-3.o در
Makefile این
فایل مورد build
قرار
می گیرد.
مثال Hello
world – قسمت
چهارم
در این مثال
به بررسی چند ماکــروی دیگر میپردازیــم
که بعضی امکانات مفید مانند license
و
documentation
را
به یک ماژول اضافه می کنند.
ایــن ماکروها
عموما از هستـه2.4
و به
بعد اضافه شدهانـد .
license را
می توانید با ماکروی()MODULE_LICENSE
تعیین
کنید.
مــاکـــروهــای
()MODULE_DESCRIPTION
و
()MODULE_AUTHOR
بــه
ترتیب بــرای توضیح کاری که ماژول انجام
میدهد و نویسنده ماژول
به کار می روند.
بــرای
اینـــکــه مشـــخــص کــنــید کـــه
مـــاژول چـــه دستــــهای
از دستگاهها را
پشتـــیبانی مــیکــنــد
از مـــاکـــروی ()MODULE_SUPPORTED_DEVICE
استفاده
کنید. این
ماکروها همگی در <linux/module.h>
تعریف
شدهاند.
این اطلاعات
که در ماژولها ذخیره
میشوند، توســـط
ابـــزارهایی مانند objdump
که
برای نشان دادن اطلاعاتی از فایل های
object به
کار میروند قابل مشاهده
هستند. به
مثال hello-4.c
که
این موارد را نشان میدهد
توجه کنید:
/* hello-4.c */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#define DRIVER_AUTHOR “Peter Jay
Salzman <p@dirac.org>”
#define DRIVER_DESC “A sample
driver”
static int __init
hello_4_init(void)
{
printk(KERN_INFO “Hello, World 4\n”);
return 0;
}
static void __exit
hello_4_exit(void)
{
printk(KERN_INFO “Goodbye, World 4\n”);
}
module_init(hello_4_init);
module_exit(hello_4_exit);
MODULE_LICENSE(“GPL”);/* macro for setting license information */
MODULE_AUTHOR(DRIVER_AUTHOR); /*idenfying module author */
MODULE_DESCRIPTION(DRIVER_DESC); /*describe module with this macro */
MODULE_SUPPORTED_DEVICE(“testdevice”); /* identifying devices module can
support and work – here is test and is not important */

ترجمه
و تکمیل :
سعید
تقوی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 |