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


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

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

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

   ورود کاربران




 


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

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

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

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


در قسمت قبل با Device Driver‌ها یـا همان راه انداز‌ها به عنوان دسته مهمی‌ از ماژول‌های هسته اشنا شدیم و بعضی مفاهیم بنیادی در هسته لینوکس را مــورد ارزیـابی قرار دادیم.در این قسمت و قسمت اینده توجهمان را به دسته بسیار مهمی‌از راه انداز‌ها که همان راه اندازهای دستگاه‌های کاراکتری هستند معطوف می‌نماییم.


راه انداز‌های دستگاه‌های کاراکتری


ساختار داده file_operations

ساختار داده file_operations در <linux/fs.h> تعریف شــده است و اشــاره گرهایی به توابع مختلف که توسط راه انداز تعریف شده و عملیات مختلفی بر روی دستگاه انجام می‌دهند را نگه داری می‌کند. هر فیلدی از این ساختار داده متناظر آدرس تابعی تعریف شده از راه انداز است که می‌تواند یک درخواست را براورده سازد. به عنوان مثال هر راه انداز دستگاه کاراکتری نیاز به تابعی دارد که بتواند از دستگاه بخواند.

ساختار داده file_operations ادرس توابع مـاژول که این عملیات را انجام می‌دهند در خود نگه می‌دارد. در ذیل تعریف این ساختار داده را بر اساس هسته 2.6.13 مشاهده می‌کنید:

struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*aio_read) (struct kiocb *, char __user *, size_t,  loff_t);
        ssize_t (*write) (struct file *, const char __user *, size_t,  loff_t *);
        ssize_t (*aio_write) (struct kiocb *, const char __user *,size_t, loff_t);
        int (*readdir) (struct file *, void *, filldir_t);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, struct dentry *, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
        ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
        ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
        ssize_t (*sendfile) (struct file *, loff_t *, size_t,  read_actor_t, void *);
        ssize_t (*sendpage) (struct file *, struct page *, int, size_t,  loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *,unsigned long, unsigned long, unsigned long,  unsigned long);
        int (*check_flags)(int);
        int (*dir_notify)(struct file *filp, unsigned long arg);
        int (*flock) (struct file *, int, struct file_lock *);
};

بعضـی از عمـــلگرها توسط راه انداز پـیاده سازی نمی‌شوند. به عنوان مثال یک راه انداز کارت گرافیک نیازی ندارد که تابع مربوط به خواندن از ساختارهای دایرکــتوری ( directory structures ) را پیــاده ســازی کند. فیــلد متناظر در ساختار داده file_operations که استفاده نمی‌شود به NULL مقدار دهی می‌شود.

امکاناتی در GNU C Compiler ) gcc ) وجــود دارد کــه مقدار دادن به این ساختار داده را بسیــار راحت می‌کند. شما این موارد را در راه اندازهای مدرن امروزی خواهید دید که ممکن اســت باعث تعجب شما شـود. در زیر نحوه مقدار دهی را با استفاده از این امکانات می‌بینید:

struct file_operations fops = {
	  read: device_read,
	  write: device_write,
	  open: device_open,
	  release: device_release<
};

Syntax رایج تر برای مقدار دادن به این ساختار داده روش C99 است که برای ســازگاری بیشتر توصیه می‌گردد که از این روش استفاده گردد. در زیر این روش را مشاهده می‌کنید:

struct file_operations fops = {
	 .read = device_read,
	 .write = device_write,
	 .open = device_open,
	 .release = device_release
};

معنی هر دو ساختار تقریبا مشخص است. تــوجه داشته باشید کـــه بقیـه فیـــلدهای سـاختار داده file_operations که توسط دو روش بالا مقداردهی به صورت مشخص نگردد توسط gcc به NULL مقدار دهی می‌شود.


ساختار داده file

هر دستگاه در هسته توسط یک ســاختار داده file نشان داده می‌شود کـــه در <linux/fs.h> تعــریف شده است. توجه داشته باشید که این ساختار یک ساختار سطح هسته است و هرگــز در بـــرنــامه‌های معمـولی که در فضای کاربر اجرا می‌شوند ظاهر نخواهد شد. ایــن ســاختــار بــا ساختار FILE که در کتابخانه استاندارد زبان C تعریف شده است متفاوت می‌باشد.

نام این ساختار ممکن است شما را دچار اشتباه کند. در حقیقت این ساختار یک تجرید ( abstraction ) می‌باشد و تصور اینکه این ساختار یک فایل در دیسک که با ساختار inode مشخص می‌گردد را نشان می‌دهد نیز کاملا اشتباه است.

یک اشاره گر به ساختار داده file معمولا filp نامیده می‌شود. در زیر تعریف ساختار file در هسته 2.6.13 را می‌بینید:

struct file {
        struct list_head      
 	     f_list;
        struct dentry          
 	    *f_dentry;
        struct vfsmount       
   	 *f_vfsmnt;
        struct file_operations 
  	     *f_op;
        atomic_t              
		  f_count;
        unsigned int           
     	  f_flags;
        mode_t                 
        f_mode;
        loff_t                 		f_pos;
        struct fown_struct   f_owner;
        unsigned int           	 f_uid, f_gid;
        struct file_ra_state  f_ra;
        size_t                  f_maxcount;
        unsigned long     f_version;
        void                   *f_security;

        /* needed for tty driver,and maybe others */
        void		*private_data;
#ifdef CONFIG_EPOLL
        /* Used by fs/eventpoll.c to link all the hooks to this file */
        struct list_head   f_ep_links;
        spinlock_t            f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL */
        struct address_space   *f_mapping;
};

بیشتر فیلدهایی که در این ساختار به کار رفته اند ( مانند dentry ) معمولا توسط راه اندازها استفاده نمی‌شوند.


ترجمه و تکمیل : سعید تقوی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 قرار دارند. بنابراین کپی و ایجاد تغییر در آنها مطابق شرایط این مجوز آزاد می‌باشد.