ماژول نویسی برای هسته لینوکس (قسمت دوم)
در قسمــت قبــل بـــا مــاژول هسته، نحوه 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>/*neededfor macros like KERN_INFO,KERN_ALERT,etc */#include <linux/init.h>/*neededfor 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);/*setshello_2_exit() as termination function */
برای اینکه این کد مانند مثال hello-1.c مورد کامپایل قرار گیرد کافی است در Makefile خط زیر را اضافه کنید:
obj-m += hello-2.oپس از اعمال این تغییر Makefile به صورت زیر خواهد بود:
کد:
obj-m += hello-1.oobj-m += hello-2.oAll: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesClean: 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 JaySalzman <p@dirac.org>”#define DRIVER_DESC “A sampledriver”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 */
__________________
در قسمــت قبــل بـــا مــاژول هسته، نحوه 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>/*neededfor macros like KERN_INFO,KERN_ALERT,etc */#include <linux/init.h>/*neededfor 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);/*setshello_2_exit() as termination function */
برای اینکه این کد مانند مثال hello-1.c مورد کامپایل قرار گیرد کافی است در Makefile خط زیر را اضافه کنید:
obj-m += hello-2.oپس از اعمال این تغییر Makefile به صورت زیر خواهد بود:
کد:
obj-m += hello-1.oobj-m += hello-2.oAll: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesClean: 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 JaySalzman <p@dirac.org>”#define DRIVER_DESC “A sampledriver”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 */
__________________
+ نوشته شده توسط امیرحسین عربی زاده در جمعه یازدهم خرداد 1386 و ساعت
15:48 |


