内核导出符号 vs 全局符号 vs 静态全局变量?

3
我对内核符号类型的含义有一点困惑。 简单的静态符号与C语言中的静态符号含义相同。因此,局部静态变量具有局部作用域和静态分配。静态函数的作用域是文件级别的。但是静态导出符号怎么办?如果宏导出静态符号,如何处理EXPORT_SYMBOL()EXPORT_PER_CPU_SYMBOL()EXPORT_UNUSED_SYMBOL()?全局符号和导出符号之间有什么区别?导出符号是否需要链接器添加额外信息?内核中的全局静态变量在所有内核和可加载模块中可见吗?
内核导出符号可以从可加载模块中访问。在内核中触及这些符号是否是良好的编程风格? 当内核解析符号时,它会通过内核符号表进行查找吗?
1个回答

6
从概念上讲,函数声明中使用 static 关键字表示具有内部链接性--因此这样的函数仅在单个翻译单元(*.o 文件)中可见。这可能涉及该函数的内联(在这种情况下,它将不可用),但由于 EXPORT_SYMBOL() 获取静态函数的地址,编译器应禁用内联优化。
实现起来有点复杂。这些内部和外部链接规则仅适用于静态 ld 链接器,该链接器在构建 vmlinux 或内核模块时起作用。通常,具有外部链接的符号会添加到 symtab ELF 部分中,当动态链接器 ld.so 加载共享对象时,它会读取该部分。
但是,当模块被加载时,Linux 内核使用单独的符号表 ksymtab。EXPORT_SYMBOL() 将符号添加到该表中,但这个过程完全对编译器-链接器工具链透明,因此与内部和外部链接性没有任何关系。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接