c语言 - 我在 Linux 内核中找不到proc_create_data函数的定义 - 或者我找到了它但无法理解它



情况

我遵循这一点是为了更好地理解Linux内核。

这里有一个关于编写自定义/proc接口的示例。以下是上面链接的示例代码的一个片段-custom-proc.c:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/types.h>
#omitted
int create_new_proc_entry(void) {
int i;
char *DATA = "Hello People";
len = strlen(DATA);
msg = kmalloc((size_t) DATA_SIZE, GFP_KERNEL); // +1 for 
if (msg != NULL) {
printk(KERN_INFO "Allocated memory for msg");
} else {
return -1;
}
strncpy(msg, DATA, len+1);
for (i=0; i < len +1 ; i++) {
printk(KERN_INFO "%c", msg[i]);
if (msg[i] == '') {
printk(KERN_INFO "YES");
}
}
proc = proc_create_data(MY_PROC_ENTRY, 0666, NULL, &proc_fops, msg);
if (proc) {
return 0;
}
return -1;
}

由于proc_create_data没有在示例中定义,我认为它必须在内核中的某个地方定义。我下载了内核5x,并在内核代码中搜索proc_create_data的所有出现,发现它被定义的唯一位置是/include/linux/proc_fs.h:

#Omitted
#define proc_create_data(name, mode, parent, proc_ops, data) ({ NULL; })
#Omitted
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *, void *)

就是这样。

我从这里读到,在C中,宏将被文本扩展,可以像函数一样使用它。

如果我在这里应用它,那么在所有的扩展之后,我将拥有

/include/linux/proc_fs.h:

#omitted
extern struct proc_dir_entry ({ NULL; })

custom-proc.c

#omitted
proc = ({ NULL; })

这对我来说似乎不对。

我对编程并不陌生,但对C并不熟悉。我读过Brian W.Kernighan和Dennis m.Ritchie的The C programming Language,但对宏的解释与上面的链接相同。

问题(主菜:(

如何理解内核中定义的proc_create_data函数?

我不是在寻找一个非常详细的技术答案,只是一种解释代码的方法,这样我就可以跟随示例,并能够在需要时阅读更多的内核代码。

配菜我在某个地方听说,尽管内核是用C编写的,但它与";正常的";C.不过,我不确定这是真的,也不确定差异的程度。

如果这是";C语言的内核版本";如果有人知道这些技巧的解释链接,那将是很有帮助的。

我已经查看了以下资源,但找不到这样的信息:

  • www.kernel.org
  • https://kernelnewbies.org/
  • Linux内核开发-Robert Love
  • Linux系统编程-Robert Love

在proc_fs.h:中是这样的

#ifdef CONFIG_PROC_FS
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *,
void *);
#else /* CONFIG_PROC_FS */
#define proc_create_data(name, mode, parent, proc_ops, data) ({NULL;})
#endif

如果用户配置的内核不支持proc文件系统,那么函数调用将扩展为只返回NULL的语句。请注意,({...})是一个gcc扩展语句表达式-不要在代码中使用不可移植的扩展,而应该使用static inline函数。语句表达式的返回值是最后一个使用的表达式的值——在本例中为NULL

如果CONFIG_PROC_FS是从用户配置中定义的,那么proc/generic.c在这里定义的函数就像任何其他函数一样,包括proc_fs.h在内的源文件会看到函数声明,而不会看到宏。

我在Linux内核中找不到proc_create_data函数的定义

不用担心-在elixir中键入proc_create_data会得到本答案中提到的所有3个定义。网络上甚至有多个索引内核源代码浏览器,以lxr为例(但我现在在lxr上看到内部错误(。如果没有,您可以使用ctags或GNUGLOBAL在计算机上索引源代码,然后浏览代码。

如何理解内核中定义的proc_create_data函数?

作为任何其他函数。不,宏没有用声明展开-编译器会看到宏或函数声明,具体取决于是否启用了PROC_FS

Side Dish我在某个地方听说,尽管内核是用C编写的,但它与";正常的";C.

Linux内核专门针对GNU GCC编译器,因此它倾向于使用GNU C扩展,有时标记为GNU C.

最新更新