首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我在Linux内核中找不到proc_create_data函数的定义--或者我可能找到了它,但没能理解它。

我在Linux内核中找不到proc_create_data函数的定义--或者我可能找到了它,但没能理解它。
EN

Stack Overflow用户
提问于 2020-10-24 18:00:32
回答 1查看 669关注 0票数 0

Situation

为了更好地理解Linux内核,我正在跟踪

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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#omitted
extern struct proc_dir_entry ({ NULL; })

custom-proc.c

代码语言:javascript
运行
复制
#omitted
proc = ({ NULL; })

我觉得这不对。

我对编程并不陌生,但不熟悉C。我读过BrianW.Kernighan和DennisM.Ritchie的The C programming Language,但是对宏的解释与上面的链接是一样的。

问题(主菜:)

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

我并不是在寻找一个非常详细的技术答案,而是一种解释代码的方法,这样我就可以按照示例来阅读更多自己需要的内核代码。

Side Dish --我在某个地方听说,尽管内核是用C编写的,但与“正常”C有一些不同。但是,我不确定这是真的还是差异的程度。

如果这是“C语言的内核版本”所使用的技巧,那么如果有人知道解释这些技巧的链接,那将是有帮助的。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-24 18:39:29

fs.h中是这样的

代码语言:javascript
运行
复制
#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上的内部错误)。如果没有,您可以使用ctagsGNU全球索引计算机上的源代码,然后浏览该代码。

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

和任何其他功能一样。不,宏不是用声明展开的-编译器可以看到宏或函数声明,这取决于是否启用了PROC_FS

我听说内核虽然是用C编写的,但与“正常”C有一些不同。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64516472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档