0

I'm targeting an embedded Linux 2.6.35.3 for a Freescale iMX53 Arm CPU board.

I need to change when all the various CAN bus related drivers (FlexCAN) get initialized and ready for use during the kernel boot process. I need the CAN bus to be initialized much sooner then it currently is so that I can send out some specific CAN raw messages a lot sooner before the user-space is ready for scripts to do the job.

How does one control WHEN the compiled (built-in) kernel modules/drivers get probed internally by the kernel during its boot up and init sequence.

I'm not talking about file system level .ko files that can be mod-probed in scripts.. this is way before that.

Sorry for my poorly formatted linux question.. i don't work in kernel space very often.. trying hack my way through this as fast as possible.

1 Answers1

1

initcall ordering is defined here:

http://lxr.free-electrons.com/source/include/linux/init.h#L194

which is, for reference:

/*
 * 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)

As module_init is #defined to be device_initcall, a general module with nothing dependent on it gets initialized towards the end of the sequence. To load your module early, you simply change its module_init call to something else that occurs earlier (like subsys_initcall, for example)

Note: just switching the order on things can break other dependencies, and you can get in a catch-22 dependency loop from hell.

Brian
  • 2,172
  • 14
  • 24
  • 1
    It's not a full picture anyway. We have two stages: module initialized, driver is probed. For the second one driver's `->probe()` will be called when device appears **and** module has been initialized. In the case of dependencies the `->probe()` may fail with -EPROBE_DEFER that allows to be re-probed later. Moreover there is an asynchronous mechanism for deferred probe nowadays. – 0andriy Nov 06 '15 at 13:04