How do I share data between kernel C programs and user level C programs?
I am using Ubuntu 9.04 with kernel 2.8.32. I created a simple system call that counts the number of clone and execve calls. When the user/shell calls this system call, I would like it to pass back to the user these two values. As of now I am using:
#include <linux/sched.h>
#include <linux/asmlinkage>
/* These two variables are extern longs which are defined in sched.h and initialized in process_32.c */
total_execve;开发者_开发技巧
total_clones;
long mycall* (int i){
int array[2];
array[0] = total_execve;
array[1] = total_clones;
return array;
}
I am not able to compile this as I get an undefined reference.
Regarding returning the array: Will my new call be able to access the array, won't the array be located in kernel memory?
Don't return pointers into the stack. Have the caller pass pointers into the function. Also, your function declaration syntax is incorrect. Here's what you want to do:
void mycall (int *execve, int *clones)
{
*execve = total_execve;
*clones = total_clones;
}
Answering your last question first: the array is indeed in "kernel" memory, but it's stack allocated which means it wilL "go away" when the mycall() function exits. Your function may appear to work, but may fail in cases where the memory gets re-used quickly.
To return multiple values, the common pattern is for the caller to pass in pointers to user-space memory, and have the kernel routine to fill them in. For example, you could pass in two pointers for your two values, or define a single struct that contains the values you need and gets filled in by the kernel routine.
You cannot return an array in this way. You need to declare static keyword to return a local array function. You could do something like this:
int *mycall (int i) {
static int array[2];
array[0] = total_execve;
array[1] = total_clones;
return array;
}
精彩评论