How can I share a global variable between two Linux kernel modules? - c

I am trying to get notification when USB is connected and disconnected.
So I am trying to implement signals. I created a file "file1" in debugfs. Then I provided a simple write file operation.
In user space there is a user space application, which will write its PID in the "file1" of debugfs.
In kernel space I can get the PID passed using the write method mentioned above. But I want to use this PID in a different kernel module. So I tried using EXPORT_SYMBOL();, but if I don't include the common header file, I get a compilation error. If I include the header file, when I flash the image, I see that PID is '0'.
Can anybody tell me, if this the right way? Or tell me where am I going wrong. Or can I get notification in different kernel module when PID is written to the file. If so how?

EXPORT_SYMBOL() is the correct approach. I do not quite understand what you mean by "if I don't include the common header file". It sounds like you are including the EXPORT_SYMBOL() in a shared header file which is not what you want to do. You want to do something like the following:
module1.c (compiles into module1.ko)
int my_exported_variable;
EXPORT_SYMBOL(my_exported_variable);
// The rest of module1.c
And then in module2.c (compiles into module2.ko which must be insmod-ed after module1.ko)
extern int my_exported_variable; // Note the extern, it is declaring but not defining it, the definition is in module1
// The rest of module2.c
After you insmod the first module you can check that the symbol is exported by doing a grep my_exported_variable /proc/kallsyms, assuming you have /proc/kallsyms on your system. If you don't see your variable there then the insmod of module2.ko will fail do to an unresolved symbol.

Related

Importing Modules — customized Modules in C

I am currently learning the C programming language and I'm having some issues with importing modules I created.
I created a small module to read with fgets and flush the buffer from stdin perfectly and I don't want to keep writing the code every single time. I just want to import this small module like I used to do in Python. I didn't knew how because I'm not using an IDE. I'm just compiling with gcc in terminal and using a text editor. I tried to search with Google,but in vain.
You should create a header for your module that declares the functions in the module – and any other information that a consumer of the module needs. You might call that header weekly.h, a pun on your name, but you can choose any name you like within reason.
You should create a library (shared or static — that's up to you) that contains the functions (and any global variables, if you're so gauche as to have any) defined by your module. You might call it libweekly.so or libweekly.a — or using the extensions appropriate to your machine (.dylib and .a on macOS, for example). The source files might or might not be weekly.c — if there's more than one function, you'll probably have multiple source files, so they won't all be weekly.c. You should put this code (the header and the source files and their makefile) into a separate source directory.
You should install the header(s) and the library in a well-known location (e.g. $HOME/include for headers and $HOME/lib for the library — or maybe in the corresponding directories under /usr/local), and then ensure that the right options are used when compiling (-I$HOME/include for the headers) or linking (-L$HOME/lib and -lweekly).
Your source code using the module would contain:
#include "weekly.h"
and your code would be available. With shared libraries in $HOME/lib, you would have to ensure that the runtime system knows where to find the library. If you install it in /usr/local, that is done for you already. If you install it in $HOME/lib, you have to investigate things like /etc/ld.so.conf or the LD_LIBRARY_PATH or DYLIB_LIBRARY_PATH environment variables, etc.
You need to create a header file (.h) with your function declarations types and extern variables. Then in the program where you want to use those functions include this .h file and and add the compiled .o file (with your functions) to the object file list. And you are done.

Undefined function inserting new module in kernel linux

I'm working on a new system call for the kernel linux 2.6.32, with the aim to do a myOpen very close to the original open.
I've modified the original struct file (linux/fs.h) with a new variable and i want to continue to use the original fileTable also with myOpen (I hope to add myOpen in the code of the original open, switching in my case with a simply flag).
To do this I compile my code in a module (module.ko) and load this dinamically on my kernel (the one with the fs.h modified).
Now the problem is that if I use some function relative to the file system (ex: get_unused_fd_flags(flags); fd_install(fd, f); etc etc), some variable are not found (i recive it like warning and also in the kernel terminal).
I think the problem is that I Try to use some kernel function, but I do the same with others like filp_open and I not recive error. How I can solve this?
Terminal:
make -C /lib/modules/2.6.32progb/build M=/home/mauro/Scrivania modules
make[1]: ingresso nella directory "/home/mauro/Scrivania/linux-2.6.32.B"
Building modules, stage 2.
MODPOST 1 modules
WARNING: "alloc_fd" [/home/mauro/Scrivania/moduloB.ko] undefined!
make[1]: uscita dalla directory "/home/mauro/Scrivania/linux-2.6.32.B"
[sudo] password for mauro: insmod: error inserting 'moduloB.ko': -1 Unknown symbol in module
alloc_fd is not exported to modules.
This is a hint by the kernel developers that they don't want to encourage module developers to call the function. Now, since the kernel is open-source, you can of course export the function anyway by simply modifying the kernel source to add: "EXPORT_SYMBOL(alloc_fd);" just after the function in fs/file.c
Some functions you're trying to use are already exported - hence you don't get a warning for them.

error: asm/uaccess.h: No such file or directory

I'm running linux kernel no. 2.6.15.51 on a ubuntu system.
I created a custom system call and added it to the kernel (containing a struct), compiled, and booted into the new kernel. Now I'm trying to create a c file that calls that system call (for testing purposes). Because I have a struct declared in my system call file, I am including the header in my test file so I can use that same struct. However, when I try including my system call file (which makes a call to access_ok() method), I get an error saying asm/uaccess.h (the file where access_ok() is declared) does not exist. Any ideas why I could be having this problem? Thank you!

Why does FUSE readdir returns Input/output error?

I am seeing a strange issue while implementing the readdir() functionality in fuse. Basically when I do ls on any directory in fuse, I get an error such as:
# ls
ls: reading directory .: Input/output error
file1.c file2.c
But the strange thing is, readdir() is doing exactly what it is supposed to do. In the sense that in that particular directory, I have two files named file1.c and file2.c and it is able to read it correctly.
While debugging the issue I noticed that fuse filler function (fuse_fill_dir_t passed as an argument to readdir() ) is what may be causing this error.
This is because if I simply print the contents of the directory using a debug printf without returning the contents using the filler function, I do not see the error.
But as soon as I start using the filler function to return the contents, I start seeing this error.
I have two questions related to this:
1) Anybody have any idea as to why the filler function might be causing this problem?
2) How do I look for the definition of the code for the fuse_fill_dir_t function? I have looked through most of the fuse functions with that kind of arguments but have had no luck until now.
Any help is appreciated!
Cheers,
Vinay
Such messages may be caused by failed calls to other (possibly unimplemented) FUSE callbacks like getxattr(). Then readdir() is called and results are obtained right.
You can debug a FUSE filesystem running its executable with key -d (debug mode), - that does not daemonize process and prints detailed debug output about FUSE calls.
Also, it would be nice to know what is your platform (Linux/OS X/etc).

Execute a C program from another program in gcc

I need to include a .h file to my project which will be supplied at the runtime. Since .h files are linked at linking time i am unable to include .h file. So i decided to write a dummy program which would create .h file and then i would call my actual program. Is there anyway to do this. Or any other solution is possible. I basically need to create a .h file before my program starts execution and need to link it up to my program.
i actually should take a file which is created by user, parse the file and then create a structure with the fields present in that file.for example if the file contains the following data:-
fno:int:4,fname:char:30,ftype:int:4
then i should create a structure like
struct somename
{
int fno;
char fname[30];
int ftype
};
Then i should be able to create instances of the structure created. This is what i like to do
dlopen is a solution. It allows to load dynamic library at runtime.
Compile your dummy program as a dynamic library.
Make use of dlopen on your .so
Call any function you need as if it has been linked by gcc (see dlsym).
What you can do is:
create .h file
fork
if in child: execve
if in father: wait (or not, depends on what you want to do)
I would use a Makefile; your program would receive the header file at runtime, (perhaps check it?) then execve() the make command passing the name of the file.
However, this sounds very cumbersome; perhaps you are trying to achieve something with the wrong tool. Maybe you want to use some scripting first? Or write two separate programs..? What are you trying to do?

Resources