file_operations 구조체에 관하여...

cjy1126의 이미지

리눅스 커널 프로그래밍 책에나온 디바이스 드라이버 모듈 프로그래밍을 하는데, 의문점이 있어서 질문올립니다.

책에 나온 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해서 종료할 수가 없습니다.

결국 리붓으로 해결했지만... 이럴때 강제로 모듈을 죽이는 방법이 없는지 알고싶습니다.

연말 잘보내시고, 새해에는 좋은 일들만 가득하시길...

ch3cooh의 이미지

리눅스 커널 프로그래밍 책들이 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의 사용법을 익히신 후에 프로그램을 조금만 수정하면.. 정상적으로 동작 할것 같네요! ^^

은영신랑의 이미지

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
  }; 

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.