In the Linux kernel startup and debugging process,initcall_debug
and ignore-loglevel
are key startup parameters that allow for deep tracking of the initialization process and log output. The following example is based on the 6.8 kernel used in the RUBIK Pi 3 Ubuntu/Debian system.
initcall_debug
After this parameter is enabled, the kernel will output execution details of all initialization functions and driver probe
functions, including function return values, execution time, and process IDs, which is essential for pinpointing boot delays or initialization failures. Check the following example:
[ 7.042579] probe of 100000000.gpio-regulator returned -517 after 0 usecs
[ 7.042587] probe of 0.gpio-regulator returned -517 after 0 usecs
[ 7.042702] calling gpio_regulator_init+0x0/0x50 @ 1
[ 7.042799] initcall gpio_regulator_init+0x0/0x50 returned 0 after 1000 usecs
Enable initcall_debug
:
- Modify the /etc/default/grub configuration file on the target board by adding the
initcall_debug
parameter to theGRUB_CMDLINE_LINUX
variable, as shown below:
GRUB_CMDLINE_LINUX="root=LABEL=writable rw console=ttyMSM0,115200n8 pcie_pme=nomsi earlycon ignore_loglevel initcall_debug"
- Execute the following commands to update the
grub
configuration. The changes apply after a reboot. If you want the kernel debug messages to be printed via the serial port during boot, add theignore_loglevel
parameter to theGRUB_CMDLINE_LINUX
variable:
sudo update-grub
sudo reboot
Alternatively, during boot, press the e
key in the GRUB menu to boot the kernel with modified boot parameters.
Source code analysis:
init/main.c
bool initcall_debug;
core_param(initcall_debug, initcall_debug, bool, 0644);
If initcall_debug
is defined in the kernel startup parameters, the initcall_debug
variable will be set to true
. In the start_kernel
function, initcall_debug_enable
will be called.
Finally, the execution parameters of the initialization functions are printed through the functions trace_initcall_start_cb
and trace_initcall_finish_cb
, as shown below:
void start_kernel(void)
{
...
if (initcall_debug)
initcall_debug_enable();
...
}
static void __init initcall_debug_enable(void)
{
int ret;
ret = register_trace_initcall_start(trace_initcall_start_cb,
&initcall_calltime);
ret |= register_trace_initcall_finish(trace_initcall_finish_cb,
&initcall_calltime);
WARN(ret, "Failed to register initcall tracepoints\n");
}
static __init_or_module void
trace_initcall_start_cb(void *data, initcall_t fn)
{
ktime_t *calltime = data;
printk(KERN_DEBUG "calling %pS @ %i\n", fn, task_pid_nr(current));
*calltime = ktime_get();
}
static __init_or_module void
trace_initcall_finish_cb(void *data, initcall_t fn, int ret)
{
ktime_t rettime, *calltime = data;
rettime = ktime_get();
printk(KERN_DEBUG "initcall %pS returned %d after %lld usecs\n",
fn, ret, (unsigned long long)ktime_us_delta(rettime, *calltime));
}
The information printing for the probe function is handled through the __driver_probe_device
function, which checks the initcall_debug
variable to determine whether to call the really_probe
or really_probe_debug
function:
drivers/base/dd.c
static int __driver_probe_device(struct device_driver *drv, struct device *dev)
{
...
if (initcall_debug)
ret = really_probe_debug(dev, drv);
else
ret = really_probe(dev, drv);
...
}
ignore_loglevel
This parameter is used to forcibly output kernel logs at all levels in the terminal to avoid the loss of debugging information due to log level filtering. It is suitable for troubleshooting problems during early startup.
Enable ignore_loglevel
:
- Modify the /etc/default/grub configuration file on the target board by adding the
ignore_loglevel
parameter to theGRUB_CMDLINE_LINUX
variable, as shown below:
GRUB_CMDLINE_LINUX="root=LABEL=writable rw console=ttyMSM0,115200n8 pcie_pme=nomsi earlycon ignore_loglevel initcall_debug"
- Execute the following commands to update the
grub
configuration. The changes apply after a reboot.
sudo update-grub
sudo reboot
Alternatively, during boot, press the e
key in the GRUB menu to boot the kernel with modified boot parameters.
Source code analysis:
kernel/printk/printk.c
static bool __read_mostly ignore_loglevel;
static int __init ignore_loglevel_setup(char *str)
{
ignore_loglevel = true;
pr_info("debug: ignoring loglevel setting.\n");
return 0;
}
early_param("ignore_loglevel", ignore_loglevel_setup);
module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ignore_loglevel,
"ignore loglevel setting (prints all kernel messages to the console)");
static bool suppress_message_printing(int level)
{
return (level >= console_loglevel && !ignore_loglevel);
}
After adding ignore_loglevel
to the startup parameters, it can be found in the above code that the ignore_loglevel
variable is set to true
, and the suppress_message_printing
function will always return false
, indicating that the log printing is not disabled.
Additionally, after booting up, you can set the ignore-loglevel
parameter at any time through the /sys/module/printk/parameters/ignore_loglevel node:
cat /sys/module/printk/parameters/ignore_loglevel # View the current status
echo 1 > /sys/module/printk/parameters/ignore_loglevel # Set to true
echo 0 > /sys/module/printk/parameters/ignore_loglevel # Set to false
For more kernel parameters, check the Documentation/admin-guide/kernel-parameters.txt file in the kernel source code.
2025-06-30T16:00:00Z
Original post: [linux 技术分享][启动调试][initcall_debug 与 ignore_loglevel] - 技术分享 - RUBIK Pi by Hongyang Zhao