我相信我可能会过度思考这个问题...我的文件系统上有一个文本文件,我在启动时解析它并将结果存储到一个结构数组中。我需要将这个数组从用户空间复制到内核空间(copy_from_user),并且必须随时由内核访问这些数据。内核空间中的数据需要由Sockets.c文件访问。是否有一个特殊的地方可以在内核空间中存储数组,或者我可以简单地在Sockets.c中添加对该数组的引用?我的C有点生锈......
感谢您的任何建议。
答案 0 :(得分:6)
我相信你的问题有两个主要部分:
将数据从用户空间传递到内核空间
将数据存储在内核空间
对于第一个问题,我建议使用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内核的任何代码时都有很多当前和重要的信息。
答案 1 :(得分:1)
您可以在内核中的某个位置定义一个extern
指针(例如,在您要使用它的sockets.c
文件中)。将其初始化为NULL
,并在某个适当的头文件中包含声明。
在执行copy_from_user()
的代码部分中,使用kmalloc()
为数组分配空间并将地址存储在指针中。将数据复制到其中。您还需要在访问阵列时锁定互斥锁。
kmalloc()
分配的内存将一直保留,直到kfree()
释放。
答案 2 :(得分:1)
您的问题基本且含糊不清,我建议您完成this book中的一些练习。整个第8章专门用于分配内核内存。