前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux的Initcall机制之初始化函数被调用的时机

Linux的Initcall机制之初始化函数被调用的时机

作者头像
灯珑LoGin
发布2023-12-30 08:03:44
3330
发布2023-12-30 08:03:44
举报
文章被收录于专栏:龙进的专栏

什么是Linux的initcall

Linux的initcall是一种初始化调用的机制,它在Linux内核启动过程中用于执行一系列的初始化任务。initcall机制向Linux内核注册了多组回调函数,这些函数在系统初始化时按照预定的顺序被调用。initcall的主要目的是对设备、内核子系统等进行初始化,以确保系统能够正常运行。

在Linux内核中,initcall机制分为8个等级,从0到7。等级越低,优先级越高,执行顺序越早。其中,early、rootfs等特殊等级用于表示在不同阶段的初始化任务。内核提供了相应的宏来注册不同等级的initcall函数,这些宏位于include/linux/init.h文件中。

我们常见的module_init()、subsys_init()宏,都是负责把函数加入到initcall初始化列表中。

在哪里定义的这些宏?

定义的地方在 include/linux/init.h

代码语言:javascript
复制
/*
 * Early initcalls run before initializing SMP.
 *
 * Only for built-in code, not modules.
 */
#define early_initcall(fn)		__define_initcall(fn, early)

/*
 * A "pure" initcall has no dependencies on anything else, and purely
 * initializes variables that couldn't be statically initialized.
 *
 * This only exists for built-in code, not for modules.
 * Keep main.c:initcall_level_names[] in sync.
 */
#define pure_initcall(fn)		__define_initcall(fn, 0)

#define core_initcall(fn)		__define_initcall(fn, 1)
#define core_initcall_sync(fn)		__define_initcall(fn, 1s)
#define postcore_initcall(fn)		__define_initcall(fn, 2)
#define postcore_initcall_sync(fn)	__define_initcall(fn, 2s)
#define arch_initcall(fn)		__define_initcall(fn, 3)
#define arch_initcall_sync(fn)		__define_initcall(fn, 3s)
#define subsys_initcall(fn)		__define_initcall(fn, 4)
#define subsys_initcall_sync(fn)	__define_initcall(fn, 4s)
#define fs_initcall(fn)			__define_initcall(fn, 5)
#define fs_initcall_sync(fn)		__define_initcall(fn, 5s)
#define rootfs_initcall(fn)		__define_initcall(fn, rootfs)
#define device_initcall(fn)		__define_initcall(fn, 6)
#define device_initcall_sync(fn)	__define_initcall(fn, 6s)
#define late_initcall(fn)		__define_initcall(fn, 7)
#define late_initcall_sync(fn)		__define_initcall(fn, 7s)

#define __initcall(fn) device_initcall(fn)

#define __exitcall(fn)						\
	static exitcall_t __exitcall_##fn __exit_call = fn

#define console_initcall(fn)	___define_initcall(fn, con, .con_initcall)

怎么调用这些initcall的?

在Linux 6.1.9中,initcall是这样被调用的:

代码语言:javascript
复制
start_kernel()->arch_call_rest_init()->rest_init()---创建新的内核线程执行-->kernel_init()->kernel_init_freeable()->do_basic_setup()->do_initcalls()

接着在do_initcalls函数中,按照优先级,依次执行各个Level的initcall。同一个level内的执行顺序跟链接顺序有关。

转载请注明来源:https://longjin666.cn/?p=1804

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023年12月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是Linux的initcall
  • 在哪里定义的这些宏?
  • 怎么调用这些initcall的?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档