内核模块静态加载的顺序

Linux驱动先注册总线,总线上可以先挂device,也可以先挂driver,那么究竟怎么控制先后的顺序呢?
Linux系统使用两种方式去加载系统中的模块:动态和静态。
静态加载:将所有模块的程序编译到Linux内核中,由do_initcall函数加载

核心进程(/init/main.c)kernel_init do_basic_setup() do_initcalls()该函数中会将在__initcall_start和__initcall_end之间定义的各个模块依次加载。

/arch/powerpc/kernel/vmlinux.lds文件,找到.initcall.init段:

.initcall.init : {__initcall_start = .;*(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init)__initcall_end = .;}

可以看出在这两个宏之间依次排列了14个等级的宏,由于这其中的宏是按先后顺序链接的,所以也就表示,这14个宏有优先级:0>1>1s>2>2s………>7>7s。

#define pure_initcall(fn)              __define_initcall("0",fn,0)
#define core_initcall(fn)              __define_initcall("1",fn,1)
#define core_initcall_sync(fn)           __define_initcall("1s",fn,1s)
#define postcore_initcall(fn)              __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn)    __define_initcall("2s",fn,2s)
#define arch_initcall(fn)        __define_initcall("3",fn,3)
#define arch_initcall_sync(fn)            __define_initcall("3s",fn,3s)
#define subsys_initcall(fn)          __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn)       __define_initcall("4s",fn,4s)
#define fs_initcall(fn)                   __define_initcall("5",fn,5)
#define fs_initcall_sync(fn)         __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn)            __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn)          __define_initcall("6",fn,6)
#define device_initcall_sync(fn)       __define_initcall("6s",fn,6s)
#define late_initcall(fn)         __define_initcall("7",fn,7)
#define late_initcall_sync(fn)             __define_initcall("7s",fn,7s)
module_init(fbtft_driver_module_init);
#define module_init(x)  __initcall(x);
#define __initcall(fn) device_initcall(fn)
//我们平时用的module_init在静态编译时就相当于device_initcall。

可以在最新的代码版本查看 device_initcall 等的定义

举个例子,在2.6.24的内核中:
gianfar_device使用的是arch_initcall,而gianfar_driver使用的是module_init,
因为arch_initcall的优先级大于module_init,所以gianfar设备驱动的device先于driver在总线上添加。

驱动模块之间的加载顺序:
查看System.map里的链接顺序,静态加载的模块命名为__initcall_xxx_init6:

c0949ba4 t __initcall_hid_init6
c0949ba8 t __initcall_fbtft_driver_module_init6
c0949bac t __initcall_flexfb_init6
c0949bb0 t __initcall_extcon_class_init6

这里链接的顺序,即是initcall list里调用的顺序。
而链接的顺序和Makefile里的顺序有关。
比如fbtft的Makefile中, fbtft 就排在 flexfb的前面。

Linux内核模块静态加载的顺序相关推荐

  1. Linux内核模块自动加载机制 .

    标题http://www.osplay.org/modules/article/view.article.php?7 思考 如果想让内核启动过程中自动加载某个模块该怎么做呢?最容易想到的方法就是到/e ...

  2. linux sata驱动加载硬盘顺序,linux安装前必备知识

    一.学习linux必备条件 1.计算器概论与硬件相关知识 2.先从linux的安装与指令学起 3.linux操作系统的基础技能:包含了使用者,群组的概念,权限概念,程序的定义,龙其权限概念,由于不同的 ...

  3. 【Linux 内核】宏内核与微内核架构 ( 操作系统需要满足的要素 | 宏内核 | 微内核 | Linux 内核动态加载机制 )

    文章目录 一.操作系统需要满足的要素 二.宏内核 三.微内核 四.Linux 内核动态加载机制 一.操作系统需要满足的要素 电脑上运行的 操作系统 , 是一个 软件 ; 设备管理 : 操作系统需要 为 ...

  4. [Linux] 动态库加载顺序

    可以看看这篇文章:linux 动态链接库的加载顺序 编译程序时链接 so 库顺序如下: gcc 编译时参数 -L 指定的路径 gcc -o demux demuxing_decoding.c -L / ...

  5. Linux动态库的动态加载与静态加载以及加载依赖了其他动态库的动态库

    Linux动态库加载 在Linux下,动态库格式一般为libxxx.so或者libxxx.so.3这种格式. 通常我们在网上下载下来源码包,编译之后会是libxxx.so软连接libxxx.so.1链 ...

  6. linux path环境变量检索目录,Linux下动态链接库加载路径及搜索路径问题

    引子 近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: "error while loading shared libraries" 这是 ...

  7. 动态加载和静态加载及其编译步骤

    在类unix操作系统中,驱动加载方式一般分为:动态加载和静态加载,下面分别对其详细论述. 一.动态加载 动态加载是将驱动模块加载到内核中,而不能放入/lib/modules/下.     在2.4内核 ...

  8. linux ipv6模块,有关Linux ipv6模块加载失败的问题

    有关Linux ipv6模块加载失败的问题 同事一个SUSE11sp3环境配置ipv6地址失败,提示不支持IPv6,请求帮助,第一反应是应该ipv6相关内核模块没有加载. 主要检查内容: ipv6地址 ...

  9. 软件库Library之静态库\动态库和静态加载\动态加载

    软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...

  10. Openvswitch原理与代码分析(3): openvswitch内核模块的加载

    上一节我们讲了ovs-vswitchd,其中虚拟网桥初始化的时候,对调用内核模块来添加虚拟网卡. 我们从openvswitch内核模块的加载过程,来看这个过程. 在datapath/datapath. ...

最新文章

  1. 提升深度学习模型性能及网络调参
  2. Java Review - 并发编程_抽象同步队列AQS
  3. 聊聊springboot2的embeded container的配置改动
  4. python获取方法的装饰方法_python中的方法和装饰器
  5. 作者:​惠丹(1991-),男,兰州大学资源环境学院硕士生。
  6. 傲游浏览器linux傲游源,Ubuntu下安装遨游浏览器
  7. window.location.href重定向 不会触发webview
  8. oracle包同义词报错,Oracle——04同义词与数据库链接
  9. case when then else end 用法
  10. Java正则表达式实例详解
  11. Salesforce新增Einstein AI支撑的自动化功能
  12. Delphi中Format与FormatDateTime函数详解
  13. iOS内存管理学习笔记二
  14. android 代码混淆原理,Android 代码混淆
  15. python对excel数据分析常用功能(一文学会如何用Python实现excel基础功能)
  16. 电视信号服务器,基于Web服务器远程控制数字电视信号节目源再利用系统
  17. python通配符_Python通配符一览
  18. 医疗人工智能与未来医院信息化建设
  19. android第三方浏览器存在泄露用户隐私漏洞
  20. 2018年第九届蓝桥杯真题解析 | 日志统计【Python】

热门文章

  1. [原]Linux 命令行浏览器
  2. php’s explode() 函数
  3. 输入字符串按照单词逆序输出
  4. mysql8.0.15源码linux_源码安装mysql8.0.20
  5. path和classpath的用途
  6. 游戏迷看过来 年末促销买个华为平板 M3可畅玩
  7. JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)
  8. Java程序员从笨鸟到菜鸟之(五十)细谈Hibernate(一)hibernate基本概念和体系结构...
  9. cmd启动某个server卡住解决办法
  10. win10下Linux子系统开启ssh服务