由于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. __attribute__编绎属性、关于__init、__initdata、__exit、__exitdata及类似的宏、关于initcall的一些宏定义、__setup宏的来源及使用...

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

  2. __init、__initdata和__exit、__exitdata

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

  3. 我的内核学习笔记5:proc目录文件创建及读写

    上一篇内核学习笔记<我的内核学习笔记4:sysfs学习>是2013年写的,彼时至今,随着工作的展开和安排,内核方面的知识可谓突飞猛进,当然,其它方面亦是如此.关于内核方面,积累的笔记大大小 ...

  4. 《Linux设备驱动开发详解》学习笔记一

    Linux设备驱动开发详解学习笔记<一> 书名:<Linux设备驱动开发详解>第二版 主机环境:Linux version 2.6.25-14.fc9.i686@Fedora ...

  5. linux学习笔记(五)编译内核模块生成ko驱动文件

    系列文章目录 linux学习笔记(五)编译内核模块生成ko驱动文件 文章目录 系列文章目录 前言 一.加载内核简介 二.第一个hello world文件 1.文件树 2.hello.c 3.Makef ...

  6. 【嵌入式环境下linux内核及驱动学习笔记-(16)linux总线、设备、驱动模型之input框架】

    目录 1.Linux内核输入子系统概念导入 1.1 输入设备工作机制 1.2 运行框架 1.3 分层思想 2.驱动开发步骤 2.1 在init()或probe()函数中 2.2 在exit()或rem ...

  7. 嵌入式学习笔记--misc

    嵌入式学习笔记–misc 一.内核自带MISC驱动简介 misc 的意思是混合.杂项的,因此 MISC 驱动也叫做杂项驱动,也就是当我们板子上的某些外设无法进行分类的时候就可以使用 MISC 驱动. ...

  8. hi3536 pcie驱动学习笔记

    Hi3536 PCIE学习笔记2(linux3.10.y) 一.PCI总线简单介绍 1.PCI总线配置 两类配置请求:Type00h配置请求,Type 01配置请求.Type 00h配置请求:访问与H ...

  9. 【嵌入式环境下linux内核及驱动学习笔记-(15-1)例程】

    目录 1.在APP直接调用标准文件IO操作I2C(针对学习笔记-15的15.3节) 1.1 mail.c 1.2 mpu6050.h 1.3 mpu6050.c 1.4 Makefile 2.以外称i ...

最新文章

  1. 面试官再问你 HashMap 底层原理,就把这篇文章甩给他看
  2. 十天学Linux内核之第二天---进程
  3. 如何在网站建设时正确设置符合SEO优化的元素?
  4. 软定时器的启动与停止
  5. centos6.5搭建php网站,Centos6.5下搭建web环境(Apache+mysql+php+phpMyAdmin)
  6. C#中字符串保留双引号
  7. JPA一对多循环引用的解决
  8. 框架详解_Qt开发技术:QtCharts(一)QtCharts基本介绍以及图表框架详解
  9. app软件测试是否强制升级_这些测试方法对于任何软件都必须是强制性的
  10. Selector#wakeup()
  11. python多进程传递参数,python多进程数据传递
  12. 【C++笔记】变量和基本类型
  13. 你的手机浏览器不支持webgle_不支持n79频段5G手机不能买?OPPO Reno3全频覆盖消除后顾之忧...
  14. C++ Primer Plus学习(七)——函数简介
  15. Spark SQL案例:分组排行榜
  16. Selenium加速执行方法
  17. GUI 自动测试工具[2021清单]
  18. 自动驾驶技术(3)- 高精度地图解决自动驾驶的功能痛点
  19. 旧主机改NAS最终成功的过程
  20. 动态IP和静态IP地址

热门文章

  1. Boost.MultiIndex 使用 multi_index_container::ctor_args_list 的示例
  2. boost::mp11::mp_power_set相关用法的测试程序
  3. boost::interprocess::interprocess_condition用法的测试程序
  4. boost::hana::detail::wrong用法的测试程序
  5. boost::fusion::move用法的测试程序
  6. Boost:字符串的RLE压缩的测试程序
  7. ITK:计算图像的正向FFT
  8. DCMTK:类OFMap的测试程序
  9. OpenCV几何变换的实例(附完整代码)
  10. Qt Creator将应用程序部署到QNX Neutrino设备