ماژول نویسی برای هسته لینوکس (قسمت سوم)
فرستادن ورودی های خط دستور به یک ماژول
ماژولها میتوانند ورودیهایی از طـریق خط دستور دریافت کنند البته این کار با استفاده از argc و argv کـه در برنامههای معمولی استفاده می شوند نیست.
بــرای این کار متغیرهایی را که میخواهید از طریق خط فرمان مقداردهی کنید را بــه صــورت global تعــریف کـــرده و بـا استفاده از مــاکــروی ()MODULE_PARM این مکانیزم را تنظیم کنید. ایــن ماکـــرو دو ورودی میگیــرد. اولـی نام متغیر و دومی نوع متغیر . نوع های قابل قبول عبارتند از:
کد:
( s" string ) - ( "l" long ) - ( "i" integer ) - ( "h" short int ) - ( "b" byte” )
String ها باید به صورت *char تعریف شوند. insmod در زمــان اجرا فضای لازم برای ان را می گیرد . به عنوان مثال شما می توانید متغیر myvariable را که یک int است در کد خود تعریف کرده و از طریق خط فرمان ان را مقدار دهی کنید .
کد:
int myvariable = 10 ; // 10 is default value
MODULE_PARM( myvariable , ”i” );//setting the type (amout of memory) for it
سپس به صورت زیر آن را مقدار دهی کنید:
# insmod ./mymodule myvariable=250ساختار داده ارایه نیز در این روش مورد پشتیبانی است . به عنوان مثال در کد زیر:
کد:
int myarray[4];
MODULE_PARM( myarray , “3-9i” );/*setting an array of integer with max & min
values 9 , 3 respectively */
یک ارایه 4 تایی از integer به ()MODULE_PARM داده شده و مقادیر مینیمم و ماکزیمم ان نیز به وسیله دو عدد 3 و 9 تعیین شده است.
مثال hello-5.c که مثال جامع تری است تمام این موارد را نشان میدهد. (به comment های کد توجه شود).
کد:
/* hello-5.c */
#include <linux/module.h> /* needed by all modules */
#include <linux/moduleparam.h> /* needed by macros like module_param(),
module_param_array(),etc . it also has definitions of many functions and structure
like kernel_param */
#include <linux/kernel.h> /* needed for macros like KERN_INFO */
#include <linux/init.h>/* needed for init and exit macros */
#include <linux/stat.h>/* needed by macros like S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP */
MODULE_LICENSE(“GPL”);//setting the module license
MODULE_AUTHOR(“Peter Jay Salzman”);//setting the module author
/* defining some variable for input from shell prompt */
static short int myshort = 1;
static int myint = 420;
static long int mylong = 9999;
static char *mystring = “blah”;
/* S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP macros are used for setting
permissions to access to variables and fuctions as common Linux permission
management system . you know in Unix systems we have 3 group of people
( owner – group – others ) and 3 kind of permissions ( read – write – execute (rwx) )
for each group. in modules we use bitwise OR of these macros for setting a user to
set or get a variable or function . */
module_param( myshort , short , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
MODULE_PARM_DESC(myshort, “A short integer”);
module_param( myint , int , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
MODULE_PARM_DESC(myint, “An integer”);
module_param(mylong, long , S_IRUSR);
MODULE_PARM_DESC(mylong, “A long integer”);
module_param(mystring, charp , 0000);
MODULE_PARM_DESC(mystring, “A character string”);
static int __init hello_5_init(void)
{
printk( KERN_INFO “Hello, World 5\n=============”);
printk( KERN_INFO “myshort is a short integer: %hd\n” , myshort );
printk( KERN_INFO “myint is an integer: %d\n” , myint );
printk( KERN_INFO “mylong is a long integer: %ld\n” , mylong );
printk( KERN_INFO “mystring is a string: %s\n”, mystring);
return 0;
}
static void __exit hello_5_exit(void)
{
printk( KERN_INFO “Goodbye, world 5\n”);
}
module_init(hello_5_init);
module_exit(hello_5_exit);
دستورات زیر را اجرا کنید تا با نحوه کار این ماژول بیشتر اشنا شوید ( فایل var/log/messeges/ دیده شود.)
کد:
# insmod ./hello-5.ko mystring=”bebop” mybyte=255 myintarray=-1
# rmmod hello-5
# insmod ./hello-5.ko mystring=”supercalifragilisticexpialidocious” \
> mybyte=256 myintarray=-1,-1
# rmmod hello-5
# insmod ./hello-5.ko mylong=hello
نوشتن یک ماژول در چندین فایل
بعضی اوقات نیاز دارید که یک ماژول هسته را در چندین فایل پیاده سازی کنید.
مثال مورد بررسی شامل دو فایل start.c و stop.c است.
کد:
/* start.c */
#include <linux/kernel.h>
#include <linux/module.h>
int init_module(void)
{
printk(“Hello, world – this is the kernel speaking\n”);
return 0;
}
/* stop.c */
#include <linux/kernel.h>
#include <linux/module.h>
void cleanup_module(void)
{
printk(“<1>short is the life of a kernel module\n”);
}
نکته مهم نحوه build با استفاده از kbuild است . برای این موضوع به تغییرات حاصل در Makefile توجه کنید.
کد:
obj-m += hello-1.o
obj-m += hello-2.o
obj-m += hello-3.o
obj-m += hello-4.o
obj-m += hello-5.o
obj-m += startstop.o
startstop-objs := start.o stop.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
در قسمت بعد با بعضی از مفاهیم بنیادی هسته لینوکس، تــوابع سیستمی آشنــا خــواهیم شــد و گــذر مختـــصری بر مفاهیم بنیادی device driver ها خواهیم داشت.
فرستادن ورودی های خط دستور به یک ماژول
ماژولها میتوانند ورودیهایی از طـریق خط دستور دریافت کنند البته این کار با استفاده از argc و argv کـه در برنامههای معمولی استفاده می شوند نیست.
بــرای این کار متغیرهایی را که میخواهید از طریق خط فرمان مقداردهی کنید را بــه صــورت global تعــریف کـــرده و بـا استفاده از مــاکــروی ()MODULE_PARM این مکانیزم را تنظیم کنید. ایــن ماکـــرو دو ورودی میگیــرد. اولـی نام متغیر و دومی نوع متغیر . نوع های قابل قبول عبارتند از:
کد:
( s" string ) - ( "l" long ) - ( "i" integer ) - ( "h" short int ) - ( "b" byte” )
String ها باید به صورت *char تعریف شوند. insmod در زمــان اجرا فضای لازم برای ان را می گیرد . به عنوان مثال شما می توانید متغیر myvariable را که یک int است در کد خود تعریف کرده و از طریق خط فرمان ان را مقدار دهی کنید .
کد:
int myvariable = 10 ; // 10 is default value
MODULE_PARM( myvariable , ”i” );//setting the type (amout of memory) for it
سپس به صورت زیر آن را مقدار دهی کنید:
# insmod ./mymodule myvariable=250ساختار داده ارایه نیز در این روش مورد پشتیبانی است . به عنوان مثال در کد زیر:
کد:
int myarray[4];
MODULE_PARM( myarray , “3-9i” );/*setting an array of integer with max & min
values 9 , 3 respectively */
یک ارایه 4 تایی از integer به ()MODULE_PARM داده شده و مقادیر مینیمم و ماکزیمم ان نیز به وسیله دو عدد 3 و 9 تعیین شده است.
مثال hello-5.c که مثال جامع تری است تمام این موارد را نشان میدهد. (به comment های کد توجه شود).
کد:
/* hello-5.c */
#include <linux/module.h> /* needed by all modules */
#include <linux/moduleparam.h> /* needed by macros like module_param(),
module_param_array(),etc . it also has definitions of many functions and structure
like kernel_param */
#include <linux/kernel.h> /* needed for macros like KERN_INFO */
#include <linux/init.h>/* needed for init and exit macros */
#include <linux/stat.h>/* needed by macros like S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP */
MODULE_LICENSE(“GPL”);//setting the module license
MODULE_AUTHOR(“Peter Jay Salzman”);//setting the module author
/* defining some variable for input from shell prompt */
static short int myshort = 1;
static int myint = 420;
static long int mylong = 9999;
static char *mystring = “blah”;
/* S_IRUSR , S_IWUSR , S_IRGRP , S_IWGRP macros are used for setting
permissions to access to variables and fuctions as common Linux permission
management system . you know in Unix systems we have 3 group of people
( owner – group – others ) and 3 kind of permissions ( read – write – execute (rwx) )
for each group. in modules we use bitwise OR of these macros for setting a user to
set or get a variable or function . */
module_param( myshort , short , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
MODULE_PARM_DESC(myshort, “A short integer”);
module_param( myint , int , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
MODULE_PARM_DESC(myint, “An integer”);
module_param(mylong, long , S_IRUSR);
MODULE_PARM_DESC(mylong, “A long integer”);
module_param(mystring, charp , 0000);
MODULE_PARM_DESC(mystring, “A character string”);
static int __init hello_5_init(void)
{
printk( KERN_INFO “Hello, World 5\n=============”);
printk( KERN_INFO “myshort is a short integer: %hd\n” , myshort );
printk( KERN_INFO “myint is an integer: %d\n” , myint );
printk( KERN_INFO “mylong is a long integer: %ld\n” , mylong );
printk( KERN_INFO “mystring is a string: %s\n”, mystring);
return 0;
}
static void __exit hello_5_exit(void)
{
printk( KERN_INFO “Goodbye, world 5\n”);
}
module_init(hello_5_init);
module_exit(hello_5_exit);
دستورات زیر را اجرا کنید تا با نحوه کار این ماژول بیشتر اشنا شوید ( فایل var/log/messeges/ دیده شود.)
کد:
# insmod ./hello-5.ko mystring=”bebop” mybyte=255 myintarray=-1
# rmmod hello-5
# insmod ./hello-5.ko mystring=”supercalifragilisticexpialidocious” \
> mybyte=256 myintarray=-1,-1
# rmmod hello-5
# insmod ./hello-5.ko mylong=hello
نوشتن یک ماژول در چندین فایل
بعضی اوقات نیاز دارید که یک ماژول هسته را در چندین فایل پیاده سازی کنید.
مثال مورد بررسی شامل دو فایل start.c و stop.c است.
کد:
/* start.c */
#include <linux/kernel.h>
#include <linux/module.h>
int init_module(void)
{
printk(“Hello, world – this is the kernel speaking\n”);
return 0;
}
/* stop.c */
#include <linux/kernel.h>
#include <linux/module.h>
void cleanup_module(void)
{
printk(“<1>short is the life of a kernel module\n”);
}
نکته مهم نحوه build با استفاده از kbuild است . برای این موضوع به تغییرات حاصل در Makefile توجه کنید.
کد:
obj-m += hello-1.o
obj-m += hello-2.o
obj-m += hello-3.o
obj-m += hello-4.o
obj-m += hello-5.o
obj-m += startstop.o
startstop-objs := start.o stop.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
در قسمت بعد با بعضی از مفاهیم بنیادی هسته لینوکس، تــوابع سیستمی آشنــا خــواهیم شــد و گــذر مختـــصری بر مفاهیم بنیادی device driver ها خواهیم داشت.
+ نوشته شده توسط امیرحسین عربی زاده در جمعه یازدهم خرداد 1386 و ساعت
15:47 |


