kernel启动过程中的调试打印

来源:互联网 发布:俄罗斯 共青城 知乎 编辑:程序博客网 时间:2024/06/05 16:36

内核启动过程中涉及到多个地方,启动过程的代码由汇编代码和C代码组成。其中的打印函数也有多个。
1. 汇编阶段
打印函数包括如下几种:
printascii
printch
printhex8
printhex4
printhex2

这些函数定义在kernel/arch/arm/kernel/debug.S中,需要在make menuconfig中使能Kernel low-level debugging functions 才会这些内容编译进内核。

2. C语言阶段启动初期
在linux系统启动的初级阶段,”真正的”console驱动还没有加载进kernel,但是此时需要打印信息来调试内核,那么就需要使用early printk来调试,它的实现包括两部分,一个是early_printk的api,另一个对应的bootconsole驱动。
(1)early_printk函数是在kernel/kernel/printk.c文件中实现的
(2)bootconsole驱动一般属于平台相关,是在kernel/arch/arm/kernel/early_printk.c文件中实现

想要使用early_printk模块,还需要在make menuconfig中使能Early printk才会编译进内核。实际上在early_printk.c中对于bootconsole驱动的实现,也是调用到了前面汇编阶段所实现的代码printch的,也就是说最终打印所调用的底层函数都是汇编中的实现。那么就有一种依赖关系,具体的Makefile和Kconfig如下所示:

kernel/arch/arm/kernel/Makefileobj-$(CONFIG_DEBUG_LL)  += debug.oobj-$(CONFIG_EARLY_PRINTK)  += early_printk.oKernel/arch/arm/Kconfig.debugconfig DEBUG_LL      bool "Kernel low-level debugging functions "      depends on DEBUG_KERNELconfig EARLY_PRINTK     bool "Early printk"     depends on DEBUG_LL

可以看出EARLY_PRINTK是依赖于DEBUG_LL的,也就是说要使能early_printk,必须也要使能DEBUG_LL才行。
在early_printk.c中:

static int __init setup_early_printk(char *buf){    printk("%s enter\n", __func__);    register_console(&early_console);    return 0;}early_param("earlyprintk", setup_early_printk);

虽然内核配置了,但是要让内核调用setup_early_printk还必须在u-boot给内核传参的时候给bootargs在加上一个参数”earlyprintk”,比如:

set bootargs ‘console=ttyS5,115200,115200n8 androidboot.console=ttySAC0 uhost0=n ctp=2 skipcali=y vmalloc=384m lcd=S70 **earlyprintk**’

3. C语言启动后期
这是在真正的consolo驱动加载以后,此时就不再使用debug.S中的打印实现了,而是另外实现了一个linux标准tty驱动来作为printk的输出,这个也就是我们常用的pirntk了。

所以说当kernel启动不了,但又没有什么提示消息时,可以打开early printk查看。

因为在内核刚启动时,有些打印语句可能在串口还没有注册之前就调用了,那就不能显示了,early printk就是实现这个功能。
选上以下内核配置就可以了:
Kernel hacking —> Kernel low-level debugging functions –> Early printk
比如内核打印如下:
Starting kernel …

Uncompressing Linux… done, booting the kernel.
接着就什么都没了,这时候把early printk选上,果然看到kernel刚启动的信息了。

0 0
原创粉丝点击