Написание модуля для linux ядра. (linux kernel module)
Ключевые слова: linux, kernel, module, (найти похожие документы)
Date: Thu, 2 May 2002 01:51:24 +0000 (UTC)
From: Stepan Koltsov <yozh@mx1.ru>
Newsgroups: fido7.ru.unix.prog
Subject: Написание модуля для linux ядра.
Там у тебя всё ясно, как божий день, кто ж так пишет :-)
Там у тебя много всего, поэтому отвечаю сверху.
Короче -- ты неправильно заполняешь таблицу file_operations.
Её объявление в моём ядре:
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, 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);
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 (*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 (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
т. е. процедура open находится со смещением в 36 байт (в i386) от начала,
а у тебя там находится как раз процедура test_release, что и подтверждается
твоими показаниями.
Надо писать:
struct file_operations test_fops = {
lseek: test_lseek, /* test_seek */
read: test_read, /* test_read */
write: test_write, /* test_write */
open: test_open, /* test_open */
release: test_release, /* test_release */
};
может быть там ещё ошибки, у меня тут сейчас нет возможности компилировать.
Удачи.
> Сейчас я пытаюсь написать свой динамически подгружаемый модуль.
> Хочу, чтобы в конце концов он выполнял следующую задачу:
> в устройство /dev/testdata посылаем число (например echo "23" > /dev/testdata),
> а модуль то преобразовывает в слова и выводит на экран
> (e.g. twenty three). Для этого создал свое устройство:
> mknod /dev/testdata c 21 0
> chmod 0666 /dev/testdata
> Затем написал код модуля, который компилировал со следующими опциями:
> gcc -O2 -DMODULE -D__KERNEL__ -c hello.c
> В результате получил hello.o, который попытался вставить в ядро.
> Вот, что выводтся на экран:
> [root@xlrd truedrv]# insmod hello.o
> hello.c: init_module called
> init_module: Test Data Generator installed.
> init_module: Hello, world!
> [root@xlrd truedrv]# echo "hi" > /dev/testdata
> test_release
> Unable to handle kernel NULL pointer dereference at virtual address 00000021
> printing eip:
> Hиже привожу текст своего модуля. Кто уже сталкивался с написанием такого,
> подскажите, пожалуйста, что здесь некорректно. Может есть какие-то идеи,
> как что-то можно реализовать более рационально или что-то убрать/добавить.
> =============================================================================
> #include <linux/kernel.h>
> #include <linux/sched.h>
> #include <linux/tty.h>
> #include <linux/signal.h>
> #include <linux/errno.h>
> #include <linux/mm.h>
> #include <linux/compatmac.h>
> #include <asm/uaccess.h>
> #include <asm/io.h>
> #include <asm/segment.h>
> #include <asm/system.h>
> #ifdef MODULE
> #include <linux/module.h>
> #include <linux/version.h>
> #else
> #define MOD_INC_USE_COUNT;
> #define MOD_DEC_USE_COUNT;
> #endif
> static int test_major;
> char kernel_version[]="2.4.8";
> static char test_data[128]="\0";
> static int test_data_size=0;
> static int
> test_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
> {
> printk("test_lseek\n");
> return file->f_pos=0;
> }
> static int
> test_read(struct inode * inode, struct file * file, char * buffer, int count)
> {
> int err;
> printk("test_read\n");
> printk("test_read: Test Data Generator, reading %d bytes\n", count);
> err = verify_area(VERIFY_WRITE, (void *)test_data, count);
> if (!err)
> copy_to_user(/*(void *)*/test_data, /*(void *)*/buffer,
> (unsigned long)count);
> return err;
> }
> static int
> test_write(struct inode * inode, struct file * file, char * buffer, int count)
> {
> int err;
> printk("test_write\n");
> printk("Write %d bytes\n, count");
> err = verify_area(VERIFY_READ, (void *)buffer, count);
> if (!err)
> copy_from_user((void *)test_data, (void *)buffer,
> (unsigned long)count);
> return err;
> }
> static int
> test_open (struct inode * inode, struct file * file)
> {
> printk("test_open\n");
> MOD_INC_USE_COUNT;
> return 0;
> }
> static void test_release(struct inode * inode, struct file * file)
> {
> printk("test_release\n");
> MOD_DEC_USE_COUNT;
> }
> struct file_operations test_fops = {
> test_lseek, /* test_seek */
> test_read, /* test_read */
> test_write, /* test_write */
> NULL, /* test_readdir */
> NULL, /* test_select */
> NULL, /* test_ioctl */
> NULL, /* test_mmap */
> test_open, /* test_open */
> test_release, /* test_release */
> NULL
> };
> extern int printk( const char* fmt, ...);
> int init_module(void)
> {
> printk("hello.c: init_module called\n");
> printk("init_module: Test Data Generator installed.\n");
> if (register_chrdev(21, "test", &test_fops)) {
> printk("init_module: Test Data Generator error: Cannot register to
> major device 21!\n");
> return -EIO;
> } else
> printk("init_module: Hello, world!\n");
> return 0;
> }
> void cleanup_module(void)
> {
> printk("hello.c: cleanup_module called\n");
> printk("cleanup_module: Test Data Generator de-installed.\n");
> if (MOD_IN_USE)
> printk("cleanup_module: Device busy, removed delay\n");
> if (unregister_chrdev(test_major, "test")) {
> printk ("cleanup_module: unregister_chrdev: failed\n");
> } else {
> printk("cleanup_module: unregister_chrdev: succedded\n");
> }
> }
> =============================================================================
1, kas (??), 01:29, 24/08/2005 [ответить]
| +/– |
Мне идея понравилась. рульно придумано! тоже попробую воспроизвести (любопытства ради) :-) | |
|