I am trying to compile multiple source files into a single module. I am having issues with multiple definition of functions.
Here is the code snippet of file1.c file
#include <linux/init.h>
#include <linux/module.h>
#include "headerfile.h"
#include <linux/slab.h>
static void swarm_init(void)
{
printk(KERN_ALERT "swarm_init function called\n");
}
void* func1(void) {
.....some code here
}
static void swarm_exit(void)
{
printk(KERN_ALERT "swarm_exit: exit function called");
}
module_init(swarm_init);
module_exit(swarm_exit);
Second file is as follows
#include <linux/init.h>
#include <linux/module.h>
#include "headerfile.h"
#include <linux/slab.h>
static void test_init(void)
{
printk(KERN_ALERT "Test init\n");
void *x;
x = func1();
}
static void test_exit(void)
{
printk(KERN_ALERT "test: exit function called");
}
module_init(test_init);
module_exit(test_exit);
headerfile.h is as follows
#ifndef _HEADERFILE_H
#define _HEADERFILE_H
typedef struct _hashmap_element{
int key;
int in_use;
void* data;
} hashmap_element;
typedef struct _hashmap_map{
int table_size;
int size;
hashmap_element *data;
} hashmap_map;
void *func1(void);
#endif
And my makefile is
obj-m :=myfile.o
myfile-objs := file1.o file2.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
I keep getting multiple definition of init_module and cleanup_module.
any idea whats going wrong?
Single module may have at most one initialization (declared with module_init() macro) and one cleanup (module_exit()) function. If you need initialization functionality for several parts of your module, you need to combine them manually into single initialization function. The same is true for cleanup.
Related
everyone!
I want to get the return value of the shell command "ls" in a kernel module.
the following is the source code of my kernel module.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("yuuyuu");
MODULE_DESCRIPTION("kernel module hello");
MODULE_VERSION("1.0");
static int hello_init(void)
{
char * envp[] = { "HOME=/", NULL };
char * argv[] = { "/bin/ls","/home", NULL };
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
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);
Is there anyone know how to get the output of "ls /home"?
Thanks!
I'm struggling with g++ compilation over c++.11
Here is the problem I'm facing:
error: 'IGameController' does not name a type.
The IGameController is actually my class interface, where I've put the location on my g++ script.
Here it is my g++ script to compile:
cd C:\MinGW\bin\
g++ -std=c++11 -c c:\Users\me\Downloads\TheGame\TheGame.cpp
g++ -std=c++11 -Ic:\Users\me\Downloads\TheGame\GameController\inc -Ic:\Users\me\Downloads\TheGame\GameController\src -c c:\Users\me\Downloads\TheGame\GameController\src\GameController.cpp
g++ -std=c++11 -o c:\Users\me\Downloads\TheGame\TheGame.exe *.o
I don't understand why the script doesn't find my header files...
My project is structured like this:
TheGame\TheGame.cpp
TheGame\GameController\inc\GameControllerProvider.hpp
TheGame\GameController\inc\IGameController.hpp
TheGame\GameController\src\GameController.cpp
TheGame\GameController\src\GameController.hpp
Here is my source code:
[TheGame.cpp]
#include <iostream>
#include "GameController/inc/GameControllerProvider.hpp"
#include "GameController/inc/IGameController.hpp"
int main()
{
GameController::IGameController& gameController = GameController::GameControllerProvider::getGameController();
gameController.printSomething();
return 0;
}
[IGameController.hpp]
#pragma once
namespace GameController
{
class IGameController
{
public:
virtual void printSomething() = 0;
protected:
IGameController() {}
virtual ~IGameController() {}
};
}
[GameControllerProvider.hpp]
#pragma once
namespace GameController { class IGameController; }
namespace GameController
{
namespace GameControllerProvider
{
IGameController& getGameController();
}
}
[GameController.hpp]
#pragma once
#include "GameController/inc/IGameController.hpp"
namespace GameController
{
class GameController : public IGameController
{
public:
GameController();
virtual ~GameController();
void printSomething() override;
private:
};
}
[GameController.cpp]
#include <iostream>
#include "GameController/inc/IGameController.hpp"
#include "GameController/src/GameController.hpp"
#include "GameController/inc/GameControllerProvider.hpp"
namespace GameController
{
GameController::GameController() {}
GameController::~GameController(){}
void GameController::printSomething()
{
std::cout << "printSomething()" << std::endl;
}
}
// Provider
IGameController& GameControllerProvider::getGameController()
{
static GameController sGameController;
return sGameController;
}
}
I'm not familiar with namespaces, but for sure one of your problems is with the #include statements, where you give a wrong path to some files.
For instance, when you call IGameController.hpp (in inc/) from GameController.cpp (in src/), since you are using quoations marks (" "), you should give the full path to the file, and it should be written as:
#include "../inc/IGameController.hpp"
Hope it helps.
I am attempting some Linux kernel development.
I have a problem in including a header file sched.h (which exists in the path /usr/src/linux-3.12.26/kernel/sched, not in /usr/src/linux-3.12.26/include/linux ).
But when I "sudo make -C /usr/src/linux-3.12.26/ M=$(pwd) modules" I got the error "fatal error: kernel/sched/sched.h: doesn't exist"
Here is my code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/percpu.h>
#include </usr/src/linux-3.12.26/kernel/sched/sched.h>
int __init init_current(void){
int cpu_num=0;
struct task_struct *p;
for(cpu_num=0;cpu_num<8;cpu_num++)
{
p=curr_task(cpu_num);
printk(KERN_ALERT "current task on cpu %d is %d\n", cpu_num, p->pid);
}
return 0;
}
void __exit exit_current(void)
{
printk(KERN_ALERT "FINISHED!\n");
}
MODULE_LICENSE("GPL");
module_init(init_current);
module_exit(exit_current);
There may be some errors in the code. My intention is to get the current running process in different cores.
#Santosh A .Thanks for continuing concerning my puzzle.After I changed the Makefile in /usr/src/linux-3.12.26/(see my answer above,it may not be normative,but work ),the headers I include can be found.Then I get another problem. Here is my code:
#include <linux/init.h>
#include <linux/module.h>
//#include <linux/sched.h>
#include <linux/percpu.h>
#include <sched/sched.h>
static int __init init_current(void){
int cpu_num=0;
extern struct task_struct *p;
struct rq *q;
extern struct rq * cpu_rq(int);
for(cpu_num=0;cpu_num<8;cpu_num++)
{
q=cpu_rq(cpu_num);
p=q->curr;
printk(KERN_ALERT "current task on cpu %d is %d\n", cpu_num, p->pid);
}
return 0;
}
static void __exit exit_current(void)
{
printk(KERN_ALERT "FINISHED!\n");
}
MODULE_LICENSE("GPL");
module_init(init_current);
module_exit(exit_current);
Here is error info:
/home/wison/code/current/current.c: In function ‘init_current’:
kernel/sched/sched.h:539:23: error: expected identifier or ‘(’ before ‘&’ token
#define cpu_rq(cpu) (&per_cpu(runqueues, (cpu)))
^
/home/wison/code/current/current.c:11:28: note: in expansion of macro ‘cpu_rq’
extern struct rq * cpu_rq(int);
I am using LD_PRELOAD to hook a library function, and in Linux it works perfectly. But I cannot figure out how to do the equivalent in OSX.
The setup I have on Linux is as follows:
The code is:
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <ruby.h>
void
rb_raise(unsigned long exc, const char *fmt, ...)
{
static void (*libruby_rb_raise)
(unsigned long exc, const char *fmt, ...) = NULL;
void * handle;
char * error;
if (!libruby_rb_raise) {
handle = dlopen("/path/to/libruby.so",
RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
libruby_rb_raise = dlsym(handle, "rb_raise");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
}
// ...code...
return Qnil;
}
Which I then compile with:
gcc -Wall -O2 -fpic -shared -ldl -g -I/path/to/includes/ -o raise_shim.so raise_shim.c
I then execute with:
LD_PRELOAD=./raise_shim.so ruby
All of the above works well on Linux, what is the equivalent for each step to get this working on OSX? I have googled this and have not been able to get it to work with the information provided as the info for some of the steps are missing.
Thanks in advance!
Take a look at DYLD_INSERT_LIBRARIES. That's the variable you're looking for.
See also this answer.
I copy and paste code from this URL for creating and reading/writing a proc file using a kernel module and get the error that proc_root is undeclared. This same example is on a few sites so I assume it works. Any ideas why I'd get this error? Does my makefile need something different. Below is my makefile as well:
Example code for a basic proc file creation (direct copy and paste to get initial test done):
http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN769
Makefile I'm using:
obj-m := counter.o
KDIR := /MY/LINUX/SRC
PWD := $(shell pwd)
default:
$(MAKE) ARCH=um -C $(KDIR) SUBDIRS=$(PWD) modules
That example is out of date. Under the current kernel API, pass NULL for the root of procfs.
Also, instead of create_proc_entry, you should use proc_create() with a proper const struct file_operations *.
There has been a change in the interface to create an entry in the proc file system. You can have a look at http://pointer-overloading.blogspot.in/2013/09/linux-creating-entry-in-proc-file.html for details
Here is a 'hello_proc' example with the new interface:
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
static int hello_proc_show(struct seq_file *m, void *v) {
seq_printf(m, "Hello proc!\n");
return 0;
}
static int hello_proc_open(struct inode *inode, struct file *file) {
return single_open(file, hello_proc_show, NULL);
}
static const struct file_operations hello_proc_fops = {
.owner = THIS_MODULE,
.open = hello_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int __init hello_proc_init(void) {
proc_create("hello_proc", 0, NULL, &hello_proc_fops);
return 0;
}
static void __exit hello_proc_exit(void) {
remove_proc_entry("hello_proc", NULL);
}
MODULE_LICENSE("GPL");
module_init(hello_proc_init);
module_exit(hello_proc_exit);
Update:
The above accepted answer might have worked for you. It no longer works in GNU/Linux 5.6.y and above! Since 5.6, proc_create() will accept proc_ops as argument instead of file_operations. Fields are prepended with proc_ and there's no owner field in proc_ops (check here).
As a side note, a programmer would wish for a portable code. In this, same code shall work across different versions of GNU/Linux. So, you may also need to use LINUX_VERSION_CODE, KERNEL_VERSION(5,6,0) macros which are in linux/version.h. For example,
#include <linux/version.h>
...
...
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0))
static struct file_operations
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
static struct proc_ops
#endif
proc_file_ops = {
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5,6,0))
owner : THIS_MODULE,
read : proc_file_read,
write : proc_file_write
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
proc_read : proc_file_read,
proc_write : proc_file_write
#endif
};
...
...
AFAIK apart from these, I couldn't note any other major changes :)