【问题标题】:What happens with functions using macro *__init* as prefix?使用宏 *__init* 作为前缀的函数会发生什么?
【发布时间】:2015-01-16 08:38:12
【问题描述】:

从我阅读的有关 Linux 操作系统中模块初始化的信息中,我了解到具有 __init 之类前缀的函数调用将被放置在单个 ELF 位置。

例如我们通常写:

int __init module_start()
{
....
}

如果是这样,那么在初始化结束后可以覆盖或删除特定的 ELF 位置?如果我们想再次使用初始化,或者如果我想重新初始化任何模块,知道初始化例程被删除的事实,遵循的方法是什么?

【问题讨论】:

  • 我不知道为什么它被否决了。如果它缺少的细节尝试添加细节,如果它的错误问题尝试评论。
  • 匿名否决票:不酷。您的问题与编程和 Linux 一样多,stackoverflow 可能更适合(根据this

标签: kernel init elf


【解决方案1】:

__init 是一个 Linux 内核宏,它有点类似于普通的 gcc __attribute__(constructor),还有一个附加功能,它也被解释为代码一旦运行就可以被释放的提示(仅限模块,平台依赖)。在“普通”gcc/glibc C 程序中,libc 负责调用任何 init(和 fini)函数,在内核中您需要显式使用 module_init()(和 module_exit())。

来自include/linux/init.h

/* These macros are used to mark some functions or 
 * initialized data (doesn't apply to uninitialized data)
 * as `initialization' functions. The kernel can take this
 * as hint that the function is used only during the initialization
 * phase and free up used memory resources after
[...]

#define __init          __section(.init.text) __cold notrace

有类似的宏来标记退出函数和数据。这些是编译器/链接器指令:

  • __section() 将代码放在.init.text 部分(放弃)
  • __cold 指示编译器(通过__attribute__()优化调用路径,因为该函数很少被调用(一次!)
  • notrace 防止ftrace 可能出现的问题

重新调用模块初始化的一种简单方法是卸载并重新加载模块(有时对于解除设备楔入很有用)。

如果初始化例程的某些部分可能在运行时有用,则可以将它们放在标记为__init 的函数中,并从真正的初始化中调用 功能。您可以使用__init 标记多个函数,module_init() 中也必须使用一个,否则您的代码不应调用该函数。要点是模块初始化代码与设置内核 API 一样重要,因为它与初始化任何硬件或非硬件驱动程序功能一样多(我猜这是您遇到的问题)。

另见:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2018-05-06
    • 2016-09-19
    • 1970-01-01
    • 2012-09-22
    • 1970-01-01
    • 2018-06-03
    相关资源
    最近更新 更多