Situation
为了更好地理解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 \0
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] == '\0') {
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。我读过BrianW.Kernighan和DennisM.Ritchie的The C programming Language
,但是对宏的解释与上面的链接是一样的。
问题(主菜:)
如何理解内核中定义的proc_create_data
函数?
我并不是在寻找一个非常详细的技术答案,而是一种解释代码的方法,这样我就可以按照示例来阅读更多自己需要的内核代码。
Side Dish --我在某个地方听说,尽管内核是用C编写的,但与“正常”C有一些不同。但是,我不确定这是真的还是差异的程度。
如果这是“C语言的内核版本”所使用的技巧,那么如果有人知道解释这些技巧的链接,那将是有帮助的。
我已经查看过以下资源,但找不到这样的信息:
发布于 2020-10-24 18:39:29
在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函数的定义
不用担心-- 长生不老药导致了这个答案中提到的所有三个定义。网络上甚至有多个索引的内核源代码浏览器,以lxr为例(但我现在看到了lxr上的内部错误)。如果没有,您可以使用ctags或GNU全球索引计算机上的源代码,然后浏览该代码。
如何理解内核中定义的proc_create_data函数?
和任何其他功能一样。不,宏不是用声明展开的-编译器可以看到宏或函数声明,这取决于是否启用了PROC_FS
。
我听说内核虽然是用C编写的,但与“正常”C有一些不同。
Linux内核专门针对GNU GCC编译器,因此它倾向于使用GNU C扩展,有时标记为GNU。
https://stackoverflow.com/questions/64516472
复制相似问题