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);
Related
I try to build ipref3.dll for windows
I found How to compile iperf3 for Windows
Built it but i got only iperf3.exe and libiperf.a
I found, how create dll manual
gcc -s -shared -o iperf3.dll units.o timer.o tcp_window_size.o tcp_info.o net.o iperf_util.o iperf_sctp.o iperf_udp.o iperf_tcp.o iperf_server_api.o iperf_locale.o iperf_client_api.o iperf_error.o iperf_api.o cjson.o -Wl,--enable-auto-import,--export-all-symbols,--subsystem,windows
after i found how need to initialize
HMODULE h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
Now i can load dll and make initialization but when i start test iperf_run_client application is crashed
Unhandled exception at 0x611537C0 (cygwin1.dll) in iprerf-server.exe:
0xC0000005: Access violation reading location 0x00740000.
How can solve this problem?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
//#include <unistd.h>
#include <string.h>
//#include <sysexits.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "iperf_api.h"
#ifdef WIN64
#pragma comment(lib, "iperf3_64.lib")
#else
#pragma comment(lib, "iperf3.lib")
#endif
#pragma comment(lib, "ws2_32.lib")
typedef void *register_frame();
typedef int *hello_f();
typedef int(*PFN_HELLO)();
typedef void(*PFN_CYGWIN_DLL_INIT)();
#pragma pack(push, 1)
int main(int argc, char** argv)
{
WSADATA wsaData;
int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (wsaErr != 0) {
printf("WSAStartup failed with error: %d\n", wsaErr);
return 1;
}
//PFN_HELLO fnHello;
HMODULE /*hLib, */h = LoadLibrary(TEXT("cygwin1.dll"));
PFN_CYGWIN_DLL_INIT init = (PFN_CYGWIN_DLL_INIT)GetProcAddress(h, "cygwin_dll_init");
init();
char* argv0;
char* host;
int port;
struct iperf_test *test;
argv0 = strrchr(argv[0], '/');
if (argv0 != (char*)0)
++argv0;
else
argv0 = argv[0];
if (argc != 3) {
fprintf(stderr, "usage: %s [host] [port]\n", argv0);
exit(EXIT_FAILURE);
}
host = argv[1];
port = atoi(argv[2]);
test = iperf_new_test();
if (test == NULL) {
fprintf(stderr, "%s: failed to create test\n", argv0);
exit(EXIT_FAILURE);
}
iperf_defaults(test);
iperf_set_verbose(test, 1);
iperf_set_test_role(test, 'c');
iperf_set_test_server_hostname(test, host);
iperf_set_test_server_port(test, port);
/* iperf_set_test_reverse( test, 1 ); */
iperf_set_test_omit(test, 3);
iperf_set_test_duration(test, 5);
iperf_set_test_reporter_interval(test, 1);
iperf_set_test_stats_interval(test, 1);
/* iperf_set_test_json_output( test, 1 ); */
if (iperf_run_client(test) < 0) {
fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
exit(EXIT_FAILURE);
}
if (iperf_get_test_json_output_string(test)) {
fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
strlen(iperf_get_test_json_output_string(test)));
}
iperf_free_test(test);
exit(EXIT_SUCCESS);
}
The reason why the shared lib is not built is:
libtool: warning: undefined symbols not allowed in x86_64-unknown-cygwin
shared libraries; building static only
the easy way to bypass it, in a clean build is to use:
$ make libiperf_la_LIBADD="-no-undefined"
The build will include the shared libray and the import library
$ find . -name "*dll*"
./src/.libs/cygiperf-0.dll
./src/.libs/libiperf.dll.a
For what I see to make a build on cygwin is also needed to remove a definition
in src/iperf_config.h after running configure
/* #define HAVE_SETPROCESSAFFINITYMASK 1 */
PS #1: iperf-2.0.5-1 is available as cygwin package
PS #2: your code is Windows-like while Cygwin is a Unix-like system, you can not mix them
I found solution
1) It need to create addition dll: my_crt0.dll
#include <sys/cygwin.h>
#include <stdlib.h>
typedef int (*MainFunc) (int argc, char *argv[], char **env);
void my_crt0 (MainFunc f)
{
cygwin_crt0(f);
}
gcc -c my_crt0.c
gcc -o my_crt0.dll my_crt0.o -s -shared -Wl,--subsystem,windows,--enable-auto-import,--export-all-symbols,--out-implib,my_crt0.lib
2) Modify main code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <WinSock2.h>
#include <string.h>
#include "iperf_api.h"
#pragma comment(lib, "iperf3.lib")
#pragma comment(lib, "ws2_32.lib")
typedef int(*MainFunc) (int argc, char *argv[], char **env);
typedef void(*my_crt0)(MainFunc f);
int main2(int argc, char** argv, char **env)
{
char* argv0;
char* host;
int port;
struct iperf_test *test;
host = (char*)"127.0.0.1";
port = 4000;
test = iperf_new_test();
if (test == NULL) {
exit(EXIT_FAILURE);
}
iperf_defaults(test);
iperf_set_verbose(test, 1);
iperf_set_test_role(test, 'c');
iperf_set_test_server_hostname(test, host);
iperf_set_test_server_port(test, port);
/* iperf_set_test_reverse( test, 1 ); */
iperf_set_test_omit(test, 3);
iperf_set_test_duration(test, 5);
iperf_set_test_reporter_interval(test, 1);
iperf_set_test_stats_interval(test, 1);
/* iperf_set_test_json_output( test, 1 ); */
iperf_strerror(0);
if (iperf_run_client(test) < 0) {
fprintf(stderr, "%s: error - %s\n", argv0, iperf_strerror(i_errno));
exit(EXIT_FAILURE);
}
if (iperf_get_test_json_output_string(test)) {
fprintf(iperf_get_test_outfile(test), "%zd bytes of JSON emitted\n",
strlen(iperf_get_test_json_output_string(test)));
}
iperf_free_test(test);
exit(EXIT_SUCCESS);
return 1;
}
int main(int argc, char** argv)
{
WSADATA wsaData;
int wsaErr = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (wsaErr != 0) {
printf("WSAStartup failed with error: %d\n", wsaErr);
return 1;
}
{
HMODULE /*hLib, */h = LoadLibrary(TEXT("my_crt0.dll"));
my_crt0 init = (my_crt0)GetProcAddress(h, "my_crt0");
init(main2);
}
exit(EXIT_SUCCESS);
}
Now it compiled and worked to VS 2015
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 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.
I have written a kretprobe to hook on to the randomize_stack_top() function mentioned in fs/binfmt_elf.c file. On loading the LKM with insmod the register_kretprobe() call fails with a return value of -2. How do I go about debugging/rectifying that in order to get my module started ?
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/binfmts.h>
#include <linux/elf.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/current.h>
#include <asm/param.h>
/* Global variables */
int randomize_stack_retval;
// randomize_stack_top() kretprobe specific declarations
static char stack_name[NAME_MAX] = "randomize_stack_top";
static int randomize_stack_top_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
return 0;
}
static int randomize_stack_top_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
randomize_stack_retval = regs_return_value(regs); //store in global variable
printk(KERN_INFO "%d\n",randomize_stack_retval);
return 0;
}
//randomize_stack_top return probe
static struct kretprobe randomize_kretprobe = {
.handler = randomize_stack_top_ret_handler,
.entry_handler = randomize_stack_top_entry_handler,
.maxactive = NR_CPUS,
};
/* Register kretprobe */
static int __init kretprobe_init(void)
{
int ret;
randomize_kretprobe.kp.symbol_name = stack_name;
ret = register_kretprobe(&randomize_kretprobe);
if (ret < 0) {
printk(KERN_INFO "register_kretprobe failed, returned %d\n",
ret);
return -1;
}
printk(KERN_INFO "Planted return probe at %s: %p\n",
randomize_kretprobe.kp.symbol_name, randomize_kretprobe.kp.addr);
return 0;
}
/* Unregister kretprobe */
static void __exit kretprobe_exit(void)
{
unregister_kretprobe(&randomize_kretprobe);
printk(KERN_INFO "kretprobe at %p unregistered\n",
randomize_kretprobe.kp.addr);
// nmissed > 0 suggests that maxactive was set too low.
printk(KERN_INFO "Missed probing %d instances of %s\n",
randomize_kretprobe.nmissed, randomize_kretprobe.kp.symbol_name);
}
module_init(kretprobe_init);
module_exit(kretprobe_exit);
MODULE_LICENSE("GPL");
-2 corresponds to -ENOENT (you can check that in include/uapi/asm-generic/errno-base.h). Probably, it means that kprobe cannot find symbol with given name.
Note, that randomize_stack_top is static function with a short implementation and it is used only once. So it can be inlined by the gcc.
I want to create a file under a /proc/driver directory. I would like to use a macro like proc_root_driver (or something else provided) rather than use "driver/MODULE_NAME" explicitly. I use create_proc_entry :
struct proc_dir_entry *simpleproc_fops_entry;
simpleproc_fops_entry = create_proc_entry(MODULE_NAME, 0400, NULL /* proc_root_dir */);
After googling, I found suggestion to use proc_root_driver, but when I use it, I get the error
proc_root_driver undeclared in this function
And also, proc_root_driver is not available in linux/proc_fs.h.
I have tried to declare structure like this:
struct proc_dir_entry proc_root;
struct proc_dir_entry *proc_root_driver = &proc_root;
The compilation errors gone, but the file didn't appear under /proc/driver or /proc. How can I make create an entry in /proc?
Looking at proc_fs.h, proc_root_driver is defined as :
extern struct proc_dir_entry *proc_root_driver;
so long as CONFIG_PROC_FS is enabled. If you have CONFIG_PROC_FS selected when you configure your kernel, you should be able to use it as you suggested yourself i.e. :
#include <linux/proc_fs.h>
struct proc_dir_entry * procfile
procfile = create_proc_entry("myprocfile", 0400, proc_root_driver);
If this does not work, check that you have CONFIG_PROC_FS set. To make sure, you can compile your source file with the -E option and check that the create_proc_entry call includes a non NULL parameter as the last parameter. If it is NULL, or the call is not there at all, then CONFIG_PROC_FS is not enabled.
/* proc entries for ayyaz */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/ioctl.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#ifdef CONFIG_PROC_FS
/*====================================================================*/
/* Support for /proc/ayyaz */
static struct proc_dir_entry *proc_ayyaz;
DEFINE_MUTEX(ayyaz_table_mutex);
/*====================================================================*/
/* Init code */
static int ayyaz_read_proc (char *page, char **start, off_t off, int count,
int *eof, void *data_unused)
{
int len, l, i;
off_t begin = 0;
mutex_lock(&ayyaz_table_mutex);
len = sprintf(page, "hello ayyaz here\n");
mutex_unlock(&ayyaz_table_mutex);
if (off >= len+begin)
return 0;
*start = page + (off-begin);
return ((count < begin+len-off) ? count : begin+len-off);
}
static int __init init_ayyaz(void)
{
if ((proc_ayyaz = create_proc_entry( "ayyaz_maps", 0, NULL )))
proc_ayyaz->read_proc = ayyaz_read_proc;
return 0;
}
static void __exit cleanup_ayyaz(void)
{
if (proc_ayyaz)
remove_proc_entry( "ayyaz", NULL);
}
module_init(init_ayyaz);
module_exit(cleanup_ayyaz);
#else
#error "Please add CONFIG_PROC_FS=y in your .config "
#endif /* CONFIG_PROC_FS */
MODULE_LICENSE("proprietary");
MODULE_AUTHOR("Md.Ayyaz A Mulla <md.ayyaz#gmail.com>");
MODULE_DESCRIPTION("proc files for ayyaz");
Compile this driver. If it compiles sucessfully, then you will see /proc/ayyaz.
#define PROC_ENTRY_NAME "driver/XX"
static struct proc_dir_entry *proc_XX;
static int XX_read_proc (char *page, char **start, off_t off, int count,
int *eof, void *data_unused)
{
return 0;
}
static int XX_write_proc (struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
return 0;
}
static int __init XX_add_driver(void)
{
if ((proc_flash = XX_entry(PROC_ENTRY_NAME, 0, NULL))) {
proc_XX->read_proc = XX_read_proc;
proc_XX->write_proc = XX_write_proc;
}
...
}
static void __exit XX_remove(void)
{
if (proc_flash)
remove_proc_entry(PROC_ENTRY_NAME, NULL);
return;
}
Then you can find the /proc/driver/XX entry.