Storing struct array in kernel space, Linux

2019-02-21 01:43发布

I believe I may be over-thinking this problem a bit... I've got a text file located on my filesystem which I am parsing at boot and storing the results into an array of structs. I need to copy this array from user space into kernel space (copy_from_user), and must have this data accessible by the kernel at any time. The data in kernel space will need to be accessed by the Sockets.c file. Is there a special place to store an array within kernel space, or can I simply add a reference to the array in Sockets.c? My C is a bit rusty...

Thanks for any advice.

3条回答
ら.Afraid
2楼-- · 2019-02-21 02:13

You can just define an extern pointer somewhere in the kernel (say, in the sockets.c file where you're going to use it). Initialise it to NULL, and include a declaration for it in some appropriate header file.

In the part of the code that does the copy_from_user(), allocate space for the array using kmalloc() and store the address in the pointer. Copy the data into it. You'll also want a mutex to be locked around access to the array.

The memory allocated by kmalloc() will persist until freed with kfree().

查看更多
祖国的老花朵
3楼-- · 2019-02-21 02:15

Your question is basic and vague enough that I recommend you work through some of the exercises in this book. The whole of chapter 8 is dedicated to allocating kernel memory.

查看更多
Bombasti
4楼-- · 2019-02-21 02:31

I believe there are two main parts in your problem:

  • Passing the data from userspace to kernelspace

  • Storing the data in the kernelspace

For the first issue, I would suggest using a Netlink socket, rather than the more traditional system call (read/write/ioctl) interface. Netlink sockets allow configuration data to be passed to the kernel using a socket-like interface, which is significantly simpler and safer to use.

Your program should perform all the input parsing and validation and then pass the data to the kernel, preferably in a more structured form (e.g. entry-by-entry) than a massive data blob.

Unless you are interested in high throughput (megabytes of data per second), the netlink interface is fine. The following links provide an explanation, as well as an example:

http://en.wikipedia.org/wiki/Netlink

http://www.linuxjournal.com/article/7356

http://linux-net.osdl.org/index.php/Generic_Netlink_HOWTO

http://www.kernel.org/doc/Documentation/connector/

As far as the array storage goes, if you plan on storing more than 128KB of data you will have to use vmalloc() to allocate the space, otherwise kmalloc() is preferred. You should read the related chapter of the Linux Device Drivers book:

http://lwn.net/images/pdf/LDD3/ch08.pdf

Please note that buffers allocated with vmalloc() are not suitable for DMA to/from devices, since the memory pages are not contiguous. You might also want to consider a more complex data structure like a list if you do not know how many entries you will have beforehand.

As for accessing the storage globally, you can do it as with any C program:

In a header file included by all .c files that you need to access the data put something like:

extern struct my_struct *unique_name_that_will_not_conflict_with_other_symbols;

The extern keyword indicates that this declares a variable that is implemented at another source file. This will make this pointer accesible to all C files that include this header. Then in a C file, preferrably the one with the rest of your code - if one exists:

struct my_struct *unique_name_that_will_not_conflict_with_other_symbols = NULL;

Which is the actual implementation of the variable declared in the header file.

PS: If you are going to work with the Linux kernel, you really need to brush up on your C. Otherwise you will be in for some very frustrating moments and you WILL end up sorry and sore.

PS2: You will also save a lot of time if you at least skim through the whole Linux Device Drivers book. Despite its name and its relative age, it has a lot of information that is both current and important when writing any code for the Linux Kernel.

查看更多
登录 后发表回答