How to Get Details of All Modules/Drivers That Were Initialized/Probed During the Linux Kernel Boot

How to get details of all modules / drivers that were initialized / probed during the Linux kernel boot?

Passing the option "initcall_debug" on the kernel command line will cause timing information to be printed to the console for each init routine of built-in drivers. The initcalls are used to initialize statically linked kernel drivers and subsystems and contribute a significant amount of time to the Linux boot process. (Loadable modules are not available until after the root filesystem has been mounted.)

The output looks like:

calling  tty_class_init+0x0/0x44 @ 1
initcall tty_class_init+0x0/0x44 returned 0 after 9765 usecs
calling spi_init+0x0/0x90 @ 1
initcall spi_init+0x0/0x90 returned 0 after 9765 usecs

Reference: http://elinux.org/Initcall_Debug

Addendum

Specifying the kernel parameter "ignore_loglevel" along with the "initcall_debug" will ensure that the information will be displayed during boot.

Change the order that built in kernel drivers get initialized?

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.

Linux Kernel Module never reaches - probe() functions

I got it working. Removing the status="enabled" with status = "okay" fixed it.
The problem was, I had an earlier version of the OVerlay copied into /boot/overlay and in /boot/config/ my overlay was enabled. So, on every boot a false version of my overlay was loaded. But after removing the overlay from /boot/overlay and from /boot/config it worked.
My result can be found here: https://github.com/Johannes4Linux/Linux_Driver_Tutorial/tree/main/20_dt_probe

Who calls the probe() of driver

Long story short: the probe() function of the driver is called as a result of calling the register_driver for that specific bus. More precisely, it's called by the probe() of that bus_type structure. In your case: i2c_bus_type.

Here's the call chain in your I2C case:

  • i2c_register_driver
  • driver_register
  • bus_add_driver
  • driver_attach
  • __driver_attach (for your device)
  • driver_probe_device
  • really_probe
  • i2c_device_probe (this is what dev->bus->probe is for an i2c driver)
  • your_probe_function

init function invocation of drivers compiled into kernel

The init routine of a built-in driver can still use the module_init() macro to declare that entry point. Or the driver can use device_initcall() when the driver would never be compiled as a loadable module. Or to move its initialization very early in the boot sequence, the driver could use subsys_initcall().

In include/linux/init.h the sequence for invoking these init routines is described as:

/* initcalls are now grouped by functionality into separate 
* subsections. Ordering inside the subsections is determined
* by link order.
* For backwards compatibility, initcall() puts the call in
* the device init subsection.
*
* The `id' arg to __define_initcall() is needed so that multiple initcalls
* can point at the same handler without causing duplicate-symbol build errors.
*/

I assume that these subsections for device drivers correspond to the subdirectories within the drivers directory of the Linux kernel source tree, and that the link order is recorded in the built-in.o file of each subdirectory in drivers. So during kernel boot the init routine of each built-in driver is eventually executed by do_initcalls() in init/main.c.

The init routine of the device driver is responsible for probing the system to verify that the HW device actually exists. The driver should not allocate any resources or register any devices when the probe fails.

UPDATE:

Passing the option "initcall_debug" on the kernel command line will cause timing information to be printed to the console for each initcall. initcalls are used to initialize statically linked kernel drivers and subsystems and contribute a significant amount of time to the Linux boot process. The output looks like:

calling  tty_class_init+0x0/0x44 @ 1
initcall tty_class_init+0x0/0x44 returned 0 after 9765 usecs
calling spi_init+0x0/0x90 @ 1
initcall spi_init+0x0/0x90 returned 0 after 9765 usecs

Reference: http://elinux.org/Initcall_Debug

Why is pr_debug of the Linux kernel not giving any output?

Add following to Makefile, assuming filename.c is the module source file.

CFLAGS_filename.o := -DDEBUG

not

CFLAGS_[filename].o := -DDEBUG

Refer https://www.kernel.org/doc/local/pr_debug.txt

When does the probe function for a Linux kernel driver gets called?

Found the answer after some research, For a "platform" device the probe function is invoked when a platform device is registered and it's device name matchs the name specified on the device driver.

More details here:
http://comments.gmane.org/gmane.linux.kernel.kernelnewbies/37050

Now I just need to figure why the device is not being registered :\



Related Topics



Leave a reply



Submit