• Linux驱动开发 --- 模块加载和ELF文件


    __init和__exit属性

    实际上是存在于include/linux/init.h文件中的宏定义

    #define __init __section(.init.text) 
    #define __exit __section(.exit.text)
    
    • 1
    • 2

    __init关键字是与链接器相关的,它可以告诉链接器如linux下的ld,将代码放在内核对象文件中的专用部分(事先约定好的部分)。它在模块加载和init函数执行后被释放。(当然这个例子只是用于模块编译进内核的情况)

    ELF

    可执行可链接格式的目标文件,由不同的命名部分组成,其中一些部分是必须的,它们成为ELF标准的基础。
    但也可以根据自己的需要构建任意一部分,用来给程序使用,内核就是利用了这一点。
    使用objdump打印出内核模块module.ko的不同组成部分:
    .text:包含程序代码,也称为代码
    .data:包含初始化数据,也称为数据段
    .rodata:用于只读数据
    .comment:存储注释
    .bss:由符号开始的块,未初始化的数据段, block started by symbol
    在这里插入图片描述
    这里比较重要的是:
    .modeinfo:存储有关模块的信息
    .init.text:存储以__init宏为前缀的代码

    链接器负责将符号(包括了代码和数据等)放到生成的二进制文件中的适当的部分,程序执行时会被加载器处理。
    二进制文件中的这些部分可以自定义,更改他们的默认位置。
    链接器还有一种机制,你可以向他提供链接器脚本(链接器定义文件LDF或者链接器定义脚本LDS),来添加其他部分。

    Linux内核提供了一个自定义LDS文件,它位于arch/ /kernel/vmlinux.lds.S中。对于要放置在内核LDS文件所映射的专用部分中的符号,使用__init和__exit进行标记。

    总之,__init和__exit是Linux指令(实际上是宏),它们使用C编译器属性指定符号的位置。这些指令指示编译器将以它们为前缀的代码分别放在.init.text和.exit.text部分,虽然内核可以访问不同的对象部分

  • 相关阅读:
    前后端开发迭代
    深度学习基础-1
    idea Transparent-native-to-ascii 是否需要勾选?
    python类接口和抽象超类
    辣子鸡丁的家常做法 辣子鸡丁怎么做
    Java学习:反射
    VPP创建主HEAP内存
    JS面向对象---原型链继承
    日期时间参数,格式配置(SpringBoot)
    idea中maven优先从本地仓库寻找依赖包的配置
  • 原文地址:https://blog.csdn.net/weixin_43604927/article/details/126695618