我在 Linux 内核中找不到 proc_create_data 函数的定义 - 或者我找到了它但未能理解它
I couldn't find the definition of proc_create_data function in Linux kernel - or maybe I found it but failed to understand it
情况
我正在关注 this 以更好地了解 Linux 内核。
有一个编写自定义 /proc 接口的示例。这是上面示例代码 link 中的一个片段 - 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 [=12=]
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] == '[=12=]') {
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
,发现它唯一被 defined 的地方是 /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 *)
就是这样。
我从 here 了解到,在 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
,但那里对宏的解释与 link 相同以上。
问题(主菜:))
如何理解内核中定义的proc_create_data
函数?
我不是在寻找非常详细的技术答案,只是在寻找一种解释该代码的方法,这样我就可以按照示例进行操作,并能够在自己需要时阅读更多内核代码。
配菜
我在某处听说内核尽管是用 C 编写的,但与“普通”C 有一些差异。不过,我不确定这是不是真的或差异的程度。
如果这是“C 语言的内核版本”使用的技巧,如果有人知道 link 来解释这些技巧,那将会很有帮助。
我已经查看了以下资源,但找不到此类信息:
- 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
如果用户 configured kernel without proc filesystem support, then the function call is expanded to a statement that just returns NULL
. Note that ({...})
is a gcc extensions statement expression - 不要在代码中使用 non-portable 扩展,而更喜欢使用 static inline
函数。语句表达式的 return 值是最后使用的表达式的值 - 在本例中为 NULL
。
如果 CONFIG_PROC_FS
是从用户配置中定义的,那么 proc/generic.c
就像任何其他函数一样定义函数 here,包括 proc_fs.h
在内的源文件请参阅函数声明并且看不到宏。
I couldn't find the definition of proc_create_data function in Linux kernel
不用担心 - typing proc_create_data
in elixir results in all 3 definitions mentioned in this answer. There are even multiple indexed kernel source code browsers on the net, with lxr as an example (but I see internal error right now on lxr). If not, you can index the source code on your computer with ctags or GNU GLOBAL 然后浏览代码。
How do I understand the proc_create_data function as defined in the kernel?
与任何其他函数一样。不,宏没有通过声明展开 - 编译器会看到 宏或函数声明,具体取决于是否启用 PROC_FS
。
Side Dish I heard somewhere that the kernel, despite being written in C, has some differences to "normal" C.
Linux 内核专门针对 GNU GCC 编译器,因此倾向于使用 GNU C extensions,有时标记为 GNU C.
情况
我正在关注 this 以更好地了解 Linux 内核。
有一个编写自定义 /proc 接口的示例。这是上面示例代码 link 中的一个片段 - 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 [=12=]
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] == '[=12=]') {
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
,发现它唯一被 defined 的地方是 /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 *)
就是这样。
我从 here 了解到,在 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
,但那里对宏的解释与 link 相同以上。
问题(主菜:))
如何理解内核中定义的proc_create_data
函数?
我不是在寻找非常详细的技术答案,只是在寻找一种解释该代码的方法,这样我就可以按照示例进行操作,并能够在自己需要时阅读更多内核代码。
配菜 我在某处听说内核尽管是用 C 编写的,但与“普通”C 有一些差异。不过,我不确定这是不是真的或差异的程度。
如果这是“C 语言的内核版本”使用的技巧,如果有人知道 link 来解释这些技巧,那将会很有帮助。
我已经查看了以下资源,但找不到此类信息:
- 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
如果用户 configured kernel without proc filesystem support, then the function call is expanded to a statement that just returns NULL
. Note that ({...})
is a gcc extensions statement expression - 不要在代码中使用 non-portable 扩展,而更喜欢使用 static inline
函数。语句表达式的 return 值是最后使用的表达式的值 - 在本例中为 NULL
。
如果 CONFIG_PROC_FS
是从用户配置中定义的,那么 proc/generic.c
就像任何其他函数一样定义函数 here,包括 proc_fs.h
在内的源文件请参阅函数声明并且看不到宏。
I couldn't find the definition of proc_create_data function in Linux kernel
不用担心 - typing proc_create_data
in elixir results in all 3 definitions mentioned in this answer. There are even multiple indexed kernel source code browsers on the net, with lxr as an example (but I see internal error right now on lxr). If not, you can index the source code on your computer with ctags or GNU GLOBAL 然后浏览代码。
How do I understand the proc_create_data function as defined in the kernel?
与任何其他函数一样。不,宏没有通过声明展开 - 编译器会看到 宏或函数声明,具体取决于是否启用 PROC_FS
。
Side Dish I heard somewhere that the kernel, despite being written in C, has some differences to "normal" C.
Linux 内核专门针对 GNU GCC 编译器,因此倾向于使用 GNU C extensions,有时标记为 GNU C.