Kernel module with multiple source files compilation problem
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Kernel module with multiple source files compilation problem
Hi,
I have a problem with compiling my kernel module.
At this stage its a plain character device that takes input which is piped
through to the /dev/my_device file and when you cat /dev/my_device it returns
the same data.
To have 1 file for my my_device.ko file works fine but if I have multiple
source files it compiles but with warnings stating for example:
It is for the 2.6.10 UML Linux Kernel.
Here is an abstract view of my source files:
compr.c :
------------
Code:
#include "compr.h"
#include "dyn_buffer.h"
/** If we ever need to check if we're
* using a specific kernel version
*/
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(a,b,c) ((a) * 65536 + (b) * 256 + (c))
#endif
#include <asm/uaccess.h> // for put_user
#include <linux/vmalloc.h> // for vmalloc
#include <linux/proc_fs.h> // for proc file system
#include <linux/sched.h> // for sleeping
#define DEVICE_NAME "compr"
#define COMPR_MAJOR 240
//static struct proc_dir_entry *compr_proc_entry;
static struct sDynBuffer compr_buffer;
static struct cdev compr_cdev;
/** This function is called whenever a process
* attempts to open the device file
*/
static int compr_open(struct inode *inode, struct file *file)
{
return 0;
}
/** This function is called when a process closes the
* device file.
*/
static int compr_release(struct inode *inode, struct file *file)
{
return 0;
}
/** This function is called whenever a process which
* have already opened the device file attempts to
* read from it.
*/
static ssize_t compr_read( struct file *file,
char *buffer, // The buffer to fill with data
size_t length, // The length of the buffer
loff_t *offset) // Our offset in the file
{
...
}
/** This function is called when somebody tries to write
* into our device file.
*/
static ssize_t compr_write( struct file *file,
const char *buffer, // The buffer
size_t length, // The length of the buffer
loff_t *offset) // Our offset in the file
{
...
}
void __get_user_X(void)
{
}
void __put_user_bad(void)
{
}
int compr_ioctl(struct inode *inode,
struct file *file,
unsigned int ioctl_num, // The number of the ioctl
unsigned long ioctl_param) // The parameter to it
{
return -EINVAL;
}
struct file_operations compr_ops =
{
.read = compr_read,
.write = compr_write,
.ioctl = compr_ioctl,
.open = compr_open,
.release = compr_release,
};
/** Initialize the module */
//static int __init compr_init()
int init_module()
{
...
}
/** Cleanup - undid whatever init_module did */
void cleanup_module()
{
...
}
#include "dyn_buffer.h"
int dynInitBuffer(struct sDynBuffer *dbuf)
{
...
}
int dynCleanBuffer(struct sDynBuffer *dbuf)
{
...
}
//Appends chunk buffers from the speified
//given index.
//Returns the number of chunks created.
static int dynAddNumChunks(struct sDynBuffer *dbuf, int from_index, int
amount)
{
...
}
int dynAddChunk(struct sDynBuffer *dbuf, char *buf, size_t size)
{
...
}
char *dynMakeBigBuffer(struct sDynBuffer *dbuf, size_t *size)
{
...
}
dyn_buffer.h:
----------------
Code:
#ifndef _DYNAMIC_BUFFER_H
#define _DYNAMIC_BUFFER_H
#include <linux/types.h>
#include <linux/vmalloc.h>
#include "utils.h"
#define CHUNK_SIZE 4096
#define INIT_SIZE 10
//Error symbols
#define ERROR_MEM 1 /** Couldn't allocate memory for buffer */
/** A structure holding valuable
* information on a dynamic buffer.<br>
* <b>NOTE :</b> Do not alter anything
* in this structure!
*/
struct sDynBuffer
{
size_t actual_size; /** Size of data in dynamic buffer */
int size; /** Amount of data chunks */
int index; /** Current chunk index */
int offset; /** Current place in chunk */
char **data; /** Array of chunk buffers */
};
#define DYN_BUFFER_SIZE(BUFFER) (BUFFER.actual_size)
int dynInitBuffer(struct sDynBuffer *dbuf);
int dynCleanBuffer(struct sDynBuffer *dbuf);
int dynAddChunk(struct sDynBuffer *dbuf, char *buf, size_t size);
char *dynMakeBigBuffer(struct sDynBuffer *dbuf, size_t *size);
#endif //_DYNAMIC_BUFFER_H
I thoaght it might be a good idea to submit a more detailed report on what the compiler gave me:
- non-verbosed -
Code:
make -C /tmp/linux-2.6.10 M=`pwd` modules ARCH=um
make[1]: Entering directory `/tmp/linux-2.6.10'
CC [M] /home/la/compr/compr.o
In file included from /home/la/compr/compr.h:16,
from /home/la/compr/compr.c:9:
include/linux/cdev.h:24: warning: ‘struct inode’ declared inside parameter list
include/linux/cdev.h:24: warning: its scope is only this definition or declaration, which is probably not what you want
CC [M] /home/la/compr/dyn_buffer.o
CC [M] /home/la/compr/utils.o
LD [M] /home/la/compr/compr_dev.o
Building modules, stage 2.
MODPOST
*** Warning: "copyData" [/home/la/compr/dyn_buffer.ko] undefined!
*** Warning: "nullData" [/home/la/compr/dyn_buffer.ko] undefined!
*** Warning: "dynCleanBuffer" [/home/la/compr/compr.ko] undefined!
*** Warning: "dynInitBuffer" [/home/la/compr/compr.ko] undefined!
*** Warning: "dynAddChunk" [/home/la/compr/compr.ko] undefined!
*** Warning: "dynMakeBigBuffer" [/home/la/compr/compr.ko] undefined!
CC /home/la/compr/compr.mod.o
LD [M] /home/la/compr/compr.ko
CC /home/la/compr/compr_dev.mod.o
LD [M] /home/la/compr/compr_dev.ko
CC /home/la/compr/dyn_buffer.mod.o
LD [M] /home/la/compr/dyn_buffer.ko
make[1]: Leaving directory `/tmp/linux-2.6.10'
Strange, I have cut 'n' pasted all your sources into files on my pc, added some dummy return statements in the obvious places and it builds just fine. I suspect the problem is elsewhere.
This is what I get when building.
Code:
madluther@pc2:~/lkp/lq$ make V=1
make -C /lib/modules/2.6.13.2/build M=`pwd` modules ARCH=i386
make[1]: Entering directory `/usr/src/linux-2.6.13'
mkdir -p /home/madluther/lkp/lq/.tmp_versions
make -f scripts/Makefile.build obj=/home/madluther/lkp/lq
gcc -m32 -Wp,-MD,/home/madluther/lkp/lq/.dyn_buffer.o.d -nostdinc -isystem /usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DMODULE -DKBUILD_BASENAME=dyn_buffer -DKBUILD_MODNAME=compr_dev -c -o /home/madluther/lkp/lq/dyn_buffer.o /home/madluther/lkp/lq/dyn_buffer.c
/home/madluther/lkp/lq/dyn_buffer.c: In function `dynMakeBigBuffer':
/home/madluther/lkp/lq/dyn_buffer.c:28: warning: control reaches end of non-void function
/home/madluther/lkp/lq/dyn_buffer.c: At top level:
/home/madluther/lkp/lq/dyn_buffer.c:18: warning: 'dynAddNumChunks' defined but not used
gcc -m32 -Wp,-MD,/home/madluther/lkp/lq/.utils.o.d -nostdinc -isystem /usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DMODULE -DKBUILD_BASENAME=utils -DKBUILD_MODNAME=compr_dev -c -o /home/madluther/lkp/lq/utils.o /home/madluther/lkp/lq/utils.c
gcc -m32 -Wp,-MD,/home/madluther/lkp/lq/.compr.o.d -nostdinc -isystem /usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DMODULE -DKBUILD_BASENAME=compr -DKBUILD_MODNAME=compr_dev -c -o /home/madluther/lkp/lq/compr.o /home/madluther/lkp/lq/compr.c
In file included from /home/madluther/lkp/lq/compr.h:7,
from /home/madluther/lkp/lq/compr.c:1:
include/linux/cdev.h:24: warning: "struct inode" declared inside parameter list
include/linux/cdev.h:24: warning: its scope is only this definition or declaration, which is probably not what you want
/home/madluther/lkp/lq/compr.c: In function `init_module':
/home/madluther/lkp/lq/compr.c:93: warning: control reaches end of non-void function
/home/madluther/lkp/lq/compr.c: At top level:
/home/madluther/lkp/lq/compr.c:21: warning: 'compr_buffer' defined but not used
/home/madluther/lkp/lq/compr.c:23: warning: 'compr_cdev' defined but not used
ld -m elf_i386 -m elf_i386 -r -o /home/madluther/lkp/lq/compr_dev.o /home/madluther/lkp/lq/dyn_buffer.o /home/madluther/lkp/lq/utils.o /home/madluther/lkp/lq/compr.o
Building modules, stage 2.
make -rR -f /usr/src/linux-2.6.13/scripts/Makefile.modpost
scripts/mod/modpost -i /usr/src/linux-2.6.13/Module.symvers vmlinux /home/madluther/lkp/lq/compr_dev.o
gcc -m32 -Wp,-MD,/home/madluther/lkp/lq/.compr_dev.mod.o.d -nostdinc -isystem /usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=compr_dev -DKBUILD_MODNAME=compr_dev -DMODULE -c -o /home/madluther/lkp/lq/compr_dev.mod.o /home/madluther/lkp/lq/compr_dev.mod.c
ld -m elf_i386 -m elf_i386 -r -o /home/madluther/lkp/lq/compr_dev.ko /home/madluther/lkp/lq/compr_dev.o /home/madluther/lkp/lq/compr_dev.mod.o
make[1]: Leaving directory `/usr/src/linux-2.6.13'
I changed ARCH to i386, but everything else is the same.
Could it be a bad linux kernel or did I do something wrong in one of the implementation phases?
Maybe I'll try to put on the 2.6.16 kernel since that has worked before with UML but I removed it for some reason I couldn't remember.
Like I said, I have the 2.6.10 kernel for UML and 2.6.13-15 for my default SuSE.
Strange thing is that SuSE 10's release kernel doesn't want to compile into UML.
I have compiled it with my ordinary 2.6.13-15 kernel that comes with SuSE 10 but still gives me the *** warning messages.
Atleast I didn't have to add the ARCH=um in my makefile.
I finally got it with the help of Maxim at the #kernelnewbies IRC channel.
All I had to do was issue a "make -C <path to linux src> M=`pwd` clean" first
Man, another small stone that made it look like a mountain to cross!
Trust me, when you get to a problem that looks bad ... step back and check all the small stuff because the chances are good that it is just 1 thing you've missed.
Thanks to all who've helped me with this!
Last edited by Last Attacker; 05-06-2006 at 09:16 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.