Problem running "Hello World" linux module - linux

I'm trying to compile and run a "Hello World" module from the book "Linux Device Drivers"
the program ~/ldd3/hello.c I'm trying to compile is:
/*
* $Id: hello.c,v 1.5 2004/10/26 03:32:21 corbet Exp $
*/
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
And the Makefile is:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
When I run make, the compilation seems ok:
root#deb:/home/deb/ldd3# make
make -C /lib/modules/4.14.86/build M=/home/deb/ldd3 modules
make[1]: Entering directory '/home/deb/src/linux-4.14.86'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/home/deb/src/linux-4.14.86'
But when I run :
root#deb:/home/deb/ldd3# insmod ./hello.ko
root#deb:/home/deb/ldd3#
the "Hello World" message doesnt get printed.
Nor do I get a message printed when I run
rmmod hello
Can you tell me why?
Thanks

In order to see kernel messages, you can use dmesg.
Alternatively, you can see the syslog tail var/log/syslog.

Related

How to link .so library properly in C++?

I have project structure like this,
a.pb.h --- includes --> protobuf.h
b.grpc.pb.h --- includes --> a.pb.h & grpcpp.h
Also there are a.pb.cc and b.grpc.cc files.
A C++ wrapper with extern C which is wrapper.cc and wrapper.h which includes b.grpc.pb.h and grpcpp.h.
The function inside extern C is char* helloWorld(const char*, const char*, const char*);
Creating .o of a.pb.h and b.grpc.pb.h:
g++ -fpic -std=c++11 `pkg-config --cflags protobuf grpc` -c -o a.pb.o a.pb.cc
g++ -fpic -std=c++11 `pkg-config --cflags protobuf grpc` -c -o b.grpc.pb.o b.grpc.pb.cc
Steps to create libcombined.so:
The grpc and protobuf so are already provided under /usr/local/lib.
First created .so of a.pb.o and b.grpc.pb.o to compile wrapper file as:
g++ -shared -o libcombined.so *.o
Compiled wrapper as:
g++ -fpic wrapper.cc -l:./libcombined.so -c -o wrapper.o -std=c++11
.so of a.pb.o, b.grpc.pb.o and wrapper.o as libcombined.so:
g++ -shared -o libcombinedwrapper.so *.o
Compiled main.c as:
gcc main.c -l:./libcombinedwrapper.so -o main -ldl
I am calling helloWorld from my main.c file which is:
#include <stdio.h>
#include <dlfcn.h>
int main(){
char* (*fn)(const char*,const char*,const char*);
void *handle = dlopen("path_to/libcombined.so",RTLD_NOW);
if(handle==NULL){
fprintf(stderr, "Error: %s\n", dlerror());
}
fn = (char* (*)(const char*,const char*,const char*))dlsym(handle, "helloWorld");
if (!fn) {
/* no such symbol */
fprintf(stderr, "Error: %s\n", dlerror());
dlclose(handle);
return 0;
}
char* msg = fn("asd","asdas","asdasd");
printf("%s",msg);
return 0;
}
Error after executing: ./main
Error: path_to/libcombinedwrapper.so: undefined symbol: _ZN6google8protobuf2io20ZeroCopyOutputStream15WriteAliasedRawEPKvi
Error: ./main: undefined symbol: helloWorld
Segmentation fault (core dumped)
The first above error is from symbol from protobuf.h file.
Can someone please suggest what I am doing wrong while linking or is there something I am doing wrong in main.c file?
g++ -shared -o libcombined.so *.o
You need to also link in all dependencies of the objects (libgrpc here).
You can add -Wl,--no-allow-shlib-undefined to verify that libcombined.so is linking everything it needs.
P.S. To avoid core dump, you should exit or return once dlopen fails.
P.P.S. It is generally a very bad idea(TM) to link *.o. Use proper Makefile to avoid unnecessary compilations and explicitly list objects that you are intending to put into libcombined.so.

kernel demo build error

In my limited experience with kernel program, my os is Ubuntu16.04,and use sudo apt-get install linux-headers-`uname -r` to install kernel header,and the kernel_hello.c file is
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("DUAL BSD/GPL")
MODULE_AUTHOR("YANQIN")
MODULE_DESCRIPTION("kernel module hello")
MODULE_VERSION("1.0")
static int hello_init(void)
{
printk(KERN_ALERT "hello_init() start\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "hello_exit() start\n");
}
module_init(hello_init);
module_exit(hello_exit);
and the Makefile is
KERNAL_DIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m := kernel_hello.o
default:
$(MAKE) -C $(KERNAL_DIR) M=$(PWD) modules
but the build result is like this
yq#ubuntu:~/kernelProgram$ make
make -C /lib/modules/4.10.0-28-generic/build M=/home/yq/kernelProgram modules
make[1]: Entering directory '/usr/src/linux-headers-4.10.0-28-generic'
CC [M] /home/yq/kernelProgram/kernel_hello.o
In file included from ./include/linux/module.h:18:0,
from /home/yq/kernelProgram/kernel_hello.c:2:
./include/linux/moduleparam.h:21:1: error: expected ‘,’ or ‘;’ before ‘static’
static const char __UNIQUE_ID(name)[] \
^
./include/linux/module.h:161:32: note: in expansion of macro ‘__MODULE_INFO’
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
^
/home/yq/kernelProgram/kernel_hello.c:6:1: note: in expansion of macro ‘MODULE_AUTHOR’
MODULE_AUTHOR("YANQIN")
^
In file included from /home/yq/kernelProgram/kernel_hello.c:2:0:
/home/yq/kernelProgram/kernel_hello.c: In function ‘__inittest’:
/home/yq/kernelProgram/kernel_hello.c:19:13: error: ‘hello_init’ undeclared (first use in this function)
module_init(hello_init);
^
./include/linux/module.h:131:11: note: in definition of macro ‘module_init’
{ return initfn; } \
^
/home/yq/kernelProgram/kernel_hello.c: At top level:
./include/linux/module.h:132:6: error: ‘init_module’ aliased to undefined symbol ‘hello_init’
int init_module(void) __attribute__((alias(#initfn)));
^
/home/yq/kernelProgram/kernel_hello.c:19:1: note: in expansion of macro
‘module_init’
module_init(hello_init);
^
scripts/Makefile.build:301: recipe for target
'/home/yq/kernelProgram/kernel_hello.o' failed
make[2]: *** [/home/yq/kernelProgram/kernel_hello.o] Error 1
Makefile:1524: recipe for target '_module_/home/yq/kernelProgram' failed
make[1]: *** [_module_/home/yq/kernelProgram] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-4.10.0-28-generic'
Makefile:7: recipe for target 'default' failed
make: *** [default] Error 2
i don't know why it saids the linux kernel header has error
Calls to MODULE_LICENSE and other MODULE_* macros, which setup information about the module, should be terminated with ; like common C instructions

sysctl doesn't creates file in proc

To communicate in kernel mode and user space, I am using this C program. I am using following Makefile to create .ko file to load.
bj-m := sysctl_test.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
After successful execution, and loading the .ko file, it should have create /proc/sys/net/test directory, and value1 and value2 file in that directory.
When I load this module, it doesn't create any file or directory. Am I doing something wrong here or code need some changes?
I have tried by modifying values in structures as:
static ctl_table test_net_table[] = {
{
...
.procname = "/proc/sys/net/test",
...
},
{ .ctl_name = 0 }
};
static ctl_table test_root_table[] = {
{
...
.procname = "/proc/sys/net/",
...
},
{ .ctl_name = 0 }
};
The original values was test and net respectively.
Thanks for your time!
Try changing
bj-m := sysctl_test.o
to
obj-m := sysctl_test.o
it worked for me.
PS:Its an old question, but I update answer for those who come across same error and stop her.

Kernel module with multiple files - unknown symbol

Hello stackoverflowers :)
For the last several hours I've been trying to compile+load a multiple file module. The compilation emits a strange warning and the module fails to load. Here are the module, Makefile, compilation output and dmesg.
header:
// header.h
#ifndef _HEADER_H
#define _HEADER_H
void do_module_func(void);
void do_other_func(void);
#endif
'main' module file:
//mymodule.c
#include <linux/module.h>
#include <linux/kernel.h>
#include "header.h"
void do_module_func(void)
{
printk(KERN_INFO "module_func\n");
}
static int mymodule_init(void)
{
printk(KERN_INFO "Hello world\n");
do_other_func();
return 0;
}
module_init(mymodule_init);
static void mymodule_exit(void)
{
printk(KERN_INFO "Goodbye, cruel world\n");
}
module_exit(mymodule_exit);
MODULE_LICENSE("GPL")
other c file, which calls do_module_func() that sits in the 'main' module
//other_file.c
#include "header.h"
#include <linux/kernel.h>
void do_other_func(void)
{
printk(KERN_INFO "other_func\n");
do_module_func();
}
Makefile
//Makefile
obj-m := mymodule.o
mymodule-objs := other_file.o
CROSS:=arm-unknown-linux-gnueabi-
KERNEL:= ~/work/linux-davinci-2.6.38/
ARCH:=arm
PWD:=$(shell pwd)
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
clean:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) clean
I'm cross compiling but I believe this shouldn't be a problem.
make output:
make CROSS_COMPILE....
make[1]: Entering directory .../linux-davinci-2.6.38
CC [M] .../other_file.o
LD [M] .../mymodule.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "do_module_func" [.../mymodule.o] undefined! <--- warning here
CC .../mymodule.mod.o
LD [M] .../mymodule.ko
make[1]: Leaving directory .../linux-davinci-2.6.38
insmod output:
can't insert 'mymodule.ko': unknown symbol in module, or unknown parameter
dmesg:
mymodule: Unknown symbol do_mdule_func (err 0)
Thus the module compiles with a (linkage?) warning and the module doesn't load.
Now, I see that in the make output there appears to be a linkage attempt after compiling other_file.c, but shouldn't there be a compilation of also mymodule.c before the linkage?
Thanks! :)
Turns out the problem was in the Makefile. The 'trick' is that you define in obj-m the module that will be compiled (into a .ko) and in the -objs you write all the source files.
Thus the definitions in this Makefile turn to:
obj-m := moduleko.o
moduleko-objs := other_file.o mymodule.o
and this is compiled into moduleko.ko.
This is because file_2 required file_1 symbol reference for building file_2 as LKM.
To overcome this, build file_1(LKM) and place the Module.symvers of file_1 in file_2 location. And build the file_2 again.
all:
$(MAKE) CROSS_COMPILE=$(CROSS) ARCH=$(ARCH) -C $(KERNEL) M=$(PWD) modules
instead try like this
$(MAKE) -C $(KERNEL) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS) M=$(PWD) /
this will run each file and links with object.hope this would solve your problem

compile rpcgen program on ubuntu

I am new to rpcgen programming.
On compiling the following sample rpcgen example on ubuntu I get error.The main functionality is to calculate the square of a given number
square.X
struct square_in {
long arg1;
};
struct square_out {
long res1;
};
program SQUARE_PROG {
version SQUARE_VERS {
square_out SQUAREPROC(square_in) = 1;
/* procedure number = 1 */
} = 1; /* version number = 1 */
} = 0x31230000; /* program number = 0x31230000 */
client.c
#include <rpc/rpc.h>
#include "square.h"
int
main(int argc, char **argv)
{
CLIENT *cl;
square_in in;
square_out *outp;
if (argc != 3)
//err_quit("usage: client <hostname> <integer-value>");
exit(0);
cl = clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp");
in.arg1 = atol(argv[2]);
if ( (outp = squareproc_1(&in, cl)) == NULL)
//err_quit("%s", clnt_sperror(cl, argv[1]));
exit(0);
printf("result: %ld\n", outp->res1);
exit(0);
}
server.c
#include <rpc/rpc.h>
#include "square.h"
#include <stdio.h>
square_out *
squareproc_1_svc(square_in *inp, struct svc_req *rqstp)
{
static square_out out;
printf("thread %d started, arg = %ld\n",
pr_thread_id(NULL), inp->arg1);
sleep(5);
out.res1 = inp->arg1 * inp->arg1;
printf("thread %d done\n", pr_thread_id(NULL));
return(&out);
}
makefile:
PROGS = client server
CFLAGS += -DDEBUG
all: ${PROGS}
square.h square_clnt.c square_svc.c square_xdr.c: square.x
rpcgen -C square.x
square_clnt.o: square_clnt.c square.h
square_svc.o: square_svc.c square.h
client: square.h client.o square_clnt.o square_xdr.o
${CC} ${CFLAGS} -o $# client.o square_clnt.o square_xdr.o \
${LIBS} ${LIBS_RPC}
server: square.h server.o square_svc.o square_xdr.o
${CC} ${CFLAGS} -o $# server.o square_svc.o square_xdr.o \
${LIBS} ${LIBS_RPC}
clean:
rm -f ${PROGS} ${CLEANFILES} *_clnt.c *_svc.c *_xdr.c square.h
On execution, I get the following error:
cc -DDEBUG -c -o client.o client.c
cc -DDEBUG -o client client.o square_clnt.o square_xdr.o \
cc -DDEBUG -c -o server.o server.c
cc -DDEBUG -o server server.o square_svc.o square_xdr.o \
server.o: In function `squareproc_1_svc':
server.c:(.text+0x14): undefined reference to `pr_thread_id'
server.c:(.text+0x52): undefined reference to `pr_thread_id'
collect2: error: ld returned 1 exit status
make: *** [server] Error 1
use server file like this
// SERVER FILE: server.c
#include"rpc/rpc.h"
#include"square.h"
#include"stdio.h"
#include"stdlib.h"
#include"math.h"
square_out *squareproc_1_svc(square_in *inp,struct svc_req *rqstp)
{
static square_out out;
out.res1 = inp->arg1 * inp->arg1;
return(&out);
}
and run program using
[root#localhost ~]# rpcgen -C square.x
[root#localhost ~]# cc -c client.c -o client.o
[root#localhost ~]# cc -c square_clnt.c -o square_clnt.o
[root#localhost ~]# cc -c square_xdr.c -o square_xdr.o
[root#localhost ~]# cc -o client client.o square_clnt.o square_xdr.o
[root#localhost ~]# cc -c client.c server.c square_xdr.c
[root#localhost ~]# cc -c server.c -o server.o
[root#localhost ~]# cc -c square_svc.c -o square_svc.o
[root#localhost ~]# cc -o server server.o square_svc.o square_xdr.o
[root#localhost ~]# ./server &
[1] 3334
[root#localhost ~]# ./client localhost 4
result is : 16
I don't think you need to use pr_thread_id. Try compiling without it.

Resources