由于4年前对于C语言和Linux的知识贫乏,所以当时对于模块中的函数定义没有细看。这次在温习《LDD3》的时候,重新看了一下关于__init、__initdata和__exit、__exitdata的知识,记录如下:

对于__init、__initdata和__exit、__exitdata的定义位于<linux/init.h>,这些宏定义的作用是告诉编译器将这些函数或者数据放入相应的section中,而在模块加载的阶段,.ko文件中的代码和数据的加载区域是根据section来加载的。

比如:如果函数的定义中带有__init,那么这个函数的所有代码会被放入.init.text的section中。

如果函数的定义中带有__initdata,那么这个函数的所有代码会被放入.init.data的section中。

之所以要使用这个宏定义,其中一个原因是标记为初始化的函数和数据,表明该函数和数据仅在初始化期间使用。在模块装载之后,模块装载就会将初始化函数扔掉。这样可以将该函数占用的内存释放出来。

这种释放根据是否编译进内核是有区别的:

(1)模块编译进内核:所有的初始化数据和函数都是在系统启动的最后阶段,在所有模块都初始化完成以后被内核统一释放的。所有你一般可以在内核启动信息的后面看到:

  1. PHY: 0:01 - Link is Up - 100/Full
  2. VFS: Mounted root (nfs filesystem) on device 0:14.
  3. devtmpfs: mounted
  4. Freeing init memory: 196K
  5. INIT: version 2.86 booting

(2)独立的模块:模块是通过module-init-tool中的insmod的程序利用系统调用来挂载的,而所有的初始化数据和函数都是被这个系统调用所使用的,在模块挂载完成并初始化过后,由系统调用来完成对初始化数据和函数所占空间的释放。

所以对于将内核驱动代码中的函数和数据定义为“初始化”时需要注意:不要将驱动定义的文件方法(如 open、read、write、close)或者驱动在实际工作中需要使用的函数和数据定义为“初始化”属性,因为在驱动初始化后这些东东就已经被释放了,如果使用了就会Oops。

有些网上的文章中写到:

  1. __init宏使内建模块中的init函数在执行完成后释放掉,不过可装载的模块不受影响。

这个是错误的,这些“初始化”宏同样影响可装载模块。从模块装载的系统调用源码中你可以找到释放的地方,他释放的是整个“初始化”section。具体的情况请参考《深入Linux内核构架》的《第七章 模块》

从代码上可以证明“初始化”宏同样影响可装载模块,从实验中同样可以,实验步骤:

(1)在一个简单的字符驱动中定义一个“初始化”字符串,并在模块初始化时打印出来。在驱动的其他方法中也试图打印这个字符串,如果这个方法被系统调用执行了,那么你就得到了一个Oops。

(2)去掉这个字符串定义时的“初始化”宏,再做一边实验,字符串依然可以被打印出来。

__init、__initdata和__exit、__exitdata相关推荐

  1. 关于__init、__initdata和__exit、__exitdata的学习笔记

    由于4年前对于C语言和Linux的知识贫乏,所以当时对于模块中的函数定义没有细看.这次在温习<LDD3>的时候,重新看了一下关于__init.__initdata和__exit.__exi ...

  2. __attribute__编绎属性、关于__init、__initdata、__exit、__exitdata及类似的宏、关于initcall的一些宏定义、__setup宏的来源及使用...

    1. gcc的__attribute__编绎属性 要了解Linux Kernel代码的分段信息,需要了解一下gcc的__attribute__的编绎属性,__attribute__主要用于改变所声明或 ...

  3. Linux 内核编程指南

    Linux 内核编程指南   PeterJay Salzman MichaelBurian OriPomerantz Copyright© 2001 Peter Jay Salzman 2007−05 ...

  4. The Linux Kernel Module Programming Guide 2.4 中文版

    The Linux Kernel Module Programming Guide 2.4 中文版 分类: Linux/os 2007-09-29 11:14 820人阅读 评论(0) 收藏 举报 T ...

  5. 《Linux内核驱动模块编程指南》

    Foreword Table of Contents 作者声明 版本和注意 感谢 译者注 作者声明 <Linux内核驱动模块编程指南>最初是由Ori Pomerantz为2.2版本的内核编 ...

  6. linux驱动 打印变量,linux驱动 内核函数 变量 宏定义

    insmod modprobe(自动检测 模块加载时需要的别的模块) rmmod 用户空间工具, 加载模块到运行中的内核以及去除它们. #include module_init(init_functi ...

  7. Linux内核模块的概念和基本的编程方法

    Linux内核模块的概念和基本的编程方法 标签: Linux内核模块 2013-06-14 18:29 1864人阅读 评论(0) 收藏 举报 分类: linux内核(34) 版权声明:本文为博主原创 ...

  8. linux内核驱动模块开发步骤及实例入门介绍

    最近在搞一个linux的项目,其中主要是在编写一些应用模块,对内核及其驱动模块涉及很少,遇到了一些驱动模块的问题时,临时查了些资料,大致了解了一下驱动模块开发的基本步骤和常规步骤,并从网上也收集到了一 ...

  9. 内核中_init,_exit中的作用

    __init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链 ...

最新文章

  1. JS - Promise使用随笔
  2. Java经典面试题详解:springboot文件下载大小限制
  3. python3转为unicode编码_「小技能get记」· 如何用python3解码unicode
  4. struts2教程(2)--配置
  5. 程序集强命名与GAC
  6. Python学习笔记:Day 9 编写API
  7. 如何处理 Hybris Accelerator css style 显示不正确的问题
  8. javaScript学习笔记之运算符
  9. JVM 调优 2:GC 如何判断对象是否为垃圾,三色标记算法应用原理及存在的问题?
  10. 最长上升子序列LIS 动态规划 二分查找算法
  11. python 利用递归求阶乘
  12. 如何快速清空一个文件内容
  13. VFP基础教程 2.8 使用命令建立和操作索引文件
  14. 服务器行业深度解析:服务器未来需求知多少
  15. 外星人m15键盘灯光设置_Alienware Command Center灯光软件高级设置
  16. zmeet会议在金融、教育和场景特点与产品功能方案
  17. iOS GPUImage 自定义美颜滤镜
  18. UG NX 12抽取复合曲线
  19. 错误 error C2220: 警告被视为错误 - 没有生成“object”文件 (..\..\src\caffe\util\math_functions.cpp)
  20. 网络安全等级保护等级保护对象的安全保护等级

热门文章

  1. 17 FI配置-财务会计-定义雇员的容差组
  2. ubuntu编译ubus及相关依赖库
  3. linuxPci驱动获取指定设备bus、device以及devfn数据方式
  4. 九州云腾双因素认证系统_阿里云全资收购九州云腾,加速构建云上零信任体系...
  5. OpenGL:纹理映射bmp图像
  6. 剑指Offer14-剪绳子12
  7. c语言加速度积分得到速度_自编微积分教材-第一章 微积分漫谈(1)
  8. IE8 打开网站首页显示的却是手机网站
  9. 使用 stm32实现锂电充电_千次循环使用,ZMI可充电锂电池套装,够用一辈子吗?...
  10. python class def 格式_Python symbol.classdef方法代码示例