Linux驱动-late_initcall
一 init的初始化内存分布
vmlinux.lds文件用来决定初始化所用的内存分布
内存的分布可以用下图来说明:
__init用来标示的是初始化函数,在初始化后不会再调用
__initdata是初始化数据
__initparam是初始化参数,其他7个初始化宏就是初始化函数会用到的。
所有标示为__init的函数都会在链接的时候都会放在.init.text中,放的顺序是不确定的与编译、链接顺序有关。
同时所有__init函数都会在.initcallx.init中放一个函数指针,初始化的时候照.initcall1.init->.initcall7.init的顺序初始化,.initcallx.init有不同的别名,在init.h中定义
二 late_initcall的定义
在include\linux\init.h 可以看到 late_initcall 的定义,是放在了 .initcall7.init中,即第7段。
而常言的 module_init 是定义为了 device_initcall,即放在了第6个段中。
__define_initcall 在这里就不展开了,详情可以看:
https://blog.csdn.net/weixin_47491758/article/details/131139872?spm=1001.2014.3001.5501
三 late_initcall 和 module_init 的区别
前面有提到,module_init 的放在于第6个段执行,
而 late_initcall 是放在第7个段执行,
所以 late_initcall 的优先级最低,是最后执行的。
这里就涉及到了设备之间的依赖关系。
个人认为,使用 late_initcall 可以保证具有依赖关系的设备,可以先等依赖设备先加载好,再去加载该设备。
例如B设备的加载要依赖A设备,可以让A设备用 module_init加载,B设备使用late_initcall 加载。
四 参考
https://blog.csdn.net/Ivan804638781/article/details/88419376
https://blog.csdn.net/qq_39491794/article/details/80412630