在内核空间中存储结构体数组,Linux

发布于 2024-10-04 05:48:23 字数 227 浏览 5 评论 0原文

我相信我可能有点过度思考这个问题...我的文件系统上有一个文本文件,我在启动时解析该文件并将结果存储到结构数组中。我需要将此数组从用户空间复制到内核空间(copy_from_user),并且必须让内核随时可以访问此数据。内核空间中的数据需要通过 Sockets.c 文件来访问。内核空间中是否有一个特殊的位置来存储数组,或者我可以简单地在 Sockets.c 中添加对数组的引用吗?我的 C 有点生锈了...

谢谢你的建议。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

江城子 2024-10-11 05:48:23

我相信您的问题有两个主要部分:

  • 将数据从用户空间传递到内核空间

  • 将数据存储在内核空间中

对于第一个问题,我建议使用 Netlink 套接字,而不是更传统的系统调用(读/写/ioctl)接口。 Netlink 套接字允许使用类似套接字的接口将配置数据传递到内核,这使用起来更加简单和安全。

您的程序应该执行所有输入解析和验证,然后将数据传递到内核,最好以比大量数据 blob 更结构化的形式(例如逐项)。

除非您对高吞吐量(每秒兆字节数据)感兴趣,否则 netlink 接口就很好。以下链接提供了说明以及示例:

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/

就数组而言存储方面,如果您计划存储超过 128KB 的数据,则必须使用 vmalloc() 来分配空间,否则首选 kmalloc()。您应该阅读《Linux 设备驱动程序》一书的相关章节:

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

请注意,使用 vmalloc() 分配的缓冲区不适合与设备进行 DMA 传输,因为内存页面不连续。如果您事先不知道有多少条目,您可能还需要考虑更复杂的数据结构,例如列表。

至于全局访问存储,您可以像使用任何 C 程序一样进行操作:

在您需要访问数据的所有 .c 文件包含的头文件中,放置如下内容:

extern struct my_struct *unique_name_that_will_not_conflict_with_other_symbols;

extern 关键字表明这声明了一个在另一个源文件中实现的变量。这将使包含该标头的所有 C 文件都可以访问该指针。
然后在一个 C 文件中,最好是包含其余代码的文件 - 如果存在:

struct my_struct *unique_name_that_will_not_conflict_with_other_symbols = NULL;

这是头文件中声明的变量的实际实现。

PS:如果你要使用 Linux 内核,你真的需要温习你的 C 语言。否则你将会经历一些非常令人沮丧的时刻,并且最终会感到抱歉和痛苦。

PS2:如果您至少浏览整本 Linux 设备驱动程序书籍,您还将节省大量时间。尽管它的名称和相对年龄,它包含许多在为 Linux 内核编写任何代码时既最新又重要的信息。

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.

羅雙樹 2024-10-11 05:48:23

您可以在内核中的某个位置定义一个 extern 指针(例如,在您要使用它的 sockets.c 文件中)。将其初始化为 NULL,并在某个适当的头文件中包含它的声明。

在执行 copy_from_user() 的代码部分中,使用 kmalloc() 为数组分配空间,并将地址存储在指针中。将数据复制到其中。您还需要锁定一个互斥锁来访问数组。

kmalloc() 分配的内存将持续存在,直到使用 kfree() 释放为止。

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().

假装不在乎 2024-10-11 05:48:23

您的问题非常基本且模糊,因此我建议您完成本书中的一些练习。第 8 章的全部内容都致力于分配内核内存。

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.

遥远的绿洲 2024-10-11 05:48:23

将数组初始化为内核模块中的全局变量将使其永远可以访问,直到内核正在运行,即直到您的系统正在运行。

Initializing the Array as a global variable in your Kernel Module will make it accessible forever until the kernel is running i.e. until your system is running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文