2017-08-07 74 views
2

我看到在一些操作系统内核下面的代码。但我不明白__section的使用方式,不知道这段代码是什么意思。什么__section()意味着Linux内核源

#define KEEP_PAGER(sym) \ 
    extern const unsigned long ____keep_pager_##sym; \ 
    const unsigned long ____keep_pager_##sym \ 
     __section("__keep_meta_vars_pager") = (unsigned long)&sym 
+0

结束时,你是否尝试过*它搜索*的代码,看看它的声明或任何定义的? –

+2

谢谢,明白吧。它在另一个#define中定义。我在徘徊,为什么它没有包含属性。我终于我发现以下的#define:'#定义__section(X)\t __attribute __((段(X)))' –

回答

3

它是围绕GCC extension环绕的特定linux内核C macro definition,指定atttribute to use for an object。这是写部分属性定义

历史Linux内核的一个较短的方式已经written specifically for building with the GCC compiler,并大量使用低水平扩展做具体的硬件操作和最佳化。

部分属性专门用于确定标记与它的对象的存储位置。 ELF binary format安排目标文件到指定的段,并使用这样的属性,允许程序员更精确地指定为加标签的物体的信息将被放置在目标对象

多年来,有许多人的工作投入到增加不同的编译器之间的这些编译器扩展的兼容性,以及让Linux编译与替代编译器(如果你看看the linux header file where the macro is defined你会发现它充满了各种编译器特征的条件指令)。像这样的宏可以是一种有用的方式,可以为跨越不同编译器实现的低级功能提供可移植的内部API。

内核和内核驱动程序的C代码是非典型关心的物理硬件实现直接的细节,并需要明确有关的方式编译二进制输出应用级别的C代码很少会。

为什么linux内核使用命名段的一个例子是在init handling中 - 仅在启动时使用的函数和数据被分组为一段内存,一旦启动完成后可以轻松释放 - 您可能熟悉沿着“释放未使用的内核内存:...”的线启动消息对linux的启动顺序

+1

是的,这的确是一个宏观的包装属性,我将展开解释 – cms

+0

这将是为什么发明了你自家酿造的宏观语言是一个坏主意。这个宏只是天真的,因为一些其他的编译器可能会使用的东西,比如'#pragma'内存部分,在这种情况下,该宏将无法正常工作。无论如何,Linux永远不会在GCC以外的任何其他编译器上工作,只是过度依赖编译器特有的功能。 – Lundin

0

这是很难说__section到底是什么没有它的定义,但它可能是一个变量“一节”属性。它用于将编译器的地址变量放入与“bss”或“data”不同的部分。详情请参阅GCC documentation