I am currently trying to run my Hello World Kernel Module but I am struggling a bit and I do not know why.
First of all
uname -r
2.6.32-358.23.2.el6.x86_64
My Hello.c
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
MODULE_LICENSE("GPL");
My Makefile
obj-m += hello.o
all:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
make -C /lib/modules/`uname -r`/build M=`pwd` clean
Error message when running
$ sudo insmod ./hello.ko
insmod: error inserting './hello.ko': -1 Invalid module format
dmesg output
hello: no symbol version for module_layout
files in folder
hello.c hello.ko hello.ko.unsigned hello.mod.c hello.mod.o hello.o include Makefile modules.order Module.symvers
What is needed to insert this module and complete my further work?
Related
I wrote a simple c++ code. I wanted to choose to execute one of the codes through the -D option of makefile, but it didn't execute? For example, code1 and code2.
1.main.cpp
#include "./common.h"
#include "./ns_api.h"
int TestFunc3(void)
{
}
int test = 10;
int main(int argv, char **argc)
{
extern int b;
int a = b;
printf("This is a test!\n");
#ifdef TEST_ADD
printf("test_add!\n"); //code1
#endif
#if TEST_SUB
printf("test_sub!\n"); //code2
#endif
return 0;
}
int b;
2.makefile
root#cat makefile
GPP = g++
CFLAGS += -O3
objects = *.o
src = *.cpp
test:$(objects)
$(GPP) $(CFLAGS) -o test $(objects)
$(objects):$(src)
$(GPP) -c $(src)
.PHONY:clean
clean:
rm test *.o
3.compile
root#make CFLAGS=-DTEST_ADD CFLAGS+=-DTEST_SUB=1
g++ -c *.cpp
g++ -DTEST_ADD -DTEST_SUB=1 -o test *.o
4.result:
root#./test
This is a test!
Similar questions got asked a lot, but I still don't quite get what's wrong with how I compiled and installed my shared library.
As far as compiling goes I do
> gcc -c -fPIC libt.c
> gcc -shared -Wl,-soname,libt.so.0 -o libt.so.0.1 libt.o
In order to install the library I run
> cp libt.so.0.1 /usr/local/lib/
> cp libt.h /usr/local/include/
> ln -s /usr/local/lib/libt.so.0.1 /usr/local/lib/libt.so.0 # ldconfig would setup this symlink itself ...
> ln -s /usr/local/lib/libt.so.0 /usr/local/lib/libt.so # ... but not this one, so I do it myself
> sudo ldconfig
/usr/local/lib is included in /etc/ld.so.conf.d/libc.conf, and ldconfig -p | grep libt yields
libt.so.0 (libc6,x86-64) => /usr/local/lib/libt.so.0
libt.so (libc6,x86-64) => /usr/local/lib/libt.so
So, as far as I can tell, everything looks okay until this point. However, compiling a program that's supposed to use my library fails:
> gcc -o prog main.c -llibt
/usr/bin/ld: cannot find -llibt
libt.h
#ifndef libt_h__
#define libt_h__
extern int add(int, int);
#endif
libt.c
int
add(int a, int b)
{
return a + b;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "libt.h"
void
print_usage()
{
printf("usage: ./prog <number a> <number b>\n");
}
int
main(int argc, char *argv[])
{
int a = 0, b = 0, c = 0;
if (argc != 3) {
print_usage();
return 1;
}
a = atoi(argv[1]);
b = atoi(argv[2]);
c = add(a, b);
printf("%d\n", c);
return 0;
}
Figured it out. While library names have to be prefixed with "lib", that prefix must not be specified when linking. That is, gcc -o prog main.c -llibt is wrong while gcc -o prog main.c -lt works as expected.
Makefile isn't using implicit rules correctly. I am following this guide here.
Here's my makefile:
objects = main.o hello.o
hello : $(objects)
cc -o hello $(objects)
hello.o : defs.h
main.o : defs.h hello.h
.PHONY : clean
clean :
-rm hello $(objects)
I get the following error:
cc: error: main.o: No such file or directory
It creates the object code hello.o, but does not do it for main.c. If I swap lines and main is above, it'll create main.o but not hello.o.
Here's my main.c file:
#include "defs.h"
#include "hello.h"
int main(int argc, char** argv) {
display_hello();
return (EXIT_SUCCESS);
}
Here's my hello.c file:
#include "defs.h"
void display_hello()
{
printf("Hello!\n");
}
My hello.h file:
#ifndef HELLO_H
#define HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* HELLO_H */
void display_hello();
Here's my defs.h file:
#ifndef DEFS_H
#define DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* DEFS_H */
#include <stdio.h>
#include <stdlib.h>
Works fine for me, I created the files as https://gist.github.com/boyvinall/f23420215707fa3e73e21c3f9a5ff22b
$ make
cc -c -o main.o main.c
cc -c -o hello.o hello.c
cc -o hello main.o hello.o
Might be the version of make like #Beta said, but even an old version of GNU make should work just fine for this.
Otherwise, ensure you're using tabs to indent in the makefile, not spaces.
I am executing a simple makefile that contait 3 parts but it does not work well these are details of my files .h and .c:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main (void)
{
hello();
return EXIT_SUCCESS;
}
hello.h
#ifndef hello
#define hello
void hello (void);
#endif
hello.c
#include <stdio.h>
#include <stdlib.h>
void hello (void)
{
printf("Hello World\n");
}
makefile
all: hello
hello: hello.o main.o
gcc -o hello hello.o main.o
hello.o: hello.c
gcc -o hello.o -c hello.c -W -Wall -ansi -pedantic
main.o: main.c hello.h
gcc -o main.o -c main.c -W -Wall -ansi -pedantic
clean:
rm -rf *.o
mrproper: clean
rm -rf hello
I get this error:
When you write #define hello you define hello to be an empty token. Thus the function declaration on the next string effectively becomes this:
void (void);
which is not valid C code.
What you are trying to do is probably the Include guard, its purpose is to avoid multiple inclusion of one header. The name of the guard have to differ from any other token you use. Usual naming is FILENAME_H:
#ifndef HELLO_H
#define HELLO_H
void hello(void);
#endif
In hello.h, line 2 you are defining 'hello' as an empty token. Remove that line.
Im using gcc on Linux and creating a shared library for static libraries. I dont want symbols from some static libraries to be exported.
gcc version is 4.8.0.
Im trying this option at gcc command and it's not working:
-Wl,--exclude-libs,libabc.a .
If I use this option, it's removing all the symbols which not what I want.:
-Wl,--exclude-libs,ALL
Can somebody help in how to use --exclude-option and not to export symbols from specific static library, please?
Thanks
Chandra
Please ignore my comment to question, it is incorrect.
Minimal example:
test1.c:
int testvar1;
int test1(void) {
return 1;
}
test2.c:
extern int testvar1;
int test1(void);
int test2(void) {
testvar1 = -1;
return test1() + 2;
}
test.c:
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *lib = dlopen("./libtest2.so", RTLD_NOW);
int (*f)(void) = dlsym(lib, "test2");
printf("%d\n", f());
return 0;
}
Build:
$ gcc -fPIC -c test1.c
$ ar cru libtest1.a test1.o
$ gcc -fPIC -c test2.c
$ gcc -shared -o libtest2.so test2.o -L. -ltest1 -Wl,--exclude-libs,libtest1.a
$ gcc test.c -ldl
$ ./a.out
3
$ readelf --syms -D libtest2.so | grep test1
$