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
Command Not Found in Bash's If-Else Condition When Using [! -D "$Dir"]
Linux:How to Set Default Route from C
Extending a Script to Loop Over Multiple Files and Generate Output Names
How to List One Filename Per Output Line in Linux
How to Mount One Partition from an Image File That Contains Multiple Partitions on Linux
Shell Script Current Directory
Is There a Good Way to Detect a Stale Nfs Mount
How to Find Substring Inside a String (Or How to Grep a Variable)
Using Linux, How to Specify Which Ethernet Interface Data Is Transmitted On
Changing Default Shell in Linux
Execute Command Line and Return Command Output
How to Set a Variable Used in a Perl Script as Environment Variable
Why Do My Results Different Following Along the Tiny Asm Example
Redirecting Tcp-Traffic to a Unix Domain Socket Under Linux