Linux init机制

本文详细介绍了Linux内核的initcall机制,包括驱动程序的初始化、initcall的源码分析以及函数调用流程。通过使用xxx_initcall()宏,驱动开发者可以将初始化函数添加到内核启动时执行的队列中,按照优先级进行调用。在启动过程中,do_initcalls()函数负责执行这些初始化函数,确保驱动按顺序正确启动。
摘要由CSDN通过智能技术生成

一、init机制

我们都知道,linux对驱动程序提供静态编译进内核和动态加载两种方式,当我们试图将一个驱动程序编译进内核时,开发者通常提供一个xxx_init()函数接口以启动这个驱动程序同时提供某些服务。那么,根据常识来说,这个xxx_init()函数肯定是要在系统启动的某个时候被调用,才能启动这个驱动程序。最简单直观地做法就是:开发者试图添加一个驱动程序时,在内核启动init程序的某个地方直接添加调用自己驱动程序的xxx_init()函数,在内核启动时自然会调用到这个程序。但是,回头一想,这种做法在单人开发的小系统中或许可以,但是在linux中,如果驱动程序是这么个添加法,那就是一场灾难,这个道理我想不用我多说。不难想到另一种方式,就是集中提供一个地方,如果你要添加你的驱动程序,你就将你的初始化函数在这个地方进行添加,在内核启动的时候统一扫描这个地方,再执行这一部分的所有被 添加的驱动程序。那到底怎么添加呢?直接在C文件中作一个列表,在里面添加初始化函数?我想随着驱动程序数量的增加,这个列表会让人头昏眼花。当然,对于Linux大神而言,这些都不是事,Linux的做法是:底层实现上,在内核镜像文件中,自定义一个段,这个段里面专门用来存放这些初始化函数的地址,内核启动时,只需要在这个段地址处取出函数指针,一个个执行即可。对上层而言,linux内核提供xxx_init(init_func)宏定义接口,驱动开发者只需要将驱动程序的init_func使用xxx_init()来修饰,这个函数就被自动添加到了上述的段中,开发者完全不需要关心实现细节。对于各种各样的驱动而言,可能存在一定的依赖关系,需要遵循先后顺序来进行初始化,考虑到这个,linux也对这一部分做了分级处理。

二、initcall的源码

/*Only for built-in code, not modules.*/

#define early_initcall(fn)      __define_initcall(fn, early)

#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_init
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值