[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 390
  • Last Modified:

building char driver on linux-2.6.10

I need help with the following,
---------------------------------------------------------------------------------------------
I am trying to build a basic char driver (register, open, release, unregister). When I compile the source I get the following errors, even on linux-2.4,
:variable fops has initializer but incomplete type
:unknown field open in fops
:unknown field release in fops
:storage size of fops not known
and a lot of warnings (not only in the source but also in the files that I include in the program - kernel.h,module.h,fs.h,asm/access.h) even though I have the option -Wall in the makefile. I tried including the files from /usr/src/linux/include and also /lib/modules/`uname -r`/build/include/. No change in the output.

thanks,
Prashanth
0
PrashanthPenumarthy
Asked:
PrashanthPenumarthy
  • 5
  • 3
  • 2
  • +2
1 Solution
 
jojuCommented:
please post your program, if u didnt solve the problems yet
0
 
person1994Commented:
Your file operation definition should look like this:

static struct file_operations   my_fops
{
    owner:  THIS_MODULE,
    read: read_func,
    write: write_func,
    open: open_func,
    release: release_func
};

If this does not help you, plase post your code.

Good luck
0
 
manish_regmiCommented:
i think you forgot to include fs.h

regards
Manish Regmi


0
Transaction-level recovery for Oracle database

Veeam Explore for Oracle delivers low RTOs and RPOs with agentless transaction log backup and transaction-level recovery of Oracle databases. You can restore the database to a precise point in time, even to a specific transaction.

 
PrashanthPenumarthyAuthor Commented:
Sorry I should have done it, Here is the code, I have been breaking my head for about
 weeks now,  Any help is truly appreciated.

#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
#include <linux/modversions.h>
#define MODVERSIONS
#endif
                                                                                                                             
#define _KERNEL_
#define MODULE
                                                                                                                             
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
                                                                                                                             
//static int module_init(void);
//static void module_exit(void);
static int prcdd_open(struct inode *,struct file *);
static int prcdd_release(struct inode *,struct file *);
                                                                                                                             
#define SUCCESS 0
#define DEVICE_NAME "prcdd"
                                                                                                                             
static int Major;
static int Device_open = 0;
                                                                                                                             
static struct file_operations fops = {
        .owner = THIS_MODULE,
        .open = prcdd_open,
        .release = prcdd_release,
};
                                                                                                                             
static int prcdd_init(void)
{
        Major = register_chrdev(0,DEVICE_NAME,&fops);
        if (Major < 0)
        {
                printk("Registering the character device failed with %d \n",Major);
                return Major;
        }
                                                                                                                             
        printk("<1>The assigned major number is %d \n",Major);
        return 0;
}
                                                                                                                             
static void prcdd_exit(void)
{
        int ret = unregister_chrdev(Major,DEVICE_NAME);
        if (ret < 0)
        {
                printk("Error in unregister_chrdev: %d \n",ret);
        }
}
                                                                                                                             
static int prcdd_open(struct inode *inode, struct file *file)
{
        if (Device_open)
        {
                return -EBUSY;
        }
        Device_open++;
                                                                                                                             
        MOD_INC_USE_COUNT;
        return SUCCESS;
}
                                                                                                                             
static int prcdd_release(struct inode *inode, struct file *file)
{
        Device_open--;
                                                                                                                             
        MOD_DEC_USE_COUNT;
        return 0;
}
                                                                                                                             
module_init(prcdd_init);
module_exit(prcdd_exit);
                                                                                                                     

0
 
person1994Commented:
Try changing your file_operations definition to this:

static struct file_operations fops = {
        .owner: THIS_MODULE,
        .open: prcdd_open,
        .release: prcdd_release,
};



Good luck

0
 
jojuCommented:
1. include one more header file
#include <linux/init.h>

2. use __init before init function
static int __init  prcdd_init(void)

3. use __exit before exit function
static void  __exit prcdd_exit(void)

4. compile using "gcc -c driver.c -D__KERNEL__ -DMODULE -Wall -I/usr/include/linux"

No Warnings or errors in 2.4.x kernel
and module is working fine
0
 
PrashanthPenumarthyAuthor Commented:
I have made the changes as suggested in the comments, no luck, this is what I get on compilation (May be I should re-think on configuring the kernel again). I used the same piece of code (with changes in the comments) above.

prcdd.c:6:1: warning: "__KERNEL__" redefined
prcdd.c:1:1: warning: this is the location of the previous definition
prcdd.c:7:1: warning: "MODULE" redefined
prcdd.c:1:1: warning: this is the location of the previous definition
In file included from /usr/include/linux/fs.h:23,
                 from prcdd.c:11:
/usr/include/linux/string.h:8:2: warning: #warning Using kernel header in userland!
prcdd.c:12:25: asm/uaccess.h: No such file or directory
prcdd.c:17: warning: `struct file' declared inside parameter list
prcdd.c:17: warning: its scope is only this definition or declaration, which is probably not what you want
prcdd.c:17: warning: `struct inode' declared inside parameter list
prcdd.c:18: warning: `struct file' declared inside parameter list
prcdd.c:18: warning: `struct inode' declared inside parameter list
prcdd.c:26: variable `fops' has initializer but incomplete type
prcdd.c:27: unknown field `owner' specified in initializer
prcdd.c:27: warning: excess elements in struct initializer
prcdd.c:27: warning: (near initialization for `fops')
prcdd.c:28: unknown field `open' specified in initializer
prcdd.c:28: warning: excess elements in struct initializer
prcdd.c:28: warning: (near initialization for `fops')
prcdd.c:29: unknown field `release' specified in initializer
prcdd.c:29: warning: excess elements in struct initializer
prcdd.c:29: warning: (near initialization for `fops')
prcdd.c: In function `prcdd_init':
prcdd.c:34: warning: implicit declaration of function `register_chrdev'
prcdd.c:38: warning: implicit declaration of function `printk'
prcdd.c: In function `prcdd_exit':
prcdd.c:48: warning: implicit declaration of function `unregister_chrdev'
prcdd.c: At top level:
prcdd.c:55: warning: `struct file' declared inside parameter list
prcdd.c:55: warning: `struct inode' declared inside parameter list
prcdd.c:56: conflicting types for `prcdd_open'
prcdd.c:17: previous declaration of `prcdd_open'
prcdd.c: In function `prcdd_open':
prcdd.c:59: `EBUSY' undeclared (first use in this function)
prcdd.c:59: (Each undeclared identifier is reported only once
prcdd.c:59: for each function it appears in.)
prcdd.c:63: warning: implicit declaration of function `atomic_inc'
prcdd.c:63: union has no member named `usecount'
prcdd.c: At top level:
prcdd.c:67: warning: `struct file' declared inside parameter list
prcdd.c:67: warning: `struct inode' declared inside parameter list
prcdd.c:68: conflicting types for `prcdd_release'
prcdd.c:18: previous declaration of `prcdd_release'
prcdd.c: In function `prcdd_release':
prcdd.c:71: warning: implicit declaration of function `atomic_dec'
prcdd.c:71: union has no member named `usecount'
prcdd.c: At top level:
prcdd.c:26: storage size of `fops' isn't known
0
 
person1994Commented:
Try this....  It works under kernel 2.6


#include <linux/config.h>

#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS)
#include <linux/modversions.h>
#define MODVERSIONS
#endif

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

static int major = 0;
static int Device_open = 0;

#define SUCCESS 0
#define DEVICE_NAME "prcdd"


static int prcdd_open(struct inode *inode, struct file *file)
{
        if (Device_open)
        {
                return -EBUSY;
        }
        Device_open++;

        return SUCCESS;
}
                                                                                                                             
static int prcdd_release(struct inode *inode, struct file *file)
{
        Device_open--;
                                                                                                                             
        return 0;
}


static struct file_operations fops =
{
      .owner =    THIS_MODULE,
      .open =     prcdd_open,
      .release =  prcdd_release,
};


static int __init prcdd_init (void)
{
      major = register_chrdev(0, DEVICE_NAME, &fops);

      if (major < 0)
      {
            printk("Registering the character device failed with %d \n",major);
            return major;
      }

      printk("<1>The assigned major number is %d \n",major);

      return 0;
}

static void __exit prcdd_exit (void)
{
      int ret = unregister_chrdev(major, DEVICE_NAME);
      if (ret < 0)
      {
            printk("Error in unregister_chrdev: %d \n",ret);
      }
}

module_init(prcdd_init);
module_exit(prcdd_exit);

MODULE_LICENSE("GPL");



Good luck...

0
 
PrashanthPenumarthyAuthor Commented:
Hi guys I tried the program mentioned in the last comment, the number of warnings has come down but I still get the following errors on 2.6.10. No matter what I try the following errors are repititive!
:variable fops has initializer but incomplete type
:unknown field open in fops
:unknown field release in fops
:storage size of fops not known

Is it a kernel config issue? or Is the file fs.h not picked up properly? Is it a problem with my gcc version? I am lost

Prashanth
0
 
PrashanthPenumarthyAuthor Commented:
I solved the problem finally, the header files that you include in the program,
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

in my case do not have the definitions for file_operations structure. Hence I had to compile by using the following,

gcc -c prcdd.c -D_KERNEL_ -DMODULE -WALL -I/lib/modules/`uname -r`/build/include

It worked. Thanks to everyone who spent time on this.
0
 
PrashanthPenumarthyAuthor Commented:
I mean in the above comment #include <linux/fs.h>, did not include the definition of file_operations structure.
0
 
moduloCommented:
PAQed with points refunded (200)

modulo
Community Support Moderator
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now