对于静态加载的驱动,内核定义了诸如early_initcall、pure_initcall、core_initcall 等众多宏。就拿 core_initcall 来说,它背后其实是 __define_initcall 宏在发挥关键作用。展开来看,__define_initcall(fn, 1)(这里以 core_initcall 的参数 1 为例),经过层层解析,就像是一场奇妙的 “魔术表演”:先是定义了一个...
xxx_initcall的定义位于include/linux/init.h中,从这个文件的名字也可以看出xxx_initcall是针对初始化操作的。 #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...
其实开启DEBUG宏的方法很简单,在需要pr_debug/dev_dbg输出的模块开头,直接#define DEBUG即可,kernel中有一个例子: /* init/main.c */ #define DEBUG /* Enable initcall_debug */ 不过这种方法有个缺点:我们必须准确的知道需要debug那个C文件,如果想大网撒鱼(例如,想debug为什么新修改的DTS文件没有起作用,而又...
这样做的目的是在内核kmsg中记录每个initcall的calling和initcall时间,本工具分析依赖于这些kmsg。 [ ](javascript:void(0); "复制代码") staticint__init_or_moduledo_one_initcall_debug(initcall_tfn){ktime_tcalltime, delta, rettime;unsignedlonglongduration;intret;printk(KERN_DEBUG"calling %pF @ %i\n...
lichee\linux-3.10\arch\arm64\kernel\early_printk.c 2、initcall_debug initcall_debug参数定位初始化过程中的错误信息发生的位置。 3、内核打印 Linux内核用函数printk打印调试信息,该函数的用法与C库打印函数printf格式类似,但在内核使用。用户可在内核代码中的某位置加入函数printk,直接把所关心的信息打打印到屏幕...
1.1.1 打开initcall_debug bool initcall_debug = true; 这样做的目的是在内核kmsg中记录每个initcall的calling和initcall时间,本工具分析依赖于这些kmsg。 static int __init_or_module do_one_initcall_debug(initcall_t fn) { ktime_t calltime, delta, rettime; unsigned long long duration; int ret; pr...
如使用initcall_debug可能需要在内核配置中使用CONFIG_LOG_BUF_SHIFT增加日志缓冲区的大小。还可能需要使能CONFIG_PRINTK_TIME和CONFIG_KALLSYMS。 1.2 使用内核启动图进行有目的的优化 使用initcall_debug可以生成启动图,从而轻松查看哪些内核初始化函数需要最多时间来执行。
但 Linux 系统如此庞大复杂,驱动数量众多,要是每添加一个驱动,都得去改动 kernel_init() 代码,那简直就是一场 “灾难”。一方面,这极易引入人为错误,稍有不慎就可能导致系统启动故障;另一方面,代码的可维护性会变得极差,后续排查问题、升级驱动都会让人头疼不已。
Linux 内核启动流程之 start_kernel 上次我们写过了Linux启动详细流程,这次单独解析 start_kernel 函数。 如下请参考注释: Linux kernel-6.1/init/main.c asmlinkage __visiblevoid __init __no_sanitize_address start_kernel(void) { char *command_line;...
三、进阶 | Linux 内核概念(2):initcall initcall 机制 介绍 就像你从标题所理解的,这部分将涉及 Linux 内核中有趣且重要的概念,称之为initcall。在 Linux 内核中,我们可以看到类似这样的定义: early_param("debug", debug_kernel); 或者 arch_initcall(init_pit_clocksource);...