ماژول نویسی برای هسته لینوکس (قسمت پنحم)(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 |