kernel的console_init和printk

来源:互联网 发布:贷款软件哪个最快 编辑:程序博客网 时间:2024/05/21 14:08

linux kernel在start_kernel里面调用console_init执行控制台的初始化。使用printk执行打印。

但是在console_init之前有一部分printk。需要在console_init之后才能打印出来,也就是说之前prinkt的数据都保存在了一个缓冲区内,等到console_init以后才打印出来。


console_init的执行流程在/drivers/tty的tty_io.c里面

void __init console_init(void){initcall_t *call;/* Setup the default TTY line discipline. */tty_ldisc_begin();/* * set up the console device so that later boot sequences can * inform about problems etc.. */call = __con_initcall_start;while (call < __con_initcall_end) {(*call)();call++;}}

tty_ldisc_begin()暂时先不看。直接看后面注册函数的调用。

也就是从 __con_initcall_start到__con_initcall_end的函数都会被调用执行。

在linux/init.h里面有

#define console_initcall(fn) \static initcall_t __initcall_##fn \__used __section(.con_initcall.init) = fn

通过 console_initcall(fn)定义的fn函数都会被放到.con_initcall.init段里面。这个段的开始是__con_initcall_start,结束是__con_initcall_end

我的树莓派里面定义了一个函数在drivers\tty\serial\8250\8250_core.c里面

console_initcall(univ8250_console_init);

所以console_init就会调用univ8250_console_init。

static int __init univ8250_console_init(void){serial8250_isa_init_ports();register_console(&univ8250_console);return 0;}console_initcall(univ8250_console_init);
univ8250_console_init首先初始化了ports然后调用register_console注册了这个univ8250_console设备

在kernel/printk/printk.c中有register_console函数


register_console 将这个设备注册到console_drivers里面。后面printk->vprintk_emit->console_unlock->call_console_drivers->con->write(con, text, len);实现了输出

0 0
原创粉丝点击