2002-03-24 16:16:15

by Anthony Chee

[permalink] [raw]
Subject: undefined reference

The case is quite complicated.

I am now developing a module. This module need communicate with the kernel.
So I exported a function func(), by using EXPORT_SYMBOL(func). In the header
file, I set "extern int func()".

I also modified the kernel source code, which is inode.c, and insert the
func() and the module header file.

After the above procedure, I use "make bzImage" to build the kernel. At the
compile stage, it does not appear warning message, but it appears in the
linking object stage, which is

fs/fs.o(.text+0x1377d): undefined reference to `func'

How can I solve this issue? Or any parameter for "ld" to avoid checking the
undefined reference?
Thanks.


2002-03-25 21:46:09

by Bart Trojanowski

[permalink] [raw]
Subject: Re: undefined reference

* Anthony Chee <[email protected]> [020324 11:17]:
> I am now developing a module. This module need communicate with the kernel.
> So I exported a function func(), by using EXPORT_SYMBOL(func). In the header
> file, I set "extern int func()".
<snip>

The problem you face is that the kernel needs to know where foo is to
generate a the bytecode that calls it. Here is a better scenario...

You expose an interface in the kernel such as

typedef void (*func_t)(int);
void register_func ( func_t func );
EXPORT_SYMBOL (register_func);

Then in your modules you call 'register_func' and that will pass the
function in question to the kernel. The kernel can then do whatever it
wants to that pointer (like call it).

B.

--
WebSig: http://www.jukie.net/~bart/sig/


Attachments:
(No filename) (778.00 B)
(No filename) (232.00 B)
Download all attachments

2002-03-26 04:18:09

by Anthony Chee

[permalink] [raw]
Subject: Re: undefined reference

Or let me say clearly.

The suitution is I want the kernel source use the symbol from module.

What I did in the module code are:
1. EXPORT_SYMBOL(func) in the source code of module
2. Set "extern int func()" in the module header

What I did in the kernel source code are:
1. Insert "func()" in the inode.c
2. Add the module header in the kernel source code

Then I use "make bzImage", I got no error message on compiling inode.c, but
I got

"fs/fs.o(.text+0x1377d): undefined reference to `func'"

in the linking stage.

I also set condition inode.c to check the existing of module before calling
func()

Thanks

Regards,
Anthony

----- Original Message -----
From: "Bart Trojanowski" <[email protected]>
To: "Anthony Chee" <[email protected]>;
<[email protected]>
Cc: <[email protected]>; <[email protected]>;
<[email protected]>
Sent: Tuesday, March 26, 2002 5:45 AM
Subject: Re: undefined reference



2002-03-26 12:56:29

by Keith Owens

[permalink] [raw]
Subject: Re: undefined reference

On Tue, 26 Mar 2002 12:17:50 +0800,
"Anthony Chee" <[email protected]> wrote:
>Or let me say clearly.
>
>The suitution is I want the kernel source use the symbol from module.
>
>What I did in the module code are:
>1. EXPORT_SYMBOL(func) in the source code of module
>2. Set "extern int func()" in the module header
>
>What I did in the kernel source code are:
>1. Insert "func()" in the inode.c
>2. Add the module header in the kernel source code
>
>Then I use "make bzImage", I got no error message on compiling inode.c, but
>I got
>
>"fs/fs.o(.text+0x1377d): undefined reference to `func'"

You cannot do that. The kernel must be self contained. The only way
for the kernel to access module code and data is for the module to
register that code and data when the module is loaded and for the
kernel to access the module via the registration list.

See any module that handles a filesystem. sys_open() does not call the
module directly. A module registers its file operations on load. The
kernel (dentry_open) calls the module via f->f_op->open.

2002-03-30 14:19:28

by Anthony Chee

[permalink] [raw]
Subject: Re: undefined reference

> >
> >Then I use "make bzImage", I got no error message on compiling inode.c,
but
> >I got
> >
> >"fs/fs.o(.text+0x1377d): undefined reference to `func'"
>
> You cannot do that. The kernel must be self contained. The only way
> for the kernel to access module code and data is for the module to
> register that code and data when the module is loaded and for the
> kernel to access the module via the registration list.
>
> See any module that handles a filesystem. sys_open() does not call the
> module directly. A module registers its file operations on load. The
> kernel (dentry_open) calls the module via f->f_op->open.
>
>

Thanks for your help. I use another apporach to communicate with module,
similiar to the method you stated above.

What I did in the kernel source,

1. In fs.h, I added one line in struct super_operations
int (*query_module) (struct inode *);

2. In write_inode() of inode.c, added
result = inode->i_sb->s_op->query_module(inode);

What I did in the module,

1. Build up my own function, kernel_query_module(struct inode *inode)

2. In init_module(), added
struct super_block *sb_ptr;
sb_ptr = get_super(MKDEV(8,1)); /* suppose I want to
get super_block of /dev/sda1 */
sb_ptr -> s_op -> query_module = &kernel_query_module;

Then, I compile the module and didi not get error message
When I compile the kernel, I got the follow error message,

inode.c:195: structure has no member named `query_module'

It made me crazy. Why the module can access the s_op and register the
address of kernel_query_module, but not the kernel source? I already added
one more item in the struct super_operation, but got the error message the
struct has no such member.

Any thing I missed? Thanks.