file_operations 구조체에 관하여...
글쓴이: cjy1126 / 작성시간: 월, 2003/12/29 - 7:00오후
리눅스 커널 프로그래밍 책에나온 디바이스 드라이버 모듈 프로그래밍을 하는데, 의문점이 있어서 질문올립니다.
책에 나온 mydrv.c 파일입니다.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "mydrv"
#define MYDRV_MAJOR 250
static int mydrv_open(struct inode *inode, struct file *file)
{
if(MAJOR(inode->i_rdev) != MYDRV_MAJOR)
return -1;
MOD_INC_USE_COUNT;
return 0;
}
static int mydrv_release(struct inode *inode, struct file *file)
{
if(MAJOR(inode->i_rdev) != MYDRV_MAJOR)
return -1;
MOD_DEC_USE_COUNT;
return 0;
}
static ssize_t mydrv_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
printk("mydrv_read is invoked\n");
return(0);
}
static ssize_t mydrv_write(struct file *file, char *buf, size_t count, loff_t *ppos)
{
printk("mydrv_write is invoked\n");
return(0);
}
struct file_operations mydrv_fops = {
NULL, mydrv_read, mydrv_write, NULL, NULL, NULL, NULL,
mydrv_open, NULL, mydrv_release, NULL, NULL, NULL, NULL
};
int init_module(void)
{
int result;
result = register_chrdev(MYDRV_MAJOR, "mydrv", &mydrv_fops);
if(result<0)
{
printk("mydrv: %d character device driver can't be registered\n", MYDRV_MAJOR);
return result;
}
return(0);
}
void cleanup_module(void)
{
unregister_chrdev(MYDRV_MAJOR, "mydrv");
}
이 파일을 컴파일하면 계속 아래와같은 경고가 나옵니다.
gcc -D__KERNEL__ -D_LINUX -DMODULE -c mydrv.c mydrv.c:38: warning: initialization from incompatible pointer type
경고가 나오는 부분입니다.
struct file_operations mydrv_fops = {
NULL, mydrv_read, mydrv_write, NULL, NULL, NULL, NULL,
mydrv_open, NULL, mydrv_release, NULL, NULL, NULL, NULL
};
인터넷과 다른 책을 찾아서 제 linux/fs.h에 있는 file_operations의 인자값과 맞춰서 아래와 같이 고쳤는데도 계속 같은 경고가 나옵니다.
struct file_operations mydrv_fops = {
NULL, NULL, mydrv_read, mydrv_write, NULL, NULL, NULL, NULL,
mydrv_open, NULL, mydrv_release, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
제 linux/fs.h입니다.
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);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
};
제 linux/fs.h구조체대로 숫자를 맞춰줘야 하지않나요?
어떻게해줘야 경고를 잡을 수 있는지 모르겠습니다.
제대로 실행은되는데, 경고가 눈에 거슬리네요.
또 한번은 계속 수정하다가 module테스트 프로그램을 돌리면 모듈의 use by가 -1씩 증가되어 rmmod를하면 module이 busy해서 종료할 수가 없습니다.
결국 리붓으로 해결했지만... 이럴때 강제로 모듈을 죽이는 방법이 없는지 알고싶습니다.
연말 잘보내시고, 새해에는 좋은 일들만 가득하시길...
Forums:


리눅스 커널 프로그래밍 책들이 Kernel 2.2대를 기준으로 프로그램이
리눅스 커널 프로그래밍 책들이 Kernel 2.2대를 기준으로 프로그램이 되어 있어 현재 많이 사용하고 있는 Kernel2.4에서는 Kernel Programming 사용형식이 조금 다른것으로 알고 있습니다.
그 대표적인 것이 int init_module(void)와 void cleanup_module(void)이 module_init(module_begin); module_exit(module_end);으로 매크로화 시킨 것으로 압니다. 2.4의 사용법을 익히신 후에 프로그램을 조금만 수정하면.. 정상적으로 동작 할것 같네요! ^^
file operation structure 관련.
struct file_operations mydrv_fops = { NULL, mydrv_read, mydrv_write, NULL, NULL, NULL, NULL, mydrv_open, NULL, mydrv_release, NULL, NULL, NULL, NULL };을 이렇게 한번 고쳐보세요.
struct file_operations mydrv_fops = { read: mydrv_read, write: mydrv_write, open: mydrv_open, release: mydrv_release };댓글 달기